mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-11 03:17:40 +03:00
Compare commits
32 Commits
feature/h2
...
feat/plugi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18388ffb6d | ||
|
|
05fa7ee56d | ||
|
|
fb2c0ef237 | ||
|
|
9a6b861ce3 | ||
|
|
e6008c0883 | ||
|
|
cfe3673b22 | ||
|
|
8ddb4db0de | ||
|
|
bc21551185 | ||
|
|
ee7339b64b | ||
|
|
a11e442f1d | ||
|
|
714fe54f77 | ||
|
|
b724cb6631 | ||
|
|
5d8aa9610a | ||
|
|
383969d456 | ||
|
|
f47eee24d3 | ||
|
|
4e26e7233e | ||
|
|
43bc76d9a9 | ||
|
|
e4566d32be | ||
|
|
0918f9319c | ||
|
|
da04681289 | ||
|
|
32756f0402 | ||
|
|
6c89dd4e50 | ||
|
|
c00d284786 | ||
|
|
c334d05214 | ||
|
|
6fd1176661 | ||
|
|
e3c6ec309d | ||
|
|
ba41b54c4b | ||
|
|
3668b01721 | ||
|
|
db8e03dbc7 | ||
|
|
e5fd028caa | ||
|
|
25b29c0b53 | ||
|
|
ecddf3d18f |
93
.github/workflows/build_all.yml
vendored
93
.github/workflows/build_all.yml
vendored
@@ -122,73 +122,54 @@ jobs:
|
||||
arch: universal
|
||||
macos-combine-only: true
|
||||
secrets: inherit
|
||||
# One test job per built arch, on the runner that built it.
|
||||
unit_tests_linux_x86_64:
|
||||
name: Linux x86_64
|
||||
unit_tests:
|
||||
name: Unit Tests
|
||||
# Tests are built on the aarch64 leg by default (faster GitHub arm runner),
|
||||
# so run them there; self-hosted builds them on the amd64 server instead.
|
||||
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }}
|
||||
needs: build_linux
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
|
||||
artifact: ${{ github.sha }}-tests-linux-x86_64
|
||||
unit_tests_linux_aarch64:
|
||||
name: Linux aarch64
|
||||
needs: build_linux
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ubuntu-24.04-arm
|
||||
artifact: ${{ github.sha }}-tests-linux-aarch64
|
||||
unit_tests_windows_x64:
|
||||
name: Windows x64
|
||||
needs: build_windows
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-win-server' || 'windows-latest' }}
|
||||
artifact: ${{ github.sha }}-tests-windows-x64
|
||||
unit_tests_windows_arm64:
|
||||
name: Windows arm64
|
||||
needs: build_windows
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: windows-11-arm
|
||||
artifact: ${{ github.sha }}-tests-windows-arm64
|
||||
test-dir: build-arm64/tests
|
||||
unit_tests_macos_arm64:
|
||||
name: macOS arm64
|
||||
needs: build_macos_arch
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-macos-arm64' || 'macos-14' }}
|
||||
artifact: ${{ github.sha }}-tests-macos-arm64
|
||||
test-dir: build/arm64/tests
|
||||
publish_test_results:
|
||||
name: Publish Test Results
|
||||
needs: [unit_tests_linux_x86_64, unit_tests_linux_aarch64, unit_tests_windows_x64, unit_tests_windows_arm64, unit_tests_macos_arm64]
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Test Results
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
scripts
|
||||
tests
|
||||
- name: Apt-Install Dependencies
|
||||
if: ${{ !vars.SELF_HOSTED }}
|
||||
uses: ./.github/actions/apt-install-deps
|
||||
- name: Restore Test Artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: test-results-*
|
||||
path: test-results
|
||||
# Best-effort: a read-only token (e.g. fork PRs) can't write the check, so
|
||||
# don't let a publish failure fail the run. The test jobs gate correctness.
|
||||
name: ${{ github.sha }}-tests
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true # <--= Use the local cache (default is 'false').
|
||||
useCloudCache: true
|
||||
- name: Unpackage and Run Unit Tests
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
tar -xvf build_tests.tar
|
||||
scripts/run_unit_tests.sh
|
||||
- name: Upload Test Logs
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: unit-test-logs
|
||||
path: build/tests/**/*.log
|
||||
- name: Publish Test Results
|
||||
continue-on-error: true
|
||||
if: always()
|
||||
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||
with:
|
||||
files: "test-results/**/*.xml"
|
||||
- name: Delete Test Results
|
||||
files: "ctest_results.xml"
|
||||
- name: Delete Test Artifact
|
||||
if: success()
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: test-results-*
|
||||
failOnError: false
|
||||
name: ${{ github.sha }}-tests
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
container:
|
||||
|
||||
60
.github/workflows/build_orca.yml
vendored
60
.github/workflows/build_orca.yml
vendored
@@ -141,26 +141,8 @@ jobs:
|
||||
- name: Build slicer mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only
|
||||
working-directory: ${{ github.workspace }}
|
||||
# arm64 only: build the tests here; the unit_tests_macos job runs them.
|
||||
env:
|
||||
ORCA_TESTS_BUILD_ONLY: ${{ inputs.arch == 'arm64' && '1' || '' }}
|
||||
run: |
|
||||
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 ${{ inputs.arch == 'arm64' && '-T' || '' }}
|
||||
|
||||
- name: Pack unit tests mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar -cvf build_tests.tar build/arm64/tests
|
||||
|
||||
- name: Upload Test Artifact mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests-macos-arm64
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15
|
||||
|
||||
- name: Pack macOS app bundle ${{ inputs.arch }}
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only
|
||||
@@ -222,9 +204,14 @@ jobs:
|
||||
security list-keychain -d user -s $KEYCHAIN_PATH
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $P12_PASSWORD $KEYCHAIN_PATH
|
||||
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app
|
||||
# --deep is deprecated and signing/sealing can fail or skip files in
|
||||
# non-standard layouts (python/bin, python/lib/**, tools/uv). Verify
|
||||
# here so coverage gaps fail at CI time rather than at notarization.
|
||||
codesign --verify --deep --strict --verbose=2 ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app
|
||||
# Sign OrcaSlicer_profile_validator.app if it exists
|
||||
if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then
|
||||
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app
|
||||
codesign --verify --deep --strict --verbose=2 ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app
|
||||
fi
|
||||
|
||||
# Create main OrcaSlicer DMG without the profile validator helper
|
||||
@@ -353,28 +340,11 @@ jobs:
|
||||
# env:
|
||||
# WindowsSdkDir: 'C:\Program Files (x86)\Windows Kits\10\'
|
||||
# WindowsSDKVersion: '10.0.26100.0\'
|
||||
# "tests" builds the unit tests too; the unit_tests_windows_* jobs run them.
|
||||
run: |
|
||||
$arch = "${{ inputs.arch }}"
|
||||
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 tests } else { .\build_release_vs.bat slicer tests }
|
||||
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 } else { .\build_release_vs.bat slicer }
|
||||
shell: pwsh
|
||||
|
||||
- name: Pack unit tests Win
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ${{ github.workspace }}
|
||||
shell: pwsh
|
||||
run: tar -cvf build_tests.tar ${{ env.BUILD_DIR }}/tests
|
||||
|
||||
- name: Upload Test Artifact Win
|
||||
if: runner.os == 'Windows'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests-windows-${{ inputs.arch }}
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
# NSIS is x86-only; it runs (and the installer it emits runs) under ARM64's
|
||||
# x86 emulation, packaging the native arm64 payload from build-arm64.
|
||||
- name: Create installer Win
|
||||
@@ -487,22 +457,26 @@ jobs:
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
# Build + tar the unit tests (-t) on both Linux legs so each arch
|
||||
# (x86_64 + aarch64) gets tested by its own unit_tests_linux_* job.
|
||||
./build_linux.sh -istrlL
|
||||
# Build + tar the unit tests (-t) only on the leg that runs them: the
|
||||
# aarch64 leg by default (faster GitHub arm runner), or amd64 when using
|
||||
# self-hosted runners (no arm self-hosted server). unit_tests downloads
|
||||
# this tarball. The profile validator is built with -s, so amd64 keeps it.
|
||||
tests=${{ (!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64') }}
|
||||
if $tests; then flags=-istrlL; else flags=-isrlL; fi
|
||||
./build_linux.sh "$flags"
|
||||
./scripts/check_appimage_libs.sh ./build/package ./build/package/bin/orca-slicer
|
||||
appimage=./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
|
||||
mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage "$appimage"
|
||||
chmod +x "$appimage"
|
||||
tar -cvf build_tests.tar build/tests
|
||||
if $tests; then tar -cvpf build_tests.tar build/tests; fi
|
||||
|
||||
# Use tar because upload-artifacts won't always preserve directory structure
|
||||
# and doesn't preserve file permissions
|
||||
- name: Upload Test Artifact
|
||||
if: runner.os == 'Linux'
|
||||
if: runner.os == 'Linux' && ((!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64'))
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }}
|
||||
name: ${{ github.sha }}-tests
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
|
||||
29
.github/workflows/check_profiles.yml
vendored
29
.github/workflows/check_profiles.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
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 all system profiles.
|
||||
# validate profiles
|
||||
- name: validate system profiles
|
||||
id: validate_system
|
||||
continue-on-error: true
|
||||
@@ -57,6 +57,20 @@ jobs:
|
||||
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]}
|
||||
# Flag inherits/compatible_printers/compatible_prints references that point at a deleted or
|
||||
# renamed preset. Opt-in per vendor for now (via -r); enabled for BBL and Qidi until other
|
||||
# vendors' profiles are cleaned up. Runs before the custom-preset injection below.
|
||||
- name: validate preset references for BBL and Qidi profiles
|
||||
id: validate_preset_references
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set +e
|
||||
rc=0
|
||||
for v in BBL Qidi; do
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 -v "$v" -r 2>&1 | tee -a ${{ runner.temp }}/validate_preset_references.log
|
||||
[ ${PIPESTATUS[0]} -ne 0 ] && rc=1
|
||||
done
|
||||
exit $rc
|
||||
|
||||
- name: validate custom presets
|
||||
id: validate_custom
|
||||
@@ -166,7 +180,7 @@ jobs:
|
||||
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
||||
|
||||
- name: Prepare comment artifact
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_preset_references.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
{
|
||||
# Marker matched by check_profiles_comment.yml to delete prior comments.
|
||||
@@ -201,6 +215,15 @@ jobs:
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_preset_references.outcome }}" = "failure" ]; then
|
||||
echo "### BBL/Qidi Preset Reference Validation Failed"
|
||||
echo ""
|
||||
echo '```'
|
||||
head -c 30000 ${{ runner.temp }}/validate_preset_references.log || echo "No output captured"
|
||||
echo '```'
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_custom.outcome }}" = "failure" ]; then
|
||||
echo "### Custom Preset Validation Failed"
|
||||
echo ""
|
||||
@@ -223,7 +246,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: Fail if any check failed
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_preset_references.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
echo "One or more profile checks failed. See above for details."
|
||||
exit 1
|
||||
|
||||
2
.github/workflows/dedupe-issues.yml
vendored
2
.github/workflows/dedupe-issues.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
with:
|
||||
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
model: "claude-sonnet-4-5-20250929"
|
||||
claude_args: "--model claude-sonnet-4-5-20250929"
|
||||
claude_env: |
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
73
.github/workflows/unit_tests.yml
vendored
73
.github/workflows/unit_tests.yml
vendored
@@ -1,73 +0,0 @@
|
||||
name: Unit Tests
|
||||
|
||||
# Download a platform's test artifact, run ctest, and upload the JUnit
|
||||
# results for aggregation. Called once per arch from build_all.yml.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
artifact:
|
||||
description: Test artifact uploaded by the build leg
|
||||
required: true
|
||||
type: string
|
||||
test-dir:
|
||||
description: Built tests dir; defaults to build/tests, override for arch-separated builds
|
||||
required: false
|
||||
type: string
|
||||
default: build/tests
|
||||
|
||||
jobs:
|
||||
unit_tests:
|
||||
# Static "Unit Tests"; the per-arch label is the caller's job name, so the
|
||||
# graph shows e.g. "Windows x64 / Unit Tests".
|
||||
name: Unit Tests
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
# tests/data is referenced by absolute path (TEST_DATA_DIR).
|
||||
sparse-checkout: |
|
||||
.github
|
||||
scripts
|
||||
tests
|
||||
- name: Apt-Install Dependencies
|
||||
if: runner.os == 'Linux' && !vars.SELF_HOSTED
|
||||
uses: ./.github/actions/apt-install-deps
|
||||
- name: Restore Test Artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true
|
||||
useCloudCache: true
|
||||
- name: Unpackage and Run Unit Tests
|
||||
timeout-minutes: 20
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xvf build_tests.tar
|
||||
# Multi-config generators (Windows/macOS) need a config; Linux is single-config.
|
||||
scripts/run_unit_tests.sh "${{ inputs.test-dir }}" "${{ runner.os != 'Linux' && 'Release' || '' }}"
|
||||
- name: Upload Test Logs
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: unit-test-logs-${{ inputs.artifact }}
|
||||
path: ${{ inputs.test-dir }}/**/*.log
|
||||
- name: Upload Test Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: test-results-${{ inputs.artifact }}
|
||||
path: ctest_results.xml
|
||||
retention-days: 5
|
||||
if-no-files-found: warn
|
||||
- name: Delete Test Artifact
|
||||
if: success()
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
220
CMakeLists.txt
220
CMakeLists.txt
@@ -125,6 +125,131 @@ option(SLIC3R_PCH "Use precompiled headers" 1)
|
||||
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
||||
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||
|
||||
# Python stubgen module
|
||||
option(ORCA_BUILD_PYTHON_STUBGEN_MODULE "Build importable Python module for pybind11-stubgen" ON)
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE "" CACHE FILEPATH "Path to a uv executable to bundle for Python package installation. Leave empty to auto-download.")
|
||||
|
||||
# Auto-download uv if not provided by the user.
|
||||
# uv is pinned: the executable ships inside the signed app, so the build must
|
||||
# be reproducible and the download verified. To upgrade, bump ORCA_UV_VERSION
|
||||
# and refresh every hash below from the release's .sha256 assets, e.g.:
|
||||
# curl -sL https://github.com/astral-sh/uv/releases/download/<ver>/uv-<triple>.tar.gz.sha256
|
||||
set(ORCA_UV_VERSION "0.11.21")
|
||||
set(ORCA_UV_SHA256_aarch64-apple-darwin "1f921d491ba5ffeea774eb04d6681ecee379101341cbb1500394993b541bf3f4")
|
||||
set(ORCA_UV_SHA256_x86_64-apple-darwin "f3c8e5708a84b920c18b691214d54d2b0da6b984789caae95d47c95120cb7765")
|
||||
set(ORCA_UV_SHA256_aarch64-unknown-linux-gnu "88e800834007cc5efd4675f166eb2a51e7e3ad19876d85fa8805a6fb5c922397")
|
||||
set(ORCA_UV_SHA256_x86_64-unknown-linux-gnu "8c88519b0ef0af9801fcdee419bbb12116bd9e6b18e162ae093c932d8b264050")
|
||||
set(ORCA_UV_SHA256_x86_64-pc-windows-msvc "ace861f360c6de2babedc1607d0f454b6b09a820dbc8182dc15af927e4df9589")
|
||||
|
||||
# Version-scoped cache dir so a version bump invalidates the cached binary.
|
||||
set(ORCA_UV_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/.uv/${ORCA_UV_VERSION}")
|
||||
set(ORCA_UV_BINARY "${ORCA_UV_DOWNLOAD_DIR}/uv")
|
||||
if(WIN32)
|
||||
set(ORCA_UV_BINARY "${ORCA_UV_DOWNLOAD_DIR}/uv.exe")
|
||||
endif()
|
||||
|
||||
# Older configures FORCE-cached the auto-downloaded path; any cache entry
|
||||
# under .uv/ is that legacy value -- clear it so auto-download re-resolves
|
||||
# (user-provided paths never live under .uv/).
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE MATCHES "/\\.uv/")
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE "" CACHE FILEPATH "Path to the auto-downloaded uv executable" FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
if(NOT EXISTS "${ORCA_UV_BINARY}")
|
||||
# Select uv by TARGET arch. On macOS universal builds each leg sets a single
|
||||
# CMAKE_OSX_ARCHITECTURES (and the x86_64 leg cross-builds on an arm64 runner),
|
||||
# so prefer it over the host CMAKE_SYSTEM_PROCESSOR -- otherwise both legs fetch
|
||||
# the same arch and the later universal lipo merge of tools/uv/uv fails.
|
||||
set(_orca_uv_proc "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
set(_orca_uv_proc "${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif()
|
||||
# All release archives are tar.gz except the Windows zip.
|
||||
set(ORCA_UV_EXT "tar.gz")
|
||||
if(_orca_uv_proc MATCHES "x86_64|AMD64|amd64")
|
||||
if(WIN32)
|
||||
set(ORCA_UV_ARCH "x86_64-pc-windows-msvc")
|
||||
set(ORCA_UV_EXT "zip")
|
||||
elseif(APPLE)
|
||||
set(ORCA_UV_ARCH "x86_64-apple-darwin")
|
||||
else()
|
||||
set(ORCA_UV_ARCH "x86_64-unknown-linux-gnu")
|
||||
endif()
|
||||
elseif(_orca_uv_proc MATCHES "aarch64|arm64|ARM64")
|
||||
if(APPLE)
|
||||
set(ORCA_UV_ARCH "aarch64-apple-darwin")
|
||||
else()
|
||||
set(ORCA_UV_ARCH "aarch64-unknown-linux-gnu")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Unsupported architecture for auto-downloading uv: ${_orca_uv_proc}")
|
||||
endif()
|
||||
|
||||
if(ORCA_UV_ARCH)
|
||||
set(ORCA_UV_URL "https://github.com/astral-sh/uv/releases/download/${ORCA_UV_VERSION}/uv-${ORCA_UV_ARCH}.${ORCA_UV_EXT}")
|
||||
set(ORCA_UV_ARCHIVE "${ORCA_UV_DOWNLOAD_DIR}/uv-archive.${ORCA_UV_EXT}")
|
||||
file(MAKE_DIRECTORY "${ORCA_UV_DOWNLOAD_DIR}")
|
||||
message(STATUS "Downloading uv ${ORCA_UV_VERSION} from ${ORCA_UV_URL} ...")
|
||||
file(DOWNLOAD "${ORCA_UV_URL}" "${ORCA_UV_ARCHIVE}" STATUS ORCA_UV_DL_STATUS TLS_VERIFY ON)
|
||||
list(GET ORCA_UV_DL_STATUS 0 ORCA_UV_DL_CODE)
|
||||
list(GET ORCA_UV_DL_STATUS 1 ORCA_UV_DL_MSG)
|
||||
if(NOT ORCA_UV_DL_CODE EQUAL 0)
|
||||
# Network failure keeps the historical graceful degradation (uv is
|
||||
# optional at build time) -- but a hash mismatch below is fatal.
|
||||
message(WARNING "Failed to download uv: ${ORCA_UV_DL_MSG}")
|
||||
file(REMOVE "${ORCA_UV_ARCHIVE}")
|
||||
else()
|
||||
file(SHA256 "${ORCA_UV_ARCHIVE}" _orca_uv_actual_sha256)
|
||||
if(NOT _orca_uv_actual_sha256 STREQUAL "${ORCA_UV_SHA256_${ORCA_UV_ARCH}}")
|
||||
file(REMOVE "${ORCA_UV_ARCHIVE}")
|
||||
message(FATAL_ERROR
|
||||
"uv archive checksum mismatch for ${ORCA_UV_ARCH} ${ORCA_UV_VERSION}:\n"
|
||||
" expected ${ORCA_UV_SHA256_${ORCA_UV_ARCH}}\n"
|
||||
" actual ${_orca_uv_actual_sha256}\n"
|
||||
"Possible tampering or a stale pin; refusing to bundle.")
|
||||
endif()
|
||||
message(STATUS "Extracting uv ...")
|
||||
file(ARCHIVE_EXTRACT INPUT "${ORCA_UV_ARCHIVE}" DESTINATION "${ORCA_UV_DOWNLOAD_DIR}")
|
||||
file(REMOVE "${ORCA_UV_ARCHIVE}")
|
||||
# Pinned archives have a fixed layout: the tarballs hold
|
||||
# uv-<triple>/uv, the Windows zip holds uv.exe at the root
|
||||
# (already at ORCA_UV_BINARY). A layout change implies a new
|
||||
# archive, hence a hash bump -- and RENAME fails loudly.
|
||||
if(NOT WIN32)
|
||||
file(RENAME "${ORCA_UV_DOWNLOAD_DIR}/uv-${ORCA_UV_ARCH}/uv" "${ORCA_UV_BINARY}")
|
||||
file(REMOVE_RECURSE "${ORCA_UV_DOWNLOAD_DIR}/uv-${ORCA_UV_ARCH}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(EXISTS "${ORCA_UV_BINARY}")
|
||||
# Plain set (shadows the empty cache entry for this configure run):
|
||||
# the version-scoped path re-derives every configure, so a version
|
||||
# bump takes effect in warm build dirs without cache surgery.
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE "${ORCA_UV_BINARY}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Resolve ORCA_BUNDLED_UV_EXECUTABLE -> ORCA_BUNDLED_UV_EXECUTABLE_CONFIG / ORCA_BUNDLED_UV_FILENAME
|
||||
# Must run before add_subdirectory(src) so target_compile_definitions sees it.
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
if(EXISTS "${ORCA_BUNDLED_UV_EXECUTABLE}")
|
||||
file(TO_CMAKE_PATH "${ORCA_BUNDLED_UV_EXECUTABLE}" ORCA_BUNDLED_UV_EXECUTABLE_CONFIG)
|
||||
get_filename_component(ORCA_BUNDLED_UV_FILENAME "${ORCA_BUNDLED_UV_EXECUTABLE}" NAME)
|
||||
else()
|
||||
message(WARNING "ORCA_BUNDLED_UV_EXECUTABLE does not exist: ${ORCA_BUNDLED_UV_EXECUTABLE}")
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE "")
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE_CONFIG "")
|
||||
set(ORCA_BUNDLED_UV_FILENAME "")
|
||||
endif()
|
||||
else()
|
||||
set(ORCA_BUNDLED_UV_EXECUTABLE_CONFIG "")
|
||||
set(ORCA_BUNDLED_UV_FILENAME "")
|
||||
endif()
|
||||
|
||||
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable.
|
||||
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow performing desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
|
||||
|
||||
@@ -710,7 +835,7 @@ endif ()
|
||||
set(L10N_DIR "${SLIC3R_RESOURCES_DIR}/i18n")
|
||||
set(BBL_L18N_DIR "${CMAKE_CURRENT_SOURCE_DIR}/localization/i18n")
|
||||
add_custom_target(gettext_make_pot
|
||||
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_CTX:1,2c --keyword=_CTX_utf8:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
|
||||
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
|
||||
-f "${BBL_L18N_DIR}/list.txt"
|
||||
-o "${BBL_L18N_DIR}/OrcaSlicer.pot"
|
||||
COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${BBL_L18N_DIR}
|
||||
@@ -750,6 +875,86 @@ endforeach()
|
||||
|
||||
find_package(NLopt 1.4 REQUIRED)
|
||||
|
||||
# Use bundled Python from deps instead of system Python
|
||||
set(_bundled_python_version "3.12.13")
|
||||
set(_bundled_python_abi "312")
|
||||
string(REGEX REPLACE "^([0-9]+\\.[0-9]+)\\..*$" "\\1" _bundled_python_version_short "${_bundled_python_version}")
|
||||
set(_bundled_python_root "${CMAKE_PREFIX_PATH}/libpython")
|
||||
set(Python3_ROOT_DIR "${_bundled_python_root}" CACHE PATH "Root directory for bundled Python" FORCE)
|
||||
set(Python3_USE_STATIC_LIBS OFF)
|
||||
set(Python3_FIND_STRATEGY LOCATION)
|
||||
set(Python3_FIND_IMPLEMENTATIONS CPython)
|
||||
|
||||
if(WIN32)
|
||||
set(_bundled_python_executable "${_bundled_python_root}/python.exe")
|
||||
set(_bundled_python_library "${_bundled_python_root}/libs/python${_bundled_python_abi}.lib")
|
||||
if(EXISTS "${_bundled_python_root}/python_d.exe")
|
||||
set(_bundled_python_executable "${_bundled_python_root}/python_d.exe")
|
||||
endif()
|
||||
if(EXISTS "${_bundled_python_root}/libs/python${_bundled_python_abi}_d.lib")
|
||||
set(_bundled_python_library "${_bundled_python_root}/libs/python${_bundled_python_abi}_d.lib")
|
||||
endif()
|
||||
|
||||
set(Python3_FIND_REGISTRY NEVER)
|
||||
set(Python3_EXECUTABLE "${_bundled_python_executable}" CACHE FILEPATH "Bundled Python executable" FORCE)
|
||||
set(Python3_INCLUDE_DIR "${_bundled_python_root}/include" CACHE PATH "Bundled Python include directory" FORCE)
|
||||
set(Python3_LIBRARY "${_bundled_python_library}" CACHE FILEPATH "Bundled Python embed import library" FORCE)
|
||||
elseif(APPLE)
|
||||
set(Python3_FIND_FRAMEWORK NEVER)
|
||||
|
||||
find_program(_bundled_python_executable
|
||||
NAMES python${_bundled_python_version_short} python3
|
||||
PATHS "${_bundled_python_root}/bin"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_path(_bundled_python_include_dir
|
||||
NAMES Python.h
|
||||
PATHS
|
||||
"${_bundled_python_root}/include/python${_bundled_python_version_short}"
|
||||
"${_bundled_python_root}/include"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_library(_bundled_python_library
|
||||
NAMES python${_bundled_python_version_short} libpython${_bundled_python_version_short}
|
||||
PATHS "${_bundled_python_root}/lib"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(NOT _bundled_python_executable)
|
||||
message(FATAL_ERROR "Bundled Python executable not found under ${_bundled_python_root}/bin")
|
||||
endif()
|
||||
if(NOT _bundled_python_include_dir)
|
||||
message(FATAL_ERROR "Bundled Python headers not found under ${_bundled_python_root}/include")
|
||||
endif()
|
||||
if(NOT _bundled_python_library)
|
||||
message(FATAL_ERROR "Bundled Python library not found under ${_bundled_python_root}/lib")
|
||||
endif()
|
||||
|
||||
set(Python3_EXECUTABLE "${_bundled_python_executable}" CACHE FILEPATH "Bundled Python executable" FORCE)
|
||||
set(Python3_INCLUDE_DIR "${_bundled_python_include_dir}" CACHE PATH "Bundled Python include directory" FORCE)
|
||||
set(Python3_LIBRARY "${_bundled_python_library}" CACHE FILEPATH "Bundled Python embed library" FORCE)
|
||||
endif()
|
||||
|
||||
find_package(Python3 ${_bundled_python_version} EXACT REQUIRED
|
||||
COMPONENTS Interpreter Development.Embed
|
||||
)
|
||||
|
||||
# Provide a minimal pybind11::embed target sourced from deps_src/pybind11 headers.
|
||||
set(PYBIND11_SOURCE_DIR "${CMAKE_SOURCE_DIR}/deps_src/pybind11")
|
||||
if(NOT EXISTS "${PYBIND11_SOURCE_DIR}/include/pybind11/pybind11.h")
|
||||
message(FATAL_ERROR "pybind11 headers not found in ${PYBIND11_SOURCE_DIR}. Did you initialize submodules?")
|
||||
endif()
|
||||
|
||||
add_library(pybind11_headers INTERFACE)
|
||||
target_include_directories(pybind11_headers INTERFACE "${PYBIND11_SOURCE_DIR}/include")
|
||||
add_library(pybind11::headers ALIAS pybind11_headers)
|
||||
add_library(pybind11::pybind11 ALIAS pybind11_headers)
|
||||
|
||||
add_library(pybind11_embed INTERFACE)
|
||||
target_link_libraries(pybind11_embed INTERFACE pybind11_headers Python3::Python)
|
||||
target_compile_definitions(pybind11_embed INTERFACE PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
add_library(pybind11::embed ALIAS pybind11_embed)
|
||||
|
||||
|
||||
if(SLIC3R_STATIC)
|
||||
set(OPENVDB_USE_STATIC_LIBS ON)
|
||||
@@ -899,10 +1104,12 @@ if (NOT WIN32 AND NOT APPLE)
|
||||
configure_file(${LIBDIR}/dev-utils/platform/unix/build_appimage.sh.in ${CMAKE_CURRENT_BINARY_DIR}/build_appimage.sh USE_SOURCE_PERMISSIONS @ONLY)
|
||||
endif()
|
||||
|
||||
|
||||
# Resources install target, configure fhs.hpp on UNIX
|
||||
if (WIN32)
|
||||
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "./resources")
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "./resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
|
||||
endif()
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
install (PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ".")
|
||||
@@ -912,6 +1119,9 @@ elseif (SLIC3R_FHS)
|
||||
install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/ DESTINATION ${SLIC3R_FHS_RESOURCES}
|
||||
PATTERN "*/udev" EXCLUDE
|
||||
)
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${SLIC3R_FHS_RESOURCES}/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
|
||||
endif()
|
||||
install(FILES src/dev-utils/platform/unix/com.orcaslicer.OrcaSlicer.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
|
||||
foreach(SIZE 32 128 192)
|
||||
install(FILES ${SLIC3R_RESOURCES_DIR}/images/OrcaSlicer_${SIZE}px.png
|
||||
@@ -920,9 +1130,15 @@ elseif (SLIC3R_FHS)
|
||||
endforeach()
|
||||
elseif (CMAKE_MACOSX_BUNDLE)
|
||||
# install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/OrcaSlicer.app/Contents/resources")
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${CMAKE_INSTALL_PREFIX}/OrcaSlicer.app/Contents/Resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
|
||||
endif()
|
||||
else ()
|
||||
install(FILES src/dev-utils/platform/unix/com.orcaslicer.OrcaSlicer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
|
||||
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources")
|
||||
if(ORCA_BUNDLED_UV_EXECUTABLE)
|
||||
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.txt DESTINATION ".")
|
||||
|
||||
@@ -59,7 +59,7 @@ while getopts ":dpa:snt:xbc:i:1Tuh" opt; do
|
||||
echo " -c: Set CMake build configuration, default is Release"
|
||||
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
|
||||
echo " -1: Use single job for building"
|
||||
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
|
||||
echo " -T: Build and run tests"
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
@@ -179,6 +179,45 @@ function pack_deps() {
|
||||
)
|
||||
}
|
||||
|
||||
# --- Bundled Python runtime verification --------------------------------------
|
||||
# Relocation is handled at the source: deps/python3/python3.cmake stamps
|
||||
# libpython with an @rpath id and src/CMakeLists.txt gives the app a matching
|
||||
# rpath. This gate catches regressions that would otherwise only surface as
|
||||
# launch failures on end users' machines (the absolute deps path still exists
|
||||
# on the build host, so a plain run can pass while relocation is broken --
|
||||
# hence the otool checks). The x86_64 leg runs under Rosetta on arm64 hosts.
|
||||
function verify_python_runtime() {
|
||||
local app="$1"
|
||||
local pydir="$app/Contents/MacOS/python"
|
||||
[ -d "$pydir" ] || return 0 # app doesn't bundle Python (e.g. profile validator)
|
||||
# Version-agnostic interpreter name so a CPython version bump cannot
|
||||
# silently skip the gate; if the dir exists the interpreter must too.
|
||||
local pybin="$pydir/bin/python3"
|
||||
if [ ! -x "$pybin" ]; then
|
||||
echo "ERROR: bundled python/ present but no interpreter at $pybin" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo " Verifying bundled Python runtime in $(basename "$app")..."
|
||||
local bad
|
||||
bad=$(otool -arch all -L "$pybin" "$app/Contents/MacOS/OrcaSlicer" | grep "libpython" | grep -v "@rpath/" || true)
|
||||
if [ -n "$bad" ]; then
|
||||
echo "ERROR: a bundled binary references libpython by absolute path (relocation regression):" >&2
|
||||
echo "$bad" >&2
|
||||
exit 1
|
||||
fi
|
||||
# otool -L shows load commands only; assert the consumer rpath separately.
|
||||
# Its loss is masked on the build host by CMake's absolute build-tree rpath.
|
||||
if ! otool -arch all -l "$app/Contents/MacOS/OrcaSlicer" | grep -q "path @executable_path/python/lib "; then
|
||||
echo "ERROR: OrcaSlicer lacks the @executable_path/python/lib rpath (relocation regression)" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! "$pybin" -c "import ssl"; then
|
||||
echo "ERROR: bundled Python failed to start (libpython relocation broken," >&2
|
||||
echo " or missing Rosetta 2 for the x86_64 leg?)" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_slicer() {
|
||||
# iterate over two architectures: x86_64 and arm64
|
||||
for _ARCH in x86_64 arm64; do
|
||||
@@ -209,10 +248,13 @@ function build_slicer() {
|
||||
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
|
||||
)
|
||||
|
||||
# -T also runs the tests; ORCA_TESTS_BUILD_ONLY=1 builds them without
|
||||
# running, so CI can build here and run them in a dedicated job.
|
||||
if [ "1." == "$BUILD_TESTS". ] && [ "1." != "$ORCA_TESTS_BUILD_ONLY". ]; then
|
||||
"$PROJECT_DIR/scripts/run_unit_tests.sh" "build/$_ARCH/tests" "$BUILD_CONFIG"
|
||||
if [ "1." == "$BUILD_TESTS". ]; then
|
||||
echo "Running tests for $_ARCH..."
|
||||
(
|
||||
set -x
|
||||
cd "$PROJECT_BUILD_DIR"
|
||||
ctest --build-config "$BUILD_CONFIG" --output-on-failure
|
||||
)
|
||||
fi
|
||||
|
||||
echo "Verify localization with gettext..."
|
||||
@@ -236,6 +278,8 @@ function build_slicer() {
|
||||
cp -R "$resources_path" ./OrcaSlicer.app/Contents/Resources
|
||||
# delete .DS_Store file
|
||||
find ./OrcaSlicer.app/ -name '.DS_Store' -delete
|
||||
|
||||
verify_python_runtime ./OrcaSlicer.app
|
||||
|
||||
# Copy OrcaSlicer_profile_validator.app if it exists
|
||||
if [ -f "../src$BUILD_DIR_CONFIG_SUBDIR/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then
|
||||
@@ -244,6 +288,7 @@ function build_slicer() {
|
||||
cp -pR "../src$BUILD_DIR_CONFIG_SUBDIR/OrcaSlicer_profile_validator.app" ./OrcaSlicer_profile_validator.app
|
||||
# delete .DS_Store file
|
||||
find ./OrcaSlicer_profile_validator.app/ -name '.DS_Store' -delete
|
||||
verify_python_runtime ./OrcaSlicer_profile_validator.app
|
||||
fi
|
||||
)
|
||||
|
||||
@@ -299,6 +344,7 @@ function build_universal() {
|
||||
echo "Creating universal binaries for OrcaSlicer.app..."
|
||||
lipo_dir "$UNIVERSAL_APP" "$X86_64_APP"
|
||||
echo "Universal OrcaSlicer.app created at $UNIVERSAL_APP"
|
||||
verify_python_runtime "$UNIVERSAL_APP"
|
||||
|
||||
# Create universal binary for profile validator if it exists
|
||||
ARM64_VALIDATOR="$PROJECT_DIR/build/arm64/OrcaSlicer/OrcaSlicer_profile_validator.app"
|
||||
|
||||
@@ -20,12 +20,6 @@ for %%a in (%*) do (
|
||||
if "%%a"=="-x" set USE_NINJA=1
|
||||
)
|
||||
|
||||
@REM Check for unit-tests option ("tests")
|
||||
set BUILD_TESTS=OFF
|
||||
for %%a in (%*) do (
|
||||
if /I "%%a"=="tests" set BUILD_TESTS=ON
|
||||
)
|
||||
|
||||
if "%USE_NINJA%"=="1" (
|
||||
echo Using Ninja Multi-Config generator
|
||||
set CMAKE_GENERATOR="Ninja Multi-Config"
|
||||
@@ -151,10 +145,10 @@ cd %build_dir%
|
||||
echo on
|
||||
set CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
if "%USE_NINJA%"=="1" (
|
||||
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
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 %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -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
|
||||
|
||||
2
deps/CMakeLists.txt
vendored
2
deps/CMakeLists.txt
vendored
@@ -422,6 +422,7 @@ endif ()
|
||||
|
||||
include(OCCT/OCCT.cmake)
|
||||
include(OpenCV/OpenCV.cmake)
|
||||
include(python3/python3.cmake)
|
||||
|
||||
set(_dep_list
|
||||
dep_Boost
|
||||
@@ -444,6 +445,7 @@ set(_dep_list
|
||||
${ZLIB_PKG}
|
||||
${EXPAT_PKG}
|
||||
dep_libnoise
|
||||
dep_python3
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
269
deps/python3/python3.cmake
vendored
Normal file
269
deps/python3/python3.cmake
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(NPROC)
|
||||
|
||||
set(_python_version "3.12.13")
|
||||
string(REGEX REPLACE "^([0-9]+\\.[0-9]+)\\..*" "\\1" _python_version_short "${_python_version}")
|
||||
set(_python_url "https://www.python.org/ftp/python/${_python_version}/Python-${_python_version}.tar.xz")
|
||||
set(_python_sha256 "c08bc65a81971c1dd5783182826503369466c7e67374d1646519adf05207b684")
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC_VERSION EQUAL 1800)
|
||||
set(_python_platform_toolset v120)
|
||||
elseif(MSVC_VERSION EQUAL 1900)
|
||||
set(_python_platform_toolset v140)
|
||||
elseif(MSVC_VERSION LESS 1920)
|
||||
set(_python_platform_toolset v141)
|
||||
elseif(MSVC_VERSION LESS 1930)
|
||||
set(_python_platform_toolset v142)
|
||||
elseif(MSVC_VERSION LESS 1950)
|
||||
set(_python_platform_toolset v143)
|
||||
elseif(MSVC_VERSION LESS 1960)
|
||||
set(_python_platform_toolset v145)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported MSVC version for CPython build: ${MSVC_VERSION}")
|
||||
endif()
|
||||
|
||||
# 64-bit-hosted MSBuild selection (see the build-step comment below). Default
|
||||
# to the amd64 host + x64 tools; only the native ARM64 build differs.
|
||||
set(_python_msbuild_host amd64)
|
||||
set(_python_tool_arch x64)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
|
||||
set(_python_pcbuild_platform ARM64)
|
||||
set(_python_layout_arch arm64)
|
||||
set(_python_pcbuild_output_dir arm64)
|
||||
set(_python_msbuild_host arm64) # native ARM64 MSBuild already hosts arm64 tools
|
||||
set(_python_tool_arch "")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_python_pcbuild_platform x64)
|
||||
set(_python_layout_arch amd64)
|
||||
set(_python_pcbuild_output_dir amd64)
|
||||
else()
|
||||
set(_python_pcbuild_platform Win32)
|
||||
set(_python_layout_arch win32)
|
||||
set(_python_pcbuild_output_dir win32)
|
||||
endif()
|
||||
|
||||
set(_python_pcbuild_config Release)
|
||||
set(_python_layout_debug OFF)
|
||||
if(DEFINED DEP_DEBUG AND DEP_DEBUG)
|
||||
set(_python_pcbuild_config Debug)
|
||||
set(_python_layout_debug ON)
|
||||
endif()
|
||||
|
||||
# CPython's PCbuild needs a 64-bit-hosted toolchain: find_msbuild.bat picks the
|
||||
# 32-bit Bin\MSBuild.exe, whose x86 cl.exe/link.exe run out of address space
|
||||
# (fatal C1002 "out of heap space") building the LTCG-optimized pythoncore.
|
||||
# That 32-bit MSBuild ignores PreferredToolArchitecture, so build.bat must be
|
||||
# pointed at a 64-bit MSBuild via the MSBUILD env var. The native arm64 MSBuild
|
||||
# then hosts arm64 tools on its own; the amd64 MSBuild still defaults to x86, so
|
||||
# PreferredToolArchitecture pins it to x64. Scoped to this build step, so
|
||||
# CPython's own sources stay untouched.
|
||||
set(_python_env_args "GIT_CEILING_DIRECTORIES=<SOURCE_DIR>/..")
|
||||
if(CMAKE_GENERATOR_INSTANCE) # empty for non-VS generators (e.g. Ninja)
|
||||
set(_python_msbuild "${CMAKE_GENERATOR_INSTANCE}/MSBuild/Current/Bin/${_python_msbuild_host}/MSBuild.exe")
|
||||
if(EXISTS "${_python_msbuild}")
|
||||
file(TO_NATIVE_PATH "${_python_msbuild}" _python_msbuild_native)
|
||||
list(APPEND _python_env_args "MSBUILD=${_python_msbuild_native}")
|
||||
else()
|
||||
# Loud signal: a silent fall-through to the 32-bit MSBuild reintroduces C1002.
|
||||
message(WARNING "Bundled Python: 64-bit MSBuild not found at '${_python_msbuild}'. "
|
||||
"CPython will fall back to find_msbuild.bat's default (32-bit) MSBuild, which may "
|
||||
"fail with C1002 (out of heap space) building the optimized pythoncore.")
|
||||
endif()
|
||||
endif()
|
||||
if(_python_tool_arch)
|
||||
list(APPEND _python_env_args "PreferredToolArchitecture=${_python_tool_arch}")
|
||||
endif()
|
||||
|
||||
set(_conf_cmd
|
||||
cmd /c "echo /p:PlatformToolset=${_python_platform_toolset}>PCbuild\\msbuild.rsp"
|
||||
)
|
||||
set(_build_cmd
|
||||
${CMAKE_COMMAND} -E env ${_python_env_args}
|
||||
cmd /c PCbuild\\build.bat
|
||||
-p ${_python_pcbuild_platform}
|
||||
-c ${_python_pcbuild_config}
|
||||
--no-tkinter
|
||||
)
|
||||
set(_install_cmd
|
||||
${CMAKE_COMMAND}
|
||||
-DPYTHON_SOURCE_DIR=<SOURCE_DIR>
|
||||
-DPYTHON_BUILD_DIR=<SOURCE_DIR>/PCbuild/${_python_pcbuild_output_dir}
|
||||
-DPYTHON_DEST_DIR=${DESTDIR}/libpython
|
||||
-DPYTHON_LAYOUT_ARCH=${_python_layout_arch}
|
||||
-DPYTHON_DEBUG=${_python_layout_debug}
|
||||
-P ${CMAKE_CURRENT_LIST_DIR}/stage_windows.cmake
|
||||
)
|
||||
elseif(APPLE)
|
||||
# macOS configuration
|
||||
if(CMAKE_OSX_ARCHITECTURES)
|
||||
set(_python_target_arch "${CMAKE_OSX_ARCHITECTURES}")
|
||||
else()
|
||||
set(_python_target_arch "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|arm64|aarch64")
|
||||
set(_python_build_arch aarch64)
|
||||
set(_python_build_arch_flag "arm64")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
|
||||
set(_python_build_arch x86_64)
|
||||
set(_python_build_arch_flag "x86_64")
|
||||
else()
|
||||
set(_python_build_arch "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(_python_build_arch_flag "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if(_python_target_arch MATCHES "ARM64|arm64|aarch64")
|
||||
set(_python_host_arch aarch64)
|
||||
set(_python_arch_flag "arm64")
|
||||
elseif(_python_target_arch MATCHES "x86_64|AMD64|amd64")
|
||||
set(_python_host_arch x86_64)
|
||||
set(_python_arch_flag "x86_64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported macOS Python target architecture: ${_python_target_arch}")
|
||||
endif()
|
||||
|
||||
set(_python_arch_flags "-arch ${_python_arch_flag} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
# No -rpath: all other deps are static, so libpython has no shared
|
||||
# dependencies to find there. headerpad reserves load-command space for
|
||||
# the post-install -add_rpath below.
|
||||
set(_python_ldflags "${_python_arch_flags} -Wl,-headerpad_max_install_names")
|
||||
|
||||
if(IS_CROSS_COMPILE)
|
||||
set(_python_build_tgt --build=${_python_build_arch}-apple-darwin --host=${_python_host_arch}-apple-darwin)
|
||||
set(_python_build_arch_flags "-arch ${_python_build_arch_flag} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
set(_python_build_ldflags "${_python_build_arch_flags} -Wl,-rpath,${DESTDIR}/lib")
|
||||
set(_python_build_python_dir "<SOURCE_DIR>/build-python-host")
|
||||
set(_python_build_python "${_python_build_python_dir}/python")
|
||||
set(_conf_cmd
|
||||
/bin/sh -c
|
||||
"rm -rf '${_python_build_python_dir}' && \
|
||||
mkdir -p '${_python_build_python_dir}' && \
|
||||
cd '${_python_build_python_dir}' && \
|
||||
env \
|
||||
CC='${CMAKE_C_COMPILER}' \
|
||||
CXX='${CMAKE_CXX_COMPILER}' \
|
||||
CFLAGS='${_python_build_arch_flags}' \
|
||||
CXXFLAGS='${_python_build_arch_flags}' \
|
||||
LDFLAGS='${_python_build_ldflags}' \
|
||||
MACOSX_DEPLOYMENT_TARGET='${CMAKE_OSX_DEPLOYMENT_TARGET}' \
|
||||
../configure \
|
||||
--prefix='${_python_build_python_dir}/install' \
|
||||
--enable-shared \
|
||||
--without-static-libpython \
|
||||
--disable-test-modules \
|
||||
--build=${_python_build_arch}-apple-darwin && \
|
||||
make -j${NPROC} python && \
|
||||
cd '<SOURCE_DIR>' && \
|
||||
env \
|
||||
CC='${CMAKE_C_COMPILER}' \
|
||||
CXX='${CMAKE_CXX_COMPILER}' \
|
||||
CFLAGS='${_python_arch_flags}' \
|
||||
CXXFLAGS='${_python_arch_flags}' \
|
||||
LDFLAGS='${_python_ldflags}' \
|
||||
MACOSX_DEPLOYMENT_TARGET='${CMAKE_OSX_DEPLOYMENT_TARGET}' \
|
||||
./configure \
|
||||
--prefix='${DESTDIR}/libpython' \
|
||||
--enable-shared \
|
||||
--enable-optimizations \
|
||||
--without-static-libpython \
|
||||
--with-openssl='${DESTDIR}' \
|
||||
--disable-test-modules \
|
||||
${_python_build_tgt} \
|
||||
--with-build-python='${_python_build_python}' \
|
||||
py_cv_module__tkinter=n/a"
|
||||
)
|
||||
else()
|
||||
set(_python_build_tgt --build=${_python_host_arch}-apple-darwin)
|
||||
set(_conf_cmd
|
||||
env
|
||||
"CC=${CMAKE_C_COMPILER}"
|
||||
"CXX=${CMAKE_CXX_COMPILER}"
|
||||
"CFLAGS=${_python_arch_flags}"
|
||||
"CXXFLAGS=${_python_arch_flags}"
|
||||
"LDFLAGS=${_python_ldflags}"
|
||||
"MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
./configure
|
||||
--prefix=${DESTDIR}/libpython
|
||||
--enable-shared
|
||||
--enable-optimizations
|
||||
--without-static-libpython
|
||||
--with-openssl=${DESTDIR}
|
||||
--disable-test-modules
|
||||
${_python_build_tgt}
|
||||
# Tcl/Tk 9.0 (e.g. from Homebrew) is incompatible with CPython 3.12's
|
||||
# _tkinter; OrcaSlicer's embedded Python does not need tkinter anyway.
|
||||
py_cv_module__tkinter=n/a
|
||||
)
|
||||
endif()
|
||||
set(_build_cmd make -j${NPROC})
|
||||
|
||||
# CPython stamps libpython with an absolute install name ($prefix/lib/...),
|
||||
# which every consumer inherits at link time and which only exists on the
|
||||
# build host. Normalize once here, before anything links against the dep:
|
||||
# give the dylib an @rpath id and teach the interpreter to find it relative
|
||||
# to itself. Consumers then just need an rpath entry (src/CMakeLists.txt).
|
||||
# install_name_tool invalidates code signatures, so re-sign ad-hoc; CI
|
||||
# re-signs the whole bundle with the real identity later.
|
||||
# ld collapses '//' in -install_name (but not in -rpath) strings, while
|
||||
# ${DESTDIR} ends with a slash -- collapse slashes so -change matches the
|
||||
# recorded install name.
|
||||
string(REGEX REPLACE "/+" "/" _python_prefix "${DESTDIR}/libpython")
|
||||
set(_python_dylib "${_python_prefix}/lib/libpython${_python_version_short}.dylib")
|
||||
set(_python_bin "${_python_prefix}/bin/python${_python_version_short}")
|
||||
set(_install_cmd make install
|
||||
COMMAND install_name_tool -id "@rpath/libpython${_python_version_short}.dylib" "${_python_dylib}"
|
||||
COMMAND install_name_tool -change "${_python_dylib}" "@rpath/libpython${_python_version_short}.dylib" "${_python_bin}"
|
||||
COMMAND install_name_tool -add_rpath "@loader_path/../lib" "${_python_bin}"
|
||||
COMMAND codesign --force --sign - "${_python_dylib}"
|
||||
COMMAND codesign --force --sign - "${_python_bin}"
|
||||
)
|
||||
else()
|
||||
# Linux/Unix
|
||||
# Kept verbatim, no slash normalization (unlike the macOS branch's
|
||||
# collapsed copy): the LDFLAGS rpath below is recorded byte-for-byte in
|
||||
# the ELF, and the OLD_RPATH handed to relocate_linux.cmake must match it
|
||||
# exactly -- both derive from this one variable to make that structural.
|
||||
set(_python_prefix "${DESTDIR}/libpython")
|
||||
# The rpath points at libpython's real install dir, so the interpreter runs
|
||||
# in-tree pre-relocation -- and, critically, it reserves enough RUNPATH
|
||||
# bytes for the in-place $ORIGIN rewrite at install time (Flatpak's
|
||||
# DESTDIR is the short /app) -- see relocate_linux.cmake.
|
||||
set(_conf_cmd ./configure
|
||||
--prefix=${_python_prefix}
|
||||
--enable-shared
|
||||
--enable-optimizations
|
||||
--with-openssl=${DESTDIR}
|
||||
--without-static-libpython
|
||||
--disable-test-modules
|
||||
# Tcl/Tk 9.0 is incompatible with CPython 3.12's _tkinter; not needed here.
|
||||
py_cv_module__tkinter=n/a
|
||||
LDFLAGS=-Wl,-rpath,${_python_prefix}/lib
|
||||
)
|
||||
set(_build_cmd make -j${NPROC})
|
||||
set(_install_cmd make install
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DPYTHON_BIN=${_python_prefix}/bin/python${_python_version_short}"
|
||||
"-DOLD_RPATH=${_python_prefix}/lib"
|
||||
-P "${CMAKE_CURRENT_LIST_DIR}/relocate_linux.cmake"
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(dep_python3
|
||||
URL "${_python_url}"
|
||||
URL_HASH SHA256=${_python_sha256}
|
||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/python3
|
||||
BUILD_IN_SOURCE ON
|
||||
CONFIGURE_COMMAND ${_conf_cmd}
|
||||
BUILD_COMMAND ${_build_cmd}
|
||||
INSTALL_COMMAND ${_install_cmd}
|
||||
)
|
||||
|
||||
# Python depends on OpenSSL and ZLIB
|
||||
if(TARGET dep_OpenSSL)
|
||||
add_dependencies(dep_python3 dep_OpenSSL)
|
||||
endif()
|
||||
if(TARGET dep_ZLIB)
|
||||
add_dependencies(dep_python3 dep_ZLIB)
|
||||
endif()
|
||||
10
deps/python3/relocate_linux.cmake
vendored
Normal file
10
deps/python3/relocate_linux.cmake
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Repoint the installed interpreter's RUNPATH from the absolute deps dir to a
|
||||
# self-relative entry so the bundled runtime is relocatable (the deps tree,
|
||||
# Flatpak /app/libpython, and AppImage $APPDIR/lib/python all keep bin/ and
|
||||
# lib/ as siblings). $ORIGIN is expanded by the dynamic loader; CMake leaves
|
||||
# it alone (only ${...} is expanded here). RPATH_CHANGE edits the ELF in
|
||||
# place, so the new entry must not be longer than the old one: the reserved
|
||||
# ${DESTDIR}/libpython/lib is at least 18 bytes even for the shortest
|
||||
# supported DESTDIR (Flatpak's /app), longer than the 14-byte $ORIGIN/../lib.
|
||||
# Invoked from python3.cmake with -DPYTHON_BIN=... -DOLD_RPATH=...
|
||||
file(RPATH_CHANGE FILE "${PYTHON_BIN}" OLD_RPATH "${OLD_RPATH}" NEW_RPATH "$ORIGIN/../lib")
|
||||
72
deps/python3/stage_windows.cmake
vendored
Normal file
72
deps/python3/stage_windows.cmake
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(_python_abi "312")
|
||||
|
||||
foreach(_var PYTHON_SOURCE_DIR PYTHON_BUILD_DIR PYTHON_DEST_DIR PYTHON_LAYOUT_ARCH)
|
||||
if(NOT DEFINED ${_var} OR "${${_var}}" STREQUAL "")
|
||||
message(FATAL_ERROR "${_var} is required")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(_python_exe "${PYTHON_BUILD_DIR}/python.exe")
|
||||
if(PYTHON_DEBUG)
|
||||
set(_python_exe "${PYTHON_BUILD_DIR}/python_d.exe")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_python_exe}")
|
||||
message(FATAL_ERROR "Built Python executable not found: ${_python_exe}")
|
||||
endif()
|
||||
|
||||
file(REMOVE_RECURSE "${PYTHON_DEST_DIR}")
|
||||
file(MAKE_DIRECTORY "${PYTHON_DEST_DIR}")
|
||||
|
||||
# CPython's Windows layout helper reads LICENSE.txt from the build output.
|
||||
# Source archives ship this file as LICENSE, so provide the expected name.
|
||||
if(EXISTS "${PYTHON_SOURCE_DIR}/LICENSE" AND NOT EXISTS "${PYTHON_BUILD_DIR}/LICENSE.txt")
|
||||
configure_file("${PYTHON_SOURCE_DIR}/LICENSE" "${PYTHON_BUILD_DIR}/LICENSE.txt" COPYONLY)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E env
|
||||
"PYTHONHOME="
|
||||
"PYTHONPATH=${PYTHON_SOURCE_DIR}/Lib"
|
||||
"${_python_exe}"
|
||||
"${PYTHON_SOURCE_DIR}/PC/layout"
|
||||
--source "${PYTHON_SOURCE_DIR}"
|
||||
--build "${PYTHON_BUILD_DIR}"
|
||||
--arch "${PYTHON_LAYOUT_ARCH}"
|
||||
--copy "${PYTHON_DEST_DIR}"
|
||||
--include-dev
|
||||
WORKING_DIRECTORY "${PYTHON_SOURCE_DIR}"
|
||||
RESULT_VARIABLE _layout_result
|
||||
)
|
||||
|
||||
if(NOT _layout_result EQUAL 0)
|
||||
message(FATAL_ERROR "CPython Windows layout staging failed with exit code ${_layout_result}")
|
||||
endif()
|
||||
|
||||
set(_required_files
|
||||
"${PYTHON_DEST_DIR}/Lib/encodings/__init__.py"
|
||||
"${PYTHON_DEST_DIR}/include/Python.h"
|
||||
)
|
||||
|
||||
if(PYTHON_DEBUG)
|
||||
list(APPEND _required_files
|
||||
"${PYTHON_DEST_DIR}/python_d.exe"
|
||||
"${PYTHON_DEST_DIR}/python${_python_abi}_d.dll"
|
||||
"${PYTHON_DEST_DIR}/libs/python${_python_abi}_d.lib"
|
||||
)
|
||||
else()
|
||||
list(APPEND _required_files
|
||||
"${PYTHON_DEST_DIR}/python.exe"
|
||||
"${PYTHON_DEST_DIR}/python${_python_abi}.dll"
|
||||
"${PYTHON_DEST_DIR}/libs/python${_python_abi}.lib"
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(_required_file IN LISTS _required_files)
|
||||
if(NOT EXISTS "${_required_file}")
|
||||
message(FATAL_ERROR "Staged Python file missing: ${_required_file}")
|
||||
endif()
|
||||
endforeach()
|
||||
29
deps_src/pybind11/LICENSE
Normal file
29
deps_src/pybind11/LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
|
||||
external contributions to this project including patches, pull requests, etc.
|
||||
216
deps_src/pybind11/README.rst
Normal file
216
deps_src/pybind11/README.rst
Normal file
@@ -0,0 +1,216 @@
|
||||
.. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
|
||||
:alt: pybind11 logo
|
||||
|
||||
**pybind11 (v3) — Seamless interoperability between C++ and Python**
|
||||
|
||||
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions|
|
||||
|
||||
|CI| |Build status| |SPEC 4 — Using and Creating Nightly Wheels|
|
||||
|
||||
|Repology| |PyPI package| |Conda-forge| |Python Versions|
|
||||
|
||||
`Setuptools example <https://github.com/pybind/python_example>`_
|
||||
• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_
|
||||
• `CMake example <https://github.com/pybind/cmake_example>`_
|
||||
|
||||
.. start
|
||||
|
||||
|
||||
**pybind11** is a lightweight header-only library that exposes C++ types
|
||||
in Python and vice versa, mainly to create Python bindings of existing
|
||||
C++ code. Its goals and syntax are similar to the excellent
|
||||
`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_
|
||||
library by David Abrahams: to minimize boilerplate code in traditional
|
||||
extension modules by inferring type information using compile-time
|
||||
introspection.
|
||||
|
||||
The main issue with Boost.Python—and the reason for creating such a
|
||||
similar project—is Boost. Boost is an enormously large and complex suite
|
||||
of utility libraries that works with almost every C++ compiler in
|
||||
existence. This compatibility has its cost: arcane template tricks and
|
||||
workarounds are necessary to support the oldest and buggiest of compiler
|
||||
specimens. Now that C++11-compatible compilers are widely available,
|
||||
this heavy machinery has become an excessively large and unnecessary
|
||||
dependency.
|
||||
|
||||
Think of this library as a tiny self-contained version of Boost.Python
|
||||
with everything stripped away that isn't relevant for binding
|
||||
generation. Without comments, the core header files only require ~4K
|
||||
lines of code and depend on Python (CPython 3.8+, PyPy, or GraalPy) and the C++
|
||||
standard library. This compact implementation was possible thanks to some C++11
|
||||
language features (specifically: tuples, lambda functions and variadic
|
||||
templates). Since its creation, this library has grown beyond Boost.Python in
|
||||
many ways, leading to dramatically simpler binding code in many common
|
||||
situations.
|
||||
|
||||
Tutorial and reference documentation is provided at
|
||||
`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
|
||||
A PDF version of the manual is available
|
||||
`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.
|
||||
And the source code is always available at
|
||||
`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.
|
||||
|
||||
|
||||
Core features
|
||||
-------------
|
||||
|
||||
|
||||
pybind11 can map the following core C++ features to Python:
|
||||
|
||||
- Functions accepting and returning custom data structures per value,
|
||||
reference, or pointer
|
||||
- Instance methods and static methods
|
||||
- Overloaded functions
|
||||
- Instance attributes and static attributes
|
||||
- Arbitrary exception types
|
||||
- Enumerations
|
||||
- Callbacks
|
||||
- Iterators and ranges
|
||||
- Custom operators
|
||||
- Single and multiple inheritance
|
||||
- STL data structures
|
||||
- Smart pointers with reference counting like ``std::shared_ptr``
|
||||
- Internal references with correct reference counting
|
||||
- C++ classes with virtual (and pure virtual) methods can be extended
|
||||
in Python
|
||||
- Integrated NumPy support (NumPy 2 requires pybind11 2.12+)
|
||||
|
||||
Goodies
|
||||
-------
|
||||
|
||||
In addition to the core functionality, pybind11 provides some extra
|
||||
goodies:
|
||||
|
||||
- CPython 3.8+, PyPy3 7.3.17+, and GraalPy 24.1+ are supported with an
|
||||
implementation-agnostic interface (see older versions for older CPython
|
||||
and PyPy versions).
|
||||
|
||||
- It is possible to bind C++11 lambda functions with captured
|
||||
variables. The lambda capture data is stored inside the resulting
|
||||
Python function object.
|
||||
|
||||
- pybind11 uses C++11 move constructors and move assignment operators
|
||||
whenever possible to efficiently transfer custom data types.
|
||||
|
||||
- It's easy to expose the internal storage of custom data types through
|
||||
Pythons' buffer protocols. This is handy e.g. for fast conversion
|
||||
between C++ matrix classes like Eigen and NumPy without expensive
|
||||
copy operations.
|
||||
|
||||
- pybind11 can automatically vectorize functions so that they are
|
||||
transparently applied to all entries of one or more NumPy array
|
||||
arguments.
|
||||
|
||||
- Python's slice-based access and assignment operations can be
|
||||
supported with just a few lines of code.
|
||||
|
||||
- Everything is contained in just a few header files; there is no need
|
||||
to link against any additional libraries.
|
||||
|
||||
- Binaries are generally smaller by a factor of at least 2 compared to
|
||||
equivalent bindings generated by Boost.Python. A recent pybind11
|
||||
conversion of PyRosetta, an enormous Boost.Python binding project,
|
||||
`reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
|
||||
a binary size reduction of **5.4x** and compile time reduction by
|
||||
**5.8x**.
|
||||
|
||||
- Function signatures are precomputed at compile time (using
|
||||
``constexpr``), leading to smaller binaries.
|
||||
|
||||
- With little extra effort, C++ types can be pickled and unpickled
|
||||
similar to regular Python objects.
|
||||
|
||||
Supported compilers
|
||||
-------------------
|
||||
|
||||
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
|
||||
newer)
|
||||
2. GCC 4.8 or newer
|
||||
3. Microsoft Visual Studio 2022 or newer (2019 probably works, but was dropped in CI)
|
||||
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
|
||||
5. Cygwin/GCC (previously tested on 2.5.1)
|
||||
6. NVCC (CUDA 11.0 tested in CI)
|
||||
7. NVIDIA PGI (20.9 tested in CI)
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
* Windows, Linux, macOS, and iOS
|
||||
* CPython 3.8+, Pyodide, PyPy, and GraalPy
|
||||
* C++11, C++14, C++17, C++20, and C++23
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
This project was created by `Wenzel
|
||||
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
|
||||
improvements to the code were contributed by
|
||||
Jonas Adler,
|
||||
Lori A. Burns,
|
||||
Sylvain Corlay,
|
||||
Eric Cousineau,
|
||||
Aaron Gokaslan,
|
||||
Ralf Grosse-Kunstleve,
|
||||
Trent Houliston,
|
||||
Axel Huebl,
|
||||
@hulucc,
|
||||
Yannick Jadoul,
|
||||
Sergey Lyskov,
|
||||
Johan Mabille,
|
||||
Tomasz Miąsko,
|
||||
Dean Moldovan,
|
||||
Ben Pritchard,
|
||||
Jason Rhinelander,
|
||||
Boris Schäling,
|
||||
Pim Schellart,
|
||||
Henry Schreiner,
|
||||
Ivan Smirnov,
|
||||
Dustin Spicuzza,
|
||||
Boris Staletic,
|
||||
Ethan Steinberg,
|
||||
Patrick Stewart,
|
||||
Ivor Wanders,
|
||||
and
|
||||
Xiaofei Wang.
|
||||
|
||||
We thank Google for a generous financial contribution to the continuous
|
||||
integration infrastructure used by this project.
|
||||
|
||||
|
||||
Contributing
|
||||
~~~~~~~~~~~~
|
||||
|
||||
See the `contributing
|
||||
guide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_
|
||||
for information on building and contributing to pybind11.
|
||||
|
||||
License
|
||||
~~~~~~~
|
||||
|
||||
pybind11 is provided under a BSD-style license that can be found in the
|
||||
`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_
|
||||
file. By using, distributing, or contributing to this project, you agree
|
||||
to the terms and conditions of this license.
|
||||
|
||||
.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest
|
||||
:target: http://pybind11.readthedocs.org/en/latest
|
||||
.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg
|
||||
:target: http://pybind11.readthedocs.org/en/stable
|
||||
.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg
|
||||
:target: https://gitter.im/pybind/Lobby
|
||||
.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg
|
||||
:target: https://github.com/pybind/pybind11/actions
|
||||
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true
|
||||
:target: https://ci.appveyor.com/project/wjakob/pybind11
|
||||
.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg
|
||||
:target: https://pypi.org/project/pybind11/
|
||||
.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg
|
||||
:target: https://github.com/conda-forge/pybind11-feedstock
|
||||
.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg
|
||||
:target: https://repology.org/project/python:pybind11/versions
|
||||
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
|
||||
:target: https://pypi.org/project/pybind11/
|
||||
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
|
||||
:target: https://github.com/pybind/pybind11/discussions
|
||||
.. |SPEC 4 — Using and Creating Nightly Wheels| image:: https://img.shields.io/badge/SPEC-4-green?labelColor=%23004811&color=%235CA038
|
||||
:target: https://scientific-python.org/specs/spec-0004/
|
||||
722
deps_src/pybind11/include/pybind11/attr.h
Normal file
722
deps_src/pybind11/include/pybind11/attr.h
Normal file
@@ -0,0 +1,722 @@
|
||||
/*
|
||||
pybind11/attr.h: Infrastructure for processing custom
|
||||
type and function attributes
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "cast.h"
|
||||
#include "trampoline_self_life_support.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
/// \addtogroup annotations
|
||||
/// @{
|
||||
|
||||
/// Annotation for methods
|
||||
struct is_method {
|
||||
handle class_;
|
||||
explicit is_method(const handle &c) : class_(c) {}
|
||||
};
|
||||
|
||||
/// Annotation for setters
|
||||
struct is_setter {};
|
||||
|
||||
/// Annotation for operators
|
||||
struct is_operator {};
|
||||
|
||||
/// Annotation for classes that cannot be subclassed
|
||||
struct is_final {};
|
||||
|
||||
/// Annotation for parent scope
|
||||
struct scope {
|
||||
handle value;
|
||||
explicit scope(const handle &s) : value(s) {}
|
||||
};
|
||||
|
||||
/// Annotation for documentation
|
||||
struct doc {
|
||||
const char *value;
|
||||
explicit doc(const char *value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Annotation for function names
|
||||
struct name {
|
||||
const char *value;
|
||||
explicit name(const char *value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Annotation indicating that a function is an overload associated with a given "sibling"
|
||||
struct sibling {
|
||||
handle value;
|
||||
explicit sibling(const handle &value) : value(value.ptr()) {}
|
||||
};
|
||||
|
||||
/// Annotation indicating that a class derives from another given type
|
||||
template <typename T>
|
||||
struct base {
|
||||
|
||||
PYBIND11_DEPRECATED(
|
||||
"base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
|
||||
base() = default;
|
||||
};
|
||||
|
||||
/// Keep patient alive while nurse lives
|
||||
template <size_t Nurse, size_t Patient>
|
||||
struct keep_alive {};
|
||||
|
||||
/// Annotation indicating that a class is involved in a multiple inheritance relationship
|
||||
struct multiple_inheritance {};
|
||||
|
||||
/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
|
||||
struct dynamic_attr {};
|
||||
|
||||
/// Annotation which enables the buffer protocol for a type
|
||||
struct buffer_protocol {};
|
||||
|
||||
/// Annotation which enables releasing the GIL before calling the C++ destructor of wrapped
|
||||
/// instances (pybind/pybind11#1446).
|
||||
struct release_gil_before_calling_cpp_dtor {};
|
||||
|
||||
/// Annotation which requests that a special metaclass is created for a type
|
||||
struct metaclass {
|
||||
handle value;
|
||||
|
||||
PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
|
||||
metaclass() = default;
|
||||
|
||||
/// Override pybind11's default metaclass
|
||||
explicit metaclass(handle value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that
|
||||
/// may be used to customize the Python type.
|
||||
///
|
||||
/// The callback is invoked immediately before `PyType_Ready`.
|
||||
///
|
||||
/// Note: This is an advanced interface, and uses of it may require changes to
|
||||
/// work with later versions of pybind11. You may wish to consult the
|
||||
/// implementation of `make_new_python_type` in `detail/classes.h` to understand
|
||||
/// the context in which the callback will be run.
|
||||
struct custom_type_setup {
|
||||
using callback = std::function<void(PyHeapTypeObject *heap_type)>;
|
||||
|
||||
explicit custom_type_setup(callback value) : value(std::move(value)) {}
|
||||
|
||||
callback value;
|
||||
};
|
||||
|
||||
/// Annotation that marks a class as local to the module:
|
||||
struct module_local {
|
||||
const bool value;
|
||||
constexpr explicit module_local(bool v = true) : value(v) {}
|
||||
};
|
||||
|
||||
/// Annotation to mark enums as an arithmetic type
|
||||
struct arithmetic {};
|
||||
|
||||
/// Mark a function for addition at the beginning of the existing overload chain instead of the end
|
||||
struct prepend {};
|
||||
|
||||
/** \rst
|
||||
A call policy which places one or more guard variables (``Ts...``) around the function call.
|
||||
|
||||
For example, this definition:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", foo, py::call_guard<T>());
|
||||
|
||||
is equivalent to the following pseudocode:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", [](args...) {
|
||||
T scope_guard;
|
||||
return foo(args...); // forwarded arguments
|
||||
});
|
||||
\endrst */
|
||||
template <typename... Ts>
|
||||
struct call_guard;
|
||||
|
||||
template <>
|
||||
struct call_guard<> {
|
||||
using type = detail::void_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct call_guard<T> {
|
||||
static_assert(std::is_default_constructible<T>::value,
|
||||
"The guard type must be default constructible");
|
||||
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct call_guard<T, Ts...> {
|
||||
struct type {
|
||||
T guard{}; // Compose multiple guard types with left-to-right default-constructor order
|
||||
typename call_guard<Ts...>::type next{};
|
||||
};
|
||||
};
|
||||
|
||||
/// @} annotations
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
/* Forward declarations */
|
||||
enum op_id : int;
|
||||
enum op_type : int;
|
||||
struct undefined_t;
|
||||
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
|
||||
struct op_;
|
||||
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
|
||||
|
||||
/// Internal data structure which holds metadata about a keyword argument
|
||||
struct argument_record {
|
||||
const char *name; ///< Argument name
|
||||
const char *descr; ///< Human-readable version of the argument value
|
||||
handle value; ///< Associated Python object
|
||||
bool convert : 1; ///< True if the argument is allowed to convert when loading
|
||||
bool none : 1; ///< True if None is allowed when loading
|
||||
|
||||
argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
|
||||
: name(name), descr(descr), value(value), convert(convert), none(none) {}
|
||||
};
|
||||
|
||||
/// Internal data structure which holds metadata about a bound function (signature, overloads,
|
||||
/// etc.)
|
||||
#define PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID "v1" // PLEASE UPDATE if the struct is changed.
|
||||
struct function_record {
|
||||
function_record()
|
||||
: is_constructor(false), is_new_style_constructor(false), is_stateless(false),
|
||||
is_operator(false), is_method(false), is_setter(false), has_args(false),
|
||||
has_kwargs(false), prepend(false) {}
|
||||
|
||||
/// Function name
|
||||
char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
|
||||
|
||||
// User-specified documentation string
|
||||
char *doc = nullptr;
|
||||
|
||||
/// Human-readable version of the function signature
|
||||
char *signature = nullptr;
|
||||
|
||||
/// List of registered keyword arguments
|
||||
std::vector<argument_record> args;
|
||||
|
||||
/// Pointer to lambda function which converts arguments and performs the actual call
|
||||
handle (*impl)(function_call &) = nullptr;
|
||||
|
||||
/// Storage for the wrapped function pointer and captured data, if any
|
||||
void *data[3] = {};
|
||||
|
||||
/// Pointer to custom destructor for 'data' (if needed)
|
||||
void (*free_data)(function_record *ptr) = nullptr;
|
||||
|
||||
/// Return value policy associated with this function
|
||||
return_value_policy policy = return_value_policy::automatic;
|
||||
|
||||
/// True if name == '__init__'
|
||||
bool is_constructor : 1;
|
||||
|
||||
/// True if this is a new-style `__init__` defined in `detail/init.h`
|
||||
bool is_new_style_constructor : 1;
|
||||
|
||||
/// True if this is a stateless function pointer
|
||||
bool is_stateless : 1;
|
||||
|
||||
/// True if this is an operator (__add__), etc.
|
||||
bool is_operator : 1;
|
||||
|
||||
/// True if this is a method
|
||||
bool is_method : 1;
|
||||
|
||||
/// True if this is a setter
|
||||
bool is_setter : 1;
|
||||
|
||||
/// True if the function has a '*args' argument
|
||||
bool has_args : 1;
|
||||
|
||||
/// True if the function has a '**kwargs' argument
|
||||
bool has_kwargs : 1;
|
||||
|
||||
/// True if this function is to be inserted at the beginning of the overload resolution chain
|
||||
bool prepend : 1;
|
||||
|
||||
/// Number of arguments (including py::args and/or py::kwargs, if present)
|
||||
std::uint16_t nargs;
|
||||
|
||||
/// Number of leading positional arguments, which are terminated by a py::args or py::kwargs
|
||||
/// argument or by a py::kw_only annotation.
|
||||
std::uint16_t nargs_pos = 0;
|
||||
|
||||
/// Number of leading arguments (counted in `nargs`) that are positional-only
|
||||
std::uint16_t nargs_pos_only = 0;
|
||||
|
||||
/// Python method object
|
||||
PyMethodDef *def = nullptr;
|
||||
|
||||
/// Python handle to the parent scope (a class or a module)
|
||||
handle scope;
|
||||
|
||||
/// Python handle to the sibling function representing an overload chain
|
||||
handle sibling;
|
||||
|
||||
/// Pointer to next overload
|
||||
function_record *next = nullptr;
|
||||
};
|
||||
// The main purpose of this macro is to make it easy to pin-point the critically related code
|
||||
// sections.
|
||||
#define PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(...) \
|
||||
static_assert( \
|
||||
__VA_ARGS__, \
|
||||
"Violation of precondition for pybind11/functional.h performance optimizations!")
|
||||
|
||||
/// Special data structure which (temporarily) holds metadata about a bound class
|
||||
struct type_record {
|
||||
PYBIND11_NOINLINE type_record()
|
||||
: multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
|
||||
module_local(false), is_final(false), release_gil_before_calling_cpp_dtor(false) {}
|
||||
|
||||
/// Handle to the parent scope
|
||||
handle scope;
|
||||
|
||||
/// Name of the class
|
||||
const char *name = nullptr;
|
||||
|
||||
// Pointer to RTTI type_info data structure
|
||||
const std::type_info *type = nullptr;
|
||||
|
||||
/// How large is the underlying C++ type?
|
||||
size_t type_size = 0;
|
||||
|
||||
/// What is the alignment of the underlying C++ type?
|
||||
size_t type_align = 0;
|
||||
|
||||
/// How large is the type's holder?
|
||||
size_t holder_size = 0;
|
||||
|
||||
/// The global operator new can be overridden with a class-specific variant
|
||||
void *(*operator_new)(size_t) = nullptr;
|
||||
|
||||
/// Function pointer to class_<..>::init_instance
|
||||
void (*init_instance)(instance *, const void *) = nullptr;
|
||||
|
||||
/// Function pointer to class_<..>::dealloc
|
||||
void (*dealloc)(detail::value_and_holder &) = nullptr;
|
||||
|
||||
/// Function pointer for casting alias class (aka trampoline) pointer to
|
||||
/// trampoline_self_life_support pointer. Sidesteps cross-DSO RTTI issues
|
||||
/// on platforms like macOS (see PR #5728 for details).
|
||||
get_trampoline_self_life_support_fn get_trampoline_self_life_support
|
||||
= [](void *) -> trampoline_self_life_support * { return nullptr; };
|
||||
|
||||
/// List of base classes of the newly created type
|
||||
list bases;
|
||||
|
||||
/// Optional docstring
|
||||
const char *doc = nullptr;
|
||||
|
||||
/// Custom metaclass (optional)
|
||||
handle metaclass;
|
||||
|
||||
/// Custom type setup.
|
||||
custom_type_setup::callback custom_type_setup_callback;
|
||||
|
||||
/// Multiple inheritance marker
|
||||
bool multiple_inheritance : 1;
|
||||
|
||||
/// Does the class manage a __dict__?
|
||||
bool dynamic_attr : 1;
|
||||
|
||||
/// Does the class implement the buffer protocol?
|
||||
bool buffer_protocol : 1;
|
||||
|
||||
/// Is the class definition local to the module shared object?
|
||||
bool module_local : 1;
|
||||
|
||||
/// Is the class inheritable from python classes?
|
||||
bool is_final : 1;
|
||||
|
||||
/// Solves pybind/pybind11#1446
|
||||
bool release_gil_before_calling_cpp_dtor : 1;
|
||||
|
||||
holder_enum_t holder_enum_v = holder_enum_t::undefined;
|
||||
|
||||
PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
|
||||
auto *base_info = detail::get_type_info(base, false);
|
||||
if (!base_info) {
|
||||
std::string tname(base.name());
|
||||
detail::clean_type_id(tname);
|
||||
pybind11_fail("generic_type: type \"" + std::string(name)
|
||||
+ "\" referenced unknown base type \"" + tname + "\"");
|
||||
}
|
||||
|
||||
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks.
|
||||
bool this_has_unique_ptr_holder = (holder_enum_v == holder_enum_t::std_unique_ptr);
|
||||
bool base_has_unique_ptr_holder
|
||||
= (base_info->holder_enum_v == holder_enum_t::std_unique_ptr);
|
||||
if (this_has_unique_ptr_holder != base_has_unique_ptr_holder) {
|
||||
std::string tname(base.name());
|
||||
detail::clean_type_id(tname);
|
||||
pybind11_fail("generic_type: type \"" + std::string(name) + "\" "
|
||||
+ (this_has_unique_ptr_holder ? "does not have" : "has")
|
||||
+ " a non-default holder type while its base \"" + tname + "\" "
|
||||
+ (base_has_unique_ptr_holder ? "does not" : "does"));
|
||||
}
|
||||
|
||||
bases.append((PyObject *) base_info->type);
|
||||
|
||||
#ifdef PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET
|
||||
dynamic_attr |= base_info->type->tp_dictoffset != 0;
|
||||
#else
|
||||
dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
|
||||
#endif
|
||||
|
||||
if (caster) {
|
||||
base_info->implicit_casts.emplace_back(type, caster);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {
|
||||
args.reserve(f.nargs);
|
||||
args_convert.reserve(f.nargs);
|
||||
}
|
||||
|
||||
/// Tag for a new-style `__init__` defined in `detail/init.h`
|
||||
struct is_new_style_constructor {};
|
||||
|
||||
/**
|
||||
* Partial template specializations to process custom attributes provided to
|
||||
* cpp_function_ and class_. These are either used to initialize the respective
|
||||
* fields in the type_record and function_record data structures or executed at
|
||||
* runtime to deal with custom call policies (e.g. keep_alive).
|
||||
*/
|
||||
template <typename T, typename SFINAE = void>
|
||||
struct process_attribute;
|
||||
|
||||
template <typename T>
|
||||
struct process_attribute_default {
|
||||
/// Default implementation: do nothing
|
||||
static void init(const T &, function_record *) {}
|
||||
static void init(const T &, type_record *) {}
|
||||
static void precall(function_call &) {}
|
||||
static void postcall(function_call &, handle) {}
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's name
|
||||
template <>
|
||||
struct process_attribute<name> : process_attribute_default<name> {
|
||||
static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's docstring
|
||||
template <>
|
||||
struct process_attribute<doc> : process_attribute_default<doc> {
|
||||
static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's docstring (provided as a C-style string)
|
||||
template <>
|
||||
struct process_attribute<const char *> : process_attribute_default<const char *> {
|
||||
static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }
|
||||
static void init(const char *d, type_record *r) { r->doc = d; }
|
||||
};
|
||||
template <>
|
||||
struct process_attribute<char *> : process_attribute<const char *> {};
|
||||
|
||||
/// Process an attribute indicating the function's return value policy
|
||||
template <>
|
||||
struct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {
|
||||
static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this is an overloaded function associated with a
|
||||
/// given sibling
|
||||
template <>
|
||||
struct process_attribute<sibling> : process_attribute_default<sibling> {
|
||||
static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is a method
|
||||
template <>
|
||||
struct process_attribute<is_method> : process_attribute_default<is_method> {
|
||||
static void init(const is_method &s, function_record *r) {
|
||||
r->is_method = true;
|
||||
r->scope = s.class_;
|
||||
}
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is a setter
|
||||
template <>
|
||||
struct process_attribute<is_setter> : process_attribute_default<is_setter> {
|
||||
static void init(const is_setter &, function_record *r) { r->is_setter = true; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates the parent scope of a method
|
||||
template <>
|
||||
struct process_attribute<scope> : process_attribute_default<scope> {
|
||||
static void init(const scope &s, function_record *r) { r->scope = s.value; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is an operator
|
||||
template <>
|
||||
struct process_attribute<is_operator> : process_attribute_default<is_operator> {
|
||||
static void init(const is_operator &, function_record *r) { r->is_operator = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<is_new_style_constructor>
|
||||
: process_attribute_default<is_new_style_constructor> {
|
||||
static void init(const is_new_style_constructor &, function_record *r) {
|
||||
r->is_new_style_constructor = true;
|
||||
}
|
||||
};
|
||||
|
||||
inline void check_kw_only_arg(const arg &a, function_record *r) {
|
||||
if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) {
|
||||
pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or "
|
||||
"args() argument");
|
||||
}
|
||||
}
|
||||
|
||||
inline void append_self_arg_if_needed(function_record *r) {
|
||||
if (r->is_method && r->args.empty()) {
|
||||
r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Process a keyword argument attribute (*without* a default value)
|
||||
template <>
|
||||
struct process_attribute<arg> : process_attribute_default<arg> {
|
||||
static void init(const arg &a, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
|
||||
|
||||
check_kw_only_arg(a, r);
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a keyword argument attribute (*with* a default value)
|
||||
template <>
|
||||
struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
||||
static void init(const arg_v &a, function_record *r) {
|
||||
if (r->is_method && r->args.empty()) {
|
||||
r->args.emplace_back(
|
||||
"self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);
|
||||
}
|
||||
|
||||
if (!a.value) {
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
std::string descr("'");
|
||||
if (a.name) {
|
||||
descr += std::string(a.name) + ": ";
|
||||
}
|
||||
descr += a.type + "'";
|
||||
if (r->is_method) {
|
||||
if (r->name) {
|
||||
descr += " in method '" + (std::string) str(r->scope) + "."
|
||||
+ (std::string) r->name + "'";
|
||||
} else {
|
||||
descr += " in method of '" + (std::string) str(r->scope) + "'";
|
||||
}
|
||||
} else if (r->name) {
|
||||
descr += " in function '" + (std::string) r->name + "'";
|
||||
}
|
||||
pybind11_fail("arg(): could not convert default argument " + descr
|
||||
+ " into a Python object (type not registered yet?)");
|
||||
#else
|
||||
pybind11_fail("arg(): could not convert default argument "
|
||||
"into a Python object (type not registered yet?). "
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
||||
"more information.");
|
||||
#endif
|
||||
}
|
||||
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
||||
|
||||
check_kw_only_arg(a, r);
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a keyword-only-arguments-follow pseudo argument
|
||||
template <>
|
||||
struct process_attribute<kw_only> : process_attribute_default<kw_only> {
|
||||
static void init(const kw_only &, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {
|
||||
pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative "
|
||||
"argument location (or omit kw_only() entirely)");
|
||||
}
|
||||
r->nargs_pos = static_cast<std::uint16_t>(r->args.size());
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a positional-only-argument maker
|
||||
template <>
|
||||
struct process_attribute<pos_only> : process_attribute_default<pos_only> {
|
||||
static void init(const pos_only &, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());
|
||||
if (r->nargs_pos_only > r->nargs_pos) {
|
||||
pybind11_fail("pos_only(): cannot follow a py::args() argument");
|
||||
}
|
||||
// It also can't follow a kw_only, but a static_assert in pybind11.h checks that
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees
|
||||
/// that)
|
||||
template <typename T>
|
||||
struct process_attribute<T, enable_if_t<is_pyobject<T>::value>>
|
||||
: process_attribute_default<handle> {
|
||||
static void init(const handle &h, type_record *r) { r->bases.append(h); }
|
||||
};
|
||||
|
||||
/// Process a parent class attribute (deprecated, does not support multiple inheritance)
|
||||
template <typename T>
|
||||
struct process_attribute<base<T>> : process_attribute_default<base<T>> {
|
||||
static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
|
||||
};
|
||||
|
||||
/// Process a multiple inheritance attribute
|
||||
template <>
|
||||
struct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {
|
||||
static void init(const multiple_inheritance &, type_record *r) {
|
||||
r->multiple_inheritance = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {
|
||||
static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<custom_type_setup> {
|
||||
static void init(const custom_type_setup &value, type_record *r) {
|
||||
r->custom_type_setup_callback = value.value;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<is_final> : process_attribute_default<is_final> {
|
||||
static void init(const is_final &, type_record *r) { r->is_final = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
|
||||
static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<metaclass> : process_attribute_default<metaclass> {
|
||||
static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<module_local> : process_attribute_default<module_local> {
|
||||
static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<release_gil_before_calling_cpp_dtor>
|
||||
: process_attribute_default<release_gil_before_calling_cpp_dtor> {
|
||||
static void init(const release_gil_before_calling_cpp_dtor &, type_record *r) {
|
||||
r->release_gil_before_calling_cpp_dtor = true;
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a 'prepend' attribute, putting this at the beginning of the overload chain
|
||||
template <>
|
||||
struct process_attribute<prepend> : process_attribute_default<prepend> {
|
||||
static void init(const prepend &, function_record *r) { r->prepend = true; }
|
||||
};
|
||||
|
||||
/// Process an 'arithmetic' attribute for enums (does nothing here)
|
||||
template <>
|
||||
struct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};
|
||||
|
||||
template <typename... Ts>
|
||||
struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};
|
||||
|
||||
/**
|
||||
* Process a keep_alive call policy -- invokes keep_alive_impl during the
|
||||
* pre-call handler if both Nurse, Patient != 0 and use the post-call handler
|
||||
* otherwise
|
||||
*/
|
||||
template <size_t Nurse, size_t Patient>
|
||||
struct process_attribute<keep_alive<Nurse, Patient>>
|
||||
: public process_attribute_default<keep_alive<Nurse, Patient>> {
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
||||
static void precall(function_call &call) {
|
||||
keep_alive_impl(Nurse, Patient, call, handle());
|
||||
}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
||||
static void postcall(function_call &, handle) {}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
||||
static void precall(function_call &) {}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
||||
static void postcall(function_call &call, handle ret) {
|
||||
keep_alive_impl(Nurse, Patient, call, ret);
|
||||
}
|
||||
};
|
||||
|
||||
/// Recursively iterate over variadic template arguments
|
||||
template <typename... Args>
|
||||
struct process_attributes {
|
||||
static void init(const Args &...args, function_record *r) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
||||
using expander = int[];
|
||||
(void) expander{
|
||||
0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
||||
}
|
||||
static void init(const Args &...args, type_record *r) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
||||
using expander = int[];
|
||||
(void) expander{0,
|
||||
(process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
||||
}
|
||||
static void precall(function_call &call) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);
|
||||
using expander = int[];
|
||||
(void) expander{0,
|
||||
(process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};
|
||||
}
|
||||
static void postcall(function_call &call, handle fn_ret) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);
|
||||
using expander = int[];
|
||||
(void) expander{
|
||||
0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using is_call_guard = is_instantiation<call_guard, T>;
|
||||
|
||||
/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
|
||||
template <typename... Extra>
|
||||
using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
|
||||
|
||||
/// Check the number of named arguments at compile time
|
||||
template <typename... Extra,
|
||||
size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
|
||||
size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
|
||||
constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);
|
||||
return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
208
deps_src/pybind11/include/pybind11/buffer_info.h
Normal file
208
deps_src/pybind11/include/pybind11/buffer_info.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
pybind11/buffer_info.h: Python buffer object interface
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Default, C-style strides
|
||||
inline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
|
||||
auto ndim = shape.size();
|
||||
std::vector<ssize_t> strides(ndim, itemsize);
|
||||
if (ndim > 0) {
|
||||
for (size_t i = ndim - 1; i > 0; --i) {
|
||||
strides[i - 1] = strides[i] * shape[i];
|
||||
}
|
||||
}
|
||||
return strides;
|
||||
}
|
||||
|
||||
// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
|
||||
inline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
|
||||
auto ndim = shape.size();
|
||||
std::vector<ssize_t> strides(ndim, itemsize);
|
||||
for (size_t i = 1; i < ndim; ++i) {
|
||||
strides[i] = strides[i - 1] * shape[i - 1];
|
||||
}
|
||||
return strides;
|
||||
}
|
||||
|
||||
template <typename T, typename SFINAE = void>
|
||||
struct compare_buffer_info;
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Information record describing a Python buffer object
|
||||
struct buffer_info {
|
||||
void *ptr = nullptr; // Pointer to the underlying storage
|
||||
ssize_t itemsize = 0; // Size of individual items in bytes
|
||||
ssize_t size = 0; // Total number of entries
|
||||
std::string format; // For homogeneous buffers, this should be set to
|
||||
// format_descriptor<T>::format()
|
||||
ssize_t ndim = 0; // Number of dimensions
|
||||
std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension)
|
||||
std::vector<ssize_t> strides; // Number of bytes between adjacent entries
|
||||
// (for each per dimension)
|
||||
bool readonly = false; // flag to indicate if the underlying storage may be written to
|
||||
|
||||
buffer_info() = default;
|
||||
|
||||
buffer_info(void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t ndim,
|
||||
detail::any_container<ssize_t> shape_in,
|
||||
detail::any_container<ssize_t> strides_in,
|
||||
bool readonly = false)
|
||||
: ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),
|
||||
shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {
|
||||
if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {
|
||||
pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
|
||||
}
|
||||
for (size_t i = 0; i < (size_t) ndim; ++i) {
|
||||
size *= shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(T *ptr,
|
||||
detail::any_container<ssize_t> shape_in,
|
||||
detail::any_container<ssize_t> strides_in,
|
||||
bool readonly = false)
|
||||
: buffer_info(private_ctr_tag(),
|
||||
ptr,
|
||||
sizeof(T),
|
||||
format_descriptor<T>::format(),
|
||||
static_cast<ssize_t>(shape_in->size()),
|
||||
std::move(shape_in),
|
||||
std::move(strides_in),
|
||||
readonly) {}
|
||||
|
||||
buffer_info(void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t size,
|
||||
bool readonly = false)
|
||||
: buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(T *ptr, ssize_t size, bool readonly = false)
|
||||
: buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(const T *ptr, ssize_t size, bool readonly = true)
|
||||
: buffer_info(
|
||||
const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}
|
||||
|
||||
explicit buffer_info(Py_buffer *view, bool ownview = true)
|
||||
: buffer_info(
|
||||
view->buf,
|
||||
view->itemsize,
|
||||
view->format,
|
||||
view->ndim,
|
||||
{view->shape, view->shape + view->ndim},
|
||||
/* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
|
||||
* ignore this flag and return a view with NULL strides.
|
||||
* When strides are NULL, build them manually. */
|
||||
view->strides
|
||||
? std::vector<ssize_t>(view->strides, view->strides + view->ndim)
|
||||
: detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),
|
||||
(view->readonly != 0)) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
this->m_view = view;
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
this->ownview = ownview;
|
||||
}
|
||||
|
||||
buffer_info(const buffer_info &) = delete;
|
||||
buffer_info &operator=(const buffer_info &) = delete;
|
||||
|
||||
buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }
|
||||
|
||||
buffer_info &operator=(buffer_info &&rhs) noexcept {
|
||||
ptr = rhs.ptr;
|
||||
itemsize = rhs.itemsize;
|
||||
size = rhs.size;
|
||||
format = std::move(rhs.format);
|
||||
ndim = rhs.ndim;
|
||||
shape = std::move(rhs.shape);
|
||||
strides = std::move(rhs.strides);
|
||||
std::swap(m_view, rhs.m_view);
|
||||
std::swap(ownview, rhs.ownview);
|
||||
readonly = rhs.readonly;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~buffer_info() {
|
||||
if (m_view && ownview) {
|
||||
PyBuffer_Release(m_view);
|
||||
delete m_view;
|
||||
}
|
||||
}
|
||||
|
||||
Py_buffer *view() const { return m_view; }
|
||||
Py_buffer *&view() { return m_view; }
|
||||
|
||||
/* True if the buffer item type is equivalent to `T`. */
|
||||
// To define "equivalent" by example:
|
||||
// `buffer_info::item_type_is_equivalent_to<int>(b)` and
|
||||
// `buffer_info::item_type_is_equivalent_to<long>(b)` may both be true
|
||||
// on some platforms, but `int` and `unsigned` will never be equivalent.
|
||||
// For the ground truth, please inspect `detail::compare_buffer_info<>`.
|
||||
template <typename T>
|
||||
bool item_type_is_equivalent_to() const {
|
||||
return detail::compare_buffer_info<T>::compare(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
struct private_ctr_tag {};
|
||||
|
||||
buffer_info(private_ctr_tag,
|
||||
void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t ndim,
|
||||
detail::any_container<ssize_t> &&shape_in,
|
||||
detail::any_container<ssize_t> &&strides_in,
|
||||
bool readonly)
|
||||
: buffer_info(
|
||||
ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}
|
||||
|
||||
Py_buffer *m_view = nullptr;
|
||||
bool ownview = false;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename T, typename SFINAE>
|
||||
struct compare_buffer_info {
|
||||
static bool compare(const buffer_info &b) {
|
||||
// NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *`
|
||||
return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
|
||||
static bool compare(const buffer_info &b) {
|
||||
return (size_t) b.itemsize == sizeof(T)
|
||||
&& (b.format == format_descriptor<T>::value
|
||||
|| ((sizeof(T) == sizeof(long))
|
||||
&& b.format == (std::is_unsigned<T>::value ? "L" : "l"))
|
||||
|| ((sizeof(T) == sizeof(size_t))
|
||||
&& b.format == (std::is_unsigned<T>::value ? "N" : "n")));
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
2361
deps_src/pybind11/include/pybind11/cast.h
Normal file
2361
deps_src/pybind11/include/pybind11/cast.h
Normal file
File diff suppressed because it is too large
Load Diff
228
deps_src/pybind11/include/pybind11/chrono.h
Normal file
228
deps_src/pybind11/include/pybind11/chrono.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime
|
||||
|
||||
Copyright (c) 2016 Trent Houliston <trent@houliston.me> and
|
||||
Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <datetime.h>
|
||||
#include <mutex>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename type>
|
||||
class duration_caster {
|
||||
public:
|
||||
using rep = typename type::rep;
|
||||
using period = typename type::period;
|
||||
|
||||
// signed 25 bits required by the standard.
|
||||
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
|
||||
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
// If invoked with datetime.delta object
|
||||
if (PyDelta_Check(src.ptr())) {
|
||||
value = type(duration_cast<duration<rep, period>>(
|
||||
days(PyDateTime_DELTA_GET_DAYS(src.ptr()))
|
||||
+ seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))
|
||||
+ microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));
|
||||
return true;
|
||||
}
|
||||
// If invoked with a float we assume it is seconds and convert
|
||||
if (PyFloat_Check(src.ptr())) {
|
||||
value = type(duration_cast<duration<rep, period>>(
|
||||
duration<double>(PyFloat_AsDouble(src.ptr()))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a duration just return it back
|
||||
static const std::chrono::duration<rep, period> &
|
||||
get_duration(const std::chrono::duration<rep, period> &src) {
|
||||
return src;
|
||||
}
|
||||
static const std::chrono::duration<rep, period> &
|
||||
get_duration(const std::chrono::duration<rep, period> &&)
|
||||
= delete;
|
||||
|
||||
// If this is a time_point get the time_since_epoch
|
||||
template <typename Clock>
|
||||
static std::chrono::duration<rep, period>
|
||||
get_duration(const std::chrono::time_point<Clock, std::chrono::duration<rep, period>> &src) {
|
||||
return src.time_since_epoch();
|
||||
}
|
||||
|
||||
static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Use overloaded function to get our duration from our source
|
||||
// Works out if it is a duration or time_point and get the duration
|
||||
auto d = get_duration(src);
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
// Declare these special duration types so the conversions happen with the correct
|
||||
// primitive types (int)
|
||||
using dd_t = duration<int, std::ratio<86400>>;
|
||||
using ss_t = duration<int, std::ratio<1>>;
|
||||
using us_t = duration<int, std::micro>;
|
||||
|
||||
auto dd = duration_cast<dd_t>(d);
|
||||
auto subd = d - dd;
|
||||
auto ss = duration_cast<ss_t>(subd);
|
||||
auto us = duration_cast<us_t>(subd - ss);
|
||||
return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(type, const_name("datetime.timedelta"));
|
||||
};
|
||||
|
||||
inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {
|
||||
#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER)
|
||||
if (localtime_s(buf, time))
|
||||
return nullptr;
|
||||
return buf;
|
||||
#else
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
std::tm *tm_ptr = std::localtime(time);
|
||||
if (tm_ptr != nullptr) {
|
||||
*buf = *tm_ptr;
|
||||
}
|
||||
return tm_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is for casting times on the system clock into datetime.datetime instances
|
||||
template <typename Duration>
|
||||
class type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {
|
||||
public:
|
||||
using type = std::chrono::time_point<std::chrono::system_clock, Duration>;
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tm cal;
|
||||
microseconds msecs;
|
||||
|
||||
if (PyDateTime_Check(src.ptr())) {
|
||||
cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());
|
||||
cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());
|
||||
cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());
|
||||
cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
|
||||
cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
|
||||
cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));
|
||||
} else if (PyDate_Check(src.ptr())) {
|
||||
cal.tm_sec = 0;
|
||||
cal.tm_min = 0;
|
||||
cal.tm_hour = 0;
|
||||
cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
|
||||
cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
|
||||
cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(0);
|
||||
} else if (PyTime_Check(src.ptr())) {
|
||||
cal.tm_sec = PyDateTime_TIME_GET_SECOND(src.ptr());
|
||||
cal.tm_min = PyDateTime_TIME_GET_MINUTE(src.ptr());
|
||||
cal.tm_hour = PyDateTime_TIME_GET_HOUR(src.ptr());
|
||||
cal.tm_mday = 1; // This date (day, month, year) = (1, 0, 70)
|
||||
cal.tm_mon = 0; // represents 1-Jan-1970, which is the first
|
||||
cal.tm_year = 70; // earliest available date for Python's datetime
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(PyDateTime_TIME_GET_MICROSECOND(src.ptr()));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const std::chrono::time_point<std::chrono::system_clock, Duration> &src,
|
||||
return_value_policy /* policy */,
|
||||
handle /* parent */) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
// Get out microseconds, and make sure they are positive, to avoid bug in eastern
|
||||
// hemisphere time zones (cfr. https://github.com/pybind/pybind11/issues/2417)
|
||||
using us_t = duration<int, std::micro>;
|
||||
auto us = duration_cast<us_t>(src.time_since_epoch() % seconds(1));
|
||||
if (us.count() < 0) {
|
||||
us += duration_cast<us_t>(seconds(1));
|
||||
}
|
||||
|
||||
// Subtract microseconds BEFORE `system_clock::to_time_t`, because:
|
||||
// > If std::time_t has lower precision, it is implementation-defined whether the value is
|
||||
// rounded or truncated. (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t)
|
||||
std::time_t tt
|
||||
= system_clock::to_time_t(time_point_cast<system_clock::duration>(src - us));
|
||||
|
||||
std::tm localtime;
|
||||
std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime);
|
||||
if (!localtime_ptr) {
|
||||
throw cast_error("Unable to represent system_clock in local time");
|
||||
}
|
||||
return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,
|
||||
localtime.tm_mon + 1,
|
||||
localtime.tm_mday,
|
||||
localtime.tm_hour,
|
||||
localtime.tm_min,
|
||||
localtime.tm_sec,
|
||||
us.count());
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(type, const_name("datetime.datetime"));
|
||||
};
|
||||
|
||||
// Other clocks that are not the system clock are not measured as datetime.datetime objects
|
||||
// since they are not measured on calendar time. So instead we just make them timedeltas
|
||||
// Or if they have passed us a time as a float we convert that
|
||||
template <typename Clock, typename Duration>
|
||||
class type_caster<std::chrono::time_point<Clock, Duration>>
|
||||
: public duration_caster<std::chrono::time_point<Clock, Duration>> {};
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
class type_caster<std::chrono::duration<Rep, Period>>
|
||||
: public duration_caster<std::chrono::duration<Rep, Period>> {};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
2
deps_src/pybind11/include/pybind11/common.h
Normal file
2
deps_src/pybind11/include/pybind11/common.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "detail/common.h"
|
||||
#warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'."
|
||||
74
deps_src/pybind11/include/pybind11/complex.h
Normal file
74
deps_src/pybind11/include/pybind11/complex.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
pybind11/complex.h: Complex number support
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <complex>
|
||||
|
||||
/// glibc defines I as a macro which breaks things, e.g., boost template names
|
||||
#ifdef I
|
||||
# undef I
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
template <typename T>
|
||||
struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
|
||||
static constexpr const char c = format_descriptor<T>::c;
|
||||
static constexpr const char value[3] = {'Z', c, '\0'};
|
||||
static std::string format() { return std::string(value); }
|
||||
};
|
||||
|
||||
#ifndef PYBIND11_CPP17
|
||||
|
||||
template <typename T>
|
||||
constexpr const char
|
||||
format_descriptor<std::complex<T>,
|
||||
detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];
|
||||
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename T>
|
||||
struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
|
||||
static constexpr bool value = true;
|
||||
static constexpr int index = is_fmt_numeric<T>::index + 3;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class type_caster<std::complex<T>> {
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
if (!convert && !PyComplex_Check(src.ptr())) {
|
||||
return false;
|
||||
}
|
||||
Py_complex result = PyComplex_AsCComplex(src.ptr());
|
||||
if (result.real == -1.0 && PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
value = std::complex<T>((T) result.real, (T) result.imag);
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle
|
||||
cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
|
||||
};
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
15
deps_src/pybind11/include/pybind11/conduit/README.txt
Normal file
15
deps_src/pybind11/include/pybind11/conduit/README.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
NOTE
|
||||
----
|
||||
|
||||
The C++ code here
|
||||
|
||||
** only depends on <Python.h> **
|
||||
|
||||
and nothing else.
|
||||
|
||||
DO NOT ADD CODE WITH OTHER EXTERNAL DEPENDENCIES TO THIS DIRECTORY.
|
||||
|
||||
Read on:
|
||||
|
||||
pybind11_conduit_v1.h — Type-safe interoperability between different
|
||||
independent Python/C++ bindings systems.
|
||||
116
deps_src/pybind11/include/pybind11/conduit/pybind11_conduit_v1.h
Normal file
116
deps_src/pybind11/include/pybind11/conduit/pybind11_conduit_v1.h
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2024 The pybind Community.
|
||||
|
||||
/* The pybind11_conduit_v1 feature enables type-safe interoperability between
|
||||
|
||||
* different independent Python/C++ bindings systems,
|
||||
|
||||
* including pybind11 versions with different PYBIND11_INTERNALS_VERSION's.
|
||||
|
||||
* NOTE: The conduit feature
|
||||
only covers from-Python-to-C++ conversions, it
|
||||
does not cover from-C++-to-Python conversions.
|
||||
(For the latter, a different feature would have to be added.)
|
||||
|
||||
The naming of the feature is a bit misleading:
|
||||
|
||||
* The feature is in no way tied to pybind11 internals.
|
||||
|
||||
* It just happens to originate from pybind11 and currently still lives there.
|
||||
|
||||
* The only external dependency is <Python.h>.
|
||||
|
||||
The implementation is a VERY light-weight dependency. It is designed to be
|
||||
compatible with any ISO C++11 (or higher) compiler, and does NOT require
|
||||
C++ Exception Handling to be enabled.
|
||||
|
||||
Please see https://github.com/pybind/pybind11/pull/5296 for more background.
|
||||
|
||||
The implementation involves a
|
||||
|
||||
def _pybind11_conduit_v1_(
|
||||
self,
|
||||
pybind11_platform_abi_id: bytes,
|
||||
cpp_type_info_capsule: capsule,
|
||||
pointer_kind: bytes) -> capsule
|
||||
|
||||
method that is meant to be added to Python objects wrapping C++ objects
|
||||
(e.g. pybind11::class_-wrapped types).
|
||||
|
||||
The design of the _pybind11_conduit_v1_ feature provides two layers of
|
||||
protection against C++ ABI mismatches:
|
||||
|
||||
* The first and most important layer is that the pybind11_platform_abi_id's
|
||||
must match between extensions. — This will never be perfect, but is the same
|
||||
pragmatic approach used in pybind11 since 2017
|
||||
(https://github.com/pybind/pybind11/commit/96997a4b9d4ec3d389a570604394af5d5eee2557,
|
||||
PYBIND11_INTERNALS_ID).
|
||||
|
||||
* The second layer is that the typeid(std::type_info).name()'s must match
|
||||
between extensions.
|
||||
|
||||
The implementation below (which is shorter than this comment!), serves as a
|
||||
battle-tested specification. The main API is this one function:
|
||||
|
||||
auto *cpp_pointer = pybind11_conduit_v1::get_type_pointer_ephemeral<YourType>(py_obj);
|
||||
|
||||
It is meant to be a minimalistic reference implementation, intentionally
|
||||
without comprehensive error reporting. It is expected that major bindings
|
||||
systems will roll their own, compatible implementations, potentially with
|
||||
system-specific error reporting. The essential specifications all bindings
|
||||
systems need to agree on are merely:
|
||||
|
||||
* PYBIND11_PLATFORM_ABI_ID (const char* literal).
|
||||
|
||||
* The cpp_type_info capsule (see below: a void *ptr and a const char *name).
|
||||
|
||||
* The cpp_conduit capsule (see below: a void *ptr and a const char *name).
|
||||
|
||||
* "raw_pointer_ephemeral" means: the lifetime of the pointer is the lifetime
|
||||
of the py_obj.
|
||||
|
||||
*/
|
||||
|
||||
// THIS MUST STAY AT THE TOP!
|
||||
#include "pybind11_platform_abi_id.h"
|
||||
|
||||
#include <Python.h>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace pybind11_conduit_v1 {
|
||||
|
||||
inline void *get_raw_pointer_ephemeral(PyObject *py_obj, const std::type_info *cpp_type_info) {
|
||||
PyObject *cpp_type_info_capsule
|
||||
= PyCapsule_New(const_cast<void *>(static_cast<const void *>(cpp_type_info)),
|
||||
typeid(std::type_info).name(),
|
||||
nullptr);
|
||||
if (cpp_type_info_capsule == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
PyObject *cpp_conduit = PyObject_CallMethod(py_obj,
|
||||
"_pybind11_conduit_v1_",
|
||||
"yOy",
|
||||
PYBIND11_PLATFORM_ABI_ID,
|
||||
cpp_type_info_capsule,
|
||||
"raw_pointer_ephemeral");
|
||||
Py_DECREF(cpp_type_info_capsule);
|
||||
if (cpp_conduit == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
void *raw_ptr = PyCapsule_GetPointer(cpp_conduit, cpp_type_info->name());
|
||||
Py_DECREF(cpp_conduit);
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return raw_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *get_type_pointer_ephemeral(PyObject *py_obj) {
|
||||
void *raw_ptr = get_raw_pointer_ephemeral(py_obj, &typeid(T));
|
||||
if (raw_ptr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<T *>(raw_ptr);
|
||||
}
|
||||
|
||||
} // namespace pybind11_conduit_v1
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
// Copyright (c) 2024 The pybind Community.
|
||||
|
||||
// To maximize reusability:
|
||||
// DO NOT ADD CODE THAT REQUIRES C++ EXCEPTION HANDLING.
|
||||
|
||||
#include "wrap_include_python_h.h"
|
||||
|
||||
// Implementation details. DO NOT USE ELSEWHERE. (Unfortunately we cannot #undef them.)
|
||||
// This is duplicated here to maximize portability.
|
||||
#define PYBIND11_PLATFORM_ABI_ID_STRINGIFY(x) #x
|
||||
#define PYBIND11_PLATFORM_ABI_ID_TOSTRING(x) PYBIND11_PLATFORM_ABI_ID_STRINGIFY(x)
|
||||
|
||||
#ifdef PYBIND11_COMPILER_TYPE
|
||||
// // To maintain backward compatibility (see PR #5439).
|
||||
# define PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE ""
|
||||
#else
|
||||
# define PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE "_"
|
||||
# if defined(__MINGW32__)
|
||||
# define PYBIND11_COMPILER_TYPE "mingw"
|
||||
# elif defined(__CYGWIN__)
|
||||
# define PYBIND11_COMPILER_TYPE "gcc_cygwin"
|
||||
# elif defined(_MSC_VER)
|
||||
# define PYBIND11_COMPILER_TYPE "msvc"
|
||||
# elif defined(__clang__) || defined(__GNUC__)
|
||||
# define PYBIND11_COMPILER_TYPE "system" // Assumed compatible with system compiler.
|
||||
# else
|
||||
# error "Unknown PYBIND11_COMPILER_TYPE: PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// PR #5439 made this macro obsolete. However, there are many manipulations of this macro in the
|
||||
// wild. Therefore, to maintain backward compatibility, it is kept around.
|
||||
#ifndef PYBIND11_STDLIB
|
||||
# define PYBIND11_STDLIB ""
|
||||
#endif
|
||||
|
||||
#ifndef PYBIND11_BUILD_ABI
|
||||
# if defined(_MSC_VER) // See PR #4953.
|
||||
# if defined(_MT) && defined(_DLL) // Corresponding to CL command line options /MD or /MDd.
|
||||
# if (_MSC_VER) / 100 == 19
|
||||
# define PYBIND11_BUILD_ABI "_md_mscver19"
|
||||
# else
|
||||
# error "Unknown major version for MSC_VER: PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
# elif defined(_MT) // Corresponding to CL command line options /MT or /MTd.
|
||||
# define PYBIND11_BUILD_ABI "_mt_mscver" PYBIND11_PLATFORM_ABI_ID_TOSTRING(_MSC_VER)
|
||||
# else
|
||||
# if (_MSC_VER) / 100 == 19
|
||||
# define PYBIND11_BUILD_ABI "_none_mscver19"
|
||||
# else
|
||||
# error "Unknown major version for MSC_VER: PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(_LIBCPP_ABI_VERSION) // https://libcxx.llvm.org/DesignDocs/ABIVersioning.html
|
||||
# define PYBIND11_BUILD_ABI \
|
||||
"_libcpp_abi" PYBIND11_PLATFORM_ABI_ID_TOSTRING(_LIBCPP_ABI_VERSION)
|
||||
# elif defined(_GLIBCXX_USE_CXX11_ABI) // See PR #5439.
|
||||
# if defined(__NVCOMPILER)
|
||||
// // Assume that NVHPC is in the 1xxx ABI family.
|
||||
// // THIS ASSUMPTION IS NOT FUTURE PROOF but apparently the best we can do.
|
||||
// // Please let us know if there is a way to validate the assumption here.
|
||||
# elif !defined(__GXX_ABI_VERSION)
|
||||
# error \
|
||||
"Unknown platform or compiler (_GLIBCXX_USE_CXX11_ABI): PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
# if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION < 1002 || __GXX_ABI_VERSION >= 2000
|
||||
# error "Unknown platform or compiler (__GXX_ABI_VERSION): PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
# define PYBIND11_BUILD_ABI \
|
||||
"_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_" PYBIND11_PLATFORM_ABI_ID_TOSTRING( \
|
||||
_GLIBCXX_USE_CXX11_ABI)
|
||||
# else
|
||||
# error "Unknown platform or compiler: PLEASE REVISE THIS CODE."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// On MSVC, debug and release builds are not ABI-compatible!
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
# define PYBIND11_BUILD_TYPE "_debug"
|
||||
#else
|
||||
# define PYBIND11_BUILD_TYPE ""
|
||||
#endif
|
||||
|
||||
#define PYBIND11_PLATFORM_ABI_ID \
|
||||
PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI PYBIND11_BUILD_TYPE
|
||||
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
// Copyright (c) 2024 The pybind Community.
|
||||
|
||||
// STRONG REQUIREMENT:
|
||||
// This header is a wrapper around `#include <Python.h>`, therefore it
|
||||
// MUST BE INCLUDED BEFORE ANY STANDARD HEADERS are included.
|
||||
// See also:
|
||||
// https://docs.python.org/3/c-api/intro.html#include-files
|
||||
// Quoting from there:
|
||||
// Note: Since Python may define some pre-processor definitions which affect
|
||||
// the standard headers on some systems, you must include Python.h before
|
||||
// any standard headers are included.
|
||||
|
||||
// To maximize reusability:
|
||||
// DO NOT ADD CODE THAT REQUIRES C++ EXCEPTION HANDLING.
|
||||
|
||||
// Disable linking to pythonX_d.lib on Windows in debug mode.
|
||||
#if defined(_MSC_VER) && defined(_DEBUG) && !defined(Py_DEBUG)
|
||||
// Workaround for a VS 2022 issue.
|
||||
// See https://github.com/pybind/pybind11/pull/3497 for full context.
|
||||
// NOTE: This workaround knowingly violates the Python.h include order
|
||||
// requirement (see above).
|
||||
# include <yvals.h>
|
||||
# if _MSVC_STL_VERSION >= 143
|
||||
# include <crtdefs.h>
|
||||
# endif
|
||||
# define PYBIND11_DEBUG_MARKER
|
||||
# undef _DEBUG
|
||||
#endif
|
||||
|
||||
// Don't let Python.h #define (v)snprintf as macro because they are implemented
|
||||
// properly in Visual Studio since 2015.
|
||||
#if defined(_MSC_VER)
|
||||
# define HAVE_SNPRINTF 1
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4505)
|
||||
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
#include <frameobject.h>
|
||||
#include <pythread.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if defined(PYBIND11_DEBUG_MARKER)
|
||||
# define _DEBUG 1
|
||||
# undef PYBIND11_DEBUG_MARKER
|
||||
#endif
|
||||
|
||||
// Python #defines overrides on all sorts of core functions, which
|
||||
// tends to wreak havok in C++ codebases that expect these to work
|
||||
// like regular functions (potentially with several overloads).
|
||||
#if defined(isalnum)
|
||||
# undef isalnum
|
||||
# undef isalpha
|
||||
# undef islower
|
||||
# undef isspace
|
||||
# undef isupper
|
||||
# undef tolower
|
||||
# undef toupper
|
||||
#endif
|
||||
|
||||
#if defined(copysign)
|
||||
# undef copysign
|
||||
#endif
|
||||
56
deps_src/pybind11/include/pybind11/critical_section.h
Normal file
56
deps_src/pybind11/include/pybind11/critical_section.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2016-2025 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pytypes.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
/// This does not do anything if there's a GIL. On free-threaded Python,
|
||||
/// it locks an object. This uses the CPython API, which has limits
|
||||
class scoped_critical_section {
|
||||
public:
|
||||
#ifdef Py_GIL_DISABLED
|
||||
explicit scoped_critical_section(handle obj1, handle obj2 = handle{}) {
|
||||
if (obj1) {
|
||||
if (obj2) {
|
||||
PyCriticalSection2_Begin(§ion2, obj1.ptr(), obj2.ptr());
|
||||
rank = 2;
|
||||
} else {
|
||||
PyCriticalSection_Begin(§ion, obj1.ptr());
|
||||
rank = 1;
|
||||
}
|
||||
} else if (obj2) {
|
||||
PyCriticalSection_Begin(§ion, obj2.ptr());
|
||||
rank = 1;
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_critical_section() {
|
||||
if (rank == 1) {
|
||||
PyCriticalSection_End(§ion);
|
||||
} else if (rank == 2) {
|
||||
PyCriticalSection2_End(§ion2);
|
||||
}
|
||||
}
|
||||
#else
|
||||
explicit scoped_critical_section(handle, handle = handle{}) {};
|
||||
~scoped_critical_section() = default;
|
||||
#endif
|
||||
|
||||
scoped_critical_section(const scoped_critical_section &) = delete;
|
||||
scoped_critical_section &operator=(const scoped_critical_section &) = delete;
|
||||
|
||||
private:
|
||||
#ifdef Py_GIL_DISABLED
|
||||
int rank{0};
|
||||
union {
|
||||
PyCriticalSection section;
|
||||
PyCriticalSection2 section2;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
823
deps_src/pybind11/include/pybind11/detail/class.h
Normal file
823
deps_src/pybind11/include/pybind11/detail/class.h
Normal file
@@ -0,0 +1,823 @@
|
||||
/*
|
||||
pybind11/detail/class.h: Python C API implementation details for py::class_
|
||||
|
||||
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/attr.h>
|
||||
#include <pybind11/options.h>
|
||||
|
||||
#include "exception_translation.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
# define PYBIND11_BUILTIN_QUALNAME
|
||||
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
|
||||
#else
|
||||
// In PyPy, we still set __qualname__ so that we can produce reliable function type
|
||||
// signatures; in CPython this macro expands to nothing:
|
||||
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) \
|
||||
setattr((PyObject *) obj, "__qualname__", nameobj)
|
||||
#endif
|
||||
|
||||
inline std::string get_fully_qualified_tp_name(PyTypeObject *type) {
|
||||
#if !defined(PYPY_VERSION)
|
||||
return type->tp_name;
|
||||
#else
|
||||
auto module_name = handle((PyObject *) type).attr("__module__").cast<std::string>();
|
||||
if (module_name == PYBIND11_BUILTINS_MODULE)
|
||||
return type->tp_name;
|
||||
else
|
||||
return std::move(module_name) + "." + type->tp_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline PyTypeObject *type_incref(PyTypeObject *type) {
|
||||
Py_INCREF(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
|
||||
/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.
|
||||
extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {
|
||||
return PyProperty_Type.tp_descr_get(self, cls, cls);
|
||||
}
|
||||
|
||||
/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.
|
||||
extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
|
||||
PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
|
||||
return PyProperty_Type.tp_descr_set(self, cls, value);
|
||||
}
|
||||
|
||||
// Forward declaration to use in `make_static_property_type()`
|
||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type);
|
||||
|
||||
/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`
|
||||
methods are modified to always use the object type instead of a concrete instance.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_static_property_type() {
|
||||
constexpr auto *name = "pybind11_static_property";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_static_property_type(): error allocating type!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
# ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
# endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyProperty_Type);
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
type->tp_descr_get = pybind11_static_get;
|
||||
type->tp_descr_set = pybind11_static_set;
|
||||
|
||||
# if PY_VERSION_HEX >= 0x030C0000
|
||||
// Since Python-3.12 property-derived types are required to
|
||||
// have dynamic attributes (to set `__doc__`)
|
||||
enable_dynamic_attributes(heap_type);
|
||||
# endif
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("make_static_property_type(): failure in PyType_Ready()!");
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str(PYBIND11_DUMMY_MODULE_NAME));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
#else // PYPY
|
||||
|
||||
/** PyPy has some issues with the above C API, so we evaluate Python code instead.
|
||||
This function will only be called once so performance isn't really a concern.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_static_property_type() {
|
||||
auto d = dict();
|
||||
PyObject *result = PyRun_String(R"(\
|
||||
class pybind11_static_property(property):
|
||||
def __get__(self, obj, cls):
|
||||
return property.__get__(self, cls, cls)
|
||||
|
||||
def __set__(self, obj, value):
|
||||
cls = obj if isinstance(obj, type) else type(obj)
|
||||
property.__set__(self, cls, value)
|
||||
)",
|
||||
Py_file_input,
|
||||
d.ptr(),
|
||||
d.ptr());
|
||||
if (result == nullptr)
|
||||
throw error_already_set();
|
||||
Py_DECREF(result);
|
||||
return (PyTypeObject *) d["pybind11_static_property"].cast<object>().release().ptr();
|
||||
}
|
||||
|
||||
#endif // PYPY
|
||||
|
||||
/** Types with static properties need to handle `Type.static_prop = x` in a specific way.
|
||||
By default, Python replaces the `static_property` itself, but for wrapped C++ types
|
||||
we need to call `static_property.__set__()` in order to propagate the new value to
|
||||
the underlying C++ data structure. */
|
||||
extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {
|
||||
// Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw
|
||||
// descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).
|
||||
PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
|
||||
|
||||
// The following assignment combinations are possible:
|
||||
// 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)`
|
||||
// 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop`
|
||||
// 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment
|
||||
auto *const static_prop = (PyObject *) get_internals().static_property_type;
|
||||
const auto call_descr_set = (descr != nullptr) && (value != nullptr)
|
||||
&& (PyObject_IsInstance(descr, static_prop) != 0)
|
||||
&& (PyObject_IsInstance(value, static_prop) == 0);
|
||||
if (call_descr_set) {
|
||||
// Call `static_property.__set__()` instead of replacing the `static_property`.
|
||||
#if !defined(PYPY_VERSION)
|
||||
return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
|
||||
#else
|
||||
if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) {
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Replace existing attribute.
|
||||
return PyType_Type.tp_setattro(obj, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing
|
||||
* methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function,
|
||||
* when called on a class, or a PyMethod, when called on an instance. Override that behaviour here
|
||||
* to do a special case bypass for PyInstanceMethod_Types.
|
||||
*/
|
||||
extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {
|
||||
PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
|
||||
if (descr && PyInstanceMethod_Check(descr)) {
|
||||
Py_INCREF(descr);
|
||||
return descr;
|
||||
}
|
||||
return PyType_Type.tp_getattro(obj, name);
|
||||
}
|
||||
|
||||
/// metaclass `__call__` function that is used to create all pybind11 objects.
|
||||
extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {
|
||||
|
||||
// use the default metaclass call to create/initialize the object
|
||||
PyObject *self = PyType_Type.tp_call(type, args, kwargs);
|
||||
if (self == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ensure that the base __init__ function(s) were called
|
||||
values_and_holders vhs(self);
|
||||
for (const auto &vh : vhs) {
|
||||
if (!vh.holder_constructed() && !vhs.is_redundant_value_and_holder(vh)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s.__init__() must be called when overriding __init__",
|
||||
get_fully_qualified_tp_name(vh.type->type).c_str());
|
||||
Py_DECREF(self);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Cleanup the type-info for a pybind11-registered type.
|
||||
extern "C" inline void pybind11_meta_dealloc(PyObject *obj) {
|
||||
with_internals([obj](internals &internals) {
|
||||
auto *type = (PyTypeObject *) obj;
|
||||
|
||||
// A pybind11-registered type will:
|
||||
// 1) be found in internals.registered_types_py
|
||||
// 2) have exactly one associated `detail::type_info`
|
||||
auto found_type = internals.registered_types_py.find(type);
|
||||
if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1
|
||||
&& found_type->second[0]->type == type) {
|
||||
|
||||
auto *tinfo = found_type->second[0];
|
||||
auto tindex = std::type_index(*tinfo->cpptype);
|
||||
internals.direct_conversions.erase(tindex);
|
||||
|
||||
if (tinfo->module_local) {
|
||||
get_local_internals().registered_types_cpp.erase(tindex);
|
||||
} else {
|
||||
internals.registered_types_cpp.erase(tindex);
|
||||
}
|
||||
internals.registered_types_py.erase(tinfo->type);
|
||||
|
||||
// Actually just `std::erase_if`, but that's only available in C++20
|
||||
auto &cache = internals.inactive_override_cache;
|
||||
for (auto it = cache.begin(), last = cache.end(); it != last;) {
|
||||
if (it->first == (PyObject *) tinfo->type) {
|
||||
it = cache.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
delete tinfo;
|
||||
}
|
||||
});
|
||||
|
||||
PyType_Type.tp_dealloc(obj);
|
||||
}
|
||||
|
||||
/** This metaclass is assigned by default to all pybind11 types and is required in order
|
||||
for static properties to function correctly. Users may override this using `py::metaclass`.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_default_metaclass() {
|
||||
constexpr auto *name = "pybind11_type";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_default_metaclass(): error allocating metaclass!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyType_Type);
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
|
||||
type->tp_call = pybind11_meta_call;
|
||||
|
||||
type->tp_setattro = pybind11_meta_setattro;
|
||||
type->tp_getattro = pybind11_meta_getattro;
|
||||
|
||||
type->tp_dealloc = pybind11_meta_dealloc;
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!");
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str(PYBIND11_DUMMY_MODULE_NAME));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/// For multiple inheritance types we need to recursively register/deregister base pointers for any
|
||||
/// base classes with pointers that are difference from the instance value pointer so that we can
|
||||
/// correctly recognize an offset base class pointer. This calls a function with any offset base
|
||||
/// ptrs.
|
||||
inline void traverse_offset_bases(void *valueptr,
|
||||
const detail::type_info *tinfo,
|
||||
instance *self,
|
||||
bool (*f)(void * /*parentptr*/, instance * /*self*/)) {
|
||||
for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
|
||||
if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
|
||||
for (auto &c : parent_tinfo->implicit_casts) {
|
||||
if (c.first == tinfo->cpptype) {
|
||||
auto *parentptr = c.second(valueptr);
|
||||
if (parentptr != valueptr) {
|
||||
f(parentptr, self);
|
||||
}
|
||||
traverse_offset_bases(parentptr, parent_tinfo, self, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
inline void enable_try_inc_ref(PyObject *obj) {
|
||||
// TODO: Replace with PyUnstable_Object_EnableTryIncRef when available.
|
||||
// See https://github.com/python/cpython/issues/128844
|
||||
if (_Py_IsImmortal(obj)) {
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&obj->ob_ref_shared);
|
||||
if ((shared & _Py_REF_SHARED_FLAG_MASK) != 0) {
|
||||
// Nothing to do if it's in WEAKREFS, QUEUED, or MERGED states.
|
||||
return;
|
||||
}
|
||||
if (_Py_atomic_compare_exchange_ssize(
|
||||
&obj->ob_ref_shared, &shared, shared | _Py_REF_MAYBE_WEAKREF)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool register_instance_impl(void *ptr, instance *self) {
|
||||
#ifdef Py_GIL_DISABLED
|
||||
enable_try_inc_ref(reinterpret_cast<PyObject *>(self));
|
||||
#endif
|
||||
with_instance_map(ptr, [&](instance_map &instances) { instances.emplace(ptr, self); });
|
||||
return true; // unused, but gives the same signature as the deregister func
|
||||
}
|
||||
inline bool deregister_instance_impl(void *ptr, instance *self) {
|
||||
return with_instance_map(ptr, [&](instance_map &instances) {
|
||||
auto range = instances.equal_range(ptr);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
if (self == it->second) {
|
||||
instances.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
inline void register_instance(instance *self, void *valptr, const type_info *tinfo) {
|
||||
register_instance_impl(valptr, self);
|
||||
if (!tinfo->simple_ancestors) {
|
||||
traverse_offset_bases(valptr, tinfo, self, register_instance_impl);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {
|
||||
bool ret = deregister_instance_impl(valptr, self);
|
||||
if (!tinfo->simple_ancestors) {
|
||||
traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Instance creation function for all pybind11 types. It allocates the internal instance layout
|
||||
/// for holding C++ objects and holders. Allocation is done lazily (the first time the instance is
|
||||
/// cast to a reference or pointer), and initialization is done by an `__init__` function.
|
||||
inline PyObject *make_new_instance(PyTypeObject *type) {
|
||||
#if defined(PYPY_VERSION)
|
||||
// PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first
|
||||
// inherited object is a plain Python type (i.e. not derived from an extension type). Fix it.
|
||||
ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));
|
||||
if (type->tp_basicsize < instance_size) {
|
||||
type->tp_basicsize = instance_size;
|
||||
}
|
||||
#endif
|
||||
PyObject *self = type->tp_alloc(type, 0);
|
||||
auto *inst = reinterpret_cast<instance *>(self);
|
||||
// Allocate the value/holder internals:
|
||||
inst->allocate_layout();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Instance creation function for all pybind11 types. It only allocates space for the
|
||||
/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.
|
||||
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {
|
||||
return make_new_instance(type);
|
||||
}
|
||||
|
||||
/// An `__init__` function constructs the C++ object. Users should provide at least one
|
||||
/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
|
||||
/// following default function will be used which simply throws an exception.
|
||||
extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
std::string msg = get_fully_qualified_tp_name(type) + ": No constructor defined!";
|
||||
set_error(PyExc_TypeError, msg.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline void add_patient(PyObject *nurse, PyObject *patient) {
|
||||
auto *instance = reinterpret_cast<detail::instance *>(nurse);
|
||||
instance->has_patients = true;
|
||||
Py_INCREF(patient);
|
||||
|
||||
with_internals([&](internals &internals) { internals.patients[nurse].push_back(patient); });
|
||||
}
|
||||
|
||||
inline void clear_patients(PyObject *self) {
|
||||
auto *instance = reinterpret_cast<detail::instance *>(self);
|
||||
std::vector<PyObject *> patients;
|
||||
|
||||
with_internals([&](internals &internals) {
|
||||
auto pos = internals.patients.find(self);
|
||||
|
||||
if (pos == internals.patients.end()) {
|
||||
pybind11_fail(
|
||||
"FATAL: Internal consistency check failed: Invalid clear_patients() call.");
|
||||
}
|
||||
|
||||
// Clearing the patients can cause more Python code to run, which
|
||||
// can invalidate the iterator. Extract the vector of patients
|
||||
// from the unordered_map first.
|
||||
patients = std::move(pos->second);
|
||||
internals.patients.erase(pos);
|
||||
});
|
||||
|
||||
instance->has_patients = false;
|
||||
for (PyObject *&patient : patients) {
|
||||
Py_CLEAR(patient);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears all internal data from the instance and removes it from registered instances in
|
||||
/// preparation for deallocation.
|
||||
inline void clear_instance(PyObject *self) {
|
||||
auto *instance = reinterpret_cast<detail::instance *>(self);
|
||||
|
||||
// Deallocate any values/holders, if present:
|
||||
for (auto &v_h : values_and_holders(instance)) {
|
||||
if (v_h) {
|
||||
|
||||
// We have to deregister before we call dealloc because, for virtual MI types, we still
|
||||
// need to be able to get the parent pointers.
|
||||
if (v_h.instance_registered()
|
||||
&& !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {
|
||||
pybind11_fail(
|
||||
"pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
|
||||
}
|
||||
|
||||
if (instance->owned || v_h.holder_constructed()) {
|
||||
v_h.type->dealloc(v_h);
|
||||
}
|
||||
} else if (v_h.holder_constructed()) {
|
||||
v_h.type->dealloc(v_h); // Disowned instance.
|
||||
}
|
||||
}
|
||||
// Deallocate the value/holder layout internals:
|
||||
instance->deallocate_layout();
|
||||
|
||||
if (instance->weakrefs) {
|
||||
PyObject_ClearWeakRefs(self);
|
||||
}
|
||||
|
||||
PyObject **dict_ptr = _PyObject_GetDictPtr(self);
|
||||
if (dict_ptr) {
|
||||
Py_CLEAR(*dict_ptr);
|
||||
}
|
||||
|
||||
if (instance->has_patients) {
|
||||
clear_patients(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
|
||||
/// to destroy the C++ object itself, while the rest is Python bookkeeping.
|
||||
extern "C" inline void pybind11_object_dealloc(PyObject *self) {
|
||||
auto *type = Py_TYPE(self);
|
||||
|
||||
// If this is a GC tracked object, untrack it first
|
||||
// Note that the track call is implicitly done by the
|
||||
// default tp_alloc, which we never override.
|
||||
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) != 0) {
|
||||
PyObject_GC_UnTrack(self);
|
||||
}
|
||||
|
||||
clear_instance(self);
|
||||
|
||||
type->tp_free(self);
|
||||
|
||||
// This was not needed before Python 3.8 (Python issue 35810)
|
||||
// https://github.com/pybind/pybind11/issues/1946
|
||||
Py_DECREF(type);
|
||||
}
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wredundant-decls")
|
||||
|
||||
std::string error_string();
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
/** Create the type which can be used as a common base for all classes. This is
|
||||
needed in order to satisfy Python's requirements for multiple inheritance.
|
||||
Return value: New reference. */
|
||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
|
||||
constexpr auto *name = "pybind11_object";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_object_base_type(): error allocating type!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyBaseObject_Type);
|
||||
type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
|
||||
type->tp_new = pybind11_object_new;
|
||||
type->tp_init = pybind11_object_init;
|
||||
type->tp_dealloc = pybind11_object_dealloc;
|
||||
|
||||
/* Support weak references (needed for the keep_alive feature) */
|
||||
type->tp_weaklistoffset = offsetof(instance, weakrefs);
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("PyType_Ready failed in make_object_base_type(): " + error_string());
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str(PYBIND11_DUMMY_MODULE_NAME));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
|
||||
return (PyObject *) heap_type;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
|
||||
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
PyObject_VisitManagedDict(self, visit, arg);
|
||||
#else
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
Py_VISIT(dict);
|
||||
#endif
|
||||
// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse
|
||||
#if PY_VERSION_HEX >= 0x03090000
|
||||
Py_VISIT(Py_TYPE(self));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Allow the GC to clear the dictionary.
|
||||
extern "C" inline int pybind11_clear(PyObject *self) {
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
PyObject_ClearManagedDict(self);
|
||||
#else
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
Py_CLEAR(dict);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Give instances of this type a `__dict__` and opt into garbage collection.
|
||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
||||
#ifdef PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET
|
||||
type->tp_dictoffset = type->tp_basicsize; // place dict at the end
|
||||
type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it
|
||||
#else
|
||||
type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;
|
||||
#endif
|
||||
type->tp_traverse = pybind11_traverse;
|
||||
type->tp_clear = pybind11_clear;
|
||||
|
||||
static PyGetSetDef getset[]
|
||||
= {{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, nullptr, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr}};
|
||||
type->tp_getset = getset;
|
||||
}
|
||||
|
||||
/// buffer_protocol: Fill in the view as specified by flags.
|
||||
extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
|
||||
// Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
|
||||
type_info *tinfo = nullptr;
|
||||
for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
|
||||
tinfo = get_type_info((PyTypeObject *) type.ptr());
|
||||
if (tinfo && tinfo->get_buffer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view == nullptr || !tinfo || !tinfo->get_buffer) {
|
||||
if (view) {
|
||||
view->obj = nullptr;
|
||||
}
|
||||
set_error(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
|
||||
return -1;
|
||||
}
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
std::unique_ptr<buffer_info> info = nullptr;
|
||||
try {
|
||||
info.reset(tinfo->get_buffer(obj, tinfo->get_buffer_data));
|
||||
} catch (...) {
|
||||
try_translate_exceptions();
|
||||
raise_from(PyExc_BufferError, "Error getting buffer");
|
||||
return -1;
|
||||
}
|
||||
if (info == nullptr) {
|
||||
pybind11_fail("FATAL UNEXPECTED SITUATION: tinfo->get_buffer() returned nullptr.");
|
||||
}
|
||||
|
||||
if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
|
||||
// view->obj = nullptr; // Was just memset to 0, so not necessary
|
||||
set_error(PyExc_BufferError, "Writable buffer requested for readonly storage");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Fill in all the information, and then downgrade as requested by the caller, or raise an
|
||||
// error if that's not possible.
|
||||
view->itemsize = info->itemsize;
|
||||
view->len = view->itemsize;
|
||||
for (auto s : info->shape) {
|
||||
view->len *= s;
|
||||
}
|
||||
view->ndim = static_cast<int>(info->ndim);
|
||||
view->shape = info->shape.data();
|
||||
view->strides = info->strides.data();
|
||||
view->readonly = static_cast<int>(info->readonly);
|
||||
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
|
||||
view->format = const_cast<char *>(info->format.c_str());
|
||||
}
|
||||
|
||||
// Note, all contiguity flags imply PyBUF_STRIDES and lower.
|
||||
if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) {
|
||||
if (PyBuffer_IsContiguous(view, 'C') == 0) {
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
set_error(PyExc_BufferError,
|
||||
"C-contiguous buffer requested for discontiguous storage");
|
||||
return -1;
|
||||
}
|
||||
} else if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) {
|
||||
if (PyBuffer_IsContiguous(view, 'F') == 0) {
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
set_error(PyExc_BufferError,
|
||||
"Fortran-contiguous buffer requested for discontiguous storage");
|
||||
return -1;
|
||||
}
|
||||
} else if ((flags & PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS) {
|
||||
if (PyBuffer_IsContiguous(view, 'A') == 0) {
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
set_error(PyExc_BufferError, "Contiguous buffer requested for discontiguous storage");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if ((flags & PyBUF_STRIDES) != PyBUF_STRIDES) {
|
||||
// If no strides are requested, the buffer must be C-contiguous.
|
||||
// https://docs.python.org/3/c-api/buffer.html#contiguity-requests
|
||||
if (PyBuffer_IsContiguous(view, 'C') == 0) {
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
set_error(PyExc_BufferError,
|
||||
"C-contiguous buffer requested for discontiguous storage");
|
||||
return -1;
|
||||
}
|
||||
|
||||
view->strides = nullptr;
|
||||
|
||||
// Since this is a contiguous buffer, it can also pretend to be 1D.
|
||||
if ((flags & PyBUF_ND) != PyBUF_ND) {
|
||||
view->shape = nullptr;
|
||||
view->ndim = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set these after all checks so they don't leak out into the caller, and can be automatically
|
||||
// cleaned up on error.
|
||||
view->buf = info->ptr;
|
||||
view->internal = info.release();
|
||||
view->obj = obj;
|
||||
Py_INCREF(view->obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// buffer_protocol: Release the resources of the buffer.
|
||||
extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
|
||||
delete (buffer_info *) view->internal;
|
||||
}
|
||||
|
||||
/// Give this type a buffer interface.
|
||||
inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
|
||||
heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
|
||||
|
||||
heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
|
||||
heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
|
||||
}
|
||||
|
||||
/** Create a brand new Python type according to the `type_record` specification.
|
||||
Return value: New reference. */
|
||||
inline PyObject *make_new_python_type(const type_record &rec) {
|
||||
auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));
|
||||
|
||||
auto qualname = name;
|
||||
if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
|
||||
qualname = reinterpret_steal<object>(
|
||||
PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
|
||||
}
|
||||
|
||||
object module_ = get_module_name_if_available(rec.scope);
|
||||
const auto *full_name = c_str(
|
||||
#if !defined(PYPY_VERSION)
|
||||
module_ ? str(module_).cast<std::string>() + "." + rec.name :
|
||||
#endif
|
||||
rec.name);
|
||||
|
||||
char *tp_doc = nullptr;
|
||||
if (rec.doc && options::show_user_defined_docstrings()) {
|
||||
/* Allocate memory for docstring (Python will free this later on) */
|
||||
size_t size = std::strlen(rec.doc) + 1;
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
tp_doc = (char *) PyMem_MALLOC(size);
|
||||
#else
|
||||
tp_doc = (char *) PyObject_MALLOC(size);
|
||||
#endif
|
||||
std::memcpy((void *) tp_doc, rec.doc, size);
|
||||
}
|
||||
|
||||
auto &internals = get_internals();
|
||||
auto bases = tuple(rec.bases);
|
||||
auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *metaclass
|
||||
= rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;
|
||||
|
||||
auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail(std::string(rec.name) + ": Unable to create type object!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name.release().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = qualname.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = full_name;
|
||||
type->tp_doc = tp_doc;
|
||||
type->tp_base = type_incref((PyTypeObject *) base);
|
||||
type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
|
||||
if (!bases.empty()) {
|
||||
type->tp_bases = bases.release().ptr();
|
||||
}
|
||||
|
||||
/* Don't inherit base __init__ */
|
||||
type->tp_init = pybind11_object_init;
|
||||
|
||||
/* Supported protocols */
|
||||
type->tp_as_number = &heap_type->as_number;
|
||||
type->tp_as_sequence = &heap_type->as_sequence;
|
||||
type->tp_as_mapping = &heap_type->as_mapping;
|
||||
type->tp_as_async = &heap_type->as_async;
|
||||
|
||||
/* Flags */
|
||||
type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
|
||||
if (!rec.is_final) {
|
||||
type->tp_flags |= Py_TPFLAGS_BASETYPE;
|
||||
}
|
||||
|
||||
if (rec.dynamic_attr) {
|
||||
enable_dynamic_attributes(heap_type);
|
||||
}
|
||||
|
||||
if (rec.buffer_protocol) {
|
||||
enable_buffer_protocol(heap_type);
|
||||
}
|
||||
|
||||
if (rec.custom_type_setup_callback) {
|
||||
rec.custom_type_setup_callback(heap_type);
|
||||
}
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail(std::string(rec.name) + ": PyType_Ready failed: " + error_string());
|
||||
}
|
||||
|
||||
assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
|
||||
|
||||
/* Register type with the parent scope */
|
||||
if (rec.scope) {
|
||||
setattr(rec.scope, rec.name, (PyObject *) type);
|
||||
} else {
|
||||
Py_INCREF(type); // Keep it alive forever (reference leak)
|
||||
}
|
||||
|
||||
if (module_) { // Needed by pydoc
|
||||
setattr((PyObject *) type, "__module__", module_);
|
||||
}
|
||||
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, qualname);
|
||||
|
||||
return (PyObject *) type;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
1348
deps_src/pybind11/include/pybind11/detail/common.h
Normal file
1348
deps_src/pybind11/include/pybind11/detail/common.h
Normal file
File diff suppressed because it is too large
Load Diff
75
deps_src/pybind11/include/pybind11/detail/cpp_conduit.h
Normal file
75
deps_src/pybind11/include/pybind11/detail/cpp_conduit.h
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2024 The pybind Community.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/pytypes.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "internals.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Forward declaration needed here: Refactoring opportunity.
|
||||
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *);
|
||||
|
||||
inline bool type_is_managed_by_our_internals(PyTypeObject *type_obj) {
|
||||
#if defined(PYPY_VERSION)
|
||||
auto &internals = get_internals();
|
||||
return bool(internals.registered_types_py.find(type_obj)
|
||||
!= internals.registered_types_py.end());
|
||||
#else
|
||||
return bool(type_obj->tp_new == pybind11_object_new);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool is_instance_method_of_type(PyTypeObject *type_obj, PyObject *attr_name) {
|
||||
PyObject *descr = _PyType_Lookup(type_obj, attr_name);
|
||||
return bool((descr != nullptr) && PyInstanceMethod_Check(descr));
|
||||
}
|
||||
|
||||
inline object try_get_cpp_conduit_method(PyObject *obj) {
|
||||
if (PyType_Check(obj)) {
|
||||
return object();
|
||||
}
|
||||
PyTypeObject *type_obj = Py_TYPE(obj);
|
||||
str attr_name("_pybind11_conduit_v1_");
|
||||
bool assumed_to_be_callable = false;
|
||||
if (type_is_managed_by_our_internals(type_obj)) {
|
||||
if (!is_instance_method_of_type(type_obj, attr_name.ptr())) {
|
||||
return object();
|
||||
}
|
||||
assumed_to_be_callable = true;
|
||||
}
|
||||
PyObject *method = PyObject_GetAttr(obj, attr_name.ptr());
|
||||
if (method == nullptr) {
|
||||
PyErr_Clear();
|
||||
return object();
|
||||
}
|
||||
if (!assumed_to_be_callable && PyCallable_Check(method) == 0) {
|
||||
Py_DECREF(method);
|
||||
return object();
|
||||
}
|
||||
return reinterpret_steal<object>(method);
|
||||
}
|
||||
|
||||
inline void *try_raw_pointer_ephemeral_from_cpp_conduit(handle src,
|
||||
const std::type_info *cpp_type_info) {
|
||||
object method = try_get_cpp_conduit_method(src.ptr());
|
||||
if (method) {
|
||||
capsule cpp_type_info_capsule(const_cast<void *>(static_cast<const void *>(cpp_type_info)),
|
||||
typeid(std::type_info).name());
|
||||
object cpp_conduit = method(bytes(PYBIND11_PLATFORM_ABI_ID),
|
||||
cpp_type_info_capsule,
|
||||
bytes("raw_pointer_ephemeral"));
|
||||
if (isinstance<capsule>(cpp_conduit)) {
|
||||
return reinterpret_borrow<capsule>(cpp_conduit).get_pointer();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
226
deps_src/pybind11/include/pybind11/detail/descr.h
Normal file
226
deps_src/pybind11/include/pybind11/detail/descr.h
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# define PYBIND11_DESCR_CONSTEXPR static constexpr
|
||||
#else
|
||||
# define PYBIND11_DESCR_CONSTEXPR const
|
||||
#endif
|
||||
|
||||
/* Concatenate type signatures at compile time */
|
||||
template <size_t N, typename... Ts>
|
||||
struct descr {
|
||||
char text[N + 1]{'\0'};
|
||||
|
||||
constexpr descr() = default;
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
|
||||
|
||||
template <size_t... Is>
|
||||
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
|
||||
|
||||
template <typename... Chars>
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
|
||||
|
||||
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
|
||||
return {{&typeid(Ts)..., nullptr}};
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>
|
||||
constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b,
|
||||
index_sequence<Is1...>,
|
||||
index_sequence<Is2...>) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
|
||||
return {a.text[Is1]..., b.text[Is2]...};
|
||||
}
|
||||
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||
constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b) {
|
||||
return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
constexpr descr<N - 1> const_name(char const (&text)[N]) {
|
||||
return descr<N - 1>(text);
|
||||
}
|
||||
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
|
||||
|
||||
template <size_t Rem, size_t... Digits>
|
||||
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
|
||||
template <size_t... Digits>
|
||||
struct int_to_str<0, Digits...> {
|
||||
// WARNING: This only works with C++17 or higher.
|
||||
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
||||
};
|
||||
|
||||
// Ternary description (like std::conditional)
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
|
||||
return const_name(text1);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
|
||||
return const_name(text2);
|
||||
}
|
||||
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {
|
||||
return d;
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
template <size_t Size>
|
||||
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||
return int_to_str<Size / 10, Size % 10>::digits;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
constexpr descr<1, Type> const_name() {
|
||||
return {'%'};
|
||||
}
|
||||
|
||||
// Use a different name based on whether the parameter is used as input or output
|
||||
template <size_t N1, size_t N2>
|
||||
constexpr descr<N1 + N2 + 1> io_name(char const (&text1)[N1], char const (&text2)[N2]) {
|
||||
return const_name("@") + const_name(text1) + const_name("@") + const_name(text2)
|
||||
+ const_name("@");
|
||||
}
|
||||
|
||||
// Ternary description for io_name (like the numeric type_caster)
|
||||
template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
|
||||
constexpr enable_if_t<B, descr<N1 + N2 + 1>>
|
||||
io_name(char const (&text1)[N1], char const (&text2)[N2], char const (&)[N3], char const (&)[N4]) {
|
||||
return io_name(text1, text2);
|
||||
}
|
||||
|
||||
template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
|
||||
constexpr enable_if_t<!B, descr<N3 + N4 + 1>>
|
||||
io_name(char const (&)[N1], char const (&)[N2], char const (&text3)[N3], char const (&text4)[N4]) {
|
||||
return io_name(text3, text4);
|
||||
}
|
||||
|
||||
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
||||
// It is therefore best to use py::detail::const_name universally.
|
||||
// This block is for backward compatibility only.
|
||||
// (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
|
||||
#ifndef _
|
||||
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||
template <size_t N>
|
||||
constexpr descr<N - 1> _(char const (&text)[N]) {
|
||||
return const_name<N>(text);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
||||
return const_name<B, N1, N2>(text1, text2);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
||||
return const_name<B, N1, N2>(text1, text2);
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
|
||||
return const_name<B, T1, T2>(d1, d2);
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
|
||||
return const_name<B, T1, T2>(d1, d2);
|
||||
}
|
||||
|
||||
template <size_t Size>
|
||||
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||
return const_name<Size>();
|
||||
}
|
||||
template <typename Type>
|
||||
constexpr descr<1, Type> _() {
|
||||
return const_name<Type>();
|
||||
}
|
||||
#endif // #ifndef _
|
||||
|
||||
constexpr descr<0> concat() { return {}; }
|
||||
constexpr descr<0> union_concat() { return {}; }
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
||||
return descr;
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N, Ts...> union_concat(const descr<N, Ts...> &descr) {
|
||||
return descr;
|
||||
}
|
||||
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||
constexpr descr<N1 + N2 + 3, Ts1..., Ts2...> operator|(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b) {
|
||||
return a + const_name(" | ") + b;
|
||||
}
|
||||
|
||||
#ifdef __cpp_fold_expressions
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b) {
|
||||
return a + const_name(", ") + b;
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
|
||||
return (d, ..., args);
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args) {
|
||||
return (d | ... | args);
|
||||
}
|
||||
|
||||
#else
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
|
||||
-> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
|
||||
return d + const_name(", ") + concat(args...);
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args)
|
||||
-> decltype(std::declval<descr<N + 3, Ts...>>() + union_concat(args...)) {
|
||||
return d + const_name(" | ") + union_concat(args...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
||||
return const_name("{") + descr + const_name("}");
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N + 4, Ts...> arg_descr(const descr<N, Ts...> &descr) {
|
||||
return const_name("@^") + descr + const_name("@!");
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N + 4, Ts...> return_descr(const descr<N, Ts...> &descr) {
|
||||
return const_name("@$") + descr + const_name("@!");
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2021 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename To, typename From, typename SFINAE = void>
|
||||
struct dynamic_raw_ptr_cast_is_possible : std::false_type {};
|
||||
|
||||
template <typename To, typename From>
|
||||
struct dynamic_raw_ptr_cast_is_possible<
|
||||
To,
|
||||
From,
|
||||
detail::enable_if_t<!std::is_same<To, void>::value && std::is_polymorphic<From>::value>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename To,
|
||||
typename From,
|
||||
detail::enable_if_t<!dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
||||
To *dynamic_raw_ptr_cast_if_possible(From * /*ptr*/) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename To,
|
||||
typename From,
|
||||
detail::enable_if_t<dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
||||
To *dynamic_raw_ptr_cast_if_possible(From *ptr) {
|
||||
return dynamic_cast<To *>(ptr);
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
pybind11/detail/exception_translation.h: means to translate C++ exceptions to Python exceptions
|
||||
|
||||
Copyright (c) 2024 The Pybind Development Team.
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "internals.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Apply all the extensions translators from a list
|
||||
// Return true if one of the translators completed without raising an exception
|
||||
// itself. Return of false indicates that if there are other translators
|
||||
// available, they should be tried.
|
||||
inline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {
|
||||
auto last_exception = std::current_exception();
|
||||
|
||||
for (auto &translator : translators) {
|
||||
try {
|
||||
translator(last_exception);
|
||||
return true;
|
||||
} catch (...) {
|
||||
last_exception = std::current_exception();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void try_translate_exceptions() {
|
||||
/* When an exception is caught, give each registered exception
|
||||
translator a chance to translate it to a Python exception. First
|
||||
all module-local translators will be tried in reverse order of
|
||||
registration. If none of the module-locale translators handle
|
||||
the exception (or there are no module-locale translators) then
|
||||
the global translators will be tried, also in reverse order of
|
||||
registration.
|
||||
|
||||
A translator may choose to do one of the following:
|
||||
|
||||
- catch the exception and call py::set_error()
|
||||
to set a standard (or custom) Python exception, or
|
||||
- do nothing and let the exception fall through to the next translator, or
|
||||
- delegate translation to the next translator by throwing a new type of exception.
|
||||
*/
|
||||
|
||||
bool handled = with_exception_translators(
|
||||
[&](std::forward_list<ExceptionTranslator> &exception_translators,
|
||||
std::forward_list<ExceptionTranslator> &local_exception_translators) {
|
||||
if (detail::apply_exception_translators(local_exception_translators)) {
|
||||
return true;
|
||||
}
|
||||
if (detail::apply_exception_translators(exception_translators)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!handled) {
|
||||
set_error(PyExc_SystemError, "Exception escaped from default exception translator!");
|
||||
}
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2024-2025 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// For background see the description of PR google/pybind11clif#30099.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/attr.h>
|
||||
#include <pybind11/conduit/pybind11_platform_abi_id.h>
|
||||
#include <pybind11/pytypes.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
struct function_record_PyObject {
|
||||
PyObject_HEAD
|
||||
function_record *cpp_func_rec;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
|
||||
|
||||
PyObject *tp_new_impl(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
||||
PyObject *tp_alloc_impl(PyTypeObject *type, Py_ssize_t nitems);
|
||||
int tp_init_impl(PyObject *self, PyObject *args, PyObject *kwds);
|
||||
void tp_dealloc_impl(PyObject *self);
|
||||
void tp_free_impl(void *self);
|
||||
|
||||
static PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *);
|
||||
|
||||
static PyMethodDef tp_methods_impl[]
|
||||
= {{"__reduce_ex__",
|
||||
// reduce_ex_impl is a PyCFunctionWithKeywords, but PyMethodDef
|
||||
// requires a PyCFunction. The cast through void* is safe and
|
||||
// idiomatic with METH_KEYWORDS, and it successfully sidesteps
|
||||
// unhelpful compiler warnings.
|
||||
// NOLINTNEXTLINE(bugprone-casting-through-void)
|
||||
reinterpret_cast<PyCFunction>(reinterpret_cast<void *>(reduce_ex_impl)),
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
nullptr},
|
||||
{nullptr, nullptr, 0, nullptr}};
|
||||
|
||||
// Python 3.12+ emits a DeprecationWarning for heap types whose tp_name does
|
||||
// not contain a dot ('.') and that lack a __module__ attribute. For pybind11's
|
||||
// internal function_record type, we do not have an actual module object to
|
||||
// attach, so we cannot use PyType_FromModuleAndSpec (introduced in Python 3.9)
|
||||
// to set __module__ automatically.
|
||||
//
|
||||
// As a workaround, we define a "qualified" type name that includes a dummy
|
||||
// module name (PYBIND11_DUMMY_MODULE_NAME). This is non‑idiomatic but avoids
|
||||
// the deprecation warning, and results in reprs like
|
||||
//
|
||||
// <class 'pybind11_builtins.pybind11_detail_function_record_...'>
|
||||
//
|
||||
// even though no real pybind11_builtins module exists. If pybind11 gains an
|
||||
// actual module object in the future, this code should switch to
|
||||
// PyType_FromModuleAndSpec for Python 3.9+ and drop the dummy module
|
||||
// workaround.
|
||||
//
|
||||
// Note that this name is versioned.
|
||||
#define PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME \
|
||||
"pybind11_detail_function_record_" PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID \
|
||||
"_" PYBIND11_PLATFORM_ABI_ID
|
||||
constexpr char tp_plainname_impl[] = PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
|
||||
constexpr char tp_qualname_impl[]
|
||||
= PYBIND11_DUMMY_MODULE_NAME "." PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
|
||||
|
||||
PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
|
||||
|
||||
static PyType_Slot function_record_PyType_Slots[] = {
|
||||
{Py_tp_dealloc,
|
||||
reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_dealloc_impl)},
|
||||
{Py_tp_methods,
|
||||
reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_methods_impl)},
|
||||
{Py_tp_init, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_init_impl)},
|
||||
{Py_tp_alloc, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_alloc_impl)},
|
||||
{Py_tp_new, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_new_impl)},
|
||||
{Py_tp_free, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_free_impl)},
|
||||
{0, nullptr}};
|
||||
|
||||
static PyType_Spec function_record_PyType_Spec
|
||||
= {function_record_PyTypeObject_methods::tp_qualname_impl,
|
||||
sizeof(function_record_PyObject),
|
||||
0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
|
||||
function_record_PyType_Slots};
|
||||
|
||||
inline PyTypeObject *get_function_record_PyTypeObject() {
|
||||
PyTypeObject *&py_type_obj = detail::get_local_internals().function_record_py_type;
|
||||
if (!py_type_obj) {
|
||||
PyObject *py_obj = PyType_FromSpec(&function_record_PyType_Spec);
|
||||
if (py_obj == nullptr) {
|
||||
throw error_already_set();
|
||||
}
|
||||
py_type_obj = reinterpret_cast<PyTypeObject *>(py_obj);
|
||||
}
|
||||
return py_type_obj;
|
||||
}
|
||||
|
||||
inline bool is_function_record_PyObject(PyObject *obj) {
|
||||
if (PyType_Check(obj) != 0) {
|
||||
return false;
|
||||
}
|
||||
PyTypeObject *obj_type = Py_TYPE(obj);
|
||||
|
||||
PyTypeObject *frtype = get_function_record_PyTypeObject();
|
||||
|
||||
// Fast path (pointer comparison).
|
||||
if (obj_type == frtype) {
|
||||
return true;
|
||||
}
|
||||
// This works across extension modules. Note that tp_name is versioned.
|
||||
if (strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_qualname_impl) == 0
|
||||
|| strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_plainname_impl)
|
||||
== 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline function_record *function_record_ptr_from_PyObject(PyObject *obj) {
|
||||
if (is_function_record_PyObject(obj)) {
|
||||
return ((detail::function_record_PyObject *) obj)->cpp_func_rec;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline object function_record_PyObject_New() {
|
||||
auto *py_func_rec = PyObject_New(function_record_PyObject, get_function_record_PyTypeObject());
|
||||
if (py_func_rec == nullptr) {
|
||||
throw error_already_set();
|
||||
}
|
||||
py_func_rec->cpp_func_rec = nullptr; // For clarity/purity. Redundant in practice.
|
||||
return reinterpret_steal<object>((PyObject *) py_func_rec);
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
|
||||
|
||||
// Guard against accidents & oversights, in particular when porting to future Python versions.
|
||||
inline PyObject *tp_new_impl(PyTypeObject *, PyObject *, PyObject *) {
|
||||
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_new_impl");
|
||||
// return nullptr; // Unreachable.
|
||||
}
|
||||
|
||||
inline PyObject *tp_alloc_impl(PyTypeObject *, Py_ssize_t) {
|
||||
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_alloc_impl");
|
||||
// return nullptr; // Unreachable.
|
||||
}
|
||||
|
||||
inline int tp_init_impl(PyObject *, PyObject *, PyObject *) {
|
||||
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_init_impl");
|
||||
// return -1; // Unreachable.
|
||||
}
|
||||
|
||||
inline void tp_free_impl(void *) {
|
||||
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_free_impl");
|
||||
}
|
||||
|
||||
inline PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *) {
|
||||
// Deliberately ignoring the arguments for simplicity (expected is `protocol: int`).
|
||||
const function_record *rec = function_record_ptr_from_PyObject(self);
|
||||
if (rec == nullptr) {
|
||||
pybind11_fail(
|
||||
"FATAL: function_record_PyTypeObject reduce_ex_impl(): cannot obtain cpp_func_rec.");
|
||||
}
|
||||
if (rec->name != nullptr && rec->name[0] != '\0' && rec->scope
|
||||
&& PyModule_Check(rec->scope.ptr()) != 0) {
|
||||
object scope_module = get_scope_module(rec->scope);
|
||||
if (scope_module) {
|
||||
auto builtins = reinterpret_borrow<dict>(PyEval_GetBuiltins());
|
||||
auto builtins_eval = builtins["eval"];
|
||||
auto reconstruct_args = make_tuple(str("__import__('importlib').import_module('")
|
||||
+ scope_module + str("')"));
|
||||
return make_tuple(std::move(builtins_eval), std::move(reconstruct_args))
|
||||
.release()
|
||||
.ptr();
|
||||
}
|
||||
}
|
||||
set_error(PyExc_RuntimeError, repr(self) + str(" is not pickleable."));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
538
deps_src/pybind11/include/pybind11/detail/init.h
Normal file
538
deps_src/pybind11/include/pybind11/detail/init.h
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
pybind11/detail/init.h: init factory function implementation and support code.
|
||||
|
||||
Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "class.h"
|
||||
#include "using_smart_holder.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <>
|
||||
class type_caster<value_and_holder> {
|
||||
public:
|
||||
bool load(handle h, bool) {
|
||||
value = reinterpret_cast<value_and_holder *>(h.ptr());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename>
|
||||
using cast_op_type = value_and_holder &;
|
||||
explicit operator value_and_holder &() { return *value; }
|
||||
static constexpr auto name = const_name<value_and_holder>();
|
||||
|
||||
private:
|
||||
value_and_holder *value = nullptr;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(initimpl)
|
||||
|
||||
inline void no_nullptr(const void *ptr) {
|
||||
if (!ptr) {
|
||||
throw type_error("pybind11::init(): factory function returned nullptr");
|
||||
}
|
||||
}
|
||||
|
||||
// Implementing functions for all forms of py::init<...> and py::init(...)
|
||||
template <typename Class>
|
||||
using Cpp = typename Class::type;
|
||||
template <typename Class>
|
||||
using Alias = typename Class::type_alias;
|
||||
template <typename Class>
|
||||
using Holder = typename Class::holder_type;
|
||||
|
||||
template <typename Class>
|
||||
using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;
|
||||
|
||||
// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.
|
||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
|
||||
bool is_alias(Cpp<Class> *ptr) {
|
||||
return dynamic_cast<Alias<Class> *>(ptr) != nullptr;
|
||||
}
|
||||
// Failing fallback version of the above for a no-alias class (always returns false)
|
||||
template <typename /*Class*/>
|
||||
constexpr bool is_alias(const void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
|
||||
// back to brace aggregate initialization so that for aggregate initialization can be used with
|
||||
// py::init, e.g. `py::init<int, int>` to initialize a `struct T { int a; int b; }`. For
|
||||
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
|
||||
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
|
||||
template <typename Class,
|
||||
typename... Args,
|
||||
detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>
|
||||
inline Class *construct_or_initialize(Args &&...args) {
|
||||
return new Class(std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename Class,
|
||||
typename... Args,
|
||||
detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>
|
||||
inline Class *construct_or_initialize(Args &&...args) {
|
||||
return new Class{std::forward<Args>(args)...};
|
||||
}
|
||||
|
||||
// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with
|
||||
// an alias to provide only a single Cpp factory function as long as the Alias can be
|
||||
// constructed from an rvalue reference of the base Cpp type. This means that Alias classes
|
||||
// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to
|
||||
// inherit all the base class constructors.
|
||||
template <typename Class>
|
||||
void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,
|
||||
value_and_holder &v_h,
|
||||
Cpp<Class> &&base) {
|
||||
v_h.value_ptr() = new Alias<Class>(std::move(base));
|
||||
}
|
||||
template <typename Class>
|
||||
[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,
|
||||
value_and_holder &,
|
||||
Cpp<Class> &&) {
|
||||
throw type_error("pybind11::init(): unable to convert returned instance to required "
|
||||
"alias class: no `Alias<Class>(Class &&)` constructor available");
|
||||
}
|
||||
|
||||
// Error-generating fallback for factories that don't match one of the below construction
|
||||
// mechanisms.
|
||||
template <typename Class>
|
||||
void construct(...) {
|
||||
static_assert(!std::is_same<Class, Class>::value /* always false */,
|
||||
"pybind11::init(): init function must return a compatible pointer, "
|
||||
"holder, or value");
|
||||
}
|
||||
|
||||
// Pointer return v1: the factory function returns a class pointer for a registered class.
|
||||
// If we don't need an alias (because this class doesn't have one, or because the final type is
|
||||
// inherited on the Python side) we can simply take over ownership. Otherwise we need to try to
|
||||
// construct an Alias from the returned base instance.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
// We're going to try to construct an alias by moving the cpp type. Whether or not
|
||||
// that succeeds, we still need to destroy the original cpp pointer (either the
|
||||
// moved away leftover, if the alias construction works, or the value itself if we
|
||||
// throw an error), but we can't just call `delete ptr`: it might have a special
|
||||
// deleter, or might be shared_from_this. So we construct a holder around it as if
|
||||
// it was a normal instance, then steal the holder away into a local variable; thus
|
||||
// the holder and destruction happens when we leave the C++ scope, and the holder
|
||||
// class gets to handle the destruction however it likes.
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.set_instance_registered(true); // Trick to prevent init_instance from registering it
|
||||
// DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
|
||||
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
|
||||
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
|
||||
v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
|
||||
v_h.set_instance_registered(false);
|
||||
// DANGER ZONE END.
|
||||
|
||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
|
||||
} else {
|
||||
// Otherwise the type isn't inherited, so we don't need an Alias
|
||||
v_h.value_ptr() = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Pointer return v2: a factory that always returns an alias instance ptr. We simply take over
|
||||
// ownership of the pointer.
|
||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
|
||||
void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
|
||||
no_nullptr(alias_ptr);
|
||||
v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);
|
||||
}
|
||||
|
||||
// Holder return: copy its pointer, and move or copy the returned holder into the new instance's
|
||||
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
|
||||
// derived type (through those holder's implicit conversion from derived class holder
|
||||
// constructors).
|
||||
template <typename Class, detail::enable_if_t<!is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
||||
no_nullptr(ptr);
|
||||
// If we need an alias, check that the held pointer is actually an alias instance
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
|
||||
"is not an alias instance");
|
||||
}
|
||||
|
||||
// Cast away constness to store in void* storage.
|
||||
// The value_and_holder storage is fundamentally untyped (void**), so we lose
|
||||
// const-correctness here by design. The const qualifier will be restored
|
||||
// when the pointer is later retrieved and cast back to the original type.
|
||||
// This explicit const_cast makes the const-removal clearly visible.
|
||||
v_h.value_ptr() = const_cast<void *>(static_cast<const void *>(ptr));
|
||||
v_h.type->init_instance(v_h.inst, &holder);
|
||||
}
|
||||
|
||||
// return-by-value version 1: returning a cpp class by value. If the class has an alias and an
|
||||
// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct
|
||||
// the alias from the base when needed (i.e. because of Python-side inheritance). When we don't
|
||||
// need it, we simply move-construct the cpp value into a new instance.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
static_assert(is_move_constructible<Cpp<Class>>::value,
|
||||
"pybind11::init() return-by-value factory function requires a movable class");
|
||||
if (Class::has_alias && need_alias) {
|
||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
|
||||
} else {
|
||||
v_h.value_ptr() = new Cpp<Class>(std::move(result));
|
||||
}
|
||||
}
|
||||
|
||||
// return-by-value version 2: returning a value of the alias type itself. We move-construct an
|
||||
// Alias instance (even if no the python-side inheritance is involved). The is intended for
|
||||
// cases where Alias initialization is always desired.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
|
||||
static_assert(
|
||||
is_move_constructible<Alias<Class>>::value,
|
||||
"pybind11::init() return-by-alias-value factory function requires a movable alias class");
|
||||
v_h.value_ptr() = new Alias<Class>(std::move(result));
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
smart_holder init_smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
|
||||
bool void_cast_raw_ptr) {
|
||||
void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
|
||||
return smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
typename D = std::default_delete<Cpp<Class>>,
|
||||
detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
auto *ptr = unq_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
|
||||
"is not an alias instance");
|
||||
}
|
||||
// Here and below: if the new object is a trampoline, the shared_from_this mechanism needs
|
||||
// to be prevented from accessing the smart_holder vptr, because it does not keep the
|
||||
// trampoline Python object alive. For types that don't inherit from enable_shared_from_this
|
||||
// it does not matter if void_cast_raw_ptr is true or false, therefore it's not necessary
|
||||
// to also inspect the type.
|
||||
auto smhldr = init_smart_holder_from_unique_ptr(
|
||||
std::move(unq_ptr), /*void_cast_raw_ptr*/ Class::has_alias && is_alias<Class>(ptr));
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
typename D = std::default_delete<Alias<Class>>,
|
||||
detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h,
|
||||
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
|
||||
bool /*need_alias*/) {
|
||||
auto *ptr = unq_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
auto smhldr
|
||||
= init_smart_holder_from_unique_ptr(std::move(unq_ptr), /*void_cast_raw_ptr*/ true);
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename PtrType, typename Class>
|
||||
void construct_from_shared_ptr(value_and_holder &v_h,
|
||||
std::shared_ptr<PtrType> &&shd_ptr,
|
||||
bool need_alias) {
|
||||
static_assert(std::is_same<PtrType, Cpp<Class>>::value
|
||||
|| std::is_same<PtrType, const Cpp<Class>>::value,
|
||||
"Expected (const) Cpp<Class> as shared_ptr pointee");
|
||||
auto *ptr = shd_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
|
||||
"is not an alias instance");
|
||||
}
|
||||
// Cast to non-const if needed, consistent with internal design
|
||||
auto smhldr
|
||||
= smart_holder::from_shared_ptr(std::const_pointer_cast<Cpp<Class>>(std::move(shd_ptr)));
|
||||
v_h.value_ptr() = const_cast<Cpp<Class> *>(ptr);
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
|
||||
construct_from_shared_ptr<Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
|
||||
}
|
||||
|
||||
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h,
|
||||
std::shared_ptr<const Cpp<Class>> &&shd_ptr,
|
||||
bool need_alias) {
|
||||
construct_from_shared_ptr<const Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
|
||||
}
|
||||
|
||||
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
||||
void construct(value_and_holder &v_h,
|
||||
std::shared_ptr<Alias<Class>> &&shd_ptr,
|
||||
bool /*need_alias*/) {
|
||||
auto *ptr = shd_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
auto smhldr = smart_holder::from_shared_ptr(shd_ptr);
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
// Implementing class for py::init<...>()
|
||||
template <typename... Args>
|
||||
struct constructor {
|
||||
template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h,
|
||||
Args... args) { // NOLINT(performance-unnecessary-value-param)
|
||||
v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
if (Py_TYPE(v_h.inst) == v_h.type->type) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
|
||||
} else {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
}
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementing class for py::init_alias<...>()
|
||||
template <typename... Args>
|
||||
struct alias_constructor {
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation class for py::init(Func) and py::init(Func, AliasFunc)
|
||||
template <typename CFunc,
|
||||
typename AFunc = void_type (*)(),
|
||||
typename = function_signature_t<CFunc>,
|
||||
typename = function_signature_t<AFunc>>
|
||||
struct factory;
|
||||
|
||||
// Specialization for py::init(Func)
|
||||
template <typename Func, typename Return, typename... Args>
|
||||
struct factory<Func, void_type (*)(), Return(Args...)> {
|
||||
remove_reference_t<Func> class_factory;
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
factory(Func &&f) : class_factory(std::forward<Func>(f)) {}
|
||||
|
||||
// The given class either has no alias or has no separate alias factory;
|
||||
// this always constructs the class itself. If the class is registered with an alias
|
||||
// type and an alias instance is needed (i.e. because the final type is a Python class
|
||||
// inheriting from the C++ type) the returned value needs to either already be an alias
|
||||
// instance, or the alias needs to be constructible from a `Class &&` argument.
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__init__",
|
||||
[func = std::move(class_factory)]
|
||||
#else
|
||||
auto &func = class_factory;
|
||||
cl.def(
|
||||
"__init__",
|
||||
[func]
|
||||
#endif
|
||||
(value_and_holder &v_h, Args... args) {
|
||||
construct<Class>(
|
||||
v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for py::init(Func, AliasFunc)
|
||||
template <typename CFunc,
|
||||
typename AFunc,
|
||||
typename CReturn,
|
||||
typename... CArgs,
|
||||
typename AReturn,
|
||||
typename... AArgs>
|
||||
struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
|
||||
static_assert(sizeof...(CArgs) == sizeof...(AArgs),
|
||||
"pybind11::init(class_factory, alias_factory): class and alias factories "
|
||||
"must have identical argument signatures");
|
||||
static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
|
||||
"pybind11::init(class_factory, alias_factory): class and alias factories "
|
||||
"must have identical argument signatures");
|
||||
|
||||
remove_reference_t<CFunc> class_factory;
|
||||
remove_reference_t<AFunc> alias_factory;
|
||||
|
||||
factory(CFunc &&c, AFunc &&a)
|
||||
: class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}
|
||||
|
||||
// The class factory is called when the `self` type passed to `__init__` is the direct
|
||||
// class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
static_assert(Class::has_alias,
|
||||
"The two-argument version of `py::init()` can "
|
||||
"only be used if the class has an alias");
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__init__",
|
||||
[class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
|
||||
#else
|
||||
auto &class_func = class_factory;
|
||||
auto &alias_func = alias_factory;
|
||||
cl.def(
|
||||
"__init__",
|
||||
[class_func, alias_func]
|
||||
#endif
|
||||
(value_and_holder &v_h, CArgs... args) {
|
||||
if (Py_TYPE(v_h.inst) == v_h.type->type) {
|
||||
// If the instance type equals the registered type we don't have inheritance,
|
||||
// so don't need the alias and can construct using the class function:
|
||||
construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
|
||||
} else {
|
||||
construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
|
||||
}
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
/// Set just the C++ state. Same as `__init__`.
|
||||
template <typename Class, typename T>
|
||||
void setstate(value_and_holder &v_h, T &&result, bool need_alias) {
|
||||
construct<Class>(v_h, std::forward<T>(result), need_alias);
|
||||
}
|
||||
|
||||
/// Set both the C++ and Python states
|
||||
template <typename Class,
|
||||
typename T,
|
||||
typename O,
|
||||
enable_if_t<std::is_convertible<O, handle>::value, int> = 0>
|
||||
void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {
|
||||
construct<Class>(v_h, std::move(result.first), need_alias);
|
||||
auto d = handle(result.second);
|
||||
if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {
|
||||
// Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.
|
||||
// See PR #2972 for details.
|
||||
return;
|
||||
}
|
||||
// Our tests never run into an unset dict, but being careful here for now (see #5658)
|
||||
auto dict = getattr((PyObject *) v_h.inst, "__dict__", none());
|
||||
if (dict.is_none()) {
|
||||
setattr((PyObject *) v_h.inst, "__dict__", d);
|
||||
} else {
|
||||
// Keep the original object dict and just update it
|
||||
if (PyDict_Update(dict.ptr(), d.ptr()) < 0) {
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation for py::pickle(GetState, SetState)
|
||||
template <typename Get,
|
||||
typename Set,
|
||||
typename = function_signature_t<Get>,
|
||||
typename = function_signature_t<Set>>
|
||||
struct pickle_factory;
|
||||
|
||||
template <typename Get,
|
||||
typename Set,
|
||||
typename RetState,
|
||||
typename Self,
|
||||
typename NewInstance,
|
||||
typename ArgState>
|
||||
struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
|
||||
static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
|
||||
"The type returned by `__getstate__` must be the same "
|
||||
"as the argument accepted by `__setstate__`");
|
||||
|
||||
remove_reference_t<Get> get;
|
||||
remove_reference_t<Set> set;
|
||||
|
||||
pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}
|
||||
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
cl.def("__getstate__", std::move(get), pos_only());
|
||||
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__setstate__",
|
||||
[func = std::move(set)]
|
||||
#else
|
||||
auto &func = set;
|
||||
cl.def(
|
||||
"__setstate__",
|
||||
[func]
|
||||
#endif
|
||||
(value_and_holder &v_h, ArgState state) {
|
||||
setstate<Class>(
|
||||
v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(initimpl)
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
799
deps_src/pybind11/include/pybind11/detail/internals.h
Normal file
799
deps_src/pybind11/include/pybind11/detail/internals.h
Normal file
@@ -0,0 +1,799 @@
|
||||
/*
|
||||
pybind11/detail/internals.h: Internal data structure and related functions
|
||||
|
||||
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/conduit/pybind11_platform_abi_id.h>
|
||||
#include <pybind11/gil_simple.h>
|
||||
#include <pybind11/pytypes.h>
|
||||
#include <pybind11/trampoline_self_life_support.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "struct_smart_holder.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
/// Tracks the `internals` and `type_info` ABI version independent of the main library version.
|
||||
///
|
||||
/// Some portions of the code use an ABI that is conditional depending on this
|
||||
/// version number. That allows ABI-breaking changes to be "pre-implemented".
|
||||
/// Once the default version number is incremented, the conditional logic that
|
||||
/// no longer applies can be removed. Additionally, users that need not
|
||||
/// maintain ABI compatibility can increase the version number in order to take
|
||||
/// advantage of any functionality/efficiency improvements that depend on the
|
||||
/// newer ABI.
|
||||
///
|
||||
/// WARNING: If you choose to manually increase the ABI version, note that
|
||||
/// pybind11 may not be tested as thoroughly with a non-default ABI version, and
|
||||
/// further ABI-incompatible changes may be made before the ABI is officially
|
||||
/// changed to the new version.
|
||||
#ifndef PYBIND11_INTERNALS_VERSION
|
||||
# define PYBIND11_INTERNALS_VERSION 11
|
||||
#endif
|
||||
|
||||
#if PYBIND11_INTERNALS_VERSION < 11
|
||||
# error "PYBIND11_INTERNALS_VERSION 11 is the minimum for all platforms for pybind11v3."
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
using ExceptionTranslator = void (*)(std::exception_ptr);
|
||||
|
||||
// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
|
||||
// Thread Specific Storage (TSS) API.
|
||||
// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
|
||||
// `Py_LIMITED_API` anyway.
|
||||
#define PYBIND11_TLS_KEY_REF Py_tss_t &
|
||||
#if defined(__clang__)
|
||||
# define PYBIND11_TLS_KEY_INIT(var) \
|
||||
_Pragma("clang diagnostic push") /**/ \
|
||||
_Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
|
||||
Py_tss_t var \
|
||||
= Py_tss_NEEDS_INIT; \
|
||||
_Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
# define PYBIND11_TLS_KEY_INIT(var) \
|
||||
_Pragma("GCC diagnostic push") /**/ \
|
||||
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
|
||||
Py_tss_t var \
|
||||
= Py_tss_NEEDS_INIT; \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
|
||||
#endif
|
||||
#define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
|
||||
#define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
|
||||
#define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
|
||||
#define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
|
||||
#define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
|
||||
|
||||
/// A smart-pointer-like wrapper around a thread-specific value. get/set of the pointer applies to
|
||||
/// the current thread only.
|
||||
template <typename T>
|
||||
class thread_specific_storage {
|
||||
public:
|
||||
thread_specific_storage() {
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||
if (!PYBIND11_TLS_KEY_CREATE(key_)) {
|
||||
pybind11_fail(
|
||||
"thread_specific_storage constructor: could not initialize the TSS key!");
|
||||
}
|
||||
}
|
||||
|
||||
~thread_specific_storage() {
|
||||
// This destructor is often called *after* Py_Finalize(). That *SHOULD BE* fine on most
|
||||
// platforms. The following details what happens when PyThread_tss_free is called in
|
||||
// CPython. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
|
||||
// nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
|
||||
// PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
|
||||
// Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
|
||||
// that the `key` be allocated with the CPython allocator (as it is by
|
||||
// PyThread_tss_create).
|
||||
// However, in GraalPy (as of v24.2 or older), TSS is implemented by Java and this call
|
||||
// requires a living Python interpreter.
|
||||
#ifdef GRAALVM_PYTHON
|
||||
if (!Py_IsInitialized() || _Py_IsFinalizing()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
PYBIND11_TLS_FREE(key_);
|
||||
}
|
||||
|
||||
thread_specific_storage(thread_specific_storage const &) = delete;
|
||||
thread_specific_storage(thread_specific_storage &&) = delete;
|
||||
thread_specific_storage &operator=(thread_specific_storage const &) = delete;
|
||||
thread_specific_storage &operator=(thread_specific_storage &&) = delete;
|
||||
|
||||
T *get() const { return reinterpret_cast<T *>(PYBIND11_TLS_GET_VALUE(key_)); }
|
||||
|
||||
T &operator*() const { return *get(); }
|
||||
explicit operator T *() const { return get(); }
|
||||
explicit operator bool() const { return get() != nullptr; }
|
||||
|
||||
void set(T *val) { PYBIND11_TLS_REPLACE_VALUE(key_, reinterpret_cast<void *>(val)); }
|
||||
void reset(T *p = nullptr) { set(p); }
|
||||
thread_specific_storage &operator=(T *pval) {
|
||||
set(pval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
PYBIND11_TLS_KEY_INIT(mutable key_)
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// This does NOT actually exist as a module.
|
||||
#define PYBIND11_DUMMY_MODULE_NAME "pybind11_builtins"
|
||||
|
||||
// Forward declarations
|
||||
inline PyTypeObject *make_static_property_type();
|
||||
inline PyTypeObject *make_default_metaclass();
|
||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass);
|
||||
inline void translate_exception(std::exception_ptr p);
|
||||
|
||||
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
|
||||
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
|
||||
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
|
||||
// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
|
||||
// which works. If not under a known-good stl, provide our own name-based hash and equality
|
||||
// functions that use the type name.
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
|
||||
using type_hash = std::hash<std::type_index>;
|
||||
using type_equal_to = std::equal_to<std::type_index>;
|
||||
#else
|
||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
|
||||
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
||||
}
|
||||
|
||||
struct type_hash {
|
||||
size_t operator()(const std::type_index &t) const {
|
||||
size_t hash = 5381;
|
||||
const char *ptr = t.name();
|
||||
while (auto c = static_cast<unsigned char>(*ptr++)) {
|
||||
hash = (hash * 33) ^ c;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
struct type_equal_to {
|
||||
bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
|
||||
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename value_type>
|
||||
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
|
||||
|
||||
struct override_hash {
|
||||
inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
|
||||
size_t value = std::hash<const void *>()(v.first);
|
||||
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
using instance_map = std::unordered_multimap<const void *, instance *>;
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// Wrapper around PyMutex to provide BasicLockable semantics
|
||||
class pymutex {
|
||||
PyMutex mutex;
|
||||
|
||||
public:
|
||||
pymutex() : mutex({}) {}
|
||||
void lock() { PyMutex_Lock(&mutex); }
|
||||
void unlock() { PyMutex_Unlock(&mutex); }
|
||||
};
|
||||
|
||||
// Instance map shards are used to reduce mutex contention in free-threaded Python.
|
||||
struct instance_map_shard {
|
||||
instance_map registered_instances;
|
||||
pymutex mutex;
|
||||
// alignas(64) would be better, but causes compile errors in macOS before 10.14 (see #5200)
|
||||
char padding[64 - (sizeof(instance_map) + sizeof(pymutex)) % 64];
|
||||
};
|
||||
|
||||
static_assert(sizeof(instance_map_shard) % 64 == 0,
|
||||
"instance_map_shard size is not a multiple of 64 bytes");
|
||||
|
||||
inline uint64_t round_up_to_next_pow2(uint64_t x) {
|
||||
// Round-up to the next power of two.
|
||||
// See https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
x--;
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
x |= (x >> 32);
|
||||
x++;
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
class loader_life_support;
|
||||
|
||||
/// Internal data structure used to track registered instances and types.
|
||||
/// Whenever binary incompatible changes are made to this structure,
|
||||
/// `PYBIND11_INTERNALS_VERSION` must be incremented.
|
||||
struct internals {
|
||||
#ifdef Py_GIL_DISABLED
|
||||
pymutex mutex;
|
||||
pymutex exception_translator_mutex;
|
||||
#endif
|
||||
// std::type_index -> pybind11's type information
|
||||
type_map<type_info *> registered_types_cpp;
|
||||
// PyTypeObject* -> base type_info(s)
|
||||
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
|
||||
#ifdef Py_GIL_DISABLED
|
||||
std::unique_ptr<instance_map_shard[]> instance_shards; // void * -> instance*
|
||||
size_t instance_shards_mask = 0;
|
||||
#else
|
||||
instance_map registered_instances; // void * -> instance*
|
||||
#endif
|
||||
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
|
||||
inactive_override_cache;
|
||||
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
|
||||
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
|
||||
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
||||
std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
|
||||
// extensions
|
||||
std::forward_list<std::string> static_strings; // Stores the std::strings backing
|
||||
// detail::c_str()
|
||||
PyTypeObject *static_property_type = nullptr;
|
||||
PyTypeObject *default_metaclass = nullptr;
|
||||
PyObject *instance_base = nullptr;
|
||||
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
||||
thread_specific_storage<PyThreadState> tstate;
|
||||
thread_specific_storage<loader_life_support> loader_life_support_tls;
|
||||
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
||||
PyInterpreterState *istate = nullptr;
|
||||
|
||||
type_map<PyObject *> native_enum_type_map;
|
||||
|
||||
internals()
|
||||
: static_property_type(make_static_property_type()),
|
||||
default_metaclass(make_default_metaclass()) {
|
||||
PyThreadState *cur_tstate = PyThreadState_Get();
|
||||
tstate = cur_tstate;
|
||||
|
||||
istate = cur_tstate->interp;
|
||||
registered_exception_translators.push_front(&translate_exception);
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// Scale proportional to the number of cores. 2x is a heuristic to reduce contention.
|
||||
// Make sure the number isn't unreasonable by limiting it to 16 bits (65K)
|
||||
auto num_shards = static_cast<std::uint16_t>(
|
||||
std::min<std::size_t>(round_up_to_next_pow2(2 * std::thread::hardware_concurrency()),
|
||||
std::numeric_limits<std::uint16_t>::max()));
|
||||
if (num_shards == 0) {
|
||||
num_shards = 1;
|
||||
}
|
||||
instance_shards.reset(new instance_map_shard[num_shards]);
|
||||
instance_shards_mask = num_shards - 1;
|
||||
#endif
|
||||
}
|
||||
internals(const internals &other) = delete;
|
||||
internals(internals &&other) = delete;
|
||||
internals &operator=(const internals &other) = delete;
|
||||
internals &operator=(internals &&other) = delete;
|
||||
~internals() = default;
|
||||
};
|
||||
|
||||
// the internals struct (above) is shared between all the modules. local_internals are only
|
||||
// for a single module. Any changes made to internals may require an update to
|
||||
// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
|
||||
// restricted to a single module. Whether a module has local internals or not should not
|
||||
// impact any other modules, because the only things accessing the local internals is the
|
||||
// module that contains them.
|
||||
struct local_internals {
|
||||
type_map<type_info *> registered_types_cpp;
|
||||
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
||||
PyTypeObject *function_record_py_type = nullptr;
|
||||
};
|
||||
|
||||
enum class holder_enum_t : uint8_t {
|
||||
undefined,
|
||||
std_unique_ptr, // Default, lacking interop with std::shared_ptr.
|
||||
std_shared_ptr, // Lacking interop with std::unique_ptr.
|
||||
smart_holder, // Full std::unique_ptr / std::shared_ptr interop.
|
||||
custom_holder,
|
||||
};
|
||||
|
||||
/// Additional type information which does not fit into the PyTypeObject.
|
||||
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
|
||||
struct type_info {
|
||||
PyTypeObject *type;
|
||||
const std::type_info *cpptype;
|
||||
size_t type_size, type_align, holder_size_in_ptrs;
|
||||
void *(*operator_new)(size_t);
|
||||
void (*init_instance)(instance *, const void *);
|
||||
void (*dealloc)(value_and_holder &v_h);
|
||||
|
||||
// Cross-DSO-safe function pointers, to sidestep cross-DSO RTTI issues
|
||||
// on platforms like macOS (see PR #5728 for details):
|
||||
memory::get_guarded_delete_fn get_memory_guarded_delete = memory::get_guarded_delete;
|
||||
get_trampoline_self_life_support_fn get_trampoline_self_life_support = nullptr;
|
||||
|
||||
std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
|
||||
std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
|
||||
std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
|
||||
buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
|
||||
void *get_buffer_data = nullptr;
|
||||
void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
|
||||
holder_enum_t holder_enum_v = holder_enum_t::undefined;
|
||||
/* A simple type never occurs as a (direct or indirect) parent
|
||||
* of a class that makes use of multiple inheritance.
|
||||
* A type can be simple even if it has non-simple ancestors as long as it has no descendants.
|
||||
*/
|
||||
bool simple_type : 1;
|
||||
/* True if there is no multiple inheritance in this type's inheritance tree */
|
||||
bool simple_ancestors : 1;
|
||||
/* true if this is a type registered with py::module_local */
|
||||
bool module_local : 1;
|
||||
};
|
||||
|
||||
#define PYBIND11_INTERNALS_ID \
|
||||
"__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
||||
PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
|
||||
|
||||
#define PYBIND11_MODULE_LOCAL_ID \
|
||||
"__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
||||
PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
|
||||
|
||||
inline PyThreadState *get_thread_state_unchecked() {
|
||||
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
|
||||
return PyThreadState_GET();
|
||||
#elif PY_VERSION_HEX < 0x030D0000
|
||||
return _PyThreadState_UncheckedGet();
|
||||
#else
|
||||
return PyThreadState_GetUnchecked();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// We use this counter to figure out if there are or have been multiple subinterpreters active at
|
||||
/// any point. This must never decrease while any interpreter may be running in any thread!
|
||||
inline std::atomic<int> &get_num_interpreters_seen() {
|
||||
static std::atomic<int> counter(0);
|
||||
return counter;
|
||||
}
|
||||
|
||||
template <class T,
|
||||
enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
||||
std::exception_ptr nested = exc.nested_ptr();
|
||||
if (nested != nullptr && nested != p) {
|
||||
translate_exception(nested);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T,
|
||||
enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
||||
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
|
||||
return handle_nested_exception(*nep, p);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool raise_err(PyObject *exc_type, const char *msg) {
|
||||
if (PyErr_Occurred()) {
|
||||
raise_from(exc_type, msg);
|
||||
return true;
|
||||
}
|
||||
set_error(exc_type, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void translate_exception(std::exception_ptr p) {
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
std::rethrow_exception(p);
|
||||
} catch (error_already_set &e) {
|
||||
handle_nested_exception(e, p);
|
||||
e.restore();
|
||||
return;
|
||||
} catch (const builtin_exception &e) {
|
||||
// Could not use template since it's an abstract class.
|
||||
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
|
||||
handle_nested_exception(*nep, p);
|
||||
}
|
||||
e.set_error();
|
||||
return;
|
||||
} catch (const std::bad_alloc &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_MemoryError, e.what());
|
||||
return;
|
||||
} catch (const std::domain_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::invalid_argument &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::length_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::out_of_range &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_IndexError, e.what());
|
||||
return;
|
||||
} catch (const std::range_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::overflow_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_OverflowError, e.what());
|
||||
return;
|
||||
} catch (const std::exception &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_RuntimeError, e.what());
|
||||
return;
|
||||
} catch (const std::nested_exception &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
|
||||
return;
|
||||
} catch (...) {
|
||||
raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__GLIBCXX__)
|
||||
inline void translate_local_exception(std::exception_ptr p) {
|
||||
try {
|
||||
if (p) {
|
||||
std::rethrow_exception(p);
|
||||
}
|
||||
} catch (error_already_set &e) {
|
||||
e.restore();
|
||||
return;
|
||||
} catch (const builtin_exception &e) {
|
||||
e.set_error();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline object get_python_state_dict() {
|
||||
object state_dict;
|
||||
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
|
||||
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
|
||||
#else
|
||||
# if PY_VERSION_HEX < 0x03090000
|
||||
PyInterpreterState *istate = _PyInterpreterState_Get();
|
||||
# else
|
||||
PyInterpreterState *istate = PyInterpreterState_Get();
|
||||
# endif
|
||||
if (istate) {
|
||||
state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
|
||||
}
|
||||
#endif
|
||||
if (!state_dict) {
|
||||
raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
|
||||
throw error_already_set();
|
||||
}
|
||||
return state_dict;
|
||||
}
|
||||
|
||||
template <typename InternalsType>
|
||||
class internals_pp_manager {
|
||||
public:
|
||||
using on_fetch_function = void(InternalsType *);
|
||||
internals_pp_manager(char const *id, on_fetch_function *on_fetch)
|
||||
: holder_id_(id), on_fetch_(on_fetch) {}
|
||||
|
||||
/// Get the current pointer-to-pointer, allocating it if it does not already exist. May
|
||||
/// acquire the GIL. Will never return nullptr.
|
||||
std::unique_ptr<InternalsType> *get_pp() {
|
||||
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
||||
if (get_num_interpreters_seen() > 1) {
|
||||
// Whenever the interpreter changes on the current thread we need to invalidate the
|
||||
// internals_pp so that it can be pulled from the interpreter's state dict. That is
|
||||
// slow, so we use the current PyThreadState to check if it is necessary.
|
||||
auto *tstate = get_thread_state_unchecked();
|
||||
if (!tstate || tstate->interp != last_istate_.get()) {
|
||||
gil_scoped_acquire_simple gil;
|
||||
if (!tstate) {
|
||||
tstate = get_thread_state_unchecked();
|
||||
}
|
||||
last_istate_ = tstate->interp;
|
||||
internals_tls_p_ = get_or_create_pp_in_state_dict();
|
||||
}
|
||||
return internals_tls_p_.get();
|
||||
}
|
||||
#endif
|
||||
if (!internals_singleton_pp_) {
|
||||
gil_scoped_acquire_simple gil;
|
||||
internals_singleton_pp_ = get_or_create_pp_in_state_dict();
|
||||
}
|
||||
return internals_singleton_pp_;
|
||||
}
|
||||
|
||||
/// Drop all the references we're currently holding.
|
||||
void unref() {
|
||||
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
||||
if (get_num_interpreters_seen() > 1) {
|
||||
last_istate_.reset();
|
||||
internals_tls_p_.reset();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
internals_singleton_pp_ = nullptr;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
||||
if (get_num_interpreters_seen() > 1) {
|
||||
auto *tstate = get_thread_state_unchecked();
|
||||
// this could be called without an active interpreter, just use what was cached
|
||||
if (!tstate || tstate->interp == last_istate_.get()) {
|
||||
auto tpp = internals_tls_p_.get();
|
||||
if (tpp) {
|
||||
delete tpp;
|
||||
}
|
||||
}
|
||||
unref();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
delete internals_singleton_pp_;
|
||||
unref();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict() {
|
||||
error_scope err_scope;
|
||||
dict state_dict = get_python_state_dict();
|
||||
auto internals_obj
|
||||
= reinterpret_steal<object>(dict_getitemstringref(state_dict.ptr(), holder_id_));
|
||||
std::unique_ptr<InternalsType> *pp = nullptr;
|
||||
if (internals_obj) {
|
||||
void *raw_ptr = PyCapsule_GetPointer(internals_obj.ptr(), /*name=*/nullptr);
|
||||
if (!raw_ptr) {
|
||||
raise_from(PyExc_SystemError,
|
||||
"pybind11::detail::internals_pp_manager::get_pp_from_dict() FAILED");
|
||||
throw error_already_set();
|
||||
}
|
||||
pp = reinterpret_cast<std::unique_ptr<InternalsType> *>(raw_ptr);
|
||||
if (on_fetch_ && pp) {
|
||||
on_fetch_(pp->get());
|
||||
}
|
||||
} else {
|
||||
pp = new std::unique_ptr<InternalsType>;
|
||||
// NOLINTNEXTLINE(bugprone-casting-through-void)
|
||||
state_dict[holder_id_] = capsule(reinterpret_cast<void *>(pp));
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
|
||||
char const *holder_id_ = nullptr;
|
||||
on_fetch_function *on_fetch_ = nullptr;
|
||||
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
||||
thread_specific_storage<PyInterpreterState> last_istate_;
|
||||
thread_specific_storage<std::unique_ptr<InternalsType>> internals_tls_p_;
|
||||
#endif
|
||||
std::unique_ptr<InternalsType> *internals_singleton_pp_;
|
||||
};
|
||||
|
||||
// If We loaded the internals through `state_dict`, our `error_already_set`
|
||||
// and `builtin_exception` may be different local classes than the ones set up in the
|
||||
// initial exception translator, below, so add another for our local exception classes.
|
||||
//
|
||||
// libstdc++ doesn't require this (types there are identified only by name)
|
||||
// libc++ with CPython doesn't require this (types are explicitly exported)
|
||||
// libc++ with PyPy still need it, awaiting further investigation
|
||||
#if !defined(__GLIBCXX__)
|
||||
inline void check_internals_local_exception_translator(internals *internals_ptr) {
|
||||
if (internals_ptr) {
|
||||
for (auto et : internals_ptr->registered_exception_translators) {
|
||||
if (et == &translate_local_exception) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
internals_ptr->registered_exception_translators.push_front(&translate_local_exception);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline internals_pp_manager<internals> &get_internals_pp_manager() {
|
||||
#if defined(__GLIBCXX__)
|
||||
# define ON_FETCH_FN nullptr
|
||||
#else
|
||||
# define ON_FETCH_FN &check_internals_local_exception_translator
|
||||
#endif
|
||||
static internals_pp_manager<internals> internals_pp_manager(PYBIND11_INTERNALS_ID,
|
||||
ON_FETCH_FN);
|
||||
#undef ON_FETCH_FN
|
||||
return internals_pp_manager;
|
||||
}
|
||||
|
||||
/// Return a reference to the current `internals` data
|
||||
PYBIND11_NOINLINE internals &get_internals() {
|
||||
auto &ppmgr = get_internals_pp_manager();
|
||||
auto &internals_ptr = *ppmgr.get_pp();
|
||||
if (!internals_ptr) {
|
||||
// Slow path, something needs fetched from the state dict or created
|
||||
gil_scoped_acquire_simple gil;
|
||||
error_scope err_scope;
|
||||
internals_ptr.reset(new internals());
|
||||
|
||||
if (!internals_ptr->instance_base) {
|
||||
// This calls get_internals, so cannot be called from within the internals constructor
|
||||
// called above because internals_ptr must be set before get_internals is called again
|
||||
internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
|
||||
}
|
||||
}
|
||||
return *internals_ptr;
|
||||
}
|
||||
|
||||
inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
|
||||
// Use the address of this static itself as part of the key, so that the value is uniquely tied
|
||||
// to where the module is loaded in memory
|
||||
static const std::string this_module_idstr
|
||||
= PYBIND11_MODULE_LOCAL_ID
|
||||
+ std::to_string(reinterpret_cast<uintptr_t>(&this_module_idstr));
|
||||
static internals_pp_manager<local_internals> local_internals_pp_manager(
|
||||
this_module_idstr.c_str(), nullptr);
|
||||
return local_internals_pp_manager;
|
||||
}
|
||||
|
||||
/// Works like `get_internals`, but for things which are locally registered.
|
||||
inline local_internals &get_local_internals() {
|
||||
auto &ppmgr = get_local_internals_pp_manager();
|
||||
auto &internals_ptr = *ppmgr.get_pp();
|
||||
if (!internals_ptr) {
|
||||
internals_ptr.reset(new local_internals());
|
||||
}
|
||||
return *internals_ptr;
|
||||
}
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
# define PYBIND11_LOCK_INTERNALS(internals) std::unique_lock<pymutex> lock((internals).mutex)
|
||||
#else
|
||||
# define PYBIND11_LOCK_INTERNALS(internals)
|
||||
#endif
|
||||
|
||||
template <typename F>
|
||||
inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
|
||||
auto &internals = get_internals();
|
||||
PYBIND11_LOCK_INTERNALS(internals);
|
||||
return cb(internals);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline auto with_exception_translators(const F &cb)
|
||||
-> decltype(cb(get_internals().registered_exception_translators,
|
||||
get_local_internals().registered_exception_translators)) {
|
||||
auto &internals = get_internals();
|
||||
#ifdef Py_GIL_DISABLED
|
||||
std::unique_lock<pymutex> lock((internals).exception_translator_mutex);
|
||||
#endif
|
||||
auto &local_internals = get_local_internals();
|
||||
return cb(internals.registered_exception_translators,
|
||||
local_internals.registered_exception_translators);
|
||||
}
|
||||
|
||||
inline std::uint64_t mix64(std::uint64_t z) {
|
||||
// David Stafford's variant 13 of the MurmurHash3 finalizer popularized
|
||||
// by the SplitMix PRNG.
|
||||
// https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline auto with_instance_map(const void *ptr, const F &cb)
|
||||
-> decltype(cb(std::declval<instance_map &>())) {
|
||||
auto &internals = get_internals();
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// Hash address to compute shard, but ignore low bits. We'd like allocations
|
||||
// from the same thread/core to map to the same shard and allocations from
|
||||
// other threads/cores to map to other shards. Using the high bits is a good
|
||||
// heuristic because memory allocators often have a per-thread
|
||||
// arena/superblock/segment from which smaller allocations are served.
|
||||
auto addr = reinterpret_cast<std::uintptr_t>(ptr);
|
||||
auto hash = mix64(static_cast<std::uint64_t>(addr >> 20));
|
||||
auto idx = static_cast<size_t>(hash & internals.instance_shards_mask);
|
||||
|
||||
auto &shard = internals.instance_shards[idx];
|
||||
std::unique_lock<pymutex> lock(shard.mutex);
|
||||
return cb(shard.registered_instances);
|
||||
#else
|
||||
(void) ptr;
|
||||
return cb(internals.registered_instances);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the number of registered instances for testing purposes. The result may not be
|
||||
// consistent if other threads are registering or unregistering instances concurrently.
|
||||
inline size_t num_registered_instances() {
|
||||
auto &internals = get_internals();
|
||||
#ifdef Py_GIL_DISABLED
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i <= internals.instance_shards_mask; ++i) {
|
||||
auto &shard = internals.instance_shards[i];
|
||||
std::unique_lock<pymutex> lock(shard.mutex);
|
||||
count += shard.registered_instances.size();
|
||||
}
|
||||
return count;
|
||||
#else
|
||||
return internals.registered_instances.size();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its
|
||||
/// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only
|
||||
/// cleared when the program exits or after interpreter shutdown (when embedding), and so are
|
||||
/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).
|
||||
template <typename... Args>
|
||||
const char *c_str(Args &&...args) {
|
||||
// GCC 4.8 doesn't like parameter unpack within lambda capture, so use
|
||||
// PYBIND11_LOCK_INTERNALS.
|
||||
auto &internals = get_internals();
|
||||
PYBIND11_LOCK_INTERNALS(internals);
|
||||
auto &strings = internals.static_strings;
|
||||
strings.emplace_front(std::forward<Args>(args)...);
|
||||
return strings.front().c_str();
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Returns a named pointer that is shared among all extension modules (using the same
|
||||
/// pybind11 version) running in the current interpreter. Names starting with underscores
|
||||
/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.
|
||||
PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
|
||||
return detail::with_internals([&](detail::internals &internals) {
|
||||
auto it = internals.shared_data.find(name);
|
||||
return it != internals.shared_data.end() ? it->second : nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
/// Set the shared data that can be later recovered by `get_shared_data()`.
|
||||
PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
|
||||
return detail::with_internals([&](detail::internals &internals) {
|
||||
internals.shared_data[name] = data;
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if
|
||||
/// such entry exists. Otherwise, a new object of default-constructible type `T` is
|
||||
/// added to the shared data under the given name and a reference to it is returned.
|
||||
template <typename T>
|
||||
T &get_or_create_shared_data(const std::string &name) {
|
||||
return *detail::with_internals([&](detail::internals &internals) {
|
||||
auto it = internals.shared_data.find(name);
|
||||
T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
|
||||
if (!ptr) {
|
||||
ptr = new T();
|
||||
internals.shared_data[name] = ptr;
|
||||
}
|
||||
return ptr;
|
||||
});
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
209
deps_src/pybind11/include/pybind11/detail/native_enum_data.h
Normal file
209
deps_src/pybind11/include/pybind11/detail/native_enum_data.h
Normal file
@@ -0,0 +1,209 @@
|
||||
// Copyright (c) 2022-2025 The pybind Community.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../pytypes.h"
|
||||
#include "common.h"
|
||||
#include "internals.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// This is a separate function only to enable easy unit testing.
|
||||
inline std::string
|
||||
native_enum_missing_finalize_error_message(const std::string &enum_name_encoded) {
|
||||
return "pybind11::native_enum<...>(\"" + enum_name_encoded + "\", ...): MISSING .finalize()";
|
||||
}
|
||||
|
||||
class native_enum_data {
|
||||
public:
|
||||
native_enum_data(const object &parent_scope,
|
||||
const char *enum_name,
|
||||
const char *native_type_name,
|
||||
const char *class_doc,
|
||||
const std::type_index &enum_type_index)
|
||||
: enum_name_encoded{enum_name}, native_type_name_encoded{native_type_name},
|
||||
enum_type_index{enum_type_index}, parent_scope(parent_scope), enum_name{enum_name},
|
||||
native_type_name{native_type_name}, class_doc(class_doc), export_values_flag{false},
|
||||
finalize_needed{false} {}
|
||||
|
||||
void finalize();
|
||||
|
||||
native_enum_data(const native_enum_data &) = delete;
|
||||
native_enum_data &operator=(const native_enum_data &) = delete;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
// This dtor cannot easily be unit tested because it terminates the process.
|
||||
~native_enum_data() {
|
||||
if (finalize_needed) {
|
||||
pybind11_fail(native_enum_missing_finalize_error_message(enum_name_encoded));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void disarm_finalize_check(const char *error_context) {
|
||||
if (!finalize_needed) {
|
||||
pybind11_fail("pybind11::native_enum<...>(\"" + enum_name_encoded
|
||||
+ "\"): " + error_context);
|
||||
}
|
||||
finalize_needed = false;
|
||||
}
|
||||
|
||||
void arm_finalize_check() {
|
||||
assert(!finalize_needed); // Catch redundant calls.
|
||||
finalize_needed = true;
|
||||
}
|
||||
|
||||
std::string enum_name_encoded;
|
||||
std::string native_type_name_encoded;
|
||||
std::type_index enum_type_index;
|
||||
|
||||
private:
|
||||
object parent_scope;
|
||||
str enum_name;
|
||||
str native_type_name;
|
||||
std::string class_doc;
|
||||
|
||||
protected:
|
||||
list members;
|
||||
list member_docs;
|
||||
bool export_values_flag : 1; // Attention: It is best to keep the bools together.
|
||||
|
||||
private:
|
||||
bool finalize_needed : 1;
|
||||
};
|
||||
|
||||
inline void global_internals_native_enum_type_map_set_item(const std::type_index &enum_type_index,
|
||||
PyObject *py_enum) {
|
||||
with_internals(
|
||||
[&](internals &internals) { internals.native_enum_type_map[enum_type_index] = py_enum; });
|
||||
}
|
||||
|
||||
inline handle
|
||||
global_internals_native_enum_type_map_get_item(const std::type_index &enum_type_index) {
|
||||
return with_internals([&](internals &internals) {
|
||||
auto found = internals.native_enum_type_map.find(enum_type_index);
|
||||
if (found != internals.native_enum_type_map.end()) {
|
||||
return handle(found->second);
|
||||
}
|
||||
return handle();
|
||||
});
|
||||
}
|
||||
|
||||
inline bool
|
||||
global_internals_native_enum_type_map_contains(const std::type_index &enum_type_index) {
|
||||
return with_internals([&](internals &internals) {
|
||||
return internals.native_enum_type_map.count(enum_type_index) != 0;
|
||||
});
|
||||
}
|
||||
|
||||
inline object import_or_getattr(const std::string &fully_qualified_name,
|
||||
const std::string &append_to_exception_message) {
|
||||
std::istringstream stream(fully_qualified_name);
|
||||
std::string part;
|
||||
|
||||
if (!std::getline(stream, part, '.') || part.empty()) {
|
||||
std::string msg = "Invalid fully-qualified name `";
|
||||
msg += fully_qualified_name;
|
||||
msg += "`";
|
||||
msg += append_to_exception_message;
|
||||
throw value_error(msg);
|
||||
}
|
||||
|
||||
auto curr_scope = reinterpret_steal<object>(PyImport_ImportModule(part.c_str()));
|
||||
if (!curr_scope) {
|
||||
std::string msg = "Failed to import top-level module `";
|
||||
msg += part;
|
||||
msg += "`";
|
||||
msg += append_to_exception_message;
|
||||
raise_from(PyExc_ImportError, msg.c_str());
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
// Now recursively getattr or import remaining parts
|
||||
std::string curr_path = part;
|
||||
while (std::getline(stream, part, '.')) {
|
||||
if (part.empty()) {
|
||||
std::string msg = "Invalid fully-qualified name `";
|
||||
msg += fully_qualified_name;
|
||||
msg += "`";
|
||||
msg += append_to_exception_message;
|
||||
throw value_error(msg);
|
||||
}
|
||||
std::string next_path = curr_path;
|
||||
next_path += ".";
|
||||
next_path += part;
|
||||
auto next_scope
|
||||
= reinterpret_steal<object>(PyObject_GetAttrString(curr_scope.ptr(), part.c_str()));
|
||||
if (!next_scope) {
|
||||
error_fetch_and_normalize stored_getattr_error("getattr");
|
||||
// Try importing the next level
|
||||
next_scope = reinterpret_steal<object>(PyImport_ImportModule(next_path.c_str()));
|
||||
if (!next_scope) {
|
||||
error_fetch_and_normalize stored_import_error("import");
|
||||
std::string msg = "Failed to import or getattr `";
|
||||
msg += part;
|
||||
msg += "` from `";
|
||||
msg += curr_path;
|
||||
msg += "`";
|
||||
msg += append_to_exception_message;
|
||||
msg += "\n-------- getattr exception --------\n";
|
||||
msg += stored_getattr_error.error_string();
|
||||
msg += "\n-------- import exception --------\n";
|
||||
msg += stored_import_error.error_string();
|
||||
throw import_error(msg.c_str());
|
||||
}
|
||||
}
|
||||
curr_scope = next_scope;
|
||||
curr_path = next_path;
|
||||
}
|
||||
return curr_scope;
|
||||
}
|
||||
|
||||
inline void native_enum_data::finalize() {
|
||||
disarm_finalize_check("DOUBLE finalize");
|
||||
if (hasattr(parent_scope, enum_name)) {
|
||||
pybind11_fail("pybind11::native_enum<...>(\"" + enum_name_encoded
|
||||
+ "\"): an object with that name is already defined");
|
||||
}
|
||||
auto py_enum_type = import_or_getattr(native_type_name, " (native_type_name)");
|
||||
auto py_enum = py_enum_type(enum_name, members);
|
||||
object module_name = get_module_name_if_available(parent_scope);
|
||||
if (module_name) {
|
||||
py_enum.attr("__module__") = module_name;
|
||||
}
|
||||
if (hasattr(parent_scope, "__qualname__")) {
|
||||
const auto parent_qualname = parent_scope.attr("__qualname__").cast<std::string>();
|
||||
py_enum.attr("__qualname__") = str(parent_qualname + "." + enum_name.cast<std::string>());
|
||||
}
|
||||
parent_scope.attr(enum_name) = py_enum;
|
||||
if (export_values_flag) {
|
||||
for (auto member : members) {
|
||||
auto member_name = member[int_(0)];
|
||||
if (hasattr(parent_scope, member_name)) {
|
||||
pybind11_fail("pybind11::native_enum<...>(\"" + enum_name_encoded + "\").value(\""
|
||||
+ member_name.cast<std::string>()
|
||||
+ "\"): an object with that name is already defined");
|
||||
}
|
||||
parent_scope.attr(member_name) = py_enum[member_name];
|
||||
}
|
||||
}
|
||||
if (!class_doc.empty()) {
|
||||
py_enum.attr("__doc__") = class_doc.c_str();
|
||||
}
|
||||
for (auto doc : member_docs) {
|
||||
py_enum[doc[int_(0)]].attr("__doc__") = doc[int_(1)];
|
||||
}
|
||||
global_internals_native_enum_type_map_set_item(enum_type_index, py_enum.release().ptr());
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2016-2025 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
// PLEASE DO NOT ADD ANY INCLUDES HERE
|
||||
|
||||
// Define some generic pybind11 helper macros for warning management.
|
||||
//
|
||||
// Note that compiler-specific push/pop pairs are baked into the
|
||||
// PYBIND11_NAMESPACE_BEGIN/PYBIND11_NAMESPACE_END pair of macros. Therefore manual
|
||||
// PYBIND11_WARNING_PUSH/PYBIND11_WARNING_POP are usually only needed in `#include` sections.
|
||||
//
|
||||
// If you find you need to suppress a warning, please try to make the suppression as local as
|
||||
// possible using these macros. Please also be sure to push/pop with the pybind11 macros. Please
|
||||
// only use compiler specifics if you need to check specific versions, e.g. Apple Clang vs. vanilla
|
||||
// Clang.
|
||||
#if defined(_MSC_VER)
|
||||
# define PYBIND11_COMPILER_MSVC
|
||||
# define PYBIND11_PRAGMA(...) __pragma(__VA_ARGS__)
|
||||
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning(push))
|
||||
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning(pop))
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
# define PYBIND11_COMPILER_INTEL
|
||||
# define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
|
||||
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning push)
|
||||
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning pop)
|
||||
#elif defined(__clang__)
|
||||
# define PYBIND11_COMPILER_CLANG
|
||||
# define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
|
||||
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(clang diagnostic push)
|
||||
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(clang diagnostic pop)
|
||||
#elif defined(__GNUC__)
|
||||
# define PYBIND11_COMPILER_GCC
|
||||
# define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
|
||||
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(GCC diagnostic push)
|
||||
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(GCC diagnostic pop)
|
||||
#endif
|
||||
|
||||
#ifdef PYBIND11_COMPILER_MSVC
|
||||
# define PYBIND11_WARNING_DISABLE_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
|
||||
#else
|
||||
# define PYBIND11_WARNING_DISABLE_MSVC(name)
|
||||
#endif
|
||||
|
||||
#ifdef PYBIND11_COMPILER_CLANG
|
||||
# define PYBIND11_WARNING_DISABLE_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
|
||||
#else
|
||||
# define PYBIND11_WARNING_DISABLE_CLANG(name)
|
||||
#endif
|
||||
|
||||
#ifdef PYBIND11_COMPILER_GCC
|
||||
# define PYBIND11_WARNING_DISABLE_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
|
||||
#else
|
||||
# define PYBIND11_WARNING_DISABLE_GCC(name)
|
||||
#endif
|
||||
|
||||
#ifdef PYBIND11_COMPILER_INTEL
|
||||
# define PYBIND11_WARNING_DISABLE_INTEL(name) PYBIND11_PRAGMA(warning disable name)
|
||||
#else
|
||||
# define PYBIND11_WARNING_DISABLE_INTEL(name)
|
||||
#endif
|
||||
|
||||
#define PYBIND11_NAMESPACE_BEGIN(name) \
|
||||
namespace name { \
|
||||
PYBIND11_WARNING_PUSH
|
||||
|
||||
#define PYBIND11_NAMESPACE_END(name) \
|
||||
PYBIND11_WARNING_POP \
|
||||
}
|
||||
|
||||
// Robust support for some features and loading modules compiled against different pybind versions
|
||||
// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
|
||||
// on the main `pybind11` namespace.
|
||||
#if !defined(PYBIND11_NAMESPACE)
|
||||
# if defined(__GNUG__) && !defined(_WIN32)
|
||||
# define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden")))
|
||||
# else
|
||||
# define PYBIND11_NAMESPACE pybind11
|
||||
# endif
|
||||
#endif
|
||||
378
deps_src/pybind11/include/pybind11/detail/struct_smart_holder.h
Normal file
378
deps_src/pybind11/include/pybind11/detail/struct_smart_holder.h
Normal file
@@ -0,0 +1,378 @@
|
||||
// Copyright (c) 2020-2024 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/* Proof-of-Concept for smart pointer interoperability.
|
||||
|
||||
High-level aspects:
|
||||
|
||||
* Support all `unique_ptr`, `shared_ptr` interops that are feasible.
|
||||
|
||||
* Cleanly and clearly report all interops that are infeasible.
|
||||
|
||||
* Meant to fit into a `PyObject`, as a holder for C++ objects.
|
||||
|
||||
* Support a system design that makes it impossible to trigger
|
||||
C++ Undefined Behavior, especially from Python.
|
||||
|
||||
* Support a system design with clean runtime inheritance casting. From this
|
||||
it follows that the `smart_holder` needs to be type-erased (`void*`).
|
||||
|
||||
* Handling of RTTI for the type-erased held pointer is NOT implemented here.
|
||||
It is the responsibility of the caller to ensure that `static_cast<T *>`
|
||||
is well-formed when calling `as_*` member functions. Inheritance casting
|
||||
needs to be handled in a different layer (similar to the code organization
|
||||
in boost/python/object/inheritance.hpp).
|
||||
|
||||
Details:
|
||||
|
||||
* The "root holder" chosen here is a `shared_ptr<void>` (named `vptr` in this
|
||||
implementation). This choice is practically inevitable because `shared_ptr`
|
||||
has only very limited support for inspecting and accessing its deleter.
|
||||
|
||||
* If created from a raw pointer, or a `unique_ptr` without a custom deleter,
|
||||
`vptr` always uses a custom deleter, to support `unique_ptr`-like disowning.
|
||||
The custom deleters could be extended to included life-time management for
|
||||
external objects (e.g. `PyObject`).
|
||||
|
||||
* If created from an external `shared_ptr`, or a `unique_ptr` with a custom
|
||||
deleter, including life-time management for external objects is infeasible.
|
||||
|
||||
* By choice, the smart_holder is movable but not copyable, to keep the design
|
||||
simple, and to guard against accidental copying overhead.
|
||||
|
||||
* The `void_cast_raw_ptr` option is needed to make the `smart_holder` `vptr`
|
||||
member invisible to the `shared_from_this` mechanism, in case the lifetime
|
||||
of a `PyObject` is tied to the pointee.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11_namespace_macros.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(memory)
|
||||
|
||||
// Default fallback.
|
||||
static constexpr bool type_has_shared_from_this(...) { return false; }
|
||||
|
||||
// This overload uses SFINAE to skip enable_shared_from_this checks when the
|
||||
// base is inaccessible (e.g. private inheritance).
|
||||
template <typename T>
|
||||
static auto type_has_shared_from_this(const T *ptr)
|
||||
-> decltype(static_cast<const std::enable_shared_from_this<T> *>(ptr), true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inaccessible base → substitution failure → fallback overload selected
|
||||
template <typename T>
|
||||
static constexpr bool type_has_shared_from_this(const void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct guarded_delete {
|
||||
// NOTE: PYBIND11_INTERNALS_VERSION needs to be bumped if changes are made to this struct.
|
||||
std::weak_ptr<void> released_ptr; // Trick to keep the smart_holder memory footprint small.
|
||||
std::function<void(void *)> del_fun; // Rare case.
|
||||
void (*del_ptr)(void *); // Common case.
|
||||
bool use_del_fun;
|
||||
bool armed_flag;
|
||||
guarded_delete(std::function<void(void *)> &&del_fun, bool armed_flag)
|
||||
: del_fun{std::move(del_fun)}, del_ptr{nullptr}, use_del_fun{true},
|
||||
armed_flag{armed_flag} {}
|
||||
guarded_delete(void (*del_ptr)(void *), bool armed_flag)
|
||||
: del_ptr{del_ptr}, use_del_fun{false}, armed_flag{armed_flag} {}
|
||||
void operator()(void *raw_ptr) const {
|
||||
if (armed_flag) {
|
||||
if (use_del_fun) {
|
||||
del_fun(raw_ptr);
|
||||
} else {
|
||||
del_ptr(raw_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline guarded_delete *get_guarded_delete(const std::shared_ptr<void> &ptr) {
|
||||
return std::get_deleter<guarded_delete>(ptr);
|
||||
}
|
||||
|
||||
using get_guarded_delete_fn = guarded_delete *(*) (const std::shared_ptr<void> &);
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_destructible<T>::value, int>::type = 0>
|
||||
inline void std_default_delete_if_destructible(void *raw_ptr) {
|
||||
std::default_delete<T>{}(static_cast<T *>(raw_ptr));
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<!std::is_destructible<T>::value, int>::type = 0>
|
||||
inline void std_default_delete_if_destructible(void *) {
|
||||
// This noop operator is needed to avoid a compilation error (for `delete raw_ptr;`), but
|
||||
// throwing an exception from a destructor will std::terminate the process. Therefore the
|
||||
// runtime check for lifetime-management correctness is implemented elsewhere (in
|
||||
// ensure_pointee_is_destructible()).
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
guarded_delete make_guarded_std_default_delete(bool armed_flag) {
|
||||
return guarded_delete(std_default_delete_if_destructible<T>, armed_flag);
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
struct custom_deleter {
|
||||
// NOTE: PYBIND11_INTERNALS_VERSION needs to be bumped if changes are made to this struct.
|
||||
D deleter;
|
||||
explicit custom_deleter(D &&deleter) : deleter{std::forward<D>(deleter)} {}
|
||||
void operator()(void *raw_ptr) { deleter(static_cast<T *>(raw_ptr)); }
|
||||
};
|
||||
|
||||
template <typename T, typename D>
|
||||
guarded_delete make_guarded_custom_deleter(D &&uqp_del, bool armed_flag) {
|
||||
return guarded_delete(
|
||||
std::function<void(void *)>(custom_deleter<T, D>(std::forward<D>(uqp_del))), armed_flag);
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
constexpr bool uqp_del_is_std_default_delete() {
|
||||
return std::is_same<D, std::default_delete<T>>::value
|
||||
|| std::is_same<D, std::default_delete<T const>>::value;
|
||||
}
|
||||
|
||||
inline bool type_info_equal_across_dso_boundaries(const std::type_info &a,
|
||||
const std::type_info &b) {
|
||||
// RTTI pointer comparison may fail across DSOs (e.g., macOS libc++).
|
||||
// Fallback to name comparison, which is generally safe and ABI-stable enough for our use.
|
||||
return a == b || std::strcmp(a.name(), b.name()) == 0;
|
||||
}
|
||||
|
||||
struct smart_holder {
|
||||
// NOTE: PYBIND11_INTERNALS_VERSION needs to be bumped if changes are made to this struct.
|
||||
const std::type_info *rtti_uqp_del = nullptr;
|
||||
std::shared_ptr<void> vptr;
|
||||
bool vptr_is_using_noop_deleter : 1;
|
||||
bool vptr_is_using_std_default_delete : 1;
|
||||
bool vptr_is_external_shared_ptr : 1;
|
||||
bool is_populated : 1;
|
||||
bool is_disowned : 1;
|
||||
|
||||
// Design choice: smart_holder is movable but not copyable.
|
||||
smart_holder(smart_holder &&) = default;
|
||||
smart_holder(const smart_holder &) = delete;
|
||||
smart_holder &operator=(smart_holder &&) = delete;
|
||||
smart_holder &operator=(const smart_holder &) = delete;
|
||||
|
||||
smart_holder()
|
||||
: vptr_is_using_noop_deleter{false}, vptr_is_using_std_default_delete{false},
|
||||
vptr_is_external_shared_ptr{false}, is_populated{false}, is_disowned{false} {}
|
||||
|
||||
bool has_pointee() const { return vptr != nullptr; }
|
||||
|
||||
template <typename T>
|
||||
static void ensure_pointee_is_destructible(const char *context) {
|
||||
if (!std::is_destructible<T>::value) {
|
||||
throw std::invalid_argument(std::string("Pointee is not destructible (") + context
|
||||
+ ").");
|
||||
}
|
||||
}
|
||||
|
||||
void ensure_is_populated(const char *context) const {
|
||||
if (!is_populated) {
|
||||
throw std::runtime_error(std::string("Unpopulated holder (") + context + ").");
|
||||
}
|
||||
}
|
||||
void ensure_is_not_disowned(const char *context) const {
|
||||
if (is_disowned) {
|
||||
throw std::runtime_error(std::string("Holder was disowned already (") + context
|
||||
+ ").");
|
||||
}
|
||||
}
|
||||
|
||||
void ensure_vptr_is_using_std_default_delete(const char *context) const {
|
||||
if (vptr_is_external_shared_ptr) {
|
||||
throw std::invalid_argument(std::string("Cannot disown external shared_ptr (")
|
||||
+ context + ").");
|
||||
}
|
||||
if (vptr_is_using_noop_deleter) {
|
||||
throw std::invalid_argument(std::string("Cannot disown non-owning holder (") + context
|
||||
+ ").");
|
||||
}
|
||||
if (!vptr_is_using_std_default_delete) {
|
||||
throw std::invalid_argument(std::string("Cannot disown custom deleter (") + context
|
||||
+ ").");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
void ensure_compatible_uqp_del(const char *context) const {
|
||||
if (!rtti_uqp_del) {
|
||||
if (!uqp_del_is_std_default_delete<T, D>()) {
|
||||
throw std::invalid_argument(std::string("Missing unique_ptr deleter (") + context
|
||||
+ ").");
|
||||
}
|
||||
ensure_vptr_is_using_std_default_delete(context);
|
||||
return;
|
||||
}
|
||||
if (uqp_del_is_std_default_delete<T, D>() && vptr_is_using_std_default_delete) {
|
||||
return;
|
||||
}
|
||||
if (!type_info_equal_across_dso_boundaries(typeid(D), *rtti_uqp_del)) {
|
||||
throw std::invalid_argument(std::string("Incompatible unique_ptr deleter (") + context
|
||||
+ ").");
|
||||
}
|
||||
}
|
||||
|
||||
void ensure_has_pointee(const char *context) const {
|
||||
if (!has_pointee()) {
|
||||
throw std::invalid_argument(std::string("Disowned holder (") + context + ").");
|
||||
}
|
||||
}
|
||||
|
||||
void ensure_use_count_1(const char *context) const {
|
||||
if (vptr == nullptr) {
|
||||
throw std::invalid_argument(std::string("Cannot disown nullptr (") + context + ").");
|
||||
}
|
||||
// In multithreaded environments accessing use_count can lead to
|
||||
// race conditions, but in the context of Python it is a bug (elsewhere)
|
||||
// if the Global Interpreter Lock (GIL) is not being held when this code
|
||||
// is reached.
|
||||
// PYBIND11:REMINDER: This may need to be protected by a mutex in free-threaded Python.
|
||||
if (vptr.use_count() != 1) {
|
||||
throw std::invalid_argument(std::string("Cannot disown use_count != 1 (") + context
|
||||
+ ").");
|
||||
}
|
||||
}
|
||||
|
||||
void reset_vptr_deleter_armed_flag(const get_guarded_delete_fn ggd_fn, bool armed_flag) const {
|
||||
auto *gd = ggd_fn(vptr);
|
||||
if (gd == nullptr) {
|
||||
throw std::runtime_error(
|
||||
"smart_holder::reset_vptr_deleter_armed_flag() called in an invalid context.");
|
||||
}
|
||||
gd->armed_flag = armed_flag;
|
||||
}
|
||||
|
||||
// Caller is responsible for precondition: ensure_compatible_uqp_del<T, D>() must succeed.
|
||||
template <typename T, typename D>
|
||||
std::unique_ptr<D> extract_deleter(const char *context,
|
||||
const get_guarded_delete_fn ggd_fn) const {
|
||||
auto *gd = ggd_fn(vptr);
|
||||
if (gd && gd->use_del_fun) {
|
||||
const auto &custom_deleter_ptr = gd->del_fun.template target<custom_deleter<T, D>>();
|
||||
if (custom_deleter_ptr == nullptr) {
|
||||
throw std::runtime_error(
|
||||
std::string("smart_holder::extract_deleter() precondition failure (") + context
|
||||
+ ").");
|
||||
}
|
||||
static_assert(std::is_copy_constructible<D>::value,
|
||||
"Required for compatibility with smart_holder functionality.");
|
||||
return std::unique_ptr<D>(new D(custom_deleter_ptr->deleter));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static smart_holder from_raw_ptr_unowned(void *raw_ptr) {
|
||||
smart_holder hld;
|
||||
hld.vptr.reset(raw_ptr, [](void *) {});
|
||||
hld.vptr_is_using_noop_deleter = true;
|
||||
hld.is_populated = true;
|
||||
return hld;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *as_raw_ptr_unowned() const {
|
||||
return static_cast<T *>(vptr.get());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static smart_holder from_raw_ptr_take_ownership(T *raw_ptr, bool void_cast_raw_ptr = false) {
|
||||
ensure_pointee_is_destructible<T>("from_raw_ptr_take_ownership");
|
||||
smart_holder hld;
|
||||
auto gd = make_guarded_std_default_delete<T>(true);
|
||||
if (void_cast_raw_ptr) {
|
||||
hld.vptr.reset(static_cast<void *>(raw_ptr), std::move(gd));
|
||||
} else {
|
||||
hld.vptr.reset(raw_ptr, std::move(gd));
|
||||
}
|
||||
hld.vptr_is_using_std_default_delete = true;
|
||||
hld.is_populated = true;
|
||||
return hld;
|
||||
}
|
||||
|
||||
// Caller is responsible for ensuring the complex preconditions
|
||||
// (see `smart_holder_type_caster_support::load_helper`).
|
||||
void disown(const get_guarded_delete_fn ggd_fn) {
|
||||
reset_vptr_deleter_armed_flag(ggd_fn, false);
|
||||
is_disowned = true;
|
||||
}
|
||||
|
||||
// Caller is responsible for ensuring the complex preconditions
|
||||
// (see `smart_holder_type_caster_support::load_helper`).
|
||||
void reclaim_disowned(const get_guarded_delete_fn ggd_fn) {
|
||||
reset_vptr_deleter_armed_flag(ggd_fn, true);
|
||||
is_disowned = false;
|
||||
}
|
||||
|
||||
// Caller is responsible for ensuring the complex preconditions
|
||||
// (see `smart_holder_type_caster_support::load_helper`).
|
||||
void release_disowned() { vptr.reset(); }
|
||||
|
||||
void ensure_can_release_ownership(const char *context = "ensure_can_release_ownership") const {
|
||||
ensure_is_not_disowned(context);
|
||||
ensure_vptr_is_using_std_default_delete(context);
|
||||
ensure_use_count_1(context);
|
||||
}
|
||||
|
||||
// Caller is responsible for ensuring the complex preconditions
|
||||
// (see `smart_holder_type_caster_support::load_helper`).
|
||||
void release_ownership(const get_guarded_delete_fn ggd_fn) {
|
||||
reset_vptr_deleter_armed_flag(ggd_fn, false);
|
||||
release_disowned();
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
static smart_holder from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
|
||||
void *void_ptr = nullptr) {
|
||||
smart_holder hld;
|
||||
hld.rtti_uqp_del = &typeid(D);
|
||||
hld.vptr_is_using_std_default_delete = uqp_del_is_std_default_delete<T, D>();
|
||||
guarded_delete gd{nullptr, false};
|
||||
if (hld.vptr_is_using_std_default_delete) {
|
||||
gd = make_guarded_std_default_delete<T>(true);
|
||||
} else {
|
||||
gd = make_guarded_custom_deleter<T, D>(std::move(unq_ptr.get_deleter()), true);
|
||||
}
|
||||
if (void_ptr != nullptr) {
|
||||
hld.vptr.reset(void_ptr, std::move(gd));
|
||||
} else {
|
||||
hld.vptr.reset(unq_ptr.get(), std::move(gd));
|
||||
}
|
||||
(void) unq_ptr.release();
|
||||
hld.is_populated = true;
|
||||
return hld;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static smart_holder from_shared_ptr(const std::shared_ptr<T> &shd_ptr) {
|
||||
smart_holder hld;
|
||||
hld.vptr = std::static_pointer_cast<void>(shd_ptr);
|
||||
hld.vptr_is_external_shared_ptr = true;
|
||||
hld.is_populated = true;
|
||||
return hld;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> as_shared_ptr() const {
|
||||
return std::static_pointer_cast<T>(vptr);
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(memory)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
1591
deps_src/pybind11/include/pybind11/detail/type_caster_base.h
Normal file
1591
deps_src/pybind11/include/pybind11/detail/type_caster_base.h
Normal file
File diff suppressed because it is too large
Load Diff
65
deps_src/pybind11/include/pybind11/detail/typeid.h
Normal file
65
deps_src/pybind11/include/pybind11/detail/typeid.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
pybind11/detail/typeid.h: Compiler-independent access to type identifiers
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(__GNUG__)
|
||||
# include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
/// Erase all occurrences of a substring
|
||||
inline void erase_all(std::string &string, const std::string &search) {
|
||||
for (size_t pos = 0;;) {
|
||||
pos = string.find(search, pos);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
string.erase(pos, search.length());
|
||||
}
|
||||
}
|
||||
|
||||
PYBIND11_NOINLINE void clean_type_id(std::string &name) {
|
||||
#if defined(__GNUG__)
|
||||
int status = 0;
|
||||
std::unique_ptr<char, void (*)(void *)> res{
|
||||
abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free};
|
||||
if (status == 0) {
|
||||
name = res.get();
|
||||
}
|
||||
#else
|
||||
detail::erase_all(name, "class ");
|
||||
detail::erase_all(name, "struct ");
|
||||
detail::erase_all(name, "enum ");
|
||||
#endif
|
||||
detail::erase_all(name, "pybind11::");
|
||||
}
|
||||
|
||||
inline std::string clean_type_id(const char *typeid_name) {
|
||||
std::string name(typeid_name);
|
||||
detail::clean_type_id(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Return a string representation of a C++ type
|
||||
template <typename T>
|
||||
static std::string type_id() {
|
||||
return detail::clean_type_id(typeid(T).name());
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2024 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "struct_smart_holder.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
using pybind11::memory::smart_holder;
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename H>
|
||||
using is_smart_holder = std::is_same<H, smart_holder>;
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
90
deps_src/pybind11/include/pybind11/detail/value_and_holder.h
Normal file
90
deps_src/pybind11/include/pybind11/detail/value_and_holder.h
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2016-2024 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
struct value_and_holder {
|
||||
instance *inst = nullptr;
|
||||
size_t index = 0u;
|
||||
const detail::type_info *type = nullptr;
|
||||
void **vh = nullptr;
|
||||
|
||||
// Main constructor for a found value/holder:
|
||||
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)
|
||||
: inst{i}, index{index}, type{type},
|
||||
vh{inst->simple_layout ? inst->simple_value_holder
|
||||
: &inst->nonsimple.values_and_holders[vpos]} {}
|
||||
|
||||
// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
|
||||
value_and_holder() = default;
|
||||
|
||||
// Used for past-the-end iterator
|
||||
explicit value_and_holder(size_t index) : index{index} {}
|
||||
|
||||
template <typename V = void>
|
||||
V *&value_ptr() const {
|
||||
return reinterpret_cast<V *&>(vh[0]);
|
||||
}
|
||||
// True if this `value_and_holder` has a non-null value pointer
|
||||
explicit operator bool() const { return value_ptr() != nullptr; }
|
||||
|
||||
template <typename H>
|
||||
H &holder() const {
|
||||
return reinterpret_cast<H &>(vh[1]);
|
||||
}
|
||||
bool holder_constructed() const {
|
||||
return inst->simple_layout
|
||||
? inst->simple_holder_constructed
|
||||
: (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;
|
||||
}
|
||||
// NOLINTNEXTLINE(readability-make-member-function-const)
|
||||
void set_holder_constructed(bool v = true) {
|
||||
if (inst->simple_layout) {
|
||||
inst->simple_holder_constructed = v;
|
||||
} else if (v) {
|
||||
inst->nonsimple.status[index] |= instance::status_holder_constructed;
|
||||
} else {
|
||||
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;
|
||||
}
|
||||
}
|
||||
bool instance_registered() const {
|
||||
return inst->simple_layout
|
||||
? inst->simple_instance_registered
|
||||
: ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);
|
||||
}
|
||||
// NOLINTNEXTLINE(readability-make-member-function-const)
|
||||
void set_instance_registered(bool v = true) {
|
||||
if (inst->simple_layout) {
|
||||
inst->simple_instance_registered = v;
|
||||
} else if (v) {
|
||||
inst->nonsimple.status[index] |= instance::status_instance_registered;
|
||||
} else {
|
||||
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is a semi-public API to check if the corresponding instance has been constructed with a
|
||||
// holder. That is, if the instance has been constructed with a holder, the `__init__` method is
|
||||
// called and the C++ object is valid. Otherwise, the C++ object might only be allocated, but not
|
||||
// initialized. This will lead to **SEGMENTATION FAULTS** if the C++ object is used in any way.
|
||||
// Example usage: https://pybind11.readthedocs.io/en/stable/advanced/classes.html#custom-type-setup
|
||||
// for `tp_traverse` and `tp_clear` implementations.
|
||||
// WARNING: The caller is responsible for ensuring that the `reinterpret_cast` is valid.
|
||||
inline bool is_holder_constructed(PyObject *obj) {
|
||||
auto *const instance = reinterpret_cast<pybind11::detail::instance *>(obj);
|
||||
return instance->get_value_and_holder().holder_constructed();
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
12
deps_src/pybind11/include/pybind11/eigen.h
Normal file
12
deps_src/pybind11/include/pybind11/eigen.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "eigen/matrix.h"
|
||||
9
deps_src/pybind11/include/pybind11/eigen/common.h
Normal file
9
deps_src/pybind11/include/pybind11/eigen/common.h
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2023 The pybind Community.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Common message for `static_assert()`s, which are useful to easily
|
||||
// preempt much less obvious errors.
|
||||
#define PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED \
|
||||
"Pointer types (in particular `PyObject *`) are not supported as scalar types for Eigen " \
|
||||
"types."
|
||||
723
deps_src/pybind11/include/pybind11/eigen/matrix.h
Normal file
723
deps_src/pybind11/include/pybind11/eigen/matrix.h
Normal file
@@ -0,0 +1,723 @@
|
||||
/*
|
||||
pybind11/eigen/matrix.h: Transparent conversion for dense and sparse Eigen matrices
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* HINT: To suppress warnings originating from the Eigen headers, use -isystem.
|
||||
See also:
|
||||
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
|
||||
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
|
||||
*/
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
|
||||
// C5054: operator '&': deprecated between enumerations of different types
|
||||
#if defined(__MINGW32__)
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/SparseCore>
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit
|
||||
// move constructors that break things. We could detect this an explicitly copy, but an extra copy
|
||||
// of matrices seems highly undesirable.
|
||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
|
||||
"Eigen matrix support in pybind11 requires Eigen >= 3.2.7");
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
|
||||
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
template <typename MatrixType>
|
||||
using EigenDRef = Eigen::Ref<MatrixType, 0, EigenDStride>;
|
||||
template <typename MatrixType>
|
||||
using EigenDMap = Eigen::Map<MatrixType, 0, EigenDStride>;
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
|
||||
using EigenIndex = Eigen::Index;
|
||||
template <typename Scalar, int Flags, typename StorageIndex>
|
||||
using EigenMapSparseMatrix = Eigen::Map<Eigen::SparseMatrix<Scalar, Flags, StorageIndex>>;
|
||||
#else
|
||||
using EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE;
|
||||
template <typename Scalar, int Flags, typename StorageIndex>
|
||||
using EigenMapSparseMatrix = Eigen::MappedSparseMatrix<Scalar, Flags, StorageIndex>;
|
||||
#endif
|
||||
|
||||
// Matches Eigen::Map, Eigen::Ref, blocks, etc:
|
||||
template <typename T>
|
||||
using is_eigen_dense_map = all_of<is_template_base_of<Eigen::DenseBase, T>,
|
||||
std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;
|
||||
template <typename T>
|
||||
using is_eigen_mutable_map = std::is_base_of<Eigen::MapBase<T, Eigen::WriteAccessors>, T>;
|
||||
template <typename T>
|
||||
using is_eigen_dense_plain
|
||||
= all_of<negation<is_eigen_dense_map<T>>, is_template_base_of<Eigen::PlainObjectBase, T>>;
|
||||
template <typename T>
|
||||
using is_eigen_sparse = is_template_base_of<Eigen::SparseMatrixBase, T>;
|
||||
// Test for objects inheriting from EigenBase<Derived> that aren't captured by the above. This
|
||||
// basically covers anything that can be assigned to a dense matrix but that don't have a typical
|
||||
// matrix data layout that can be copied from their .data(). For example, DiagonalMatrix and
|
||||
// SelfAdjointView fall into this category.
|
||||
template <typename T>
|
||||
using is_eigen_other
|
||||
= all_of<is_template_base_of<Eigen::EigenBase, T>,
|
||||
negation<any_of<is_eigen_dense_map<T>, is_eigen_dense_plain<T>, is_eigen_sparse<T>>>>;
|
||||
|
||||
// Captures numpy/eigen conformability status (returned by EigenProps::conformable()):
|
||||
template <bool EigenRowMajor>
|
||||
struct EigenConformable {
|
||||
bool conformable = false;
|
||||
EigenIndex rows = 0, cols = 0;
|
||||
EigenDStride stride{0, 0}; // Only valid if negativestrides is false!
|
||||
bool negativestrides = false; // If true, do not use stride!
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
EigenConformable(bool fits = false) : conformable{fits} {}
|
||||
// Matrix type:
|
||||
EigenConformable(EigenIndex r, EigenIndex c, EigenIndex rstride, EigenIndex cstride)
|
||||
: conformable{true}, rows{r}, cols{c},
|
||||
// TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity.
|
||||
// http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747
|
||||
stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)
|
||||
: (cstride > 0 ? cstride : 0) /* outer stride */,
|
||||
EigenRowMajor ? (cstride > 0 ? cstride : 0)
|
||||
: (rstride > 0 ? rstride : 0) /* inner stride */},
|
||||
negativestrides{rstride < 0 || cstride < 0} {}
|
||||
// Vector type:
|
||||
EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride)
|
||||
: EigenConformable(r, c, r == 1 ? c * stride : stride, c == 1 ? r : r * stride) {}
|
||||
|
||||
template <typename props>
|
||||
bool stride_compatible() const {
|
||||
// To have compatible strides, we need (on both dimensions) one of fully dynamic strides,
|
||||
// matching strides, or a dimension size of 1 (in which case the stride value is
|
||||
// irrelevant). Alternatively, if any dimension size is 0, the strides are not relevant
|
||||
// (and numpy ≥ 1.23 sets the strides to 0 in that case, so we need to check explicitly).
|
||||
if (negativestrides) {
|
||||
return false;
|
||||
}
|
||||
if (rows == 0 || cols == 0) {
|
||||
return true;
|
||||
}
|
||||
return (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner()
|
||||
|| (EigenRowMajor ? cols : rows) == 1)
|
||||
&& (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer()
|
||||
|| (EigenRowMajor ? rows : cols) == 1);
|
||||
}
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator bool() const { return conformable; }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct eigen_extract_stride {
|
||||
using type = Type;
|
||||
};
|
||||
template <typename PlainObjectType, int MapOptions, typename StrideType>
|
||||
struct eigen_extract_stride<Eigen::Map<PlainObjectType, MapOptions, StrideType>> {
|
||||
using type = StrideType;
|
||||
};
|
||||
template <typename PlainObjectType, int Options, typename StrideType>
|
||||
struct eigen_extract_stride<Eigen::Ref<PlainObjectType, Options, StrideType>> {
|
||||
using type = StrideType;
|
||||
};
|
||||
|
||||
// Helper struct for extracting information from an Eigen type
|
||||
template <typename Type_>
|
||||
struct EigenProps {
|
||||
using Type = Type_;
|
||||
using Scalar = typename Type::Scalar;
|
||||
using StrideType = typename eigen_extract_stride<Type>::type;
|
||||
static constexpr EigenIndex rows = Type::RowsAtCompileTime, cols = Type::ColsAtCompileTime,
|
||||
size = Type::SizeAtCompileTime;
|
||||
static constexpr bool row_major = Type::IsRowMajor,
|
||||
vector
|
||||
= Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1
|
||||
fixed_rows = rows != Eigen::Dynamic, fixed_cols = cols != Eigen::Dynamic,
|
||||
fixed = size != Eigen::Dynamic, // Fully-fixed size
|
||||
dynamic = !fixed_rows && !fixed_cols; // Fully-dynamic size
|
||||
|
||||
template <EigenIndex i, EigenIndex ifzero>
|
||||
using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;
|
||||
static constexpr EigenIndex inner_stride
|
||||
= if_zero<StrideType::InnerStrideAtCompileTime, 1>::value,
|
||||
outer_stride = if_zero < StrideType::OuterStrideAtCompileTime,
|
||||
vector ? size
|
||||
: row_major ? cols
|
||||
: rows > ::value;
|
||||
static constexpr bool dynamic_stride
|
||||
= inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic;
|
||||
static constexpr bool requires_row_major
|
||||
= !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1;
|
||||
static constexpr bool requires_col_major
|
||||
= !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1;
|
||||
|
||||
// Takes an input array and determines whether we can make it fit into the Eigen type. If
|
||||
// the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector
|
||||
// (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type).
|
||||
static EigenConformable<row_major> conformable(const array &a) {
|
||||
const auto dims = a.ndim();
|
||||
if (dims < 1 || dims > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dims == 2) { // Matrix type: require exact match (or dynamic)
|
||||
|
||||
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
|
||||
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
|
||||
np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
|
||||
if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {np_rows, np_cols, np_rstride, np_cstride};
|
||||
}
|
||||
|
||||
// Otherwise we're storing an n-vector. Only one of the strides will be used, but
|
||||
// whichever is used, we want the (single) numpy stride value.
|
||||
const EigenIndex n = a.shape(0),
|
||||
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
|
||||
|
||||
if (vector) { // Eigen type is a compile-time vector
|
||||
if (fixed && size != n) {
|
||||
return false; // Vector size mismatch
|
||||
}
|
||||
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
||||
}
|
||||
if (fixed) {
|
||||
// The type has a fixed size, but is not a vector: abort
|
||||
return false;
|
||||
}
|
||||
if (fixed_cols) {
|
||||
// Since this isn't a vector, cols must be != 1. We allow this only if it exactly
|
||||
// equals the number of elements (rows is Dynamic, and so 1 row is allowed).
|
||||
if (cols != n) {
|
||||
return false;
|
||||
}
|
||||
return {1, n, stride};
|
||||
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
|
||||
if (fixed_rows && rows != n) {
|
||||
return false;
|
||||
}
|
||||
return {n, 1, stride};
|
||||
}
|
||||
|
||||
static constexpr bool show_writeable
|
||||
= is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;
|
||||
static constexpr bool show_order = is_eigen_dense_map<Type>::value;
|
||||
static constexpr bool show_c_contiguous = show_order && requires_row_major;
|
||||
static constexpr bool show_f_contiguous
|
||||
= !show_c_contiguous && show_order && requires_col_major;
|
||||
|
||||
static constexpr auto descriptor
|
||||
= const_name("typing.Annotated[")
|
||||
+ io_name("numpy.typing.ArrayLike, ", "numpy.typing.NDArray[")
|
||||
+ npy_format_descriptor<Scalar>::name + io_name("", "]") + const_name(", \"[")
|
||||
+ const_name<fixed_rows>(const_name<(size_t) rows>(), const_name("m")) + const_name(", ")
|
||||
+ const_name<fixed_cols>(const_name<(size_t) cols>(), const_name("n"))
|
||||
+ const_name("]\"")
|
||||
// For a reference type (e.g. Ref<MatrixXd>) we have other constraints that might need to
|
||||
// be satisfied: writeable=True (for a mutable reference), and, depending on the map's
|
||||
// stride options, possibly f_contiguous or c_contiguous. We include them in the
|
||||
// descriptor output to provide some hint as to why a TypeError is occurring (otherwise
|
||||
// it can be confusing to see that a function accepts a
|
||||
// 'typing.Annotated[numpy.typing.NDArray[numpy.float64], "[3,2]"]' and an error message
|
||||
// that you *gave* a numpy.ndarray of the right type and dimensions.
|
||||
+ const_name<show_writeable>(", \"flags.writeable\"", "")
|
||||
+ const_name<show_c_contiguous>(", \"flags.c_contiguous\"", "")
|
||||
+ const_name<show_f_contiguous>(", \"flags.f_contiguous\"", "") + const_name("]");
|
||||
};
|
||||
|
||||
// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data,
|
||||
// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array.
|
||||
template <typename props>
|
||||
handle
|
||||
eigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) {
|
||||
constexpr ssize_t elem_size = sizeof(typename props::Scalar);
|
||||
array a;
|
||||
if (props::vector) {
|
||||
a = array({src.size()}, {elem_size * src.innerStride()}, src.data(), base);
|
||||
} else {
|
||||
a = array({src.rows(), src.cols()},
|
||||
{elem_size * src.rowStride(), elem_size * src.colStride()},
|
||||
src.data(),
|
||||
base);
|
||||
}
|
||||
|
||||
if (!writeable) {
|
||||
array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
|
||||
}
|
||||
|
||||
return a.release();
|
||||
}
|
||||
|
||||
// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that
|
||||
// reference the Eigen object's data with `base` as the python-registered base class (if omitted,
|
||||
// the base will be set to None, and lifetime management is up to the caller). The numpy array is
|
||||
// non-writeable if the given type is const.
|
||||
template <typename props, typename Type>
|
||||
handle eigen_ref_array(Type &src, handle parent = none()) {
|
||||
// none here is to get past array's should-we-copy detection, which currently always
|
||||
// copies when there is no base. Setting the base to None should be harmless.
|
||||
return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);
|
||||
}
|
||||
|
||||
// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a
|
||||
// numpy array that references the encapsulated data with a python-side reference to the capsule to
|
||||
// tie its destruction to that of any dependent python objects. Const-ness is determined by
|
||||
// whether or not the Type of the pointer given is const.
|
||||
template <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>
|
||||
handle eigen_encapsulate(Type *src) {
|
||||
capsule base(src, [](void *o) { delete static_cast<Type *>(o); });
|
||||
return eigen_ref_array<props>(*src, base);
|
||||
}
|
||||
|
||||
// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense
|
||||
// types.
|
||||
template <typename Type>
|
||||
struct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {
|
||||
using Scalar = typename Type::Scalar;
|
||||
static_assert(!std::is_pointer<Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
using props = EigenProps<Type>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
// If we're in no-convert mode, only load if given an array of the correct type
|
||||
if (!convert && !isinstance<array_t<Scalar>>(src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Coerce into an array, but don't do type conversion yet; the copy below handles it.
|
||||
auto buf = array::ensure(src);
|
||||
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto dims = buf.ndim();
|
||||
if (dims < 1 || dims > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fits = props::conformable(buf);
|
||||
if (!fits) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // See PR #5516
|
||||
// Allocate the new type, then build a numpy reference into it
|
||||
value = Type(fits.rows, fits.cols);
|
||||
PYBIND11_WARNING_POP
|
||||
auto ref = reinterpret_steal<array>(eigen_ref_array<props>(value));
|
||||
if (dims == 1) {
|
||||
ref = ref.squeeze();
|
||||
} else if (ref.ndim() == 1) {
|
||||
buf = buf.squeeze();
|
||||
}
|
||||
|
||||
int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr());
|
||||
|
||||
if (result < 0) { // Copy failed!
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Cast implementation
|
||||
template <typename CType>
|
||||
static handle cast_impl(CType *src, return_value_policy policy, handle parent) {
|
||||
switch (policy) {
|
||||
case return_value_policy::take_ownership:
|
||||
case return_value_policy::automatic:
|
||||
return eigen_encapsulate<props>(src);
|
||||
case return_value_policy::move:
|
||||
return eigen_encapsulate<props>(new CType(std::move(*src)));
|
||||
case return_value_policy::copy:
|
||||
return eigen_array_cast<props>(*src);
|
||||
case return_value_policy::reference:
|
||||
case return_value_policy::automatic_reference:
|
||||
return eigen_ref_array<props>(*src);
|
||||
case return_value_policy::reference_internal:
|
||||
return eigen_ref_array<props>(*src, parent);
|
||||
default:
|
||||
throw cast_error("unhandled return_value_policy: should not happen!");
|
||||
};
|
||||
}
|
||||
|
||||
public:
|
||||
// Normal returned non-reference, non-const value:
|
||||
static handle cast(Type &&src, return_value_policy /* policy */, handle parent) {
|
||||
return cast_impl(&src, return_value_policy::move, parent);
|
||||
}
|
||||
// If you return a non-reference const, we mark the numpy array readonly:
|
||||
static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) {
|
||||
return cast_impl(&src, return_value_policy::move, parent);
|
||||
}
|
||||
// lvalue reference return; default (automatic) becomes copy
|
||||
static handle cast(Type &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast_impl(&src, policy, parent);
|
||||
}
|
||||
// const lvalue reference return; default (automatic) becomes copy
|
||||
static handle cast(const Type &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast(&src, policy, parent);
|
||||
}
|
||||
// non-const pointer return
|
||||
static handle cast(Type *src, return_value_policy policy, handle parent) {
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
// const pointer return
|
||||
static handle cast(const Type *src, return_value_policy policy, handle parent) {
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
|
||||
static constexpr auto name = props::descriptor;
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator Type *() { return &value; }
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator Type &() { return value; }
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator Type &&() && { return std::move(value); }
|
||||
template <typename T>
|
||||
using cast_op_type = movable_cast_op_type<T>;
|
||||
|
||||
private:
|
||||
Type value;
|
||||
};
|
||||
|
||||
// Base class for casting reference/map/block/etc. objects back to python.
|
||||
template <typename MapType>
|
||||
struct eigen_map_caster {
|
||||
static_assert(!std::is_pointer<typename MapType::Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
|
||||
private:
|
||||
using props = EigenProps<MapType>;
|
||||
|
||||
public:
|
||||
// Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has
|
||||
// to stay around), but we'll allow it under the assumption that you know what you're doing
|
||||
// (and have an appropriate keep_alive in place). We return a numpy array pointing directly at
|
||||
// the ref's data (The numpy array ends up read-only if the ref was to a const matrix type.)
|
||||
// Note that this means you need to ensure you don't destroy the object in some other way (e.g.
|
||||
// with an appropriate keep_alive, or with a reference to a statically allocated matrix).
|
||||
static handle cast(const MapType &src, return_value_policy policy, handle parent) {
|
||||
switch (policy) {
|
||||
case return_value_policy::copy:
|
||||
return eigen_array_cast<props>(src);
|
||||
case return_value_policy::reference_internal:
|
||||
return eigen_array_cast<props>(src, parent, is_eigen_mutable_map<MapType>::value);
|
||||
case return_value_policy::reference:
|
||||
case return_value_policy::automatic:
|
||||
case return_value_policy::automatic_reference:
|
||||
return eigen_array_cast<props>(src, none(), is_eigen_mutable_map<MapType>::value);
|
||||
default:
|
||||
// move, take_ownership don't make any sense for a ref/map:
|
||||
pybind11_fail("Invalid return_value_policy for Eigen Map/Ref/Block type");
|
||||
}
|
||||
}
|
||||
|
||||
// return_descr forces the use of NDArray instead of ArrayLike in args
|
||||
// since Ref<...> args can only accept arrays.
|
||||
static constexpr auto name = return_descr(props::descriptor);
|
||||
|
||||
// Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return
|
||||
// types but not bound arguments). We still provide them (with an explicitly delete) so that
|
||||
// you end up here if you try anyway.
|
||||
bool load(handle, bool) = delete;
|
||||
operator MapType() = delete;
|
||||
template <typename>
|
||||
using cast_op_type = MapType;
|
||||
};
|
||||
|
||||
// We can return any map-like object (but can only load Refs, specialized next):
|
||||
template <typename Type>
|
||||
struct type_caster<Type, enable_if_t<is_eigen_dense_map<Type>::value>> : eigen_map_caster<Type> {};
|
||||
|
||||
// Loader for Ref<...> arguments. See the documentation for info on how to make this work without
|
||||
// copying (it requires some extra effort in many cases).
|
||||
template <typename PlainObjectType, typename StrideType>
|
||||
struct type_caster<
|
||||
Eigen::Ref<PlainObjectType, 0, StrideType>,
|
||||
enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>
|
||||
: public eigen_map_caster<Eigen::Ref<PlainObjectType, 0, StrideType>> {
|
||||
private:
|
||||
using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;
|
||||
using props = EigenProps<Type>;
|
||||
using Scalar = typename props::Scalar;
|
||||
static_assert(!std::is_pointer<Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;
|
||||
using Array
|
||||
= array_t<Scalar,
|
||||
array::forcecast
|
||||
| ((props::row_major ? props::inner_stride : props::outer_stride) == 1
|
||||
? array::c_style
|
||||
: (props::row_major ? props::outer_stride : props::inner_stride) == 1
|
||||
? array::f_style
|
||||
: 0)>;
|
||||
static constexpr bool need_writeable = is_eigen_mutable_map<Type>::value;
|
||||
// Delay construction (these have no default constructor)
|
||||
std::unique_ptr<MapType> map;
|
||||
std::unique_ptr<Type> ref;
|
||||
// Our array. When possible, this is just a numpy array pointing to the source data, but
|
||||
// sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an
|
||||
// incompatible layout, or is an array of a type that needs to be converted). Using a numpy
|
||||
// temporary (rather than an Eigen temporary) saves an extra copy when we need both type
|
||||
// conversion and storage order conversion. (Note that we refuse to use this temporary copy
|
||||
// when loading an argument for a Ref<M> with M non-const, i.e. a read-write reference).
|
||||
Array copy_or_ref;
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
// First check whether what we have is already an array of the right type. If not, we
|
||||
// can't avoid a copy (because the copy is also going to do type conversion).
|
||||
bool need_copy = !isinstance<Array>(src);
|
||||
|
||||
EigenConformable<props::row_major> fits;
|
||||
if (!need_copy) {
|
||||
// We don't need a converting copy, but we also need to check whether the strides are
|
||||
// compatible with the Ref's stride requirements
|
||||
auto aref = reinterpret_borrow<Array>(src);
|
||||
|
||||
if (aref && (!need_writeable || aref.writeable())) {
|
||||
fits = props::conformable(aref);
|
||||
if (!fits) {
|
||||
return false; // Incompatible dimensions
|
||||
}
|
||||
if (!fits.template stride_compatible<props>()) {
|
||||
need_copy = true;
|
||||
} else {
|
||||
copy_or_ref = std::move(aref);
|
||||
}
|
||||
} else {
|
||||
need_copy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_copy) {
|
||||
// We need to copy: If we need a mutable reference, or we're not supposed to convert
|
||||
// (either because we're in the no-convert overload pass, or because we're explicitly
|
||||
// instructed not to copy (via `py::arg().noconvert()`) we have to fail loading.
|
||||
if (!convert || need_writeable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Array copy = Array::ensure(src);
|
||||
if (!copy) {
|
||||
return false;
|
||||
}
|
||||
fits = props::conformable(copy);
|
||||
if (!fits || !fits.template stride_compatible<props>()) {
|
||||
return false;
|
||||
}
|
||||
copy_or_ref = std::move(copy);
|
||||
loader_life_support::add_patient(copy_or_ref);
|
||||
}
|
||||
|
||||
ref.reset();
|
||||
map.reset(new MapType(data(copy_or_ref),
|
||||
fits.rows,
|
||||
fits.cols,
|
||||
make_stride(fits.stride.outer(), fits.stride.inner())));
|
||||
ref.reset(new Type(*map));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator Type *() { return ref.get(); }
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator Type &() { return *ref; }
|
||||
template <typename _T>
|
||||
using cast_op_type = pybind11::detail::cast_op_type<_T>;
|
||||
|
||||
private:
|
||||
template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value, int> = 0>
|
||||
Scalar *data(Array &a) {
|
||||
return a.mutable_data();
|
||||
}
|
||||
|
||||
template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value, int> = 0>
|
||||
const Scalar *data(Array &a) {
|
||||
return a.data();
|
||||
}
|
||||
|
||||
// Attempt to figure out a constructor of `Stride` that will work.
|
||||
// If both strides are fixed, use a default constructor:
|
||||
template <typename S>
|
||||
using stride_ctor_default = bool_constant<S::InnerStrideAtCompileTime != Eigen::Dynamic
|
||||
&& S::OuterStrideAtCompileTime != Eigen::Dynamic
|
||||
&& std::is_default_constructible<S>::value>;
|
||||
// Otherwise, if there is a two-index constructor, assume it is (outer,inner) like
|
||||
// Eigen::Stride, and use it:
|
||||
template <typename S>
|
||||
using stride_ctor_dual
|
||||
= bool_constant<!stride_ctor_default<S>::value
|
||||
&& std::is_constructible<S, EigenIndex, EigenIndex>::value>;
|
||||
// Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use
|
||||
// it (passing whichever stride is dynamic).
|
||||
template <typename S>
|
||||
using stride_ctor_outer
|
||||
= bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value
|
||||
&& S::OuterStrideAtCompileTime == Eigen::Dynamic
|
||||
&& S::InnerStrideAtCompileTime != Eigen::Dynamic
|
||||
&& std::is_constructible<S, EigenIndex>::value>;
|
||||
template <typename S>
|
||||
using stride_ctor_inner
|
||||
= bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value
|
||||
&& S::InnerStrideAtCompileTime == Eigen::Dynamic
|
||||
&& S::OuterStrideAtCompileTime != Eigen::Dynamic
|
||||
&& std::is_constructible<S, EigenIndex>::value>;
|
||||
|
||||
template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value, int> = 0>
|
||||
static S make_stride(EigenIndex, EigenIndex) {
|
||||
return S();
|
||||
}
|
||||
template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value, int> = 0>
|
||||
static S make_stride(EigenIndex outer, EigenIndex inner) {
|
||||
return S(outer, inner);
|
||||
}
|
||||
template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value, int> = 0>
|
||||
static S make_stride(EigenIndex outer, EigenIndex) {
|
||||
return S(outer);
|
||||
}
|
||||
template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value, int> = 0>
|
||||
static S make_stride(EigenIndex, EigenIndex inner) {
|
||||
return S(inner);
|
||||
}
|
||||
};
|
||||
|
||||
// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not
|
||||
// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout).
|
||||
// load() is not supported, but we can cast them into the python domain by first copying to a
|
||||
// regular Eigen::Matrix, then casting that.
|
||||
template <typename Type>
|
||||
struct type_caster<Type, enable_if_t<is_eigen_other<Type>::value>> {
|
||||
static_assert(!std::is_pointer<typename Type::Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
|
||||
protected:
|
||||
using Matrix
|
||||
= Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;
|
||||
using props = EigenProps<Matrix>;
|
||||
|
||||
public:
|
||||
static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
handle h = eigen_encapsulate<props>(new Matrix(src));
|
||||
return h;
|
||||
}
|
||||
static handle cast(const Type *src, return_value_policy policy, handle parent) {
|
||||
return cast(*src, policy, parent);
|
||||
}
|
||||
|
||||
static constexpr auto name = props::descriptor;
|
||||
|
||||
// Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return
|
||||
// types but not bound arguments). We still provide them (with an explicitly delete) so that
|
||||
// you end up here if you try anyway.
|
||||
bool load(handle, bool) = delete;
|
||||
operator Type() = delete;
|
||||
template <typename>
|
||||
using cast_op_type = Type;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
|
||||
using Scalar = typename Type::Scalar;
|
||||
static_assert(!std::is_pointer<Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
using StorageIndex = remove_reference_t<decltype(*std::declval<Type>().outerIndexPtr())>;
|
||||
using Index = typename Type::Index;
|
||||
static constexpr bool rowMajor = Type::IsRowMajor;
|
||||
|
||||
bool load(handle src, bool) {
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto obj = reinterpret_borrow<object>(src);
|
||||
object sparse_module = module_::import("scipy.sparse");
|
||||
object matrix_type = sparse_module.attr(rowMajor ? "csr_matrix" : "csc_matrix");
|
||||
|
||||
if (!type::handle_of(obj).is(matrix_type)) {
|
||||
try {
|
||||
obj = matrix_type(obj);
|
||||
} catch (const error_already_set &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto values = array_t<Scalar>((object) obj.attr("data"));
|
||||
auto innerIndices = array_t<StorageIndex>((object) obj.attr("indices"));
|
||||
auto outerIndices = array_t<StorageIndex>((object) obj.attr("indptr"));
|
||||
auto shape = pybind11::tuple((pybind11::object) obj.attr("shape"));
|
||||
auto nnz = obj.attr("nnz").cast<Index>();
|
||||
|
||||
if (!values || !innerIndices || !outerIndices) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = EigenMapSparseMatrix<Scalar,
|
||||
Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
|
||||
StorageIndex>(shape[0].cast<Index>(),
|
||||
shape[1].cast<Index>(),
|
||||
std::move(nnz),
|
||||
outerIndices.mutable_data(),
|
||||
innerIndices.mutable_data(),
|
||||
values.mutable_data());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
const_cast<Type &>(src).makeCompressed();
|
||||
|
||||
object matrix_type
|
||||
= module_::import("scipy.sparse").attr(rowMajor ? "csr_matrix" : "csc_matrix");
|
||||
|
||||
array data(src.nonZeros(), src.valuePtr());
|
||||
array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
|
||||
array innerIndices(src.nonZeros(), src.innerIndexPtr());
|
||||
|
||||
return matrix_type(pybind11::make_tuple(
|
||||
std::move(data), std::move(innerIndices), std::move(outerIndices)),
|
||||
pybind11::make_tuple(src.rows(), src.cols()))
|
||||
.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(Type,
|
||||
const_name<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[",
|
||||
"scipy.sparse.csc_matrix[")
|
||||
+ npy_format_descriptor<Scalar>::name + const_name("]"));
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
521
deps_src/pybind11/include/pybind11/eigen/tensor.h
Normal file
521
deps_src/pybind11/include/pybind11/eigen/tensor.h
Normal file
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
pybind11/eigen/tensor.h: Transparent conversion for Eigen tensors
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
|
||||
#endif
|
||||
|
||||
// Disable warnings for Eigen
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4554)
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
#if defined(__MINGW32__)
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||
#endif
|
||||
|
||||
#include <unsupported/Eigen/CXX11/Tensor>
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
|
||||
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
inline bool is_tensor_aligned(const void *data) {
|
||||
return (reinterpret_cast<std::size_t>(data) % EIGEN_DEFAULT_ALIGN_BYTES) == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr int compute_array_flag_from_tensor() {
|
||||
static_assert((static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor))
|
||||
|| (static_cast<int>(T::Layout) == static_cast<int>(Eigen::ColMajor)),
|
||||
"Layout must be row or column major");
|
||||
return (static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor)) ? array::c_style
|
||||
: array::f_style;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct eigen_tensor_helper {};
|
||||
|
||||
template <typename Scalar_, int NumIndices_, int Options_, typename IndexType>
|
||||
struct eigen_tensor_helper<Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>> {
|
||||
using Type = Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>;
|
||||
using ValidType = void;
|
||||
|
||||
static Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape(const Type &f) {
|
||||
return f.dimensions();
|
||||
}
|
||||
|
||||
static constexpr bool
|
||||
is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> & /*shape*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct helper {};
|
||||
|
||||
template <size_t... Is>
|
||||
struct helper<index_sequence<Is...>> {
|
||||
static constexpr auto value = ::pybind11::detail::concat(const_name(((void) Is, "?"))...);
|
||||
};
|
||||
|
||||
static constexpr auto dimensions_descriptor
|
||||
= helper<decltype(make_index_sequence<Type::NumIndices>())>::value;
|
||||
|
||||
template <typename... Args>
|
||||
static Type *alloc(Args &&...args) {
|
||||
return new Type(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void free(Type *tensor) { delete tensor; }
|
||||
};
|
||||
|
||||
template <typename Scalar_, typename std::ptrdiff_t... Indices, int Options_, typename IndexType>
|
||||
struct eigen_tensor_helper<
|
||||
Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>> {
|
||||
using Type = Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>;
|
||||
using ValidType = void;
|
||||
|
||||
static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices>
|
||||
get_shape(const Type & /*f*/) {
|
||||
return get_shape();
|
||||
}
|
||||
|
||||
static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape() {
|
||||
return Eigen::DSizes<typename Type::Index, Type::NumIndices>(Indices...);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> &shape) {
|
||||
return get_shape() == shape;
|
||||
}
|
||||
|
||||
static constexpr auto dimensions_descriptor
|
||||
= ::pybind11::detail::concat(const_name<Indices>()...);
|
||||
|
||||
template <typename... Args>
|
||||
static Type *alloc(Args &&...args) {
|
||||
Eigen::aligned_allocator<Type> allocator;
|
||||
return ::new (allocator.allocate(1)) Type(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void free(Type *tensor) {
|
||||
Eigen::aligned_allocator<Type> allocator;
|
||||
tensor->~Type();
|
||||
allocator.deallocate(tensor, 1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type, bool ShowDetails, bool NeedsWriteable = false>
|
||||
struct get_tensor_descriptor {
|
||||
static constexpr auto details
|
||||
= const_name<NeedsWriteable>(", \"flags.writeable\"", "") + const_name
|
||||
< static_cast<int>(Type::Layout)
|
||||
== static_cast<int>(Eigen::RowMajor)
|
||||
> (", \"flags.c_contiguous\"", ", \"flags.f_contiguous\"");
|
||||
static constexpr auto value
|
||||
= const_name("typing.Annotated[")
|
||||
+ io_name("numpy.typing.ArrayLike, ", "numpy.typing.NDArray[")
|
||||
+ npy_format_descriptor<typename Type::Scalar>::name + io_name("", "]")
|
||||
+ const_name(", \"[") + eigen_tensor_helper<remove_cv_t<Type>>::dimensions_descriptor
|
||||
+ const_name("]\"") + const_name<ShowDetails>(details, const_name("")) + const_name("]");
|
||||
};
|
||||
|
||||
// When EIGEN_AVOID_STL_ARRAY is defined, Eigen::DSizes<T, 0> does not have the begin() member
|
||||
// function. Falling back to a simple loop works around this issue.
|
||||
//
|
||||
// We need to disable the type-limits warning for the inner loop when size = 0.
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
|
||||
|
||||
template <typename T, int size>
|
||||
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {
|
||||
std::vector<T> result(size);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
result[i] = arr[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, int size>
|
||||
Eigen::DSizes<T, size> get_shape_for_array(const array &arr) {
|
||||
Eigen::DSizes<T, size> result;
|
||||
const T *shape = arr.shape();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
result[i] = shape[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
template <typename Type>
|
||||
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
|
||||
static_assert(!std::is_pointer<typename Type::Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
using Helper = eigen_tensor_helper<Type>;
|
||||
static constexpr auto temp_name = get_tensor_descriptor<Type, false>::value;
|
||||
PYBIND11_TYPE_CASTER(Type, temp_name);
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
if (!convert) {
|
||||
if (!isinstance<array>(src)) {
|
||||
return false;
|
||||
}
|
||||
array temp = array::ensure(src);
|
||||
if (!temp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!temp.dtype().is(dtype::of<typename Type::Scalar>())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()> arr(
|
||||
reinterpret_borrow<object>(src));
|
||||
|
||||
if (arr.ndim() != Type::NumIndices) {
|
||||
return false;
|
||||
}
|
||||
auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);
|
||||
|
||||
if (!Helper::is_correct_shape(shape)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
|
||||
auto data_pointer = arr.data();
|
||||
#else
|
||||
// Handle Eigen bug
|
||||
auto data_pointer = const_cast<typename Type::Scalar *>(arr.data());
|
||||
#endif
|
||||
|
||||
if (is_tensor_aligned(arr.data())) {
|
||||
value = Eigen::TensorMap<const Type, Eigen::Aligned>(data_pointer, shape);
|
||||
} else {
|
||||
value = Eigen::TensorMap<const Type>(data_pointer, shape);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(Type &&src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::reference
|
||||
|| policy == return_value_policy::reference_internal) {
|
||||
pybind11_fail("Cannot use a reference return value policy for an rvalue");
|
||||
}
|
||||
return cast_impl(&src, return_value_policy::move, parent);
|
||||
}
|
||||
|
||||
static handle cast(const Type &&src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::reference
|
||||
|| policy == return_value_policy::reference_internal) {
|
||||
pybind11_fail("Cannot use a reference return value policy for an rvalue");
|
||||
}
|
||||
return cast_impl(&src, return_value_policy::move, parent);
|
||||
}
|
||||
|
||||
static handle cast(Type &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast_impl(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(const Type &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(Type *src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic) {
|
||||
policy = return_value_policy::take_ownership;
|
||||
} else if (policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::reference;
|
||||
}
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(const Type *src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic) {
|
||||
policy = return_value_policy::take_ownership;
|
||||
} else if (policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::reference;
|
||||
}
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
static handle cast_impl(C *src, return_value_policy policy, handle parent) {
|
||||
object parent_object;
|
||||
bool writeable = false;
|
||||
switch (policy) {
|
||||
case return_value_policy::move:
|
||||
if (std::is_const<C>::value) {
|
||||
pybind11_fail("Cannot move from a constant reference");
|
||||
}
|
||||
|
||||
src = Helper::alloc(std::move(*src));
|
||||
|
||||
parent_object
|
||||
= capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });
|
||||
writeable = true;
|
||||
break;
|
||||
|
||||
case return_value_policy::take_ownership:
|
||||
if (std::is_const<C>::value) {
|
||||
// This cast is ugly, and might be UB in some cases, but we don't have an
|
||||
// alternative here as we must free that memory
|
||||
Helper::free(const_cast<Type *>(src));
|
||||
pybind11_fail("Cannot take ownership of a const reference");
|
||||
}
|
||||
|
||||
parent_object
|
||||
= capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });
|
||||
writeable = true;
|
||||
break;
|
||||
|
||||
case return_value_policy::copy:
|
||||
writeable = true;
|
||||
break;
|
||||
|
||||
case return_value_policy::reference:
|
||||
parent_object = none();
|
||||
writeable = !std::is_const<C>::value;
|
||||
break;
|
||||
|
||||
case return_value_policy::reference_internal:
|
||||
// Default should do the right thing
|
||||
if (!parent) {
|
||||
pybind11_fail("Cannot use reference internal when there is no parent");
|
||||
}
|
||||
parent_object = reinterpret_borrow<object>(parent);
|
||||
writeable = !std::is_const<C>::value;
|
||||
break;
|
||||
|
||||
default:
|
||||
pybind11_fail("pybind11 bug in eigen.h, please file a bug report");
|
||||
}
|
||||
|
||||
auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(
|
||||
convert_dsizes_to_vector(Helper::get_shape(*src)), src->data(), parent_object);
|
||||
|
||||
if (!writeable) {
|
||||
array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
|
||||
}
|
||||
|
||||
return result.release();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename StoragePointerType,
|
||||
bool needs_writeable,
|
||||
enable_if_t<!needs_writeable, bool> = true>
|
||||
StoragePointerType get_array_data_for_type(array &arr) {
|
||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
|
||||
return reinterpret_cast<StoragePointerType>(arr.data());
|
||||
#else
|
||||
// Handle Eigen bug
|
||||
return reinterpret_cast<StoragePointerType>(const_cast<void *>(arr.data()));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename StoragePointerType,
|
||||
bool needs_writeable,
|
||||
enable_if_t<needs_writeable, bool> = true>
|
||||
StoragePointerType get_array_data_for_type(array &arr) {
|
||||
return reinterpret_cast<StoragePointerType>(arr.mutable_data());
|
||||
}
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct get_storage_pointer_type;
|
||||
|
||||
template <typename MapType>
|
||||
struct get_storage_pointer_type<MapType, void_t<typename MapType::StoragePointerType>> {
|
||||
using SPT = typename MapType::StoragePointerType;
|
||||
};
|
||||
|
||||
template <typename MapType>
|
||||
struct get_storage_pointer_type<MapType, void_t<typename MapType::PointerArgType>> {
|
||||
using SPT = typename MapType::PointerArgType;
|
||||
};
|
||||
|
||||
template <typename Type, int Options>
|
||||
struct type_caster<Eigen::TensorMap<Type, Options>,
|
||||
typename eigen_tensor_helper<remove_cv_t<Type>>::ValidType> {
|
||||
static_assert(!std::is_pointer<typename Type::Scalar>::value,
|
||||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
|
||||
using MapType = Eigen::TensorMap<Type, Options>;
|
||||
using Helper = eigen_tensor_helper<remove_cv_t<Type>>;
|
||||
|
||||
bool load(handle src, bool /*convert*/) {
|
||||
// Note that we have a lot more checks here as we want to make sure to avoid copies
|
||||
if (!isinstance<array>(src)) {
|
||||
return false;
|
||||
}
|
||||
auto arr = reinterpret_borrow<array>(src);
|
||||
if ((arr.flags() & compute_array_flag_from_tensor<Type>()) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!arr.dtype().is(dtype::of<typename Type::Scalar>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arr.ndim() != Type::NumIndices) {
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;
|
||||
|
||||
if (is_aligned && !is_tensor_aligned(arr.data())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);
|
||||
|
||||
if (!Helper::is_correct_shape(shape)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needs_writeable && !arr.writeable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = get_array_data_for_type<typename get_storage_pointer_type<MapType>::SPT,
|
||||
needs_writeable>(arr);
|
||||
|
||||
value.reset(new MapType(std::move(result), std::move(shape)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(MapType &&src, return_value_policy policy, handle parent) {
|
||||
return cast_impl(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(const MapType &&src, return_value_policy policy, handle parent) {
|
||||
return cast_impl(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(MapType &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast_impl(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(const MapType &src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::copy;
|
||||
}
|
||||
return cast(&src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(MapType *src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic) {
|
||||
policy = return_value_policy::take_ownership;
|
||||
} else if (policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::reference;
|
||||
}
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
|
||||
static handle cast(const MapType *src, return_value_policy policy, handle parent) {
|
||||
if (policy == return_value_policy::automatic) {
|
||||
policy = return_value_policy::take_ownership;
|
||||
} else if (policy == return_value_policy::automatic_reference) {
|
||||
policy = return_value_policy::reference;
|
||||
}
|
||||
return cast_impl(src, policy, parent);
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
static handle cast_impl(C *src, return_value_policy policy, handle parent) {
|
||||
object parent_object;
|
||||
constexpr bool writeable = !std::is_const<C>::value;
|
||||
switch (policy) {
|
||||
case return_value_policy::reference:
|
||||
parent_object = none();
|
||||
break;
|
||||
|
||||
case return_value_policy::reference_internal:
|
||||
// Default should do the right thing
|
||||
if (!parent) {
|
||||
pybind11_fail("Cannot use reference internal when there is no parent");
|
||||
}
|
||||
parent_object = reinterpret_borrow<object>(parent);
|
||||
break;
|
||||
|
||||
default:
|
||||
// move, take_ownership don't make any sense for a ref/map:
|
||||
pybind11_fail("Invalid return_value_policy for Eigen Map type, must be either "
|
||||
"reference or reference_internal");
|
||||
}
|
||||
|
||||
auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(
|
||||
convert_dsizes_to_vector(Helper::get_shape(*src)),
|
||||
src->data(),
|
||||
std::move(parent_object));
|
||||
|
||||
if (!writeable) {
|
||||
array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
|
||||
}
|
||||
|
||||
return result.release();
|
||||
}
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
|
||||
|
||||
static constexpr bool needs_writeable = !std::is_const<typename std::remove_pointer<
|
||||
typename get_storage_pointer_type<MapType>::SPT>::type>::value;
|
||||
#else
|
||||
// Handle Eigen bug
|
||||
static constexpr bool needs_writeable = !std::is_const<Type>::value;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// TODO: Move to std::optional once std::optional has more support
|
||||
std::unique_ptr<MapType> value;
|
||||
|
||||
public:
|
||||
// return_descr forces the use of NDArray instead of ArrayLike since refs can only reference
|
||||
// arrays
|
||||
static constexpr auto name
|
||||
= return_descr(get_tensor_descriptor<Type, true, needs_writeable>::value);
|
||||
explicit operator MapType *() { return value.get(); }
|
||||
explicit operator MapType &() { return *value; }
|
||||
explicit operator MapType &&() && { return std::move(*value); }
|
||||
|
||||
template <typename T_>
|
||||
using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
320
deps_src/pybind11/include/pybind11/embed.h
Normal file
320
deps_src/pybind11/include/pybind11/embed.h
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
pybind11/embed.h: Support for embedding the interpreter
|
||||
|
||||
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
#include "eval.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#if defined(PYPY_VERSION)
|
||||
# error Embedding the interpreter is not supported with PyPy
|
||||
#endif
|
||||
|
||||
#define PYBIND11_EMBEDDED_MODULE_IMPL(name) \
|
||||
extern "C" PyObject *pybind11_init_impl_##name(); \
|
||||
extern "C" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }
|
||||
|
||||
/** \rst
|
||||
Add a new module to the table of builtins for the interpreter. Must be
|
||||
defined in global scope. The first macro parameter is the name of the
|
||||
module (without quotes). The second parameter is the variable which will
|
||||
be used as the interface to add functions and classes to the module.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_EMBEDDED_MODULE(example, m) {
|
||||
// ... initialize functions and classes here
|
||||
m.def("foo", []() {
|
||||
return "Hello, World!";
|
||||
});
|
||||
}
|
||||
|
||||
The third and subsequent macro arguments are optional, and can be used to
|
||||
mark the module as supporting various Python features.
|
||||
|
||||
- ``mod_gil_not_used()``
|
||||
- ``multiple_interpreters::per_interpreter_gil()``
|
||||
- ``multiple_interpreters::shared_gil()``
|
||||
- ``multiple_interpreters::not_supported()``
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_EMBEDDED_MODULE(example, m, py::mod_gil_not_used()) {
|
||||
m.def("foo", []() {
|
||||
return "Hello, Free-threaded World!";
|
||||
});
|
||||
}
|
||||
|
||||
\endrst */
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
|
||||
#define PYBIND11_EMBEDDED_MODULE(name, variable, ...) \
|
||||
PYBIND11_MODULE_PYINIT(name, {}, ##__VA_ARGS__) \
|
||||
::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)( \
|
||||
PYBIND11_TOSTRING(name), PYBIND11_CONCAT(PyInit_, name)); \
|
||||
PYBIND11_MODULE_EXEC(name, variable)
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks.
|
||||
struct embedded_module {
|
||||
using init_t = PyObject *(*) ();
|
||||
embedded_module(const char *name, init_t init) {
|
||||
if (Py_IsInitialized() != 0) {
|
||||
pybind11_fail("Can't add new modules after the interpreter has been initialized");
|
||||
}
|
||||
|
||||
auto result = PyImport_AppendInittab(name, init);
|
||||
if (result == -1) {
|
||||
pybind11_fail("Insufficient memory to add a new module");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct wide_char_arg_deleter {
|
||||
void operator()(wchar_t *ptr) const {
|
||||
// API docs: https://docs.python.org/3/c-api/sys.html#c.Py_DecodeLocale
|
||||
PyMem_RawFree(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
inline wchar_t *widen_chars(const char *safe_arg) {
|
||||
wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);
|
||||
return widened_arg;
|
||||
}
|
||||
|
||||
inline void precheck_interpreter() {
|
||||
if (Py_IsInitialized() != 0) {
|
||||
pybind11_fail("The interpreter is already running");
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX)
|
||||
# define PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX (0x03080000)
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||
inline void initialize_interpreter_pre_pyconfig(bool init_signal_handlers,
|
||||
int argc,
|
||||
const char *const *argv,
|
||||
bool add_program_dir_to_path) {
|
||||
detail::precheck_interpreter();
|
||||
Py_InitializeEx(init_signal_handlers ? 1 : 0);
|
||||
|
||||
auto argv_size = static_cast<size_t>(argc);
|
||||
// SetArgv* on python 3 takes wchar_t, so we have to convert.
|
||||
std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
|
||||
std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries;
|
||||
widened_argv_entries.reserve(argv_size);
|
||||
for (size_t ii = 0; ii < argv_size; ++ii) {
|
||||
widened_argv_entries.emplace_back(detail::widen_chars(argv[ii]));
|
||||
if (!widened_argv_entries.back()) {
|
||||
// A null here indicates a character-encoding failure or the python
|
||||
// interpreter out of memory. Give up.
|
||||
return;
|
||||
}
|
||||
widened_argv[ii] = widened_argv_entries.back().get();
|
||||
}
|
||||
|
||||
auto *pysys_argv = widened_argv.get();
|
||||
|
||||
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
|
||||
}
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||
inline void initialize_interpreter(PyConfig *config,
|
||||
int argc = 0,
|
||||
const char *const *argv = nullptr,
|
||||
bool add_program_dir_to_path = true) {
|
||||
detail::precheck_interpreter();
|
||||
PyStatus status = PyConfig_SetBytesArgv(config, argc, const_cast<char *const *>(argv));
|
||||
if (PyStatus_Exception(status) != 0) {
|
||||
// A failure here indicates a character-encoding failure or the python
|
||||
// interpreter out of memory. Give up.
|
||||
PyConfig_Clear(config);
|
||||
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||
: "Failed to prepare CPython");
|
||||
}
|
||||
status = Py_InitializeFromConfig(config);
|
||||
if (PyStatus_Exception(status) != 0) {
|
||||
PyConfig_Clear(config);
|
||||
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||
: "Failed to init CPython");
|
||||
}
|
||||
if (add_program_dir_to_path) {
|
||||
PyRun_SimpleString("import sys, os.path; "
|
||||
"sys.path.insert(0, "
|
||||
"os.path.abspath(os.path.dirname(sys.argv[0])) "
|
||||
"if sys.argv and os.path.exists(sys.argv[0]) else '')");
|
||||
}
|
||||
PyConfig_Clear(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \rst
|
||||
Initialize the Python interpreter. No other pybind11 or CPython API functions can be
|
||||
called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The
|
||||
optional `init_signal_handlers` parameter can be used to skip the registration of
|
||||
signal handlers (see the `Python documentation`_ for details). Calling this function
|
||||
again after the interpreter has already been initialized is a fatal error.
|
||||
|
||||
If initializing the Python interpreter fails, then the program is terminated. (This
|
||||
is controlled by the CPython runtime and is an exception to pybind11's normal behavior
|
||||
of throwing exceptions on errors.)
|
||||
|
||||
The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are
|
||||
used to populate ``sys.argv`` and ``sys.path``.
|
||||
See the |PySys_SetArgvEx documentation|_ for details.
|
||||
|
||||
.. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx
|
||||
.. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation
|
||||
.. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx
|
||||
\endrst */
|
||||
inline void initialize_interpreter(bool init_signal_handlers = true,
|
||||
int argc = 0,
|
||||
const char *const *argv = nullptr,
|
||||
bool add_program_dir_to_path = true) {
|
||||
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||
detail::initialize_interpreter_pre_pyconfig(
|
||||
init_signal_handlers, argc, argv, add_program_dir_to_path);
|
||||
#else
|
||||
PyConfig config;
|
||||
PyConfig_InitPythonConfig(&config);
|
||||
// See PR #4473 for background
|
||||
config.parse_argv = 0;
|
||||
|
||||
config.install_signal_handlers = init_signal_handlers ? 1 : 0;
|
||||
initialize_interpreter(&config, argc, argv, add_program_dir_to_path);
|
||||
#endif
|
||||
|
||||
// There is exactly one interpreter alive currently.
|
||||
detail::get_num_interpreters_seen() = 1;
|
||||
}
|
||||
|
||||
/** \rst
|
||||
Shut down the Python interpreter. No pybind11 or CPython API functions can be called
|
||||
after this. In addition, pybind11 objects must not outlive the interpreter:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
{ // BAD
|
||||
py::initialize_interpreter();
|
||||
auto hello = py::str("Hello, World!");
|
||||
py::finalize_interpreter();
|
||||
} // <-- BOOM, hello's destructor is called after interpreter shutdown
|
||||
|
||||
{ // GOOD
|
||||
py::initialize_interpreter();
|
||||
{ // scoped
|
||||
auto hello = py::str("Hello, World!");
|
||||
} // <-- OK, hello is cleaned up properly
|
||||
py::finalize_interpreter();
|
||||
}
|
||||
|
||||
{ // BETTER
|
||||
py::scoped_interpreter guard{};
|
||||
auto hello = py::str("Hello, World!");
|
||||
}
|
||||
|
||||
.. warning::
|
||||
|
||||
The interpreter can be restarted by calling `initialize_interpreter` again.
|
||||
Modules created using pybind11 can be safely re-initialized. However, Python
|
||||
itself cannot completely unload binary extension modules and there are several
|
||||
caveats with regard to interpreter restarting. All the details can be found
|
||||
in the CPython documentation. In short, not all interpreter memory may be
|
||||
freed, either due to reference cycles or user-created global data.
|
||||
|
||||
\endrst */
|
||||
inline void finalize_interpreter() {
|
||||
// get rid of any thread-local interpreter cache that currently exists
|
||||
if (detail::get_num_interpreters_seen() > 1) {
|
||||
detail::get_internals_pp_manager().unref();
|
||||
detail::get_local_internals_pp_manager().unref();
|
||||
|
||||
// We know there can be no other interpreter alive now, so we can lower the count
|
||||
detail::get_num_interpreters_seen() = 1;
|
||||
}
|
||||
|
||||
// Re-fetch the internals pointer-to-pointer (but not the internals itself, which might not
|
||||
// exist). It's possible for the internals to be created during Py_Finalize() (e.g. if a
|
||||
// py::capsule calls `get_internals()` during destruction), so we get the pointer-pointer here
|
||||
// and check it after Py_Finalize().
|
||||
detail::get_internals_pp_manager().get_pp();
|
||||
detail::get_local_internals_pp_manager().get_pp();
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
detail::get_internals_pp_manager().destroy();
|
||||
|
||||
// Local internals contains data managed by the current interpreter, so we must clear them to
|
||||
// avoid undefined behaviors when initializing another interpreter
|
||||
detail::get_local_internals_pp_manager().destroy();
|
||||
|
||||
// We know there is no interpreter alive now, so we can reset the count
|
||||
detail::get_num_interpreters_seen() = 0;
|
||||
}
|
||||
|
||||
/** \rst
|
||||
Scope guard version of `initialize_interpreter` and `finalize_interpreter`.
|
||||
This a move-only guard and only a single instance can exist.
|
||||
|
||||
See `initialize_interpreter` for a discussion of its constructor arguments.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
py::print(Hello, World!);
|
||||
} // <-- interpreter shutdown
|
||||
\endrst */
|
||||
class scoped_interpreter {
|
||||
public:
|
||||
explicit scoped_interpreter(bool init_signal_handlers = true,
|
||||
int argc = 0,
|
||||
const char *const *argv = nullptr,
|
||||
bool add_program_dir_to_path = true) {
|
||||
initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||
explicit scoped_interpreter(PyConfig *config,
|
||||
int argc = 0,
|
||||
const char *const *argv = nullptr,
|
||||
bool add_program_dir_to_path = true) {
|
||||
initialize_interpreter(config, argc, argv, add_program_dir_to_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
scoped_interpreter(const scoped_interpreter &) = delete;
|
||||
scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
|
||||
scoped_interpreter &operator=(const scoped_interpreter &) = delete;
|
||||
scoped_interpreter &operator=(scoped_interpreter &&) = delete;
|
||||
|
||||
~scoped_interpreter() {
|
||||
if (is_valid) {
|
||||
finalize_interpreter();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_valid = true;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
161
deps_src/pybind11/include/pybind11/eval.h
Normal file
161
deps_src/pybind11/include/pybind11/eval.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
pybind11/eval.h: Support for evaluating Python expressions and statements
|
||||
from strings and files
|
||||
|
||||
Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and
|
||||
Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
inline void ensure_builtins_in_globals(object &global) {
|
||||
#if defined(PYPY_VERSION)
|
||||
// Running exec and eval adds `builtins` module under `__builtins__` key to
|
||||
// globals if not yet present. Python 3.8 made PyRun_String behave
|
||||
// similarly. Let's also do that for older versions, for consistency. This
|
||||
// was missing from PyPy3.8 7.3.7.
|
||||
if (!global.contains("__builtins__"))
|
||||
global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
|
||||
#else
|
||||
(void) global;
|
||||
#endif
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
enum eval_mode {
|
||||
/// Evaluate a string containing an isolated expression
|
||||
eval_expr,
|
||||
|
||||
/// Evaluate a string containing a single statement. Returns \c none
|
||||
eval_single_statement,
|
||||
|
||||
/// Evaluate a string containing a sequence of statement. Returns \c none
|
||||
eval_statements
|
||||
};
|
||||
|
||||
template <eval_mode mode = eval_expr>
|
||||
object eval(const str &expr, object global = globals(), object local = object()) {
|
||||
if (!local) {
|
||||
local = global;
|
||||
}
|
||||
|
||||
detail::ensure_builtins_in_globals(global);
|
||||
|
||||
/* PyRun_String does not accept a PyObject / encoding specifier,
|
||||
this seems to be the only alternative */
|
||||
std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
|
||||
|
||||
int start = 0;
|
||||
switch (mode) {
|
||||
case eval_expr:
|
||||
start = Py_eval_input;
|
||||
break;
|
||||
case eval_single_statement:
|
||||
start = Py_single_input;
|
||||
break;
|
||||
case eval_statements:
|
||||
start = Py_file_input;
|
||||
break;
|
||||
default:
|
||||
pybind11_fail("invalid evaluation mode");
|
||||
}
|
||||
|
||||
PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
|
||||
if (!result) {
|
||||
throw error_already_set();
|
||||
}
|
||||
return reinterpret_steal<object>(result);
|
||||
}
|
||||
|
||||
template <eval_mode mode = eval_expr, size_t N>
|
||||
object eval(const char (&s)[N], object global = globals(), object local = object()) {
|
||||
/* Support raw string literals by removing common leading whitespace */
|
||||
auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
|
||||
return eval<mode>(expr, std::move(global), std::move(local));
|
||||
}
|
||||
|
||||
inline void exec(const str &expr, object global = globals(), object local = object()) {
|
||||
eval<eval_statements>(expr, std::move(global), std::move(local));
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void exec(const char (&s)[N], object global = globals(), object local = object()) {
|
||||
eval<eval_statements>(s, std::move(global), std::move(local));
|
||||
}
|
||||
|
||||
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
|
||||
template <eval_mode mode = eval_statements>
|
||||
object eval_file(str, object, object) {
|
||||
pybind11_fail("eval_file not supported in this interpreter. Use eval");
|
||||
}
|
||||
template <eval_mode mode = eval_statements>
|
||||
object eval_file(str, object) {
|
||||
pybind11_fail("eval_file not supported in this interpreter. Use eval");
|
||||
}
|
||||
template <eval_mode mode = eval_statements>
|
||||
object eval_file(str) {
|
||||
pybind11_fail("eval_file not supported in this interpreter. Use eval");
|
||||
}
|
||||
#else
|
||||
template <eval_mode mode = eval_statements>
|
||||
object eval_file(str fname, object global = globals(), object local = object()) {
|
||||
if (!local) {
|
||||
local = global;
|
||||
}
|
||||
|
||||
detail::ensure_builtins_in_globals(global);
|
||||
|
||||
int start = 0;
|
||||
switch (mode) {
|
||||
case eval_expr:
|
||||
start = Py_eval_input;
|
||||
break;
|
||||
case eval_single_statement:
|
||||
start = Py_single_input;
|
||||
break;
|
||||
case eval_statements:
|
||||
start = Py_file_input;
|
||||
break;
|
||||
default:
|
||||
pybind11_fail("invalid evaluation mode");
|
||||
}
|
||||
|
||||
int closeFile = 1;
|
||||
std::string fname_str = (std::string) fname;
|
||||
FILE *f =
|
||||
# if PY_VERSION_HEX >= 0x030E0000
|
||||
Py_fopen(fname.ptr(), "r");
|
||||
# else
|
||||
_Py_fopen_obj(fname.ptr(), "r");
|
||||
# endif
|
||||
if (!f) {
|
||||
PyErr_Clear();
|
||||
pybind11_fail("File \"" + fname_str + "\" could not be opened!");
|
||||
}
|
||||
|
||||
if (!global.contains("__file__")) {
|
||||
global["__file__"] = std::move(fname);
|
||||
}
|
||||
|
||||
PyObject *result
|
||||
= PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);
|
||||
|
||||
if (!result) {
|
||||
throw error_already_set();
|
||||
}
|
||||
return reinterpret_steal<object>(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
147
deps_src/pybind11/include/pybind11/functional.h
Normal file
147
deps_src/pybind11/include/pybind11/functional.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
pybind11/functional.h: std::function<> support
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
PYBIND11_NAMESPACE_BEGIN(type_caster_std_function_specializations)
|
||||
|
||||
// ensure GIL is held during functor destruction
|
||||
struct func_handle {
|
||||
function f;
|
||||
#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))
|
||||
// This triggers a syntax error under very special conditions (very weird indeed).
|
||||
explicit
|
||||
#endif
|
||||
func_handle(function &&f_) noexcept
|
||||
: f(std::move(f_)) {
|
||||
}
|
||||
func_handle(const func_handle &f_) { operator=(f_); }
|
||||
func_handle &operator=(const func_handle &f_) {
|
||||
gil_scoped_acquire acq;
|
||||
f = f_.f;
|
||||
return *this;
|
||||
}
|
||||
~func_handle() {
|
||||
gil_scoped_acquire acq;
|
||||
function kill_f(std::move(f));
|
||||
}
|
||||
};
|
||||
|
||||
// to emulate 'move initialization capture' in C++11
|
||||
struct func_wrapper_base {
|
||||
func_handle hfunc;
|
||||
explicit func_wrapper_base(func_handle &&hf) noexcept : hfunc(hf) {}
|
||||
};
|
||||
|
||||
template <typename Return, typename... Args>
|
||||
struct func_wrapper : func_wrapper_base {
|
||||
using func_wrapper_base::func_wrapper_base;
|
||||
Return operator()(Args... args) const { // NOLINT(performance-unnecessary-value-param)
|
||||
gil_scoped_acquire acq;
|
||||
// casts the returned object as a rvalue to the return type
|
||||
return hfunc.f(std::forward<Args>(args)...).template cast<Return>();
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(type_caster_std_function_specializations)
|
||||
|
||||
template <typename Return, typename... Args>
|
||||
struct type_caster<std::function<Return(Args...)>> {
|
||||
using type = std::function<Return(Args...)>;
|
||||
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
||||
using function_type = Return (*)(Args...);
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (src.is_none()) {
|
||||
// Defer accepting None to other overloads (if we aren't in convert mode):
|
||||
if (!convert) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isinstance<function>(src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto func = reinterpret_borrow<function>(src);
|
||||
|
||||
/*
|
||||
When passing a C++ function as an argument to another C++
|
||||
function via Python, every function call would normally involve
|
||||
a full C++ -> Python -> C++ roundtrip, which can be prohibitive.
|
||||
Here, we try to at least detect the case where the function is
|
||||
stateless (i.e. function pointer or lambda function without
|
||||
captured variables), in which case the roundtrip can be avoided.
|
||||
*/
|
||||
if (auto cfunc = func.cpp_function()) {
|
||||
auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());
|
||||
if (cfunc_self == nullptr) {
|
||||
PyErr_Clear();
|
||||
} else {
|
||||
function_record *rec = function_record_ptr_from_PyObject(cfunc_self);
|
||||
while (rec != nullptr) {
|
||||
if (rec->is_stateless
|
||||
&& same_type(typeid(function_type),
|
||||
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
|
||||
struct capture {
|
||||
function_type f;
|
||||
|
||||
static capture *from_data(void **data) {
|
||||
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
|
||||
}
|
||||
};
|
||||
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
|
||||
std::is_standard_layout<capture>::value);
|
||||
value = capture::from_data(rec->data)->f;
|
||||
return true;
|
||||
}
|
||||
rec = rec->next;
|
||||
}
|
||||
}
|
||||
// PYPY segfaults here when passing builtin function like sum.
|
||||
// Raising an fail exception here works to prevent the segfault, but only on gcc.
|
||||
// See PR #1413 for full details
|
||||
}
|
||||
|
||||
value = type_caster_std_function_specializations::func_wrapper<Return, Args...>(
|
||||
type_caster_std_function_specializations::func_handle(std::move(func)));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {
|
||||
if (!f_) {
|
||||
return none().release();
|
||||
}
|
||||
|
||||
auto result = f_.template target<function_type>();
|
||||
if (result) {
|
||||
return cpp_function(*result, policy).release();
|
||||
}
|
||||
return cpp_function(std::forward<Func>(f_), policy).release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(
|
||||
type,
|
||||
const_name("collections.abc.Callable[[")
|
||||
+ ::pybind11::detail::concat(::pybind11::detail::arg_descr(make_caster<Args>::name)...)
|
||||
+ const_name("], ") + ::pybind11::detail::return_descr(make_caster<retval_type>::name)
|
||||
+ const_name("]"));
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
199
deps_src/pybind11/include/pybind11/gil.h
Normal file
199
deps_src/pybind11/include/pybind11/gil.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
pybind11/gil.h: RAII helpers for managing the GIL
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
|
||||
# include "detail/common.h"
|
||||
# include "gil_simple.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
using gil_scoped_acquire = gil_scoped_acquire_simple;
|
||||
using gil_scoped_release = gil_scoped_release_simple;
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
|
||||
#else
|
||||
|
||||
# include "detail/common.h"
|
||||
# include "detail/internals.h"
|
||||
|
||||
# include <cassert>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wredundant-decls")
|
||||
|
||||
// forward declarations
|
||||
PyThreadState *get_thread_state_unchecked();
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/* The functions below essentially reproduce the PyGILState_* API using a RAII
|
||||
* pattern, but there are a few important differences:
|
||||
*
|
||||
* 1. When acquiring the GIL from an non-main thread during the finalization
|
||||
* phase, the GILState API blindly terminates the calling thread, which
|
||||
* is often not what is wanted. This API does not do this.
|
||||
*
|
||||
* 2. The gil_scoped_release function can optionally cut the relationship
|
||||
* of a PyThreadState and its associated thread, which allows moving it to
|
||||
* another thread (this is a fairly rare/advanced use case).
|
||||
*
|
||||
* 3. The reference count of an acquired thread state can be controlled. This
|
||||
* can be handy to prevent cases where callbacks issued from an external
|
||||
* thread would otherwise constantly construct and destroy thread state data
|
||||
* structures.
|
||||
*
|
||||
* See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an
|
||||
* example which uses features 2 and 3 to migrate the Python thread of
|
||||
* execution to another thread (to run the event loop on the original thread,
|
||||
* in this case).
|
||||
*/
|
||||
|
||||
class gil_scoped_acquire {
|
||||
public:
|
||||
PYBIND11_NOINLINE gil_scoped_acquire() {
|
||||
auto &internals = detail::get_internals();
|
||||
tstate = internals.tstate.get();
|
||||
|
||||
if (!tstate) {
|
||||
/* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if
|
||||
calling from a Python thread). Since we use a different key, this ensures
|
||||
we don't create a new thread state and deadlock in PyEval_AcquireThread
|
||||
below. Note we don't save this state with internals.tstate, since we don't
|
||||
create it we would fail to clear it (its reference count should be > 0). */
|
||||
tstate = PyGILState_GetThisThreadState();
|
||||
}
|
||||
|
||||
if (!tstate) {
|
||||
tstate = PyThreadState_New(internals.istate);
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (!tstate) {
|
||||
pybind11_fail("scoped_acquire: could not create thread state!");
|
||||
}
|
||||
# endif
|
||||
tstate->gilstate_counter = 0;
|
||||
internals.tstate = tstate;
|
||||
} else {
|
||||
release = detail::get_thread_state_unchecked() != tstate;
|
||||
}
|
||||
|
||||
if (release) {
|
||||
PyEval_AcquireThread(tstate);
|
||||
}
|
||||
|
||||
inc_ref();
|
||||
}
|
||||
|
||||
gil_scoped_acquire(const gil_scoped_acquire &) = delete;
|
||||
gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
|
||||
|
||||
void inc_ref() { ++tstate->gilstate_counter; }
|
||||
|
||||
PYBIND11_NOINLINE void dec_ref() {
|
||||
--tstate->gilstate_counter;
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (detail::get_thread_state_unchecked() != tstate) {
|
||||
pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
|
||||
}
|
||||
if (tstate->gilstate_counter < 0) {
|
||||
pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!");
|
||||
}
|
||||
# endif
|
||||
if (tstate->gilstate_counter == 0) {
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (!release) {
|
||||
pybind11_fail("scoped_acquire::dec_ref(): internal error!");
|
||||
}
|
||||
# endif
|
||||
PyThreadState_Clear(tstate);
|
||||
if (active) {
|
||||
PyThreadState_DeleteCurrent();
|
||||
}
|
||||
detail::get_internals().tstate.reset();
|
||||
release = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// This method will disable the PyThreadState_DeleteCurrent call and the
|
||||
/// GIL won't be released. This method should be used if the interpreter
|
||||
/// could be shutting down when this is called, as thread deletion is not
|
||||
/// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
|
||||
/// protect subsequent code.
|
||||
PYBIND11_NOINLINE void disarm() { active = false; }
|
||||
|
||||
PYBIND11_NOINLINE ~gil_scoped_acquire() {
|
||||
dec_ref();
|
||||
if (release) {
|
||||
PyEval_SaveThread();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PyThreadState *tstate = nullptr;
|
||||
bool release = true;
|
||||
bool active = true;
|
||||
};
|
||||
|
||||
class gil_scoped_release {
|
||||
public:
|
||||
// PRECONDITION: The GIL must be held when this constructor is called.
|
||||
explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {
|
||||
assert(PyGILState_Check());
|
||||
// `get_internals()` must be called here unconditionally in order to initialize
|
||||
// `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an
|
||||
// initialization race could occur as multiple threads try `gil_scoped_acquire`.
|
||||
auto &internals = detail::get_internals();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
tstate = PyEval_SaveThread();
|
||||
if (disassoc) {
|
||||
internals.tstate.reset();
|
||||
}
|
||||
}
|
||||
|
||||
gil_scoped_release(const gil_scoped_release &) = delete;
|
||||
gil_scoped_release &operator=(const gil_scoped_release &) = delete;
|
||||
|
||||
/// This method will disable the PyThreadState_DeleteCurrent call and the
|
||||
/// GIL won't be acquired. This method should be used if the interpreter
|
||||
/// could be shutting down when this is called, as thread deletion is not
|
||||
/// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
|
||||
/// protect subsequent code.
|
||||
PYBIND11_NOINLINE void disarm() { active = false; }
|
||||
|
||||
~gil_scoped_release() {
|
||||
if (!tstate) {
|
||||
return;
|
||||
}
|
||||
// `PyEval_RestoreThread()` should not be called if runtime is finalizing
|
||||
if (active) {
|
||||
PyEval_RestoreThread(tstate);
|
||||
}
|
||||
if (disassoc) {
|
||||
detail::get_internals().tstate = tstate;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PyThreadState *tstate;
|
||||
bool disassoc;
|
||||
bool active = true;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
|
||||
#endif // !PYBIND11_SIMPLE_GIL_MANAGEMENT
|
||||
102
deps_src/pybind11/include/pybind11/gil_safe_call_once.h
Normal file
102
deps_src/pybind11/include/pybind11/gil_safe_call_once.h
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2023 The pybind Community.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "gil.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
# include <atomic>
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
// Use the `gil_safe_call_once_and_store` class below instead of the naive
|
||||
//
|
||||
// static auto imported_obj = py::module_::import("module_name"); // BAD, DO NOT USE!
|
||||
//
|
||||
// which has two serious issues:
|
||||
//
|
||||
// 1. Py_DECREF() calls potentially after the Python interpreter was finalized already, and
|
||||
// 2. deadlocks in multi-threaded processes (because of missing lock ordering).
|
||||
//
|
||||
// The following alternative avoids both problems:
|
||||
//
|
||||
// PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<py::object> storage;
|
||||
// auto &imported_obj = storage // Do NOT make this `static`!
|
||||
// .call_once_and_store_result([]() {
|
||||
// return py::module_::import("module_name");
|
||||
// })
|
||||
// .get_stored();
|
||||
//
|
||||
// The parameter of `call_once_and_store_result()` must be callable. It can make
|
||||
// CPython API calls, and in particular, it can temporarily release the GIL.
|
||||
//
|
||||
// `T` can be any C++ type, it does not have to involve CPython API types.
|
||||
//
|
||||
// The behavior with regard to signals, e.g. `SIGINT` (`KeyboardInterrupt`),
|
||||
// is not ideal. If the main thread is the one to actually run the `Callable`,
|
||||
// then a `KeyboardInterrupt` will interrupt it if it is running normal Python
|
||||
// code. The situation is different if a non-main thread runs the
|
||||
// `Callable`, and then the main thread starts waiting for it to complete:
|
||||
// a `KeyboardInterrupt` will not interrupt the non-main thread, but it will
|
||||
// get processed only when it is the main thread's turn again and it is running
|
||||
// normal Python code. However, this will be unnoticeable for quick call-once
|
||||
// functions, which is usually the case.
|
||||
//
|
||||
// For in-depth background, see docs/advanced/deadlock.md
|
||||
template <typename T>
|
||||
class gil_safe_call_once_and_store {
|
||||
public:
|
||||
// PRECONDITION: The GIL must be held when `call_once_and_store_result()` is called.
|
||||
template <typename Callable>
|
||||
gil_safe_call_once_and_store &call_once_and_store_result(Callable &&fn) {
|
||||
if (!is_initialized_) { // This read is guarded by the GIL.
|
||||
// Multiple threads may enter here, because the GIL is released in the next line and
|
||||
// CPython API calls in the `fn()` call below may release and reacquire the GIL.
|
||||
gil_scoped_release gil_rel; // Needed to establish lock ordering.
|
||||
std::call_once(once_flag_, [&] {
|
||||
// Only one thread will ever enter here.
|
||||
gil_scoped_acquire gil_acq;
|
||||
::new (storage_) T(fn()); // fn may release, but will reacquire, the GIL.
|
||||
is_initialized_ = true; // This write is guarded by the GIL.
|
||||
});
|
||||
// All threads will observe `is_initialized_` as true here.
|
||||
}
|
||||
// Intentionally not returning `T &` to ensure the calling code is self-documenting.
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This must only be called after `call_once_and_store_result()` was called.
|
||||
T &get_stored() {
|
||||
assert(is_initialized_);
|
||||
PYBIND11_WARNING_PUSH
|
||||
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5
|
||||
// Needed for gcc 4.8.5
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
||||
#endif
|
||||
return *reinterpret_cast<T *>(storage_);
|
||||
PYBIND11_WARNING_POP
|
||||
}
|
||||
|
||||
constexpr gil_safe_call_once_and_store() = default;
|
||||
PYBIND11_DTOR_CONSTEXPR ~gil_safe_call_once_and_store() = default;
|
||||
|
||||
private:
|
||||
alignas(T) char storage_[sizeof(T)] = {};
|
||||
std::once_flag once_flag_ = {};
|
||||
#ifdef Py_GIL_DISABLED
|
||||
std::atomic_bool
|
||||
#else
|
||||
bool
|
||||
#endif
|
||||
is_initialized_{false};
|
||||
// The `is_initialized_`-`storage_` pair is very similar to `std::optional`,
|
||||
// but the latter does not have the triviality properties of former,
|
||||
// therefore `std::optional` is not a viable alternative here.
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
37
deps_src/pybind11/include/pybind11/gil_simple.h
Normal file
37
deps_src/pybind11/include/pybind11/gil_simple.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2016-2025 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
class gil_scoped_acquire_simple {
|
||||
PyGILState_STATE state;
|
||||
|
||||
public:
|
||||
gil_scoped_acquire_simple() : state{PyGILState_Ensure()} {}
|
||||
gil_scoped_acquire_simple(const gil_scoped_acquire_simple &) = delete;
|
||||
gil_scoped_acquire_simple &operator=(const gil_scoped_acquire_simple &) = delete;
|
||||
~gil_scoped_acquire_simple() { PyGILState_Release(state); }
|
||||
};
|
||||
|
||||
class gil_scoped_release_simple {
|
||||
PyThreadState *state;
|
||||
|
||||
public:
|
||||
// PRECONDITION: The GIL must be held when this constructor is called.
|
||||
gil_scoped_release_simple() {
|
||||
assert(PyGILState_Check());
|
||||
state = PyEval_SaveThread();
|
||||
}
|
||||
gil_scoped_release_simple(const gil_scoped_release_simple &) = delete;
|
||||
gil_scoped_release_simple &operator=(const gil_scoped_release_simple &) = delete;
|
||||
~gil_scoped_release_simple() { PyEval_RestoreThread(state); }
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
265
deps_src/pybind11/include/pybind11/iostream.h
Normal file
265
deps_src/pybind11/include/pybind11/iostream.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python
|
||||
|
||||
Copyright (c) 2017 Henry F. Schreiner
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
WARNING: The implementation in this file is NOT thread safe. Multiple
|
||||
threads writing to a redirected ostream concurrently cause data races
|
||||
and potentially buffer overflows. Therefore it is currently a requirement
|
||||
that all (possibly) concurrent redirected ostream writes are protected by
|
||||
a mutex.
|
||||
#HelpAppreciated: Work on iostream.h thread safety.
|
||||
For more background see the discussions under
|
||||
https://github.com/pybind/pybind11/pull/2982 and
|
||||
https://github.com/pybind/pybind11/pull/2995.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Buffer that writes to Python instead of C++
|
||||
class pythonbuf : public std::streambuf {
|
||||
private:
|
||||
using traits_type = std::streambuf::traits_type;
|
||||
|
||||
const size_t buf_size;
|
||||
std::unique_ptr<char[]> d_buffer;
|
||||
object pywrite;
|
||||
object pyflush;
|
||||
|
||||
int overflow(int c) override {
|
||||
if (!traits_type::eq_int_type(c, traits_type::eof())) {
|
||||
*pptr() = traits_type::to_char_type(c);
|
||||
pbump(1);
|
||||
}
|
||||
return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();
|
||||
}
|
||||
|
||||
// Computes how many bytes at the end of the buffer are part of an
|
||||
// incomplete sequence of UTF-8 bytes.
|
||||
// Precondition: pbase() < pptr()
|
||||
size_t utf8_remainder() const {
|
||||
const auto rbase = std::reverse_iterator<char *>(pbase());
|
||||
const auto rpptr = std::reverse_iterator<char *>(pptr());
|
||||
auto is_ascii = [](char c) { return (static_cast<unsigned char>(c) & 0x80) == 0x00; };
|
||||
auto is_leading = [](char c) { return (static_cast<unsigned char>(c) & 0xC0) == 0xC0; };
|
||||
auto is_leading_2b = [](char c) { return static_cast<unsigned char>(c) <= 0xDF; };
|
||||
auto is_leading_3b = [](char c) { return static_cast<unsigned char>(c) <= 0xEF; };
|
||||
// If the last character is ASCII, there are no incomplete code points
|
||||
if (is_ascii(*rpptr)) {
|
||||
return 0;
|
||||
}
|
||||
// Otherwise, work back from the end of the buffer and find the first
|
||||
// UTF-8 leading byte
|
||||
const auto rpend = rbase - rpptr >= 3 ? rpptr + 3 : rbase;
|
||||
const auto leading = std::find_if(rpptr, rpend, is_leading);
|
||||
if (leading == rbase) {
|
||||
return 0;
|
||||
}
|
||||
const auto dist = static_cast<size_t>(leading - rpptr);
|
||||
size_t remainder = 0;
|
||||
|
||||
if (dist == 0) {
|
||||
remainder = 1; // 1-byte code point is impossible
|
||||
} else if (dist == 1) {
|
||||
remainder = is_leading_2b(*leading) ? 0 : dist + 1;
|
||||
} else if (dist == 2) {
|
||||
remainder = is_leading_3b(*leading) ? 0 : dist + 1;
|
||||
}
|
||||
// else if (dist >= 3), at least 4 bytes before encountering an UTF-8
|
||||
// leading byte, either no remainder or invalid UTF-8.
|
||||
// Invalid UTF-8 will cause an exception later when converting
|
||||
// to a Python string, so that's not handled here.
|
||||
return remainder;
|
||||
}
|
||||
|
||||
// This function must be non-virtual to be called in a destructor.
|
||||
int _sync() {
|
||||
if (pbase() != pptr()) { // If buffer is not empty
|
||||
gil_scoped_acquire tmp;
|
||||
// This subtraction cannot be negative, so dropping the sign.
|
||||
auto size = static_cast<size_t>(pptr() - pbase());
|
||||
size_t remainder = utf8_remainder();
|
||||
|
||||
if (size > remainder) {
|
||||
str line(pbase(), size - remainder);
|
||||
pywrite(std::move(line));
|
||||
pyflush();
|
||||
}
|
||||
|
||||
// Copy the remainder at the end of the buffer to the beginning:
|
||||
if (remainder > 0) {
|
||||
std::memmove(pbase(), pptr() - remainder, remainder);
|
||||
}
|
||||
setp(pbase(), epptr());
|
||||
pbump(static_cast<int>(remainder));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sync() override { return _sync(); }
|
||||
|
||||
public:
|
||||
explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)
|
||||
: buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
|
||||
pyflush(pyostream.attr("flush")) {
|
||||
setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
|
||||
}
|
||||
|
||||
pythonbuf(pythonbuf &&) = default;
|
||||
|
||||
/// Sync before destroy
|
||||
~pythonbuf() override { _sync(); }
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/** \rst
|
||||
This a move-only guard that redirects output.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/iostream.h>
|
||||
|
||||
...
|
||||
|
||||
{
|
||||
py::scoped_ostream_redirect output;
|
||||
std::cout << "Hello, World!"; // Python stdout
|
||||
} // <-- return std::cout to normal
|
||||
|
||||
You can explicitly pass the c++ stream and the python object,
|
||||
for example to guard stderr instead.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
{
|
||||
py::scoped_ostream_redirect output{
|
||||
std::cerr, py::module::import("sys").attr("stderr")};
|
||||
std::cout << "Hello, World!";
|
||||
}
|
||||
\endrst */
|
||||
class scoped_ostream_redirect {
|
||||
protected:
|
||||
std::streambuf *old;
|
||||
std::ostream &costream;
|
||||
detail::pythonbuf buffer;
|
||||
|
||||
public:
|
||||
explicit scoped_ostream_redirect(std::ostream &costream = std::cout,
|
||||
const object &pyostream
|
||||
= module_::import("sys").attr("stdout"))
|
||||
: costream(costream), buffer(pyostream) {
|
||||
old = costream.rdbuf(&buffer);
|
||||
}
|
||||
|
||||
~scoped_ostream_redirect() { costream.rdbuf(old); }
|
||||
|
||||
scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;
|
||||
scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;
|
||||
scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete;
|
||||
scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;
|
||||
};
|
||||
|
||||
/** \rst
|
||||
Like `scoped_ostream_redirect`, but redirects cerr by default. This class
|
||||
is provided primary to make ``py::call_guard`` easier to make.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("noisy_func", &noisy_func,
|
||||
py::call_guard<scoped_ostream_redirect,
|
||||
scoped_estream_redirect>());
|
||||
|
||||
\endrst */
|
||||
class scoped_estream_redirect : public scoped_ostream_redirect {
|
||||
public:
|
||||
explicit scoped_estream_redirect(std::ostream &costream = std::cerr,
|
||||
const object &pyostream
|
||||
= module_::import("sys").attr("stderr"))
|
||||
: scoped_ostream_redirect(costream, pyostream) {}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Class to redirect output as a context manager. C++ backend.
|
||||
class OstreamRedirect {
|
||||
bool do_stdout_;
|
||||
bool do_stderr_;
|
||||
std::unique_ptr<scoped_ostream_redirect> redirect_stdout;
|
||||
std::unique_ptr<scoped_estream_redirect> redirect_stderr;
|
||||
|
||||
public:
|
||||
explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)
|
||||
: do_stdout_(do_stdout), do_stderr_(do_stderr) {}
|
||||
|
||||
void enter() {
|
||||
if (do_stdout_) {
|
||||
redirect_stdout.reset(new scoped_ostream_redirect());
|
||||
}
|
||||
if (do_stderr_) {
|
||||
redirect_stderr.reset(new scoped_estream_redirect());
|
||||
}
|
||||
}
|
||||
|
||||
void exit() {
|
||||
redirect_stdout.reset();
|
||||
redirect_stderr.reset();
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/** \rst
|
||||
This is a helper function to add a C++ redirect context manager to Python
|
||||
instead of using a C++ guard. To use it, add the following to your binding code:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/iostream.h>
|
||||
|
||||
...
|
||||
|
||||
py::add_ostream_redirect(m, "ostream_redirect");
|
||||
|
||||
You now have a Python context manager that redirects your output:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with m.ostream_redirect():
|
||||
m.print_to_cout_function()
|
||||
|
||||
This manager can optionally be told which streams to operate on:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with m.ostream_redirect(stdout=true, stderr=true):
|
||||
m.noisy_function_with_error_printing()
|
||||
|
||||
\endrst */
|
||||
inline class_<detail::OstreamRedirect>
|
||||
add_ostream_redirect(module_ m, const std::string &name = "ostream_redirect") {
|
||||
return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())
|
||||
.def(init<bool, bool>(), arg("stdout") = true, arg("stderr") = true)
|
||||
.def("__enter__", &detail::OstreamRedirect::enter)
|
||||
.def("__exit__", [](detail::OstreamRedirect &self_, const args &) { self_.exit(); });
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
67
deps_src/pybind11/include/pybind11/native_enum.h
Normal file
67
deps_src/pybind11/include/pybind11/native_enum.h
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2022-2025 The pybind Community.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "detail/native_enum_data.h"
|
||||
#include "detail/type_caster_base.h"
|
||||
#include "cast.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <typeindex>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
/// Conversions between Python's native (stdlib) enum types and C++ enums.
|
||||
template <typename EnumType>
|
||||
class native_enum : public detail::native_enum_data {
|
||||
public:
|
||||
using Underlying = typename std::underlying_type<EnumType>::type;
|
||||
|
||||
native_enum(const object &parent_scope,
|
||||
const char *name,
|
||||
const char *native_type_name,
|
||||
const char *class_doc = "")
|
||||
: detail::native_enum_data(
|
||||
parent_scope, name, native_type_name, class_doc, std::type_index(typeid(EnumType))) {
|
||||
if (detail::get_local_type_info(typeid(EnumType)) != nullptr
|
||||
|| detail::get_global_type_info(typeid(EnumType)) != nullptr) {
|
||||
pybind11_fail(
|
||||
"pybind11::native_enum<...>(\"" + enum_name_encoded
|
||||
+ "\") is already registered as a `pybind11::enum_` or `pybind11::class_`!");
|
||||
}
|
||||
if (detail::global_internals_native_enum_type_map_contains(enum_type_index)) {
|
||||
pybind11_fail("pybind11::native_enum<...>(\"" + enum_name_encoded
|
||||
+ "\") is already registered!");
|
||||
}
|
||||
arm_finalize_check();
|
||||
}
|
||||
|
||||
/// Export enumeration entries into the parent scope
|
||||
native_enum &export_values() {
|
||||
assert(!export_values_flag); // Catch redundant calls.
|
||||
export_values_flag = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add an enumeration entry
|
||||
native_enum &value(char const *name, EnumType value, const char *doc = nullptr) {
|
||||
// Disarm for the case that the native_enum_data dtor runs during exception unwinding.
|
||||
disarm_finalize_check("value after finalize");
|
||||
members.append(make_tuple(name, static_cast<Underlying>(value)));
|
||||
if (doc) {
|
||||
member_docs.append(make_tuple(name, doc));
|
||||
}
|
||||
arm_finalize_check(); // There was no exception.
|
||||
return *this;
|
||||
}
|
||||
|
||||
native_enum(const native_enum &) = delete;
|
||||
native_enum &operator=(const native_enum &) = delete;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
2312
deps_src/pybind11/include/pybind11/numpy.h
Normal file
2312
deps_src/pybind11/include/pybind11/numpy.h
Normal file
File diff suppressed because it is too large
Load Diff
202
deps_src/pybind11/include/pybind11/operators.h
Normal file
202
deps_src/pybind11/include/pybind11/operators.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
pybind11/operator.h: Metatemplates for operator overloading
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
/// Enumeration with all supported operator types
|
||||
enum op_id : int {
|
||||
op_add,
|
||||
op_sub,
|
||||
op_mul,
|
||||
op_div,
|
||||
op_mod,
|
||||
op_divmod,
|
||||
op_pow,
|
||||
op_lshift,
|
||||
op_rshift,
|
||||
op_and,
|
||||
op_xor,
|
||||
op_or,
|
||||
op_neg,
|
||||
op_pos,
|
||||
op_abs,
|
||||
op_invert,
|
||||
op_int,
|
||||
op_long,
|
||||
op_float,
|
||||
op_str,
|
||||
op_cmp,
|
||||
op_gt,
|
||||
op_ge,
|
||||
op_lt,
|
||||
op_le,
|
||||
op_eq,
|
||||
op_ne,
|
||||
op_iadd,
|
||||
op_isub,
|
||||
op_imul,
|
||||
op_idiv,
|
||||
op_imod,
|
||||
op_ilshift,
|
||||
op_irshift,
|
||||
op_iand,
|
||||
op_ixor,
|
||||
op_ior,
|
||||
op_complex,
|
||||
op_bool,
|
||||
op_nonzero,
|
||||
op_repr,
|
||||
op_truediv,
|
||||
op_itruediv,
|
||||
op_hash
|
||||
};
|
||||
|
||||
enum op_type : int {
|
||||
op_l, /* base type on left */
|
||||
op_r, /* base type on right */
|
||||
op_u /* unary operator */
|
||||
};
|
||||
|
||||
struct self_t {};
|
||||
static const self_t self = self_t();
|
||||
|
||||
/// Type for an unused type slot
|
||||
struct undefined_t {};
|
||||
|
||||
/// Don't warn about an unused variable
|
||||
inline self_t __self() { return self; }
|
||||
|
||||
/// base template of operator implementations
|
||||
template <op_id, op_type, typename B, typename L, typename R>
|
||||
struct op_impl {};
|
||||
|
||||
/// Operator implementation generator
|
||||
template <op_id id, op_type ot, typename L, typename R>
|
||||
struct op_ {
|
||||
static constexpr bool op_enable_if_hook = true;
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) const {
|
||||
using Base = typename Class::type;
|
||||
using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
|
||||
using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
|
||||
using op = op_impl<id, ot, Base, L_type, R_type>;
|
||||
cl.def(op::name(), &op::execute, is_operator(), extra...);
|
||||
}
|
||||
template <typename Class, typename... Extra>
|
||||
void execute_cast(Class &cl, const Extra &...extra) const {
|
||||
using Base = typename Class::type;
|
||||
using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
|
||||
using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
|
||||
using op = op_impl<id, ot, Base, L_type, R_type>;
|
||||
cl.def(op::name(), &op::execute_cast, is_operator(), extra...);
|
||||
}
|
||||
};
|
||||
|
||||
#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \
|
||||
template <typename B, typename L, typename R> \
|
||||
struct op_impl<op_##id, op_l, B, L, R> { \
|
||||
static char const *name() { return "__" #id "__"; } \
|
||||
static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \
|
||||
static B execute_cast(const L &l, const R &r) { return B(expr); } \
|
||||
}; \
|
||||
template <typename B, typename L, typename R> \
|
||||
struct op_impl<op_##id, op_r, B, L, R> { \
|
||||
static char const *name() { return "__" #rid "__"; } \
|
||||
static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \
|
||||
static B execute_cast(const R &r, const L &l) { return B(expr); } \
|
||||
}; \
|
||||
inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) { \
|
||||
return op_<op_##id, op_l, self_t, self_t>(); \
|
||||
} \
|
||||
template <typename T> \
|
||||
op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \
|
||||
return op_<op_##id, op_l, self_t, T>(); \
|
||||
} \
|
||||
template <typename T> \
|
||||
op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) { \
|
||||
return op_<op_##id, op_r, T, self_t>(); \
|
||||
}
|
||||
|
||||
#define PYBIND11_INPLACE_OPERATOR(id, op, expr) \
|
||||
template <typename B, typename L, typename R> \
|
||||
struct op_impl<op_##id, op_l, B, L, R> { \
|
||||
static char const *name() { return "__" #id "__"; } \
|
||||
static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \
|
||||
static B execute_cast(L &l, const R &r) { return B(expr); } \
|
||||
}; \
|
||||
template <typename T> \
|
||||
op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \
|
||||
return op_<op_##id, op_l, self_t, T>(); \
|
||||
}
|
||||
|
||||
#define PYBIND11_UNARY_OPERATOR(id, op, expr) \
|
||||
template <typename B, typename L> \
|
||||
struct op_impl<op_##id, op_u, B, L, undefined_t> { \
|
||||
static char const *name() { return "__" #id "__"; } \
|
||||
static auto execute(const L &l) -> decltype(expr) { return expr; } \
|
||||
static B execute_cast(const L &l) { return B(expr); } \
|
||||
}; \
|
||||
inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) { \
|
||||
return op_<op_##id, op_u, self_t, undefined_t>(); \
|
||||
}
|
||||
|
||||
PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)
|
||||
PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)
|
||||
PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)
|
||||
PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)
|
||||
PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)
|
||||
PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)
|
||||
PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)
|
||||
PYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)
|
||||
PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)
|
||||
PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
|
||||
PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)
|
||||
PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)
|
||||
PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)
|
||||
PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)
|
||||
PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)
|
||||
PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)
|
||||
// PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r))
|
||||
PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)
|
||||
PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)
|
||||
PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)
|
||||
PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)
|
||||
PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)
|
||||
PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)
|
||||
PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)
|
||||
PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)
|
||||
PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)
|
||||
PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)
|
||||
PYBIND11_UNARY_OPERATOR(neg, operator-, -l)
|
||||
PYBIND11_UNARY_OPERATOR(pos, operator+, +l)
|
||||
// WARNING: This usage of `abs` should only be done for existing STL overloads.
|
||||
// Adding overloads directly in to the `std::` namespace is advised against:
|
||||
// https://en.cppreference.com/w/cpp/language/extending_std
|
||||
PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))
|
||||
PYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))
|
||||
PYBIND11_UNARY_OPERATOR(invert, operator~, (~l))
|
||||
PYBIND11_UNARY_OPERATOR(bool, operator!, !!l)
|
||||
PYBIND11_UNARY_OPERATOR(int, int_, (int) l)
|
||||
PYBIND11_UNARY_OPERATOR(float, float_, (double) l)
|
||||
|
||||
#undef PYBIND11_BINARY_OPERATOR
|
||||
#undef PYBIND11_INPLACE_OPERATOR
|
||||
#undef PYBIND11_UNARY_OPERATOR
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
using detail::self;
|
||||
// Add named operators so that they are accessible via `py::`.
|
||||
using detail::hash;
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
92
deps_src/pybind11/include/pybind11/options.h
Normal file
92
deps_src/pybind11/include/pybind11/options.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
pybind11/options.h: global settings that are configurable at runtime.
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
class options {
|
||||
public:
|
||||
// Default RAII constructor, which leaves settings as they currently are.
|
||||
options() : previous_state(global_state()) {}
|
||||
|
||||
// Class is non-copyable.
|
||||
options(const options &) = delete;
|
||||
options &operator=(const options &) = delete;
|
||||
|
||||
// Destructor, which restores settings that were in effect before.
|
||||
~options() { global_state() = previous_state; }
|
||||
|
||||
// Setter methods (affect the global state):
|
||||
|
||||
options &disable_user_defined_docstrings() & {
|
||||
global_state().show_user_defined_docstrings = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
options &enable_user_defined_docstrings() & {
|
||||
global_state().show_user_defined_docstrings = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
options &disable_function_signatures() & {
|
||||
global_state().show_function_signatures = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
options &enable_function_signatures() & {
|
||||
global_state().show_function_signatures = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
options &disable_enum_members_docstring() & {
|
||||
global_state().show_enum_members_docstring = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
options &enable_enum_members_docstring() & {
|
||||
global_state().show_enum_members_docstring = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Getter methods (return the global state):
|
||||
|
||||
static bool show_user_defined_docstrings() {
|
||||
return global_state().show_user_defined_docstrings;
|
||||
}
|
||||
|
||||
static bool show_function_signatures() { return global_state().show_function_signatures; }
|
||||
|
||||
static bool show_enum_members_docstring() {
|
||||
return global_state().show_enum_members_docstring;
|
||||
}
|
||||
|
||||
// This type is not meant to be allocated on the heap.
|
||||
void *operator new(size_t) = delete;
|
||||
|
||||
private:
|
||||
struct state {
|
||||
bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
|
||||
bool show_function_signatures = true; //< Include auto-generated function signatures
|
||||
// in docstrings.
|
||||
bool show_enum_members_docstring = true; //< Include auto-generated member list in enum
|
||||
// docstrings.
|
||||
};
|
||||
|
||||
static state &global_state() {
|
||||
static state instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
state previous_state;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
3645
deps_src/pybind11/include/pybind11/pybind11.h
Normal file
3645
deps_src/pybind11/include/pybind11/pybind11.h
Normal file
File diff suppressed because it is too large
Load Diff
2680
deps_src/pybind11/include/pybind11/pytypes.h
Normal file
2680
deps_src/pybind11/include/pybind11/pytypes.h
Normal file
File diff suppressed because it is too large
Load Diff
666
deps_src/pybind11/include/pybind11/stl.h
Normal file
666
deps_src/pybind11/include/pybind11/stl.h
Normal file
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
pybind11/stl.h: Transparent conversion for STL data types
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
#include "detail/common.h"
|
||||
#include "detail/descr.h"
|
||||
#include "detail/type_caster_base.h"
|
||||
|
||||
#include <deque>
|
||||
#include <initializer_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <valarray>
|
||||
|
||||
// See `detail/common.h` for implementation of these guards.
|
||||
#if defined(PYBIND11_HAS_OPTIONAL)
|
||||
# include <optional>
|
||||
#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
|
||||
# include <experimental/optional>
|
||||
#endif
|
||||
|
||||
#if defined(PYBIND11_HAS_VARIANT)
|
||||
# include <variant>
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
//
|
||||
// Begin: Equivalent of
|
||||
// https://github.com/google/clif/blob/ae4eee1de07cdf115c0c9bf9fec9ff28efce6f6c/clif/python/runtime.cc#L388-L438
|
||||
/*
|
||||
The three `object_is_convertible_to_*()` functions below are
|
||||
the result of converging the behaviors of pybind11 and PyCLIF
|
||||
(http://github.com/google/clif).
|
||||
|
||||
Originally PyCLIF was extremely far on the permissive side of the spectrum,
|
||||
while pybind11 was very far on the strict side. Originally PyCLIF accepted any
|
||||
Python iterable as input for a C++ `vector`/`set`/`map` argument, as long as
|
||||
the elements were convertible. The obvious (in hindsight) problem was that
|
||||
any empty Python iterable could be passed to any of these C++ types, e.g. `{}`
|
||||
was accepted for C++ `vector`/`set` arguments, or `[]` for C++ `map` arguments.
|
||||
|
||||
The functions below strike a practical permissive-vs-strict compromise,
|
||||
informed by tens of thousands of use cases in the wild. A main objective is
|
||||
to prevent accidents and improve readability:
|
||||
|
||||
- Python literals must match the C++ types.
|
||||
|
||||
- For C++ `set`: The potentially reducing conversion from a Python sequence
|
||||
(e.g. Python `list` or `tuple`) to a C++ `set` must be explicit, by going
|
||||
through a Python `set`.
|
||||
|
||||
- However, a Python `set` can still be passed to a C++ `vector`. The rationale
|
||||
is that this conversion is not reducing. Implicit conversions of this kind
|
||||
are also fairly commonly used, therefore enforcing explicit conversions
|
||||
would have an unfavorable cost : benefit ratio; more sloppily speaking,
|
||||
such an enforcement would be more annoying than helpful.
|
||||
|
||||
Additional checks have been added to allow types derived from `collections.abc.Set` and
|
||||
`collections.abc.Mapping` (`collections.abc.Sequence` is already allowed by `PySequence_Check`).
|
||||
*/
|
||||
|
||||
inline bool object_is_instance_with_one_of_tp_names(PyObject *obj,
|
||||
std::initializer_list<const char *> tp_names) {
|
||||
if (PyType_Check(obj)) {
|
||||
return false;
|
||||
}
|
||||
const char *obj_tp_name = Py_TYPE(obj)->tp_name;
|
||||
for (const auto *tp_name : tp_names) {
|
||||
if (std::strcmp(obj_tp_name, tp_name) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool object_is_convertible_to_std_vector(const handle &src) {
|
||||
// Allow sequence-like objects, but not (byte-)string-like objects.
|
||||
if (PySequence_Check(src.ptr()) != 0) {
|
||||
return !PyUnicode_Check(src.ptr()) && !PyBytes_Check(src.ptr());
|
||||
}
|
||||
// Allow generators, set/frozenset and several common iterable types.
|
||||
return (PyGen_Check(src.ptr()) != 0) || (PyAnySet_Check(src.ptr()) != 0)
|
||||
|| object_is_instance_with_one_of_tp_names(
|
||||
src.ptr(), {"dict_keys", "dict_values", "dict_items", "map", "zip"});
|
||||
}
|
||||
|
||||
inline bool object_is_convertible_to_std_set(const handle &src, bool convert) {
|
||||
// Allow set/frozenset and dict keys.
|
||||
// In convert mode: also allow types derived from collections.abc.Set.
|
||||
return ((PyAnySet_Check(src.ptr()) != 0)
|
||||
|| object_is_instance_with_one_of_tp_names(src.ptr(), {"dict_keys"}))
|
||||
|| (convert && isinstance(src, module_::import("collections.abc").attr("Set")));
|
||||
}
|
||||
|
||||
inline bool object_is_convertible_to_std_map(const handle &src, bool convert) {
|
||||
// Allow dict.
|
||||
if (PyDict_Check(src.ptr())) {
|
||||
return true;
|
||||
}
|
||||
// Allow types conforming to Mapping Protocol.
|
||||
// According to https://docs.python.org/3/c-api/mapping.html, `PyMappingCheck()` checks for
|
||||
// `__getitem__()` without checking the type of keys. In order to restrict the allowed types
|
||||
// closer to actual Mapping-like types, we also check for the `items()` method.
|
||||
if (PyMapping_Check(src.ptr()) != 0) {
|
||||
PyObject *items = PyObject_GetAttrString(src.ptr(), "items");
|
||||
if (items != nullptr) {
|
||||
bool is_convertible = (PyCallable_Check(items) != 0);
|
||||
Py_DECREF(items);
|
||||
if (is_convertible) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
// In convert mode: Allow types derived from collections.abc.Mapping
|
||||
return convert && isinstance(src, module_::import("collections.abc").attr("Mapping"));
|
||||
}
|
||||
|
||||
//
|
||||
// End: Equivalent of clif/python/runtime.cc
|
||||
//
|
||||
|
||||
/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for
|
||||
/// forwarding a container element). Typically used indirect via forwarded_type(), below.
|
||||
template <typename T, typename U>
|
||||
using forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,
|
||||
remove_reference_t<U> &,
|
||||
remove_reference_t<U> &&>;
|
||||
|
||||
/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
|
||||
/// used for forwarding a container's elements.
|
||||
template <typename T, typename U>
|
||||
constexpr forwarded_type<T, U> forward_like(U &&u) {
|
||||
return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
|
||||
}
|
||||
|
||||
// Checks if a container has a STL style reserve method.
|
||||
// This will only return true for a `reserve()` with a `void` return.
|
||||
template <typename C>
|
||||
using has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;
|
||||
|
||||
template <typename Type, typename Key>
|
||||
struct set_caster {
|
||||
using type = Type;
|
||||
using key_conv = make_caster<Key>;
|
||||
|
||||
private:
|
||||
template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
|
||||
void reserve_maybe(const anyset &s, Type *) {
|
||||
value.reserve(s.size());
|
||||
}
|
||||
void reserve_maybe(const anyset &, void *) {}
|
||||
|
||||
bool convert_iterable(const iterable &itbl, bool convert) {
|
||||
for (const auto &it : itbl) {
|
||||
key_conv conv;
|
||||
if (!conv.load(it, convert)) {
|
||||
return false;
|
||||
}
|
||||
value.insert(cast_op<Key &&>(std::move(conv)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool convert_anyset(const anyset &s, bool convert) {
|
||||
value.clear();
|
||||
reserve_maybe(s, &value);
|
||||
return convert_iterable(s, convert);
|
||||
}
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!object_is_convertible_to_std_set(src, convert)) {
|
||||
return false;
|
||||
}
|
||||
if (isinstance<anyset>(src)) {
|
||||
value.clear();
|
||||
return convert_anyset(reinterpret_borrow<anyset>(src), convert);
|
||||
}
|
||||
if (!convert) {
|
||||
return false;
|
||||
}
|
||||
assert(isinstance<iterable>(src));
|
||||
value.clear();
|
||||
return convert_iterable(reinterpret_borrow<iterable>(src), convert);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
if (!std::is_lvalue_reference<T>::value) {
|
||||
policy = return_value_policy_override<Key>::policy(policy);
|
||||
}
|
||||
pybind11::set s;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
key_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_ || !s.add(std::move(value_))) {
|
||||
return handle();
|
||||
}
|
||||
}
|
||||
return s.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(type,
|
||||
io_name("collections.abc.Set", "set") + const_name("[") + key_conv::name
|
||||
+ const_name("]"));
|
||||
};
|
||||
|
||||
template <typename Type, typename Key, typename Value>
|
||||
struct map_caster {
|
||||
using key_conv = make_caster<Key>;
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
private:
|
||||
template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
|
||||
void reserve_maybe(const dict &d, Type *) {
|
||||
value.reserve(d.size());
|
||||
}
|
||||
void reserve_maybe(const dict &, void *) {}
|
||||
|
||||
bool convert_elements(const dict &d, bool convert) {
|
||||
value.clear();
|
||||
reserve_maybe(d, &value);
|
||||
for (const auto &it : d) {
|
||||
key_conv kconv;
|
||||
value_conv vconv;
|
||||
if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {
|
||||
return false;
|
||||
}
|
||||
value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!object_is_convertible_to_std_map(src, convert)) {
|
||||
return false;
|
||||
}
|
||||
if (isinstance<dict>(src)) {
|
||||
return convert_elements(reinterpret_borrow<dict>(src), convert);
|
||||
}
|
||||
if (!convert) {
|
||||
return false;
|
||||
}
|
||||
auto items = reinterpret_steal<object>(PyMapping_Items(src.ptr()));
|
||||
if (!items) {
|
||||
throw error_already_set();
|
||||
}
|
||||
assert(isinstance<iterable>(items));
|
||||
return convert_elements(dict(reinterpret_borrow<iterable>(items)), convert);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
dict d;
|
||||
return_value_policy policy_key = policy;
|
||||
return_value_policy policy_value = policy;
|
||||
if (!std::is_lvalue_reference<T>::value) {
|
||||
policy_key = return_value_policy_override<Key>::policy(policy_key);
|
||||
policy_value = return_value_policy_override<Value>::policy(policy_value);
|
||||
}
|
||||
for (auto &&kv : src) {
|
||||
auto key = reinterpret_steal<object>(
|
||||
key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));
|
||||
auto value = reinterpret_steal<object>(
|
||||
value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));
|
||||
if (!key || !value) {
|
||||
return handle();
|
||||
}
|
||||
d[std::move(key)] = std::move(value);
|
||||
}
|
||||
return d.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(Type,
|
||||
io_name("collections.abc.Mapping", "dict") + const_name("[")
|
||||
+ key_conv::name + const_name(", ") + value_conv::name
|
||||
+ const_name("]"));
|
||||
};
|
||||
|
||||
template <typename Type, typename Value>
|
||||
struct list_caster {
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
if (!object_is_convertible_to_std_vector(src)) {
|
||||
return false;
|
||||
}
|
||||
if (isinstance<sequence>(src)) {
|
||||
return convert_elements(src, convert);
|
||||
}
|
||||
if (!convert) {
|
||||
return false;
|
||||
}
|
||||
// Designed to be behavior-equivalent to passing tuple(src) from Python:
|
||||
// The conversion to a tuple will first exhaust the generator object, to ensure that
|
||||
// the generator is not left in an unpredictable (to the caller) partially-consumed
|
||||
// state.
|
||||
assert(isinstance<iterable>(src));
|
||||
return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
|
||||
void reserve_maybe(const sequence &s, Type *) {
|
||||
value.reserve(s.size());
|
||||
}
|
||||
void reserve_maybe(const sequence &, void *) {}
|
||||
|
||||
bool convert_elements(handle seq, bool convert) {
|
||||
auto s = reinterpret_borrow<sequence>(seq);
|
||||
value.clear();
|
||||
reserve_maybe(s, &value);
|
||||
for (const auto &it : seq) {
|
||||
value_conv conv;
|
||||
if (!conv.load(it, convert)) {
|
||||
return false;
|
||||
}
|
||||
value.push_back(cast_op<Value &&>(std::move(conv)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
if (!std::is_lvalue_reference<T>::value) {
|
||||
policy = return_value_policy_override<Value>::policy(policy);
|
||||
}
|
||||
list l(src.size());
|
||||
ssize_t index = 0;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
value_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_) {
|
||||
return handle();
|
||||
}
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(Type,
|
||||
io_name("collections.abc.Sequence", "list") + const_name("[")
|
||||
+ value_conv::name + const_name("]"));
|
||||
};
|
||||
|
||||
template <typename Type, typename Alloc>
|
||||
struct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};
|
||||
|
||||
template <typename Type, typename Alloc>
|
||||
struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};
|
||||
|
||||
template <typename Type, typename Alloc>
|
||||
struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
|
||||
|
||||
template <typename ArrayType, typename V, size_t... I>
|
||||
ArrayType vector_to_array_impl(V &&v, index_sequence<I...>) {
|
||||
return {{std::move(v[I])...}};
|
||||
}
|
||||
|
||||
// Based on https://en.cppreference.com/w/cpp/container/array/to_array
|
||||
template <typename ArrayType, size_t N, typename V>
|
||||
ArrayType vector_to_array(V &&v) {
|
||||
return vector_to_array_impl<ArrayType, V>(std::forward<V>(v), make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
|
||||
struct array_caster {
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
private:
|
||||
std::unique_ptr<ArrayType> value;
|
||||
|
||||
template <bool R = Resizable, enable_if_t<R, int> = 0>
|
||||
bool convert_elements(handle seq, bool convert) {
|
||||
auto l = reinterpret_borrow<sequence>(seq);
|
||||
value.reset(new ArrayType{});
|
||||
// Using `resize` to preserve the behavior exactly as it was before PR #5305
|
||||
// For the `resize` to work, `Value` must be default constructible.
|
||||
// For `std::valarray`, this is a requirement:
|
||||
// https://en.cppreference.com/w/cpp/named_req/NumericType
|
||||
value->resize(l.size());
|
||||
size_t ctr = 0;
|
||||
for (const auto &it : l) {
|
||||
value_conv conv;
|
||||
if (!conv.load(it, convert)) {
|
||||
return false;
|
||||
}
|
||||
(*value)[ctr++] = cast_op<Value &&>(std::move(conv));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <bool R = Resizable, enable_if_t<!R, int> = 0>
|
||||
bool convert_elements(handle seq, bool convert) {
|
||||
auto l = reinterpret_borrow<sequence>(seq);
|
||||
if (l.size() != Size) {
|
||||
return false;
|
||||
}
|
||||
// The `temp` storage is needed to support `Value` types that are not
|
||||
// default-constructible.
|
||||
// Deliberate choice: no template specializations, for simplicity, and
|
||||
// because the compile time overhead for the specializations is deemed
|
||||
// more significant than the runtime overhead for the `temp` storage.
|
||||
std::vector<Value> temp;
|
||||
temp.reserve(l.size());
|
||||
for (auto it : l) {
|
||||
value_conv conv;
|
||||
if (!conv.load(it, convert)) {
|
||||
return false;
|
||||
}
|
||||
temp.emplace_back(cast_op<Value &&>(std::move(conv)));
|
||||
}
|
||||
value.reset(new ArrayType(vector_to_array<ArrayType, Size>(std::move(temp))));
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!object_is_convertible_to_std_vector(src)) {
|
||||
return false;
|
||||
}
|
||||
if (isinstance<sequence>(src)) {
|
||||
return convert_elements(src, convert);
|
||||
}
|
||||
if (!convert) {
|
||||
return false;
|
||||
}
|
||||
// Designed to be behavior-equivalent to passing tuple(src) from Python:
|
||||
// The conversion to a tuple will first exhaust the generator object, to ensure that
|
||||
// the generator is not left in an unpredictable (to the caller) partially-consumed
|
||||
// state.
|
||||
assert(isinstance<iterable>(src));
|
||||
return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
list l(src.size());
|
||||
ssize_t index = 0;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
value_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_) {
|
||||
return handle();
|
||||
}
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
|
||||
// Code copied from PYBIND11_TYPE_CASTER macro.
|
||||
// Intentionally preserving the behavior exactly as it was before PR #5305
|
||||
template <typename T_, enable_if_t<std::is_same<ArrayType, remove_cv_t<T_>>::value, int> = 0>
|
||||
static handle cast(T_ *src, return_value_policy policy, handle parent) {
|
||||
if (!src) {
|
||||
return none().release();
|
||||
}
|
||||
if (policy == return_value_policy::take_ownership) {
|
||||
auto h = cast(std::move(*src), policy, parent);
|
||||
delete src; // WARNING: Assumes `src` was allocated with `new`.
|
||||
return h;
|
||||
}
|
||||
return cast(*src, policy, parent);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator ArrayType *() { return &(*value); }
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator ArrayType &() { return *value; }
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator ArrayType &&() && { return std::move(*value); }
|
||||
|
||||
template <typename T_>
|
||||
using cast_op_type = movable_cast_op_type<T_>;
|
||||
|
||||
static constexpr auto name
|
||||
= const_name<Resizable>(const_name(""), const_name("typing.Annotated["))
|
||||
+ io_name("collections.abc.Sequence", "list") + const_name("[") + value_conv::name
|
||||
+ const_name("]")
|
||||
+ const_name<Resizable>(const_name(""),
|
||||
const_name(", \"FixedSize(") + const_name<Size>()
|
||||
+ const_name(")\"]"));
|
||||
};
|
||||
|
||||
template <typename Type, size_t Size>
|
||||
struct type_caster<std::array<Type, Size>>
|
||||
: array_caster<std::array<Type, Size>, Type, false, Size> {};
|
||||
|
||||
template <typename Type>
|
||||
struct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};
|
||||
|
||||
template <typename Key, typename Compare, typename Alloc>
|
||||
struct type_caster<std::set<Key, Compare, Alloc>>
|
||||
: set_caster<std::set<Key, Compare, Alloc>, Key> {};
|
||||
|
||||
template <typename Key, typename Hash, typename Equal, typename Alloc>
|
||||
struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
|
||||
: set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};
|
||||
|
||||
template <typename Key, typename Value, typename Compare, typename Alloc>
|
||||
struct type_caster<std::map<Key, Value, Compare, Alloc>>
|
||||
: map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};
|
||||
|
||||
template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>
|
||||
struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
|
||||
: map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};
|
||||
|
||||
// This type caster is intended to be used for std::optional and std::experimental::optional
|
||||
template <typename Type, typename Value = typename Type::value_type>
|
||||
struct optional_caster {
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
if (!src) {
|
||||
return none().release();
|
||||
}
|
||||
if (!std::is_lvalue_reference<T>::value) {
|
||||
policy = return_value_policy_override<Value>::policy(policy);
|
||||
}
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
return value_conv::cast(*std::forward<T>(src), policy, parent);
|
||||
}
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
if (src.is_none()) {
|
||||
return true; // default-constructed value is already empty
|
||||
}
|
||||
value_conv inner_caster;
|
||||
if (!inner_caster.load(src, convert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value.emplace(cast_op<Value &&>(std::move(inner_caster)));
|
||||
return true;
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(Type, value_conv::name | make_caster<none>::name);
|
||||
};
|
||||
|
||||
#if defined(PYBIND11_HAS_OPTIONAL)
|
||||
template <typename T>
|
||||
struct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};
|
||||
|
||||
template <>
|
||||
struct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};
|
||||
#endif
|
||||
|
||||
#if defined(PYBIND11_HAS_EXP_OPTIONAL)
|
||||
template <typename T>
|
||||
struct type_caster<std::experimental::optional<T>>
|
||||
: public optional_caster<std::experimental::optional<T>> {};
|
||||
|
||||
template <>
|
||||
struct type_caster<std::experimental::nullopt_t>
|
||||
: public void_caster<std::experimental::nullopt_t> {};
|
||||
#endif
|
||||
|
||||
/// Visit a variant and cast any found type to Python
|
||||
struct variant_caster_visitor {
|
||||
return_value_policy policy;
|
||||
handle parent;
|
||||
|
||||
using result_type = handle; // required by boost::variant in C++11
|
||||
|
||||
template <typename T>
|
||||
result_type operator()(T &&src) const {
|
||||
return make_caster<T>::cast(std::forward<T>(src), policy, parent);
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar
|
||||
/// `namespace::variant` types which provide a `namespace::visit()` function are handled here
|
||||
/// automatically using argument-dependent lookup. Users can provide specializations for other
|
||||
/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.
|
||||
template <template <typename...> class Variant>
|
||||
struct visit_helper {
|
||||
template <typename... Args>
|
||||
static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
|
||||
return visit(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
/// Generic variant caster
|
||||
template <typename Variant>
|
||||
struct variant_caster;
|
||||
|
||||
template <template <typename...> class V, typename... Ts>
|
||||
struct variant_caster<V<Ts...>> {
|
||||
static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
|
||||
|
||||
template <typename U, typename... Us>
|
||||
bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
|
||||
auto caster = make_caster<U>();
|
||||
if (caster.load(src, convert)) {
|
||||
value = cast_op<U>(std::move(caster));
|
||||
return true;
|
||||
}
|
||||
return load_alternative(src, convert, type_list<Us...>{});
|
||||
}
|
||||
|
||||
bool load_alternative(handle, bool, type_list<>) { return false; }
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
// Do a first pass without conversions to improve constructor resolution.
|
||||
// E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
|
||||
// slot of the variant. Without two-pass loading `double` would be filled
|
||||
// because it appears first and a conversion is possible.
|
||||
if (convert && load_alternative(src, false, type_list<Ts...>{})) {
|
||||
return true;
|
||||
}
|
||||
return load_alternative(src, convert, type_list<Ts...>{});
|
||||
}
|
||||
|
||||
template <typename Variant>
|
||||
static handle cast(Variant &&src, return_value_policy policy, handle parent) {
|
||||
return visit_helper<V>::call(variant_caster_visitor{policy, parent},
|
||||
std::forward<Variant>(src));
|
||||
}
|
||||
|
||||
using Type = V<Ts...>;
|
||||
PYBIND11_TYPE_CASTER(Type, ::pybind11::detail::union_concat(make_caster<Ts>::name...));
|
||||
};
|
||||
|
||||
#if defined(PYBIND11_HAS_VARIANT)
|
||||
template <typename... Ts>
|
||||
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
|
||||
|
||||
template <>
|
||||
struct type_caster<std::monostate> : public void_caster<std::monostate> {};
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
|
||||
#ifdef PYBIND11_HAS_STRING_VIEW
|
||||
os << str(obj).cast<std::string_view>();
|
||||
#else
|
||||
os << (std::string) str(obj);
|
||||
#endif
|
||||
return os;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
114
deps_src/pybind11/include/pybind11/stl/filesystem.h
Normal file
114
deps_src/pybind11/include/pybind11/stl/filesystem.h
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) 2021 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pybind11/cast.h>
|
||||
#include <pybind11/detail/common.h>
|
||||
#include <pybind11/detail/descr.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/pytypes.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#if defined(PYBIND11_HAS_FILESYSTEM)
|
||||
# include <filesystem>
|
||||
#elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||
# include <experimental/filesystem>
|
||||
#else
|
||||
# error "Neither #include <filesystem> nor #include <experimental/filesystem is available."
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#ifdef PYPY_VERSION
|
||||
# define PYBIND11_REINTERPRET_CAST_VOID_PTR_IF_NOT_PYPY(...) (__VA_ARGS__)
|
||||
#else
|
||||
# define PYBIND11_REINTERPRET_CAST_VOID_PTR_IF_NOT_PYPY(...) \
|
||||
(reinterpret_cast<void *>(__VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#if defined(PYBIND11_HAS_FILESYSTEM) || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||
template <typename T>
|
||||
struct path_caster {
|
||||
|
||||
private:
|
||||
static PyObject *unicode_from_fs_native(const std::string &w) {
|
||||
# if !defined(PYPY_VERSION)
|
||||
return PyUnicode_DecodeFSDefaultAndSize(w.c_str(), ssize_t(w.size()));
|
||||
# else
|
||||
// PyPy mistakenly declares the first parameter as non-const.
|
||||
return PyUnicode_DecodeFSDefaultAndSize(const_cast<char *>(w.c_str()), ssize_t(w.size()));
|
||||
# endif
|
||||
}
|
||||
|
||||
static PyObject *unicode_from_fs_native(const std::wstring &w) {
|
||||
return PyUnicode_FromWideChar(w.c_str(), ssize_t(w.size()));
|
||||
}
|
||||
|
||||
public:
|
||||
static handle cast(const T &path, return_value_policy, handle) {
|
||||
if (auto py_str = unicode_from_fs_native(path.native())) {
|
||||
return module_::import("pathlib")
|
||||
.attr("Path")(reinterpret_steal<object>(py_str))
|
||||
.release();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool load(handle handle, bool) {
|
||||
// PyUnicode_FSConverter and PyUnicode_FSDecoder normally take care of
|
||||
// calling PyOS_FSPath themselves, but that's broken on PyPy (PyPy
|
||||
// issue #3168) so we do it ourselves instead.
|
||||
PyObject *buf = PyOS_FSPath(handle.ptr());
|
||||
if (!buf) {
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
PyObject *native = nullptr;
|
||||
if constexpr (std::is_same_v<typename T::value_type, char>) {
|
||||
if (PyUnicode_FSConverter(buf, PYBIND11_REINTERPRET_CAST_VOID_PTR_IF_NOT_PYPY(&native))
|
||||
!= 0) {
|
||||
if (auto *c_str = PyBytes_AsString(native)) {
|
||||
// AsString returns a pointer to the internal buffer, which
|
||||
// must not be free'd.
|
||||
value = c_str;
|
||||
}
|
||||
}
|
||||
} else if constexpr (std::is_same_v<typename T::value_type, wchar_t>) {
|
||||
if (PyUnicode_FSDecoder(buf, PYBIND11_REINTERPRET_CAST_VOID_PTR_IF_NOT_PYPY(&native))
|
||||
!= 0) {
|
||||
if (auto *c_str = PyUnicode_AsWideCharString(native, nullptr)) {
|
||||
// AsWideCharString returns a new string that must be free'd.
|
||||
value = c_str; // Copies the string.
|
||||
PyMem_Free(c_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_XDECREF(native);
|
||||
Py_DECREF(buf);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(T, io_name("os.PathLike | str | bytes", "pathlib.Path"));
|
||||
};
|
||||
|
||||
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||
|
||||
#if defined(PYBIND11_HAS_FILESYSTEM)
|
||||
template <>
|
||||
struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
|
||||
#elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||
template <>
|
||||
struct type_caster<std::experimental::filesystem::path>
|
||||
: public path_caster<std::experimental::filesystem::path> {};
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
858
deps_src/pybind11/include/pybind11/stl_bind.h
Normal file
858
deps_src/pybind11/include/pybind11/stl_bind.h
Normal file
@@ -0,0 +1,858 @@
|
||||
/*
|
||||
pybind11/std_bind.h: Binding generators for STL data types
|
||||
|
||||
Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "detail/type_caster_base.h"
|
||||
#include "cast.h"
|
||||
#include "operators.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
/* SFINAE helper class used by 'is_comparable */
|
||||
template <typename T>
|
||||
struct container_traits {
|
||||
template <typename T2>
|
||||
static std::true_type
|
||||
test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
|
||||
template <typename T2>
|
||||
static std::false_type test_comparable(...);
|
||||
template <typename T2>
|
||||
static std::true_type test_value(typename T2::value_type *);
|
||||
template <typename T2>
|
||||
static std::false_type test_value(...);
|
||||
template <typename T2>
|
||||
static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
|
||||
template <typename T2>
|
||||
static std::false_type test_pair(...);
|
||||
|
||||
static constexpr const bool is_comparable
|
||||
= std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
|
||||
static constexpr const bool is_pair
|
||||
= std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
|
||||
static constexpr const bool is_vector
|
||||
= std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
|
||||
static constexpr const bool is_element = !is_pair && !is_vector;
|
||||
};
|
||||
|
||||
/* Default: is_comparable -> std::false_type */
|
||||
template <typename T, typename SFINAE = void>
|
||||
struct is_comparable : std::false_type {};
|
||||
|
||||
/* For non-map data structures, check whether operator== can be instantiated */
|
||||
template <typename T>
|
||||
struct is_comparable<
|
||||
T,
|
||||
enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>
|
||||
: std::true_type {};
|
||||
|
||||
/* For a vector/map data structure, recursively check the value type
|
||||
(which is std::pair for maps) */
|
||||
template <typename T>
|
||||
struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>>
|
||||
: is_comparable<typename recursive_container_traits<T>::type_to_check_recursively> {};
|
||||
|
||||
template <>
|
||||
struct is_comparable<recursive_bottom> : std::true_type {};
|
||||
|
||||
/* For pairs, recursively check the two data types */
|
||||
template <typename T>
|
||||
struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
|
||||
static constexpr const bool value = is_comparable<typename T::first_type>::value
|
||||
&& is_comparable<typename T::second_type>::value;
|
||||
};
|
||||
|
||||
/* Fallback functions */
|
||||
template <typename, typename, typename... Args>
|
||||
void vector_if_copy_constructible(const Args &...) {}
|
||||
template <typename, typename, typename... Args>
|
||||
void vector_if_equal_operator(const Args &...) {}
|
||||
template <typename, typename, typename... Args>
|
||||
void vector_if_insertion_operator(const Args &...) {}
|
||||
template <typename, typename, typename... Args>
|
||||
void vector_modifiers(const Args &...) {}
|
||||
|
||||
template <typename Vector, typename Class_>
|
||||
void vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {
|
||||
cl.def(init<const Vector &>(), "Copy constructor");
|
||||
}
|
||||
|
||||
template <typename Vector, typename Class_>
|
||||
void vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {
|
||||
using T = typename Vector::value_type;
|
||||
|
||||
cl.def(self == self);
|
||||
cl.def(self != self);
|
||||
|
||||
cl.def(
|
||||
"count",
|
||||
[](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
|
||||
arg("x"),
|
||||
"Return the number of times ``x`` appears in the list");
|
||||
|
||||
cl.def(
|
||||
"remove",
|
||||
[](Vector &v, const T &x) {
|
||||
auto p = std::find(v.begin(), v.end(), x);
|
||||
if (p != v.end()) {
|
||||
v.erase(p);
|
||||
} else {
|
||||
throw value_error();
|
||||
}
|
||||
},
|
||||
arg("x"),
|
||||
"Remove the first item from the list whose value is x. "
|
||||
"It is an error if there is no such item.");
|
||||
|
||||
cl.def(
|
||||
"__contains__",
|
||||
[](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
|
||||
arg("x"),
|
||||
"Return true the container contains ``x``");
|
||||
}
|
||||
|
||||
// Vector modifiers -- requires a copyable vector_type:
|
||||
// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
|
||||
// seems silly to allow deletion but not insertion, so include them here too.)
|
||||
template <typename Vector, typename Class_>
|
||||
void vector_modifiers(
|
||||
enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {
|
||||
using T = typename Vector::value_type;
|
||||
using SizeType = typename Vector::size_type;
|
||||
using DiffType = typename Vector::difference_type;
|
||||
|
||||
auto wrap_i = [](DiffType i, SizeType n) {
|
||||
if (i < 0) {
|
||||
i += n;
|
||||
}
|
||||
if (i < 0 || (SizeType) i >= n) {
|
||||
throw index_error();
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
||||
cl.def(
|
||||
"append",
|
||||
[](Vector &v, const T &value) { v.push_back(value); },
|
||||
arg("x"),
|
||||
"Add an item to the end of the list");
|
||||
|
||||
cl.def(init([](const iterable &it) {
|
||||
auto v = std::unique_ptr<Vector>(new Vector());
|
||||
v->reserve(len_hint(it));
|
||||
for (handle h : it) {
|
||||
v->push_back(h.cast<T>());
|
||||
}
|
||||
return v.release();
|
||||
}));
|
||||
|
||||
cl.def("clear", [](Vector &v) { v.clear(); }, "Clear the contents");
|
||||
|
||||
cl.def(
|
||||
"extend",
|
||||
[](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
|
||||
arg("L"),
|
||||
"Extend the list by appending all the items in the given list");
|
||||
|
||||
cl.def(
|
||||
"extend",
|
||||
[](Vector &v, const iterable &it) {
|
||||
const size_t old_size = v.size();
|
||||
v.reserve(old_size + len_hint(it));
|
||||
try {
|
||||
for (handle h : it) {
|
||||
v.push_back(h.cast<T>());
|
||||
}
|
||||
} catch (const cast_error &) {
|
||||
v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
|
||||
v.end());
|
||||
try {
|
||||
v.shrink_to_fit();
|
||||
} catch (const std::exception &) { // NOLINT(bugprone-empty-catch)
|
||||
// Do nothing
|
||||
}
|
||||
throw;
|
||||
}
|
||||
},
|
||||
arg("L"),
|
||||
"Extend the list by appending all the items in the given list");
|
||||
|
||||
cl.def(
|
||||
"insert",
|
||||
[](Vector &v, DiffType i, const T &x) {
|
||||
// Can't use wrap_i; i == v.size() is OK
|
||||
if (i < 0) {
|
||||
i += v.size();
|
||||
}
|
||||
if (i < 0 || (SizeType) i > v.size()) {
|
||||
throw index_error();
|
||||
}
|
||||
v.insert(v.begin() + i, x);
|
||||
},
|
||||
arg("i"),
|
||||
arg("x"),
|
||||
"Insert an item at a given position.");
|
||||
|
||||
cl.def(
|
||||
"pop",
|
||||
[](Vector &v) {
|
||||
if (v.empty()) {
|
||||
throw index_error();
|
||||
}
|
||||
T t = std::move(v.back());
|
||||
v.pop_back();
|
||||
return t;
|
||||
},
|
||||
"Remove and return the last item");
|
||||
|
||||
cl.def(
|
||||
"pop",
|
||||
[wrap_i](Vector &v, DiffType i) {
|
||||
i = wrap_i(i, v.size());
|
||||
T t = std::move(v[(SizeType) i]);
|
||||
v.erase(std::next(v.begin(), i));
|
||||
return t;
|
||||
},
|
||||
arg("i"),
|
||||
"Remove and return the item at index ``i``");
|
||||
|
||||
cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
|
||||
i = wrap_i(i, v.size());
|
||||
v[(SizeType) i] = t;
|
||||
});
|
||||
|
||||
/// Slicing protocol
|
||||
cl.def(
|
||||
"__getitem__",
|
||||
[](const Vector &v, const slice &slice) -> Vector * {
|
||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||
|
||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
auto *seq = new Vector();
|
||||
seq->reserve((size_t) slicelength);
|
||||
|
||||
for (size_t i = 0; i < slicelength; ++i) {
|
||||
seq->push_back(v[start]);
|
||||
start += step;
|
||||
}
|
||||
return seq;
|
||||
},
|
||||
arg("s"),
|
||||
"Retrieve list elements using a slice object");
|
||||
|
||||
cl.def(
|
||||
"__setitem__",
|
||||
[](Vector &v, const slice &slice, const Vector &value) {
|
||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
if (slicelength != value.size()) {
|
||||
throw std::runtime_error(
|
||||
"Left and right hand size of slice assignment have different sizes!");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < slicelength; ++i) {
|
||||
v[start] = value[i];
|
||||
start += step;
|
||||
}
|
||||
},
|
||||
"Assign list elements using a slice object");
|
||||
|
||||
cl.def(
|
||||
"__delitem__",
|
||||
[wrap_i](Vector &v, DiffType i) {
|
||||
i = wrap_i(i, v.size());
|
||||
v.erase(v.begin() + i);
|
||||
},
|
||||
"Delete the list elements at index ``i``");
|
||||
|
||||
cl.def(
|
||||
"__delitem__",
|
||||
[](Vector &v, const slice &slice) {
|
||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||
|
||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
if (step == 1 && false) {
|
||||
v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
|
||||
} else {
|
||||
for (size_t i = 0; i < slicelength; ++i) {
|
||||
v.erase(v.begin() + DiffType(start));
|
||||
start += step - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
"Delete list elements using a slice object");
|
||||
}
|
||||
|
||||
// If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
|
||||
// we have to access by copying; otherwise we return by reference.
|
||||
template <typename Vector>
|
||||
using vector_needs_copy
|
||||
= negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
|
||||
typename Vector::value_type &>>;
|
||||
|
||||
// The usual case: access and iterate by reference
|
||||
template <typename Vector, typename Class_>
|
||||
void vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {
|
||||
using T = typename Vector::value_type;
|
||||
using SizeType = typename Vector::size_type;
|
||||
using DiffType = typename Vector::difference_type;
|
||||
using ItType = typename Vector::iterator;
|
||||
|
||||
auto wrap_i = [](DiffType i, SizeType n) {
|
||||
if (i < 0) {
|
||||
i += n;
|
||||
}
|
||||
if (i < 0 || (SizeType) i >= n) {
|
||||
throw index_error();
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
||||
cl.def(
|
||||
"__getitem__",
|
||||
[wrap_i](Vector &v, DiffType i) -> T & {
|
||||
i = wrap_i(i, v.size());
|
||||
return v[(SizeType) i];
|
||||
},
|
||||
return_value_policy::reference_internal // ref + keepalive
|
||||
);
|
||||
|
||||
cl.def(
|
||||
"__iter__",
|
||||
[](Vector &v) {
|
||||
return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
|
||||
v.begin(), v.end());
|
||||
},
|
||||
keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
|
||||
);
|
||||
}
|
||||
|
||||
// The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
|
||||
template <typename Vector, typename Class_>
|
||||
void vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {
|
||||
using T = typename Vector::value_type;
|
||||
using SizeType = typename Vector::size_type;
|
||||
using DiffType = typename Vector::difference_type;
|
||||
using ItType = typename Vector::iterator;
|
||||
cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
|
||||
if (i < 0) {
|
||||
i += v.size();
|
||||
if (i < 0) {
|
||||
throw index_error();
|
||||
}
|
||||
}
|
||||
auto i_st = static_cast<SizeType>(i);
|
||||
if (i_st >= v.size()) {
|
||||
throw index_error();
|
||||
}
|
||||
return v[i_st];
|
||||
});
|
||||
|
||||
cl.def(
|
||||
"__iter__",
|
||||
[](Vector &v) {
|
||||
return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
|
||||
},
|
||||
keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Vector, typename Class_>
|
||||
auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
|
||||
-> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
|
||||
void()) {
|
||||
using size_type = typename Vector::size_type;
|
||||
|
||||
cl.def(
|
||||
"__repr__",
|
||||
[name](Vector &v) {
|
||||
std::ostringstream s;
|
||||
s << name << '[';
|
||||
for (size_type i = 0; i < v.size(); ++i) {
|
||||
s << v[i];
|
||||
if (i != v.size() - 1) {
|
||||
s << ", ";
|
||||
}
|
||||
}
|
||||
s << ']';
|
||||
return s.str();
|
||||
},
|
||||
"Return the canonical string representation of this list.");
|
||||
}
|
||||
|
||||
// Provide the buffer interface for vectors if we have data() and we have a format for it
|
||||
// GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
|
||||
// is insufficient, we need to check it returns an appropriate pointer
|
||||
template <typename Vector, typename = void>
|
||||
struct vector_has_data_and_format : std::false_type {};
|
||||
template <typename Vector>
|
||||
struct vector_has_data_and_format<
|
||||
Vector,
|
||||
enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
|
||||
std::declval<Vector>().data()),
|
||||
typename Vector::value_type *>::value>> : std::true_type {};
|
||||
|
||||
// [workaround(intel)] Separate function required here
|
||||
// Workaround as the Intel compiler does not compile the enable_if_t part below
|
||||
// (tested with icc (ICC) 2021.1 Beta 20200827)
|
||||
template <typename... Args>
|
||||
constexpr bool args_any_are_buffer() {
|
||||
return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
|
||||
}
|
||||
|
||||
// [workaround(intel)] Separate function required here
|
||||
// [workaround(msvc)] Can't use constexpr bool in return type
|
||||
|
||||
// Add the buffer interface to a vector
|
||||
template <typename Vector, typename Class_, typename... Args>
|
||||
void vector_buffer_impl(Class_ &cl, std::true_type) {
|
||||
using T = typename Vector::value_type;
|
||||
|
||||
static_assert(vector_has_data_and_format<Vector>::value,
|
||||
"There is not an appropriate format descriptor for this vector");
|
||||
|
||||
// numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
|
||||
// at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
|
||||
format_descriptor<T>::format();
|
||||
|
||||
cl.def_buffer([](Vector &v) -> buffer_info {
|
||||
return buffer_info(v.data(),
|
||||
static_cast<ssize_t>(sizeof(T)),
|
||||
format_descriptor<T>::format(),
|
||||
1,
|
||||
{v.size()},
|
||||
{sizeof(T)});
|
||||
});
|
||||
|
||||
cl.def(init([](const buffer &buf) {
|
||||
auto info = buf.request();
|
||||
if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
|
||||
throw type_error("Only valid 1D buffers can be copied to a vector");
|
||||
}
|
||||
if (!detail::compare_buffer_info<T>::compare(info)
|
||||
|| (ssize_t) sizeof(T) != info.itemsize) {
|
||||
throw type_error("Format mismatch (Python: " + info.format
|
||||
+ " C++: " + format_descriptor<T>::format() + ")");
|
||||
}
|
||||
|
||||
T *p = static_cast<T *>(info.ptr);
|
||||
ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
|
||||
T *end = p + info.shape[0] * step;
|
||||
if (step == 1) {
|
||||
return Vector(p, end);
|
||||
}
|
||||
Vector vec;
|
||||
vec.reserve((size_t) info.shape[0]);
|
||||
for (; p != end; p += step) {
|
||||
vec.push_back(*p);
|
||||
}
|
||||
return vec;
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename Vector, typename Class_, typename... Args>
|
||||
void vector_buffer_impl(Class_ &, std::false_type) {}
|
||||
|
||||
template <typename Vector, typename Class_, typename... Args>
|
||||
void vector_buffer(Class_ &cl) {
|
||||
vector_buffer_impl<Vector, Class_, Args...>(
|
||||
cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
//
|
||||
// std::vector
|
||||
//
|
||||
template <typename Vector, typename holder_type = default_holder_type<Vector>, typename... Args>
|
||||
class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
|
||||
using Class_ = class_<Vector, holder_type>;
|
||||
|
||||
// If the value_type is unregistered (e.g. a converting type) or is itself registered
|
||||
// module-local then make the vector binding module-local as well:
|
||||
using vtype = typename Vector::value_type;
|
||||
auto *vtype_info = detail::get_type_info(typeid(vtype));
|
||||
bool local = !vtype_info || vtype_info->module_local;
|
||||
|
||||
Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
|
||||
|
||||
// Declare the buffer interface if a buffer_protocol() is passed in
|
||||
detail::vector_buffer<Vector, Class_, Args...>(cl);
|
||||
|
||||
cl.def(init<>());
|
||||
|
||||
// Register copy constructor (if possible)
|
||||
detail::vector_if_copy_constructible<Vector, Class_>(cl);
|
||||
|
||||
// Register comparison-related operators and functions (if possible)
|
||||
detail::vector_if_equal_operator<Vector, Class_>(cl);
|
||||
|
||||
// Register stream insertion operator (if possible)
|
||||
detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
|
||||
|
||||
// Modifiers require copyable vector value type
|
||||
detail::vector_modifiers<Vector, Class_>(cl);
|
||||
|
||||
// Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
|
||||
detail::vector_accessor<Vector, Class_>(cl);
|
||||
|
||||
cl.def(
|
||||
"__bool__",
|
||||
[](const Vector &v) -> bool { return !v.empty(); },
|
||||
"Check whether the list is nonempty");
|
||||
|
||||
cl.def("__len__", [](const Vector &vec) { return vec.size(); });
|
||||
|
||||
#if 0
|
||||
// C++ style functions deprecated, leaving it here as an example
|
||||
cl.def(init<size_type>());
|
||||
|
||||
cl.def("resize",
|
||||
(void (Vector::*) (size_type count)) & Vector::resize,
|
||||
"changes the number of elements stored");
|
||||
|
||||
cl.def("erase",
|
||||
[](Vector &v, SizeType i) {
|
||||
if (i >= v.size())
|
||||
throw index_error();
|
||||
v.erase(v.begin() + i);
|
||||
}, "erases element at index ``i``");
|
||||
|
||||
cl.def("empty", &Vector::empty, "checks whether the container is empty");
|
||||
cl.def("size", &Vector::size, "returns the number of elements");
|
||||
cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
|
||||
cl.def("pop_back", &Vector::pop_back, "removes the last element");
|
||||
|
||||
cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements");
|
||||
cl.def("reserve", &Vector::reserve, "reserves storage");
|
||||
cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage");
|
||||
cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
|
||||
|
||||
cl.def("clear", &Vector::clear, "clears the contents");
|
||||
cl.def("swap", &Vector::swap, "swaps the contents");
|
||||
|
||||
cl.def("front", [](Vector &v) {
|
||||
if (v.size()) return v.front();
|
||||
else throw index_error();
|
||||
}, "access the first element");
|
||||
|
||||
cl.def("back", [](Vector &v) {
|
||||
if (v.size()) return v.back();
|
||||
else throw index_error();
|
||||
}, "access the last element ");
|
||||
|
||||
#endif
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
//
|
||||
// std::map, std::unordered_map
|
||||
//
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
/* Fallback functions */
|
||||
template <typename, typename, typename... Args>
|
||||
void map_if_insertion_operator(const Args &...) {}
|
||||
template <typename, typename, typename... Args>
|
||||
void map_assignment(const Args &...) {}
|
||||
|
||||
// Map assignment when copy-assignable: just copy the value
|
||||
template <typename Map, typename Class_>
|
||||
void map_assignment(
|
||||
enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {
|
||||
using KeyType = typename Map::key_type;
|
||||
using MappedType = typename Map::mapped_type;
|
||||
|
||||
cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
|
||||
auto it = m.find(k);
|
||||
if (it != m.end()) {
|
||||
it->second = v;
|
||||
} else {
|
||||
m.emplace(k, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Not copy-assignable, but still copy-constructible: we can update the value by erasing and
|
||||
// reinserting
|
||||
template <typename Map, typename Class_>
|
||||
void map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value
|
||||
&& is_copy_constructible<typename Map::mapped_type>::value,
|
||||
Class_> &cl) {
|
||||
using KeyType = typename Map::key_type;
|
||||
using MappedType = typename Map::mapped_type;
|
||||
|
||||
cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
|
||||
// We can't use m[k] = v; because value type might not be default constructable
|
||||
auto r = m.emplace(k, v);
|
||||
if (!r.second) {
|
||||
// value type is not copy assignable so the only way to insert it is to erase it
|
||||
// first...
|
||||
m.erase(r.first);
|
||||
m.emplace(k, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Map, typename Class_>
|
||||
auto map_if_insertion_operator(Class_ &cl, std::string const &name)
|
||||
-> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
|
||||
<< std::declval<typename Map::mapped_type>(),
|
||||
void()) {
|
||||
|
||||
cl.def(
|
||||
"__repr__",
|
||||
[name](Map &m) {
|
||||
std::ostringstream s;
|
||||
s << name << '{';
|
||||
bool f = false;
|
||||
for (auto const &kv : m) {
|
||||
if (f) {
|
||||
s << ", ";
|
||||
}
|
||||
s << kv.first << ": " << kv.second;
|
||||
f = true;
|
||||
}
|
||||
s << '}';
|
||||
return s.str();
|
||||
},
|
||||
"Return the canonical string representation of this map.");
|
||||
}
|
||||
|
||||
struct keys_view {
|
||||
virtual size_t len() = 0;
|
||||
virtual iterator iter() = 0;
|
||||
virtual bool contains(const handle &k) = 0;
|
||||
virtual ~keys_view() = default;
|
||||
};
|
||||
|
||||
struct values_view {
|
||||
virtual size_t len() = 0;
|
||||
virtual iterator iter() = 0;
|
||||
virtual ~values_view() = default;
|
||||
};
|
||||
|
||||
struct items_view {
|
||||
virtual size_t len() = 0;
|
||||
virtual iterator iter() = 0;
|
||||
virtual ~items_view() = default;
|
||||
};
|
||||
|
||||
template <typename Map>
|
||||
struct KeysViewImpl : public detail::keys_view {
|
||||
explicit KeysViewImpl(Map &map) : map(map) {}
|
||||
size_t len() override { return map.size(); }
|
||||
iterator iter() override { return make_key_iterator(map.begin(), map.end()); }
|
||||
bool contains(const handle &k) override {
|
||||
try {
|
||||
return map.find(k.template cast<typename Map::key_type>()) != map.end();
|
||||
} catch (const cast_error &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Map ↦
|
||||
};
|
||||
|
||||
template <typename Map>
|
||||
struct ValuesViewImpl : public detail::values_view {
|
||||
explicit ValuesViewImpl(Map &map) : map(map) {}
|
||||
size_t len() override { return map.size(); }
|
||||
iterator iter() override { return make_value_iterator(map.begin(), map.end()); }
|
||||
Map ↦
|
||||
};
|
||||
|
||||
template <typename Map>
|
||||
struct ItemsViewImpl : public detail::items_view {
|
||||
explicit ItemsViewImpl(Map &map) : map(map) {}
|
||||
size_t len() override { return map.size(); }
|
||||
iterator iter() override { return make_iterator(map.begin(), map.end()); }
|
||||
Map ↦
|
||||
};
|
||||
|
||||
inline str format_message_key_error_key_object(handle py_key) {
|
||||
str message = "pybind11::bind_map key";
|
||||
if (!py_key) {
|
||||
return message;
|
||||
}
|
||||
try {
|
||||
message = str(py_key);
|
||||
} catch (const std::exception &) {
|
||||
try {
|
||||
message = repr(py_key);
|
||||
} catch (const std::exception &) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
const ssize_t cut_length = 100;
|
||||
if (len(message) > 2 * cut_length + 3) {
|
||||
return str(message[slice(0, cut_length, 1)]) + str("✄✄✄")
|
||||
+ str(message[slice(-cut_length, static_cast<ssize_t>(len(message)), 1)]);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
str format_message_key_error(const KeyType &key) {
|
||||
object py_key;
|
||||
try {
|
||||
py_key = cast(key);
|
||||
} catch (const std::exception &) {
|
||||
do { // Trick to avoid "empty catch" warning/error.
|
||||
} while (false);
|
||||
}
|
||||
return format_message_key_error_key_object(py_key);
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
template <typename Map, typename holder_type = default_holder_type<Map>, typename... Args>
|
||||
class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
|
||||
using KeyType = typename Map::key_type;
|
||||
using MappedType = typename Map::mapped_type;
|
||||
using KeysView = detail::keys_view;
|
||||
using ValuesView = detail::values_view;
|
||||
using ItemsView = detail::items_view;
|
||||
using Class_ = class_<Map, holder_type>;
|
||||
|
||||
// If either type is a non-module-local bound type then make the map binding non-local as well;
|
||||
// otherwise (e.g. both types are either module-local or converting) the map will be
|
||||
// module-local.
|
||||
auto *tinfo = detail::get_type_info(typeid(MappedType));
|
||||
bool local = !tinfo || tinfo->module_local;
|
||||
if (local) {
|
||||
tinfo = detail::get_type_info(typeid(KeyType));
|
||||
local = !tinfo || tinfo->module_local;
|
||||
}
|
||||
|
||||
Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
|
||||
|
||||
// Wrap KeysView if it wasn't already wrapped
|
||||
if (!detail::get_type_info(typeid(KeysView))) {
|
||||
class_<KeysView> keys_view(scope, "KeysView", pybind11::module_local(local));
|
||||
keys_view.def("__len__", &KeysView::len);
|
||||
keys_view.def("__iter__",
|
||||
&KeysView::iter,
|
||||
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
||||
);
|
||||
keys_view.def("__contains__", &KeysView::contains);
|
||||
}
|
||||
// Similarly for ValuesView:
|
||||
if (!detail::get_type_info(typeid(ValuesView))) {
|
||||
class_<ValuesView> values_view(scope, "ValuesView", pybind11::module_local(local));
|
||||
values_view.def("__len__", &ValuesView::len);
|
||||
values_view.def("__iter__",
|
||||
&ValuesView::iter,
|
||||
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
||||
);
|
||||
}
|
||||
// Similarly for ItemsView:
|
||||
if (!detail::get_type_info(typeid(ItemsView))) {
|
||||
class_<ItemsView> items_view(scope, "ItemsView", pybind11::module_local(local));
|
||||
items_view.def("__len__", &ItemsView::len);
|
||||
items_view.def("__iter__",
|
||||
&ItemsView::iter,
|
||||
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
||||
);
|
||||
}
|
||||
|
||||
cl.def(init<>());
|
||||
|
||||
// Register stream insertion operator (if possible)
|
||||
detail::map_if_insertion_operator<Map, Class_>(cl, name);
|
||||
|
||||
cl.def(
|
||||
"__bool__",
|
||||
[](const Map &m) -> bool { return !m.empty(); },
|
||||
"Check whether the map is nonempty");
|
||||
|
||||
cl.def(
|
||||
"__iter__",
|
||||
[](Map &m) { return make_key_iterator(m.begin(), m.end()); },
|
||||
keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
|
||||
);
|
||||
|
||||
cl.def(
|
||||
"keys",
|
||||
[](Map &m) { return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map>(m)); },
|
||||
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
||||
);
|
||||
|
||||
cl.def(
|
||||
"values",
|
||||
[](Map &m) { return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map>(m)); },
|
||||
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
||||
);
|
||||
|
||||
cl.def(
|
||||
"items",
|
||||
[](Map &m) { return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map>(m)); },
|
||||
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
||||
);
|
||||
|
||||
cl.def(
|
||||
"__getitem__",
|
||||
[](Map &m, const KeyType &k) -> MappedType & {
|
||||
auto it = m.find(k);
|
||||
if (it == m.end()) {
|
||||
set_error(PyExc_KeyError, detail::format_message_key_error(k));
|
||||
throw error_already_set();
|
||||
}
|
||||
return it->second;
|
||||
},
|
||||
return_value_policy::reference_internal // ref + keepalive
|
||||
);
|
||||
|
||||
cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
|
||||
auto it = m.find(k);
|
||||
if (it == m.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Fallback for when the object is not of the key type
|
||||
cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
|
||||
|
||||
// Assignment provided only if the type is copyable
|
||||
detail::map_assignment<Map, Class_>(cl);
|
||||
|
||||
cl.def("__delitem__", [](Map &m, const KeyType &k) {
|
||||
auto it = m.find(k);
|
||||
if (it == m.end()) {
|
||||
set_error(PyExc_KeyError, detail::format_message_key_error(k));
|
||||
throw error_already_set();
|
||||
}
|
||||
m.erase(it);
|
||||
});
|
||||
|
||||
// Always use a lambda in case of `using` declaration
|
||||
cl.def("__len__", [](const Map &m) { return m.size(); });
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
299
deps_src/pybind11/include/pybind11/subinterpreter.h
Normal file
299
deps_src/pybind11/include/pybind11/subinterpreter.h
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
pybind11/subinterpreter.h: Support for creating and using subinterpreters
|
||||
|
||||
Copyright (c) 2025 The Pybind Development Team.
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "detail/internals.h"
|
||||
#include "gil.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
||||
# error "This platform does not support subinterpreters, do not include this file."
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
inline PyInterpreterState *get_interpreter_state_unchecked() {
|
||||
auto cur_tstate = get_thread_state_unchecked();
|
||||
if (cur_tstate)
|
||||
return cur_tstate->interp;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
class subinterpreter;
|
||||
|
||||
/// Activate the subinterpreter and acquire its GIL, while also releasing any GIL and interpreter
|
||||
/// currently held. Upon exiting the scope, the previous subinterpreter (if any) and its
|
||||
/// associated GIL are restored to their state as they were before the scope was entered.
|
||||
class subinterpreter_scoped_activate {
|
||||
public:
|
||||
explicit subinterpreter_scoped_activate(subinterpreter const &si);
|
||||
~subinterpreter_scoped_activate();
|
||||
|
||||
subinterpreter_scoped_activate(subinterpreter_scoped_activate &&) = delete;
|
||||
subinterpreter_scoped_activate(subinterpreter_scoped_activate const &) = delete;
|
||||
subinterpreter_scoped_activate &operator=(subinterpreter_scoped_activate &) = delete;
|
||||
subinterpreter_scoped_activate &operator=(subinterpreter_scoped_activate const &) = delete;
|
||||
|
||||
private:
|
||||
PyThreadState *old_tstate_ = nullptr;
|
||||
PyThreadState *tstate_ = nullptr;
|
||||
PyGILState_STATE gil_state_;
|
||||
bool simple_gil_ = false;
|
||||
};
|
||||
|
||||
/// Holds a Python subinterpreter instance
|
||||
class subinterpreter {
|
||||
public:
|
||||
/// empty/unusable, but move-assignable. use create() to create a subinterpreter.
|
||||
subinterpreter() = default;
|
||||
|
||||
subinterpreter(subinterpreter const ©) = delete;
|
||||
subinterpreter &operator=(subinterpreter const ©) = delete;
|
||||
|
||||
subinterpreter(subinterpreter &&old) noexcept
|
||||
: istate_(old.istate_), creation_tstate_(old.creation_tstate_) {
|
||||
old.istate_ = nullptr;
|
||||
old.creation_tstate_ = nullptr;
|
||||
}
|
||||
|
||||
subinterpreter &operator=(subinterpreter &&old) noexcept {
|
||||
std::swap(old.istate_, istate_);
|
||||
std::swap(old.creation_tstate_, creation_tstate_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Create a new subinterpreter with the specified configuration
|
||||
/// @note This function acquires (and then releases) the main interpreter GIL, but the main
|
||||
/// interpreter and its GIL are not required to be held prior to calling this function.
|
||||
static inline subinterpreter create(PyInterpreterConfig const &cfg) {
|
||||
|
||||
error_scope err_scope;
|
||||
subinterpreter result;
|
||||
{
|
||||
// we must hold the main GIL in order to create a subinterpreter
|
||||
subinterpreter_scoped_activate main_guard(main());
|
||||
|
||||
auto prev_tstate = PyThreadState_Get();
|
||||
|
||||
PyStatus status;
|
||||
|
||||
{
|
||||
/*
|
||||
Several internal CPython modules are lacking proper subinterpreter support in 3.12
|
||||
even though it is "stable" in that version. This most commonly seems to cause
|
||||
crashes when two interpreters concurrently initialize, which imports several things
|
||||
(like builtins, unicode, codecs).
|
||||
*/
|
||||
#if PY_VERSION_HEX < 0x030D0000 && defined(Py_MOD_PER_INTERPRETER_GIL_SUPPORTED)
|
||||
static std::mutex one_at_a_time;
|
||||
std::lock_guard<std::mutex> guard(one_at_a_time);
|
||||
#endif
|
||||
status = Py_NewInterpreterFromConfig(&result.creation_tstate_, &cfg);
|
||||
}
|
||||
|
||||
// this doesn't raise a normal Python exception, it provides an exit() status code.
|
||||
if (PyStatus_Exception(status)) {
|
||||
pybind11_fail("failed to create new sub-interpreter");
|
||||
}
|
||||
|
||||
// upon success, the new interpreter is activated in this thread
|
||||
result.istate_ = result.creation_tstate_->interp;
|
||||
detail::get_num_interpreters_seen() += 1; // there are now many interpreters
|
||||
detail::get_internals(); // initialize internals.tstate, amongst other things...
|
||||
|
||||
// In 3.13+ this state should be deleted right away, and the memory will be reused for
|
||||
// the next threadstate on this interpreter. However, on 3.12 we cannot do that, we
|
||||
// must keep it around (but not use it) ... see destructor.
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
PyThreadState_Clear(result.creation_tstate_);
|
||||
PyThreadState_DeleteCurrent();
|
||||
#endif
|
||||
|
||||
// we have to switch back to main, and then the scopes will handle cleanup
|
||||
PyThreadState_Swap(prev_tstate);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Calls create() with a default configuration of an isolated interpreter that disallows fork,
|
||||
/// exec, and Python threads.
|
||||
static inline subinterpreter create() {
|
||||
// same as the default config in the python docs
|
||||
PyInterpreterConfig cfg;
|
||||
std::memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.allow_threads = 1;
|
||||
cfg.check_multi_interp_extensions = 1;
|
||||
cfg.gil = PyInterpreterConfig_OWN_GIL;
|
||||
return create(cfg);
|
||||
}
|
||||
|
||||
~subinterpreter() {
|
||||
if (!creation_tstate_) {
|
||||
// non-owning wrapper, do nothing.
|
||||
return;
|
||||
}
|
||||
|
||||
PyThreadState *destroy_tstate;
|
||||
PyThreadState *old_tstate;
|
||||
|
||||
// Python 3.12 requires us to keep the original PyThreadState alive until we are ready to
|
||||
// destroy the interpreter. We prefer to use that to destroy the interpreter.
|
||||
#if PY_VERSION_HEX < 0x030D0000
|
||||
// The tstate passed to Py_EndInterpreter MUST have been created on the current OS thread.
|
||||
bool same_thread = false;
|
||||
# ifdef PY_HAVE_THREAD_NATIVE_ID
|
||||
same_thread = PyThread_get_thread_native_id() == creation_tstate_->native_thread_id;
|
||||
# endif
|
||||
if (same_thread) {
|
||||
// OK it is safe to use the creation state here
|
||||
destroy_tstate = creation_tstate_;
|
||||
old_tstate = PyThreadState_Swap(destroy_tstate);
|
||||
} else {
|
||||
// We have to make a new tstate on this thread and use that.
|
||||
destroy_tstate = PyThreadState_New(istate_);
|
||||
old_tstate = PyThreadState_Swap(destroy_tstate);
|
||||
|
||||
// We can use the one we just created, so we must delete the creation state.
|
||||
PyThreadState_Clear(creation_tstate_);
|
||||
PyThreadState_Delete(creation_tstate_);
|
||||
}
|
||||
#else
|
||||
destroy_tstate = PyThreadState_New(istate_);
|
||||
old_tstate = PyThreadState_Swap(destroy_tstate);
|
||||
#endif
|
||||
|
||||
bool switch_back = old_tstate && old_tstate->interp != istate_;
|
||||
|
||||
// Internals always exists in the subinterpreter, this class enforces it when it creates
|
||||
// the subinterpreter. Even if it didn't, this only creates the pointer-to-pointer, not the
|
||||
// internals themselves.
|
||||
detail::get_internals_pp_manager().get_pp();
|
||||
detail::get_local_internals_pp_manager().get_pp();
|
||||
|
||||
// End it
|
||||
Py_EndInterpreter(destroy_tstate);
|
||||
|
||||
// It's possible for the internals to be created during endinterpreter (e.g. if a
|
||||
// py::capsule calls `get_internals()` during destruction), so we destroy afterward.
|
||||
detail::get_internals_pp_manager().destroy();
|
||||
detail::get_local_internals_pp_manager().destroy();
|
||||
|
||||
// switch back to the old tstate and old GIL (if there was one)
|
||||
if (switch_back)
|
||||
PyThreadState_Swap(old_tstate);
|
||||
}
|
||||
|
||||
/// Get a handle to the main interpreter that can be used with subinterpreter_scoped_activate
|
||||
/// Note that destructing the handle is a noop, the main interpreter can only be ended by
|
||||
/// py::finalize_interpreter()
|
||||
static subinterpreter main() {
|
||||
subinterpreter m;
|
||||
m.istate_ = PyInterpreterState_Main();
|
||||
m.disarm(); // make destruct a noop
|
||||
return m;
|
||||
}
|
||||
|
||||
/// Get a non-owning wrapper of the currently active interpreter (if any)
|
||||
static subinterpreter current() {
|
||||
subinterpreter c;
|
||||
c.istate_ = detail::get_interpreter_state_unchecked();
|
||||
c.disarm(); // make destruct a noop, we don't own this...
|
||||
return c;
|
||||
}
|
||||
|
||||
/// Get the numerical identifier for the sub-interpreter
|
||||
int64_t id() const {
|
||||
if (istate_ != nullptr)
|
||||
return PyInterpreterState_GetID(istate_);
|
||||
else
|
||||
return -1; // CPython uses one-up numbers from 0, so negative should be safe to return
|
||||
// here.
|
||||
}
|
||||
|
||||
/// Get the interpreter's state dict. This interpreter's GIL must be held before calling!
|
||||
dict state_dict() { return reinterpret_borrow<dict>(PyInterpreterState_GetDict(istate_)); }
|
||||
|
||||
/// abandon cleanup of this subinterpreter (leak it). this might be needed during
|
||||
/// finalization...
|
||||
void disarm() { creation_tstate_ = nullptr; }
|
||||
|
||||
/// An empty wrapper cannot be activated
|
||||
bool empty() const { return istate_ == nullptr; }
|
||||
|
||||
/// Is this wrapper non-empty
|
||||
explicit operator bool() const { return !empty(); }
|
||||
|
||||
private:
|
||||
friend class subinterpreter_scoped_activate;
|
||||
PyInterpreterState *istate_ = nullptr;
|
||||
PyThreadState *creation_tstate_ = nullptr;
|
||||
};
|
||||
|
||||
class scoped_subinterpreter {
|
||||
public:
|
||||
scoped_subinterpreter() : si_(subinterpreter::create()), scope_(si_) {}
|
||||
|
||||
explicit scoped_subinterpreter(PyInterpreterConfig const &cfg)
|
||||
: si_(subinterpreter::create(cfg)), scope_(si_) {}
|
||||
|
||||
private:
|
||||
subinterpreter si_;
|
||||
subinterpreter_scoped_activate scope_;
|
||||
};
|
||||
|
||||
inline subinterpreter_scoped_activate::subinterpreter_scoped_activate(subinterpreter const &si) {
|
||||
if (!si.istate_) {
|
||||
pybind11_fail("null subinterpreter");
|
||||
}
|
||||
|
||||
if (detail::get_interpreter_state_unchecked() == si.istate_) {
|
||||
// we are already on this interpreter, make sure we hold the GIL
|
||||
simple_gil_ = true;
|
||||
gil_state_ = PyGILState_Ensure();
|
||||
return;
|
||||
}
|
||||
|
||||
// we can't really interact with the interpreter at all until we switch to it
|
||||
// not even to, for example, look in its state dict or touch its internals
|
||||
tstate_ = PyThreadState_New(si.istate_);
|
||||
|
||||
// make the interpreter active and acquire the GIL
|
||||
old_tstate_ = PyThreadState_Swap(tstate_);
|
||||
|
||||
// save this in internals for scoped_gil calls
|
||||
detail::get_internals().tstate = tstate_;
|
||||
}
|
||||
|
||||
inline subinterpreter_scoped_activate::~subinterpreter_scoped_activate() {
|
||||
if (simple_gil_) {
|
||||
// We were on this interpreter already, so just make sure the GIL goes back as it was
|
||||
PyGILState_Release(gil_state_);
|
||||
} else {
|
||||
if (tstate_) {
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (detail::get_thread_state_unchecked() != tstate_) {
|
||||
pybind11_fail("~subinterpreter_scoped_activate: thread state must be current!");
|
||||
}
|
||||
#endif
|
||||
detail::get_internals().tstate.reset();
|
||||
PyThreadState_Clear(tstate_);
|
||||
PyThreadState_DeleteCurrent();
|
||||
}
|
||||
|
||||
// Go back the previous interpreter (if any) and acquire THAT gil
|
||||
PyThreadState_Swap(old_tstate_);
|
||||
}
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2021 The Pybind Development Team.
|
||||
// All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "detail/using_smart_holder.h"
|
||||
#include "detail/value_and_holder.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
// PYBIND11:REMINDER: Needs refactoring of existing pybind11 code.
|
||||
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo);
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
// The original core idea for this struct goes back to PyCLIF:
|
||||
// https://github.com/google/clif/blob/07f95d7e69dca2fcf7022978a55ef3acff506c19/clif/python/runtime.cc#L37
|
||||
// URL provided here mainly to give proper credit.
|
||||
struct trampoline_self_life_support {
|
||||
// NOTE: PYBIND11_INTERNALS_VERSION needs to be bumped if changes are made to this struct.
|
||||
detail::value_and_holder v_h;
|
||||
|
||||
trampoline_self_life_support() = default;
|
||||
|
||||
void activate_life_support(const detail::value_and_holder &v_h_) {
|
||||
Py_INCREF((PyObject *) v_h_.inst);
|
||||
v_h = v_h_;
|
||||
}
|
||||
|
||||
void deactivate_life_support() {
|
||||
Py_DECREF((PyObject *) v_h.inst);
|
||||
v_h = detail::value_and_holder();
|
||||
}
|
||||
|
||||
~trampoline_self_life_support() {
|
||||
if (v_h.inst != nullptr && v_h.vh != nullptr) {
|
||||
void *value_void_ptr = v_h.value_ptr();
|
||||
if (value_void_ptr != nullptr) {
|
||||
PyGILState_STATE threadstate = PyGILState_Ensure();
|
||||
v_h.value_ptr() = nullptr;
|
||||
v_h.holder<smart_holder>().release_disowned();
|
||||
detail::deregister_instance(v_h.inst, value_void_ptr, v_h.type);
|
||||
Py_DECREF((PyObject *) v_h.inst); // Must be after deregister.
|
||||
PyGILState_Release(threadstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For the next two, the default implementations generate undefined behavior (ASAN failures
|
||||
// manually verified). The reason is that v_h needs to be kept default-initialized.
|
||||
trampoline_self_life_support(const trampoline_self_life_support &) {}
|
||||
trampoline_self_life_support(trampoline_self_life_support &&) noexcept {}
|
||||
|
||||
// These should never be needed (please provide test cases if you think they are).
|
||||
trampoline_self_life_support &operator=(const trampoline_self_life_support &) = delete;
|
||||
trampoline_self_life_support &operator=(trampoline_self_life_support &&) = delete;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
using get_trampoline_self_life_support_fn = trampoline_self_life_support *(*) (void *);
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2023 The pybind Community.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "detail/descr.h"
|
||||
#include "cast.h"
|
||||
#include "pytypes.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <>
|
||||
class type_caster<PyObject> {
|
||||
public:
|
||||
static constexpr auto name = const_name("object"); // See discussion under PR #4601.
|
||||
|
||||
// This overload is purely to guard against accidents.
|
||||
template <typename T,
|
||||
detail::enable_if_t<!is_same_ignoring_cvref<T, PyObject *>::value, int> = 0>
|
||||
static handle cast(T &&, return_value_policy, handle /*parent*/) {
|
||||
static_assert(is_same_ignoring_cvref<T, PyObject *>::value,
|
||||
"Invalid C++ type T for to-Python conversion (type_caster<PyObject>).");
|
||||
return nullptr; // Unreachable.
|
||||
}
|
||||
|
||||
static handle cast(PyObject *src, return_value_policy policy, handle /*parent*/) {
|
||||
if (src == nullptr) {
|
||||
throw error_already_set();
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
raise_from(PyExc_SystemError, "src != nullptr but PyErr_Occurred()");
|
||||
throw error_already_set();
|
||||
}
|
||||
if (policy == return_value_policy::take_ownership) {
|
||||
return src;
|
||||
}
|
||||
if (policy == return_value_policy::reference
|
||||
|| policy == return_value_policy::automatic_reference) {
|
||||
return handle(src).inc_ref();
|
||||
}
|
||||
pybind11_fail("type_caster<PyObject>::cast(): unsupported return_value_policy: "
|
||||
+ std::to_string(static_cast<int>(policy)));
|
||||
}
|
||||
|
||||
bool load(handle src, bool) {
|
||||
value = reinterpret_borrow<object>(src);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using cast_op_type = PyObject *;
|
||||
|
||||
explicit operator PyObject *() { return value.ptr(); }
|
||||
|
||||
private:
|
||||
object value;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
298
deps_src/pybind11/include/pybind11/typing.h
Normal file
298
deps_src/pybind11/include/pybind11/typing.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
pybind11/typing.h: Convenience wrapper classes for basic Python types
|
||||
with more explicit annotations.
|
||||
|
||||
Copyright (c) 2023 Dustin Spicuzza <dustin@virtualroadside.com>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "cast.h"
|
||||
#include "pytypes.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(__cpp_nontype_template_args) && __cpp_nontype_template_args >= 201911L
|
||||
# define PYBIND11_TYPING_H_HAS_STRING_LITERAL
|
||||
# include <numeric>
|
||||
# include <ranges>
|
||||
# include <string_view>
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(typing)
|
||||
|
||||
/*
|
||||
The following types can be used to direct pybind11-generated docstrings
|
||||
to have have more explicit types (e.g., `list[str]` instead of `list`).
|
||||
Just use these in place of existing types.
|
||||
|
||||
There is no additional enforcement of types at runtime.
|
||||
*/
|
||||
|
||||
template <typename... Types>
|
||||
class Tuple : public tuple {
|
||||
using tuple::tuple;
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class Dict : public dict {
|
||||
using dict::dict;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class List : public list {
|
||||
using list::list;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Set : public set {
|
||||
using set::set;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Iterable : public iterable {
|
||||
using iterable::iterable;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Iterator : public iterator {
|
||||
using iterator::iterator;
|
||||
};
|
||||
|
||||
template <typename Signature>
|
||||
class Callable;
|
||||
|
||||
template <typename Return, typename... Args>
|
||||
class Callable<Return(Args...)> : public function {
|
||||
using function::function;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Type : public type {
|
||||
using type::type;
|
||||
};
|
||||
|
||||
template <typename... Types>
|
||||
class Union : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(Union, object, PyObject_Type)
|
||||
using object::object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Optional : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(Optional, object, PyObject_Type)
|
||||
using object::object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Final : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(Final, object, PyObject_Type)
|
||||
using object::object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ClassVar : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(ClassVar, object, PyObject_Type)
|
||||
using object::object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypeGuard : public bool_ {
|
||||
using bool_::bool_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypeIs : public bool_ {
|
||||
using bool_::bool_;
|
||||
};
|
||||
|
||||
class NoReturn : public none {
|
||||
using none::none;
|
||||
};
|
||||
|
||||
class Never : public none {
|
||||
using none::none;
|
||||
};
|
||||
|
||||
#if defined(PYBIND11_TYPING_H_HAS_STRING_LITERAL)
|
||||
template <size_t N>
|
||||
struct StringLiteral {
|
||||
constexpr StringLiteral(const char (&str)[N]) { std::copy_n(str, N, name); }
|
||||
char name[N];
|
||||
};
|
||||
|
||||
template <StringLiteral... StrLits>
|
||||
class Literal : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(Literal, object, PyObject_Type)
|
||||
};
|
||||
|
||||
// Example syntax for creating a TypeVar.
|
||||
// typedef typing::TypeVar<"T"> TypeVarT;
|
||||
template <StringLiteral>
|
||||
class TypeVar : public object {
|
||||
PYBIND11_OBJECT_DEFAULT(TypeVar, object, PyObject_Type)
|
||||
using object::object;
|
||||
};
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(typing)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename... Types>
|
||||
struct handle_type_name<typing::Tuple<Types...>> {
|
||||
static constexpr auto name = const_name("tuple[")
|
||||
+ ::pybind11::detail::concat(make_caster<Types>::name...)
|
||||
+ const_name("]");
|
||||
};
|
||||
|
||||
template <>
|
||||
struct handle_type_name<typing::Tuple<>> {
|
||||
// PEP 484 specifies this syntax for an empty tuple
|
||||
static constexpr auto name = const_name("tuple[()]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Tuple<T, ellipsis>> {
|
||||
// PEP 484 specifies this syntax for a variable-length tuple
|
||||
static constexpr auto name
|
||||
= const_name("tuple[") + make_caster<T>::name + const_name(", ...]");
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct handle_type_name<typing::Dict<K, V>> {
|
||||
static constexpr auto name = const_name("dict[") + make_caster<K>::name + const_name(", ")
|
||||
+ make_caster<V>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::List<T>> {
|
||||
static constexpr auto name = const_name("list[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Set<T>> {
|
||||
static constexpr auto name = const_name("set[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Iterable<T>> {
|
||||
static constexpr auto name
|
||||
= const_name("collections.abc.Iterable[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Iterator<T>> {
|
||||
static constexpr auto name
|
||||
= const_name("collections.abc.Iterator[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename Return, typename... Args>
|
||||
struct handle_type_name<typing::Callable<Return(Args...)>> {
|
||||
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
||||
static constexpr auto name
|
||||
= const_name("collections.abc.Callable[[")
|
||||
+ ::pybind11::detail::concat(::pybind11::detail::arg_descr(make_caster<Args>::name)...)
|
||||
+ const_name("], ") + ::pybind11::detail::return_descr(make_caster<retval_type>::name)
|
||||
+ const_name("]");
|
||||
};
|
||||
|
||||
template <typename Return>
|
||||
struct handle_type_name<typing::Callable<Return(ellipsis)>> {
|
||||
// PEP 484 specifies this syntax for defining only return types of callables
|
||||
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
||||
static constexpr auto name = const_name("collections.abc.Callable[..., ")
|
||||
+ ::pybind11::detail::return_descr(make_caster<retval_type>::name)
|
||||
+ const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Type<T>> {
|
||||
static constexpr auto name = const_name("type[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename... Types>
|
||||
struct handle_type_name<typing::Union<Types...>> {
|
||||
static constexpr auto name = ::pybind11::detail::union_concat(make_caster<Types>::name...);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Optional<T>> {
|
||||
static constexpr auto name = make_caster<T>::name | make_caster<none>::name;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::Final<T>> {
|
||||
static constexpr auto name = const_name("typing.Final[")
|
||||
+ ::pybind11::detail::return_descr(make_caster<T>::name)
|
||||
+ const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::ClassVar<T>> {
|
||||
static constexpr auto name
|
||||
= const_name("typing.ClassVar[") + make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::TypeGuard<T>> {
|
||||
static constexpr auto name = const_name(PYBIND11_TYPE_GUARD_TYPE_HINT) + const_name("[")
|
||||
+ make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct handle_type_name<typing::TypeIs<T>> {
|
||||
static constexpr auto name = const_name(PYBIND11_TYPE_IS_TYPE_HINT) + const_name("[")
|
||||
+ make_caster<T>::name + const_name("]");
|
||||
};
|
||||
|
||||
template <>
|
||||
struct handle_type_name<typing::NoReturn> {
|
||||
static constexpr auto name = const_name("typing.NoReturn");
|
||||
};
|
||||
|
||||
template <>
|
||||
struct handle_type_name<typing::Never> {
|
||||
static constexpr auto name = const_name(PYBIND11_NEVER_TYPE_HINT);
|
||||
};
|
||||
|
||||
#if defined(PYBIND11_TYPING_H_HAS_STRING_LITERAL)
|
||||
template <typing::StringLiteral StrLit>
|
||||
consteval auto sanitize_string_literal() {
|
||||
constexpr std::string_view v(StrLit.name);
|
||||
constexpr std::string_view special_chars("!@%{}-");
|
||||
constexpr auto num_special_chars = std::accumulate(
|
||||
special_chars.begin(), special_chars.end(), (size_t) 0, [&v](auto acc, const char &c) {
|
||||
return std::move(acc) + std::ranges::count(v, c);
|
||||
});
|
||||
char result[v.size() + num_special_chars + 1];
|
||||
size_t i = 0;
|
||||
for (auto c : StrLit.name) {
|
||||
if (special_chars.find(c) != std::string_view::npos) {
|
||||
result[i++] = '!';
|
||||
}
|
||||
result[i++] = c;
|
||||
}
|
||||
return typing::StringLiteral(result);
|
||||
}
|
||||
|
||||
template <typing::StringLiteral... Literals>
|
||||
struct handle_type_name<typing::Literal<Literals...>> {
|
||||
static constexpr auto name
|
||||
= const_name("typing.Literal[")
|
||||
+ pybind11::detail::concat(const_name(sanitize_string_literal<Literals>().name)...)
|
||||
+ const_name("]");
|
||||
};
|
||||
template <typing::StringLiteral StrLit>
|
||||
struct handle_type_name<typing::TypeVar<StrLit>> {
|
||||
static constexpr auto name = const_name(sanitize_string_literal<StrLit>().name);
|
||||
};
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
75
deps_src/pybind11/include/pybind11/warnings.h
Normal file
75
deps_src/pybind11/include/pybind11/warnings.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
pybind11/warnings.h: Python warnings wrappers.
|
||||
|
||||
Copyright (c) 2024 Jan Iwaszkiewicz <jiwaszkiewicz6@gmail.com>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
#include "detail/common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
inline bool PyWarning_Check(PyObject *obj) {
|
||||
int result = PyObject_IsSubclass(obj, PyExc_Warning);
|
||||
if (result == 1) {
|
||||
return true;
|
||||
}
|
||||
if (result == -1) {
|
||||
raise_from(PyExc_SystemError,
|
||||
"pybind11::detail::PyWarning_Check(): PyObject_IsSubclass() call failed.");
|
||||
throw error_already_set();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(warnings)
|
||||
|
||||
inline object
|
||||
new_warning_type(handle scope, const char *name, handle base = PyExc_RuntimeWarning) {
|
||||
if (!detail::PyWarning_Check(base.ptr())) {
|
||||
pybind11_fail("pybind11::warnings::new_warning_type(): cannot create custom warning, base "
|
||||
"must be a subclass of "
|
||||
"PyExc_Warning!");
|
||||
}
|
||||
if (hasattr(scope, name)) {
|
||||
pybind11_fail("pybind11::warnings::new_warning_type(): an attribute with name \""
|
||||
+ std::string(name) + "\" exists already.");
|
||||
}
|
||||
std::string full_name = scope.attr("__name__").cast<std::string>() + std::string(".") + name;
|
||||
handle h(PyErr_NewException(full_name.c_str(), base.ptr(), nullptr));
|
||||
if (!h) {
|
||||
raise_from(PyExc_SystemError,
|
||||
"pybind11::warnings::new_warning_type(): PyErr_NewException() call failed.");
|
||||
throw error_already_set();
|
||||
}
|
||||
auto obj = reinterpret_steal<object>(h);
|
||||
scope.attr(name) = obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Similar to Python `warnings.warn()`
|
||||
inline void
|
||||
warn(const char *message, handle category = PyExc_RuntimeWarning, int stack_level = 2) {
|
||||
if (!detail::PyWarning_Check(category.ptr())) {
|
||||
pybind11_fail(
|
||||
"pybind11::warnings::warn(): cannot raise warning, category must be a subclass of "
|
||||
"PyExc_Warning!");
|
||||
}
|
||||
|
||||
if (PyErr_WarnEx(category.ptr(), message, stack_level) == -1) {
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(warnings)
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:50-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\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"
|
||||
@@ -64,30 +64,6 @@ msgstr ""
|
||||
msgid "%s is not supported by %s extruder."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"There may be critical print quality issues when printing '%s' with %s Bowden "
|
||||
"extruder. Use with caution!"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"There may be critical print quality issues when printing '%s' with %s "
|
||||
"extruder. Use with caution!"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"There may be print quality issues when printing '%s' with %s Bowden extruder. "
|
||||
"Use with caution."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"There may be print quality issues when printing '%s' with %s extruder. Use "
|
||||
"with caution."
|
||||
msgstr ""
|
||||
|
||||
msgid "Current AMS humidity"
|
||||
msgstr ""
|
||||
|
||||
@@ -349,7 +325,6 @@ msgstr ""
|
||||
msgid "Optimize orientation"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr ""
|
||||
|
||||
@@ -359,7 +334,6 @@ msgstr ""
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
|
||||
@@ -393,9 +367,6 @@ msgstr ""
|
||||
msgid "Object operations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Scale"
|
||||
msgstr ""
|
||||
|
||||
msgid "Volume operations"
|
||||
msgstr ""
|
||||
|
||||
@@ -417,32 +388,25 @@ msgstr ""
|
||||
msgid "Reset rotation"
|
||||
msgstr ""
|
||||
|
||||
msgid "World"
|
||||
msgid "Object coordinates"
|
||||
msgstr ""
|
||||
|
||||
msgid "Object"
|
||||
msgid "World coordinates"
|
||||
msgstr ""
|
||||
|
||||
msgid "Part"
|
||||
msgstr ""
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr ""
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgid "Part coordinates"
|
||||
msgstr ""
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
@@ -548,6 +512,12 @@ msgstr ""
|
||||
msgid "Spacing"
|
||||
msgstr ""
|
||||
|
||||
msgid "Part"
|
||||
msgstr ""
|
||||
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1850,30 +1820,23 @@ msgstr ""
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr ""
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1882,12 +1845,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1955,8 +1912,7 @@ msgstr ""
|
||||
msgid "Sync user presets"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
@@ -2166,9 +2122,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3531,7 +3484,6 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Navigation"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
@@ -4814,7 +4766,6 @@ msgstr ""
|
||||
msgid "Color change"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
@@ -4970,15 +4921,11 @@ msgstr ""
|
||||
msgid "Align to Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
@@ -5057,9 +5004,6 @@ msgstr ""
|
||||
msgid "Outline"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5102,7 +5046,7 @@ msgstr ""
|
||||
msgid "Size:"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
#, possible-boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr ""
|
||||
|
||||
@@ -5295,10 +5239,6 @@ msgstr ""
|
||||
msgid "Export G-code file"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr ""
|
||||
|
||||
@@ -7725,35 +7665,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -7766,12 +7677,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr ""
|
||||
|
||||
@@ -11791,18 +11696,6 @@ msgstr ""
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr ""
|
||||
|
||||
@@ -11955,25 +11848,21 @@ msgid ""
|
||||
"3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
@@ -12330,22 +12219,6 @@ msgstr ""
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr ""
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr ""
|
||||
|
||||
@@ -13962,9 +13835,6 @@ msgstr ""
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
msgid "Random"
|
||||
msgstr ""
|
||||
|
||||
@@ -14915,14 +14785,6 @@ msgstr ""
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr ""
|
||||
|
||||
@@ -18111,12 +17973,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -18215,278 +18071,6 @@ msgstr ""
|
||||
msgid "The filament model is unknown. A random filament preset will be used."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr ""
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgid "N"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgid "g"
|
||||
msgstr ""
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr ""
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr ""
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr ""
|
||||
|
||||
msgid "TPU High flow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr ""
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr ""
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr ""
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr ""
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr ""
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr ""
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr ""
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr ""
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr ""
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr ""
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr ""
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr ""
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr ""
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr ""
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr ""
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr ""
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set the physical nozzle count..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set nozzle count"
|
||||
msgstr ""
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr ""
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr ""
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr ""
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr ""
|
||||
|
||||
msgid "Row A"
|
||||
msgstr ""
|
||||
|
||||
msgid "Row B"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr ""
|
||||
|
||||
msgid "Read All"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reading "
|
||||
msgstr ""
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr ""
|
||||
|
||||
msgid "Running..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Raised"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Used Time: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr ""
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr ""
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr ""
|
||||
|
||||
msgid "Flush multiplier (Fast mode)"
|
||||
msgstr ""
|
||||
|
||||
msgid "The flush multiplier used in fast purge mode."
|
||||
msgstr ""
|
||||
|
||||
msgid "Prime volume mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers."
|
||||
msgstr ""
|
||||
|
||||
msgid "Saving"
|
||||
msgstr ""
|
||||
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
|
||||
msgid "Flush temperature used in fast purge mode."
|
||||
msgstr ""
|
||||
|
||||
msgid "Support fast purge mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier."
|
||||
msgstr ""
|
||||
|
||||
msgid "Deretraction speed (extruder change)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Speed for reloading filament into the nozzle when switching extruder."
|
||||
msgstr ""
|
||||
|
||||
msgid "Farthest point timelapse"
|
||||
msgstr ""
|
||||
|
||||
msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers."
|
||||
msgstr ""
|
||||
|
||||
#: resources/data/hints.ini: [hint:Precise wall]
|
||||
msgid "Precise wall\nDid you know that turning on precise wall can improve precision and layer consistency?"
|
||||
msgstr ""
|
||||
@@ -18634,91 +18218,3 @@ msgstr ""
|
||||
#: resources/data/hints.ini: [hint:Avoid warping]
|
||||
msgid "Avoid warping\nDid you know that when printing materials that are prone to warping such as ABS, appropriately increasing the heatbed temperature can reduce the probability of warping?"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection."
|
||||
msgstr ""
|
||||
|
||||
msgid "The printer is calculating nozzle mapping."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please wait a moment..."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "The current nozzle mapping may produce an extra %0.2f g of waste."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Filament switcher detected. All AMS filaments are now available for both "
|
||||
"extruders. The slicer will auto-assign for optimal printing. "
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A filament switcher is detected but not calibrated and thus currently "
|
||||
"unavailable. Please calibrate it on the printer and synchronize before use. "
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The Filament Track Switch installed on the printer does not match the slicing "
|
||||
"file. Please re-slice to avoid print quality issues."
|
||||
msgstr ""
|
||||
|
||||
msgid "This print requires a Filament Track Switch. Please install it first."
|
||||
msgstr ""
|
||||
|
||||
msgid "The Filament Track Switch has not been setup. Please setup it first."
|
||||
msgstr ""
|
||||
|
||||
msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch."
|
||||
msgstr ""
|
||||
|
||||
msgid "The Filament Track Switch has not been setup. Please setup on printer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Load %s to "
|
||||
msgstr ""
|
||||
|
||||
msgid "AMS filaments"
|
||||
msgstr ""
|
||||
|
||||
msgid "Fila Saving"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Filament Track Switch"
|
||||
msgstr ""
|
||||
|
||||
msgid "AMS has not been initialized. Please initialize it before use."
|
||||
msgstr ""
|
||||
|
||||
msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it."
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch"
|
||||
msgstr ""
|
||||
|
||||
msgid "hotend"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wait for AMS cooling"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch current filament at Filament Track Switch"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pull back current filament at Filament Track Switch"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch track at Filament Track Switch"
|
||||
msgstr ""
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -332,7 +332,6 @@ msgstr "Gizmo-Rotació"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optimitzar l'orientació"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Escalar"
|
||||
|
||||
@@ -342,9 +341,8 @@ msgstr "Gizmo-Escalar"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Error: Tanqueu primer tots els menús de la barra d'eines"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "polç"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -377,9 +375,6 @@ msgstr "Ràtios d'escala"
|
||||
msgid "Object operations"
|
||||
msgstr "Operacions amb objectes"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Escalar"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Operacions de volum"
|
||||
@@ -407,33 +402,26 @@ msgstr "Restableix la Posició"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Reinicialitza la rotació"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Coordenades de l'objecte"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objecte"
|
||||
msgid "World coordinates"
|
||||
msgstr "Coordenades cartesianes"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Peça"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Trasllada (relatiu)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Restableix la rotació actual al valor d'quan s'ha obert l'eina de rotació."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Gira (absolut)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Restableix la rotació actual a zeros reals."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Escalar"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Coordenades de la part"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -538,6 +526,12 @@ msgstr ""
|
||||
msgid "Spacing"
|
||||
msgstr "Espaiat"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Peça"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objecte"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1885,30 +1879,23 @@ msgstr "Obrir Projecte"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "La versió de l'Orca Slicer és massa antiga i s'ha d'actualitzar a la versió més recent abans que es pugui utilitzar amb normalitat"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1917,12 +1904,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1997,8 +1978,7 @@ msgstr "El nombre de perfils d'usuari emmagatzemats a memòria cau al núvol ha
|
||||
msgid "Sync user presets"
|
||||
msgstr "Sincronitzar perfils d'usuari"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2220,9 +2200,6 @@ msgstr "Cub d'Orca"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Prova de tolerància d'Orca"
|
||||
|
||||
@@ -3660,7 +3637,7 @@ msgstr "Calibratge completat. Trobeu la línia d'extrusió més uniforme al vost
|
||||
msgid "Save"
|
||||
msgstr "Desar"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Darrera"
|
||||
|
||||
@@ -5043,7 +5020,6 @@ msgstr "Canvis d'eina"
|
||||
msgid "Color change"
|
||||
msgstr "Canvi de color"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
@@ -5207,15 +5183,11 @@ msgstr "Evitar la regió de calibratge d'extrusió"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Alinear a l'eix Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Darrera"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Esquerra"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Dreta"
|
||||
|
||||
@@ -5294,9 +5266,6 @@ msgstr "Voladissos"
|
||||
msgid "Outline"
|
||||
msgstr "Contorn"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5341,7 +5310,7 @@ msgid "Size:"
|
||||
msgstr "Mida:"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "S'han trobat conflictes de rutes gcode a la capa %d, Z = %.2lfmm. Si us plau, separeu els objectes conflictius més lluny ( %s <-> %s )."
|
||||
|
||||
@@ -5544,10 +5513,6 @@ msgstr "Imprimir placa d'impressió"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Exportar el fitxer del Codi-G"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exportar fitxer de la placa laminada"
|
||||
|
||||
@@ -8092,35 +8057,6 @@ msgstr "Mostra opcions en importar fitxers STEP"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Si s'activa, apareixerà un diàleg de configuració de paràmetres durant la importació de fitxers STEP."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Nivell de qualitat per a l'exportació Draco"
|
||||
|
||||
@@ -8136,12 +8072,6 @@ msgstr ""
|
||||
"0 = compressió sense pèrdua (la geometria es preserva a plena precisió). Els valors amb pèrdua vàlids van de 8 a 30.\n"
|
||||
"Valors més baixos produeixen fitxers més petits però perden més detall geomètric; valors més alts preserven més detall a costa de fitxers més grans."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Perfil"
|
||||
|
||||
@@ -12464,18 +12394,6 @@ msgstr "Llindar de perímetres petits"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Això estableix el llindar per a la longitud perimetral petita. El llindar predeterminat és de 0mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Ordre d'impressió de perímetres"
|
||||
|
||||
@@ -12661,26 +12579,25 @@ msgstr ""
|
||||
"2. Anoteu el valor de PA òptim per a cada velocitat i acceleració del cabal volumètric. Podeu trobar el número de flux seleccionant el flux al desplegable de l'esquema de colors i moveu el control lliscant horitzontal per sobre de les línies del patró PA. El número ha de ser visible a la part inferior de la pàgina. El valor de PA ideal hauria de ser decreixent com més gran sigui el cabal volumètric. Si no és així, confirmeu que la vostra extrusora funciona correctament. Com més lent i amb menys acceleració imprimiu, més gran serà el rang de valors de PA acceptables. Si no hi ha cap diferència visible, utilitzeu el valor PA de la prova més ràpida.\n"
|
||||
"3. Introduïu els triplets dels valors de PA, flux i acceleracions al quadre de text aquí i deseu el vostre perfil de filament."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Habilita l'avanç de pressió adaptativa per als voladissos (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Avanç de pressió per als ponts"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Valor d'avanç de pressió per als ponts. Establiu a 0 per desactivar.\n"
|
||||
"\n"
|
||||
" Un valor de PA més baix quan s'imprimeixen ponts ajuda a reduir l'aparició d'una lleugera extrusió immediatament després dels ponts. Això és causat per la caiguda de pressió al broquet quan s'imprimeix a l'aire i un PA més baix ajuda a contrarestar-ho."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Amplada de línia predeterminada si altres amplades de línia estan definides com a 0. Si s'expressa en %, es calcularà sobre el diàmetre del broquet."
|
||||
@@ -13064,22 +12981,6 @@ msgstr "Direcció de farciment sòlid"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Angle per al patró de farciment sòlid, que controla l'inici o la direcció principal de la línia"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Densitat de farciment poc dens"
|
||||
|
||||
@@ -14825,10 +14726,6 @@ msgstr "Alineat"
|
||||
msgid "Aligned back"
|
||||
msgstr "Alineat al darrere"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Darrera"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Aleatori"
|
||||
|
||||
@@ -15881,14 +15778,6 @@ msgstr "Gir del poliforat"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Rotar el poliforat a cada capa."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Mida Miniatures al Codi-G"
|
||||
|
||||
@@ -19257,12 +19146,6 @@ msgstr "Nombre de cares triangulars"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Calculant, espereu..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19668,42 +19551,6 @@ msgstr ""
|
||||
"Evitar la deformació( warping )\n"
|
||||
"Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Imprimir"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "polç"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Coordenades de l'objecte"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Coordenades cartesianes"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Trasllada (relatiu)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Gira (absolut)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Coordenades de la part"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Habilita l'avanç de pressió adaptativa per als voladissos (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Avanç de pressió per als ponts"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Valor d'avanç de pressió per als ponts. Establiu a 0 per desactivar.\n"
|
||||
#~ "\n"
|
||||
#~ " Un valor de PA més baix quan s'imprimeixen ponts ajuda a reduir l'aparició d'una lleugera extrusió immediatament després dels ponts. Això és causat per la caiguda de pressió al broquet quan s'imprimeix a l'aire i un PA més baix ajuda a contrarestar-ho."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Opcions de sincronització de filament"
|
||||
|
||||
@@ -21127,6 +20974,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "Desmarcar"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Escalar"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "Forçar elevació Z"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Jakub Hencl\n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "Gizmo-Otočit"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optimalizovat orientaci"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Měřítko"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "Gizmo-Měřítko"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Nejprve prosím zavřete všechna menu nástrojové lišty"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "v"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "Poměry měřítka"
|
||||
msgid "Object operations"
|
||||
msgstr "Operace s objektem"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Měřítko"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Operace s hlasitostí"
|
||||
@@ -402,33 +397,26 @@ msgstr "Obnovit pozici"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Resetovat rotaci"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Souřadnice objektu"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
msgid "World coordinates"
|
||||
msgstr "Světové souřadnice"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Díl"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Přesunout (relativně)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Obnovit aktuální rotaci na hodnotu při otevření nástroje pro rotaci."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Otočit (absolutně)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Obnovit aktuální rotaci na skutečné nuly."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Měřítko"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Souřadnice části"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr "Mezera"
|
||||
msgid "Spacing"
|
||||
msgstr "Rozestup"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Díl"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1877,30 +1871,23 @@ msgstr "Otevřít projekt"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Verze Orca Slicer je příliš stará a je nutné ji aktualizovat na nejnovější verzi, aby ji bylo možné používat."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1909,12 +1896,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1995,9 +1976,8 @@ msgstr "Počet uživatelských předvoleb uložených v cloudu překročil povol
|
||||
msgid "Sync user presets"
|
||||
msgstr "Synchronizovat uživatelské předvolby"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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 "Obsah předvolby je příliš velký pro synchronizaci do cloudu (přesahuje 1 MB). Zmenšete velikost předvolby odstraněním vlastních nastavení nebo ji používejte pouze lokálně."
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2217,9 +2197,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3659,7 +3636,7 @@ msgstr "Kalibrace byla dokončena. Najděte na vyhřívané podložce nejrovnom
|
||||
msgid "Save"
|
||||
msgstr "Uložit"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Zpět"
|
||||
|
||||
@@ -5040,7 +5017,6 @@ msgstr "Výměny nástrojů"
|
||||
msgid "Color change"
|
||||
msgstr "Změna barvy"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Tisk"
|
||||
|
||||
@@ -5204,15 +5180,11 @@ msgstr "Vyhněte se kalibrační oblasti extruze"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Zarovnat na osu Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Zpět"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Levý"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Pravý"
|
||||
|
||||
@@ -5291,9 +5263,6 @@ msgstr "Převisy"
|
||||
msgid "Outline"
|
||||
msgstr "Obrys"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5337,7 +5306,7 @@ msgstr "Objem:"
|
||||
msgid "Size:"
|
||||
msgstr "Velikost:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Byly nalezeny konflikty drah G-kódu ve vrstvě %d, Z = %.2lf mm. Oddělte prosím konfliktní objekty více od sebe (%s <-> %s)."
|
||||
|
||||
@@ -5540,10 +5509,6 @@ msgstr "Tisková deska"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Exportovat G-code soubor"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Tisk"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exportovat nařezaný soubor desky"
|
||||
|
||||
@@ -8089,35 +8054,6 @@ msgstr "Zobrazit možnosti při importu souboru STEP"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Pokud je povoleno, během importu souboru STEP se zobrazí dialog nastavení parametrů."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Úroveň kvality pro export Draco"
|
||||
|
||||
@@ -8133,12 +8069,6 @@ msgstr ""
|
||||
"0 = bezztrátová komprese (geometrie je zachována v plné přesnosti). Platné ztrátové hodnoty jsou v rozsahu 8 až 30.\n"
|
||||
"Nižší hodnoty vytvářejí menší soubory, ale ztrácí více geometrických detailů; vyšší hodnoty zachovávají více detailů za cenu větších souborů."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Předvolba"
|
||||
|
||||
@@ -12468,18 +12398,6 @@ msgstr "Práh malých obvodů"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Tímto se nastavuje práh délky malého obvodu. Výchozí práh je 0 mm."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Pořadí tisku stěn"
|
||||
|
||||
@@ -12668,26 +12586,25 @@ msgstr ""
|
||||
"2. Poznamenejte si optimální hodnotu PA pro každou objemovou rychlost průtoku a zrychlení. Hodnotu průtoku zjistíte výběrem „Flow“ v rozbalovací nabídce barevného schématu a posunutím vodorovného posuvníku nad čárami PA vzoru. Číslo by mělo být viditelné dole na stránce. Ideální hodnota PA by měla s rostoucím objemovým průtokem klesat. Pokud tomu tak není, ověřte, že extruder funguje správně. Čím pomaleji a s menším zrychlením tisknete, tím větší je rozsah přijatelných hodnot PA. Pokud není vidět žádný rozdíl, použijte hodnotu PA z rychlejšího testu.\n"
|
||||
"3. Zadejte trojice hodnot PA, průtoku a zrychlení do textového pole zde a uložte profil filamentu."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Povolit adaptivní pressure advance pro převisy (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Pressure advance pro mosty"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Hodnota Pressure advance pro mosty. Nastavte na 0 pro vypnutí.\n"
|
||||
"\n"
|
||||
"Nižší hodnota PA při tisku mostů pomáhá omezit výskyt mírné podextruze ihned po mostech. To je způsobeno poklesem tlaku v trysce při tisku do vzduchu a nižší PA tomu pomáhá předcházet."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Výchozí šířka čáry, pokud jsou ostatní šířky čáry nastaveny na 0. Pokud je zadáno v %, bude vypočteno vůči průměru trysky."
|
||||
@@ -13070,22 +12987,6 @@ msgstr "Směr plného vyplnění"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Úhel pro vzor plného výplně, který určuje počáteční nebo hlavní směr čáry."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Hustota řídké výplně"
|
||||
|
||||
@@ -14872,10 +14773,6 @@ msgstr "Zarovnáno"
|
||||
msgid "Aligned back"
|
||||
msgstr "Zarovnat zpět"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Zpět"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Náhodně"
|
||||
|
||||
@@ -15922,14 +15819,6 @@ msgstr "Zkroucení polyotvoru"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Otočit polyotvor každou vrstvu."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Náhledy G-code"
|
||||
|
||||
@@ -19291,12 +19180,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19702,45 +19585,6 @@ msgstr ""
|
||||
"Zamezte kroucení\n"
|
||||
"Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Tisk"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "v"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Souřadnice objektu"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Světové souřadnice"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Přesunout (relativně)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Otočit (absolutně)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Souřadnice části"
|
||||
|
||||
#~ 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 "Obsah předvolby je příliš velký pro synchronizaci do cloudu (přesahuje 1 MB). Zmenšete velikost předvolby odstraněním vlastních nastavení nebo ji používejte pouze lokálně."
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Povolit adaptivní pressure advance pro převisy (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Pressure advance pro mosty"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Hodnota Pressure advance pro mosty. Nastavte na 0 pro vypnutí.\n"
|
||||
#~ "\n"
|
||||
#~ "Nižší hodnota PA při tisku mostů pomáhá omezit výskyt mírné podextruze ihned po mostech. To je způsobeno poklesem tlaku v trysce při tisku do vzduchu a nižší PA tomu pomáhá předcházet."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Možnosti synchronizace filamentů"
|
||||
|
||||
@@ -19852,198 +19696,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "°"
|
||||
#~ msgstr "°"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Hotend v neobvyklém stavu"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Dostupné trysky"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Pozor: Kombinace různých průměrů trysek v jednom tisku není podporována. Pokud je zvolená velikost pouze na jednom extruderu, bude vynucen tisk jedním extruderem."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Během aktualizace hotendu se bude tisková hlava pohybovat. Nevkládejte ruce do komory."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Povolte tuto možnost, pokud tiskárna podpěruje filtr pro chlazení"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Chyba: Není možné nastavit počet trysek na nulu."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Chyba: Počet trysek nesmí překročit %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Výměna extruderu"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Výměna hotendu"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Interval výměny hotendu"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Informace o hotendu mohou být nepřesné. Chcete hotend znovu načíst? (Informace o hotendu se mohou po vypnutí změnit.)"
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Hybridní"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Potvrzuji vše"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Indukční držák hotendu"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Ručně pro trysku"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Výběr trysky"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Ověřte prosím, zda požadovaný průměr trysky a průtok odpovídají aktuálně zobrazeným hodnotám."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Nastavte prosím počet trysek"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Teplotní rozdíl při předehřevu"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Věž pro oddělení trysky je vyžadována pro výměnu trysky. Bez věže pro oddělení trysky mohou být na modelu vady. Opravdu chcete zakázat věž pro oddělení trysky?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Znovu načíst vše"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Načítání hotendů, prosím čekejte."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Obnovit %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Synchronizovat stav trysky"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU vysoký průtok"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Teplotní rozdíl použitý během předehřevu před výměnou nástroje."
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Hotend je v neobvyklém stavu a momentálně není k dispozici. Přejděte do 'Zařízení -> Upgrade' pro aktualizaci firmwaru."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Maximální objemový průtok pro natlačení před výměnou hotendu, kde -1 znamená použití maximálního objemového průtoku."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Maximální objemová rychlost pro vytlačování před výměnou extruderu, kde -1 znamená použití maximální objemové rychlosti."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "Tisková hlava a držák hotendu se mohou pohybovat. Držte ruce mimo komoru."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Objem materiálu potřebný k předplnění extruderu při výměně hotendu na věži."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Je čas vyměnit hotend."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Aby se zabránilo vytékání, bude teplota trysky během natlačování snížena. Poznámka: provede se pouze příkaz k ochlazení a aktivace ventilátoru; dosažení cílové teploty není zaručeno. 0 znamená vypnuto."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Aby se zabránilo vytékání, bude teplota trysky během natlačování snížena. Doba natlačování proto musí být delší než doba ochlazování. 0 znamená deaktivováno."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Aby se zabránilo vytékání, provede tryska po dokončení natlačování po určitou dobu zpětný pohyb. Toto nastavení určuje dobu pohybu."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Zjištěna neznámá tryska. Proveďte aktualizaci (neaktualizované trysky budou při slicování přeskočeny)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Zjištěna neznámá tryska. Proveďte aktualizaci informací (neaktualizované trysky budou při řezání vyloučeny). Ověřte průměr trysky a průtok vzhledem k zobrazeným hodnotám."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Použít filtr pro chlazení"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Při výměně hotendu se doporučuje vytlačit určitou délku filamentu ze stávající trysky. To pomáhá minimalizovat vytékání trysky."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Pokud se tato hodnota retrakce změní, použije se jako množství filamentu zataženého v hotendu před výměnou hotendů."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "Vaše tiskárna má nainstalované různé trysky. Vyberte prosím trysku pro tento tisk."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "délka při výměně hotendu"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Na aktuální podložce jsou přiřazeny dynamické trysky. Výběr hotendu není podpěrován."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Stojan na hotend"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Stav hotendu je abnormální a momentálně není dostupný. Aktualizujte firmware a zkuste to znovu."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "Hotendy"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Informace o hotendech"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotendy na stojanu"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Přejít na stránku upgradu"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Poznámka: Číslo hotendu na %s je přiřazeno k držáku. Když je hotend přesunut do nového držáku, jeho číslo se automaticky aktualizuje."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "ID trysky"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Je nutné načíst informace o trysce"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Prosím čekejte"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Tisk s aktuální tryskou může vyprodukovat navíc %0.2f g odpadu."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Zvednuté"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Načíst vše"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Načítání "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Řada A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Řada B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Probíhá spouštění..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Vyberte filament a hotendy"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Standardní průtok"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Tisková hlava"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Tisková hlava"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Použitý čas: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "Gizmo-Drehen"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optimiere Ausrichtung"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Skalieren"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "Gizmo-Skalieren"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Fehler: Bitte schließen sie zuerst alle Werkzeugleistenmenüs"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "Skalierungsverhältnisse"
|
||||
msgid "Object operations"
|
||||
msgstr "Objekt-Operationen"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Skalieren"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Volumen Operationen"
|
||||
@@ -402,33 +397,26 @@ msgstr "Position zurücksetzen"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Rotation zurücksetzen"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Objektkoordinaten"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
msgid "World coordinates"
|
||||
msgstr "Weltkoordinaten"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Teil"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Verschieben (relativ)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Setze die aktuelle Rotation auf den Wert zurück, als das Rotationswerkzeug geöffnet wurde."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Rotation (absolut)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Setze die aktuelle Rotation auf die realen Nullen zurück."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Skalieren"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Teile Koordinaten"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr "Spalt"
|
||||
msgid "Spacing"
|
||||
msgstr "Abstand"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Teil"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1881,32 +1875,33 @@ msgstr "Projekt öffnen"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Die Version von Orca Slicer ist veraltet und muss auf die neueste Version aktualisiert werden, bevor sie normal verwendet werden kann"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Cloud-Synchronisationskonflikt: Dieses Profil hat eine neuere Version in OrcaCloud.\n"
|
||||
"Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Cloud-Synchronisationskonflikt: Ein Profil mit diesem Namen existiert bereits in OrcaCloud.\n"
|
||||
"Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Cloud-Synchronisationskonflikt: Ein Profil mit demselben Namen wurde zuvor aus der Cloud gelöscht.\n"
|
||||
"Delete löscht Ihr lokales Profil. Force Push überschreibt es mit Ihrem lokalen Profil."
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
"Cloud-Synchronisationskonflikt: Es gab einen unerwarteten oder nicht identifizierten Profilkonflikt.\n"
|
||||
"Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -1915,12 +1910,6 @@ msgstr ""
|
||||
"Force Push überschreibt die Cloud-Kopie mit Ihren lokalen Profiländerungen.\n"
|
||||
"Möchten Sie fortfahren?"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr "Cloud-Synchronisationskonflikt lösen"
|
||||
|
||||
@@ -2000,8 +1989,7 @@ msgstr "Die Anzahl der im Cloud-Cache gespeicherten Benutzerprofile hat das Limi
|
||||
msgid "Sync user presets"
|
||||
msgstr "Benutzerprofile synchronisieren"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2222,9 +2210,6 @@ msgstr "Orca Würfel"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "OrcaSliced Kombination"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca Toleranz Test"
|
||||
|
||||
@@ -3662,7 +3647,7 @@ msgstr "Kalibrierung abgeschlossen. Bitte suchen Sie die gleichmäßigste Extrus
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
@@ -5044,7 +5029,6 @@ msgstr "Werkzeugwechsel"
|
||||
msgid "Color change"
|
||||
msgstr "Farbwechsel"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "aktuelle Platte drucken"
|
||||
|
||||
@@ -5208,15 +5192,11 @@ msgstr "Vermeiden Sie den Bereich der Extrusionskalibrierung"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "An Y-Achse ausrichten"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "links"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "rechts"
|
||||
|
||||
@@ -5295,9 +5275,6 @@ msgstr "Überhänge"
|
||||
msgid "Outline"
|
||||
msgstr "Umriss"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr "Realistische Ansicht"
|
||||
|
||||
@@ -5341,7 +5318,7 @@ msgstr "Volumen:"
|
||||
msgid "Size:"
|
||||
msgstr "Größe:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Konflikte von G-Code-Pfaden wurden bei Layer %d, Z = %.2lf mm gefunden.Bitte trennen Sie die konfliktbehafteten Objekte weiter voneinander (%s <-> %s)."
|
||||
|
||||
@@ -5542,10 +5519,6 @@ msgstr "Aktuelle Platte drucken"
|
||||
msgid "Export G-code file"
|
||||
msgstr "G-Code als Datei exportieren"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "aktuelle Platte drucken"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exportiere aktuelle Platte als STL Datei"
|
||||
|
||||
@@ -8096,35 +8069,6 @@ msgstr "Optionen beim Importieren von STEP-Dateien anzeigen"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Wenn aktiviert, wird während des Imports von STEP-Dateien ein Dialogfeld "
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Qualitätsstufe für den Draco-Export"
|
||||
|
||||
@@ -8140,12 +8084,6 @@ msgstr ""
|
||||
"0 = verlustfreie Kompression (Geometrie wird mit voller Präzision beibehalten). Gültige verlustbehaftete Werte liegen zwischen 8 und 30.\n"
|
||||
"Niedrigere Werte erzeugen kleinere Dateien, verlieren jedoch mehr geometrische Details; höhere Werte bewahren mehr Details auf Kosten größerer Dateien."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Profil"
|
||||
|
||||
@@ -12574,18 +12512,6 @@ msgstr "Schwelle für kleine Strukturen"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Dies legt die Schwelle für eine kleine Umfangslänge fest. Der Standardwert für die Schwelle beträgt 0 mm."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Anordnung der Wände"
|
||||
|
||||
@@ -12774,26 +12700,27 @@ msgstr ""
|
||||
"2. Notieren Sie den optimalen PA-Wert für jede Volumenfließgeschwindigkeit und Beschleunigung. Sie können die Fließzahl auswählen, indem Sie Fluss ausdem Farbschema-Dropdown auswählen und den horizontalen Schieberegler über den PA-Musterlinien bewegen. Die Zahl sollte am unteren Rand der Seite sichtbar sein. Der ideale PA-Wert sollte abnehmen, je höher die Volumenfließgeschwin-digkeit ist. Wenn dies nicht der Fall ist, bestätigen Sie, dass Ihr Extruder korrekt funktioniert. Je langsamer und mit weniger Beschleunigung Sie drucken, desto größer ist der Bereich der akzeptablen PA-Werte. Wenn kein Unterschied sichtbar ist, verwenden Sie den PA-Wert aus dem schnelleren Test.\n"
|
||||
"3. Geben Sie die Triplets von PA-Werten, Fluss und Beschleunigungen im Textfeld hier ein und speichern Sie Ihr Filamentprofil."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Adaptives PA für Überhänge aktivieren (experimentell)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
"Aktivieren Sie adaptives PA auch für Überhänge sowie bei Flussänderungen innerhalb desselben Features. Dies ist eine experimentelle Option, da sie bei ungenau eingestelltem PA-Profil zu Uniformitätsproblemen auf den äußeren Oberflächen vor und nach Überhängen führen kann.\n"
|
||||
"Nicht kompatibel mit Prusa-Druckern, da diese pausieren, um PA-Änderungen zu verarbeiten, was zu Verzögerungen und Defekten führt."
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Pressure Advance für Brücken"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Pressure Advance-Wert für Brücken. Auf 0 setzen, um zu deaktivieren.\n"
|
||||
"\n"
|
||||
"Ein niedrigerer PA-Wert beim Drucken von Brücken hilft, das Auftreten einer leichten Unterextrusion unmittelbar nach Brücken zu reduzieren. Dies wird durch den Druckabfall in der Düse beim Drucken in der Luft verursacht, und ein niedrigerer PA hilft, dem entgegenzuwirken."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Standardmäßige Linienbreite, wenn andere Linienbreiten auf 0 gesetzt sind. Wenn als Prozentsatz angegeben, wird sie in Bezug auf den Düsendurchmesser berechnet."
|
||||
@@ -13174,22 +13101,6 @@ msgstr "Richtung des massiven Füllmusters"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Winkel des massiven Füllmusters, der die Start- oder Hauptrichtung der Linie steuert."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Fülldichte"
|
||||
|
||||
@@ -14979,10 +14890,6 @@ msgstr "Ausgerichtet"
|
||||
msgid "Aligned back"
|
||||
msgstr "Ausgerichtet hinten"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Zufall"
|
||||
|
||||
@@ -16049,14 +15956,6 @@ msgstr "Polyhole verdrehen"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Polyhole in jeder Schicht drehen."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-Code Vorschaubilder"
|
||||
|
||||
@@ -19427,12 +19326,6 @@ msgstr "Anzahl der dreieckigen Facetten"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Berechnung läuft, bitte warten..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr "Preset-Bündel"
|
||||
|
||||
@@ -19843,77 +19736,6 @@ msgstr ""
|
||||
"Verwerfungen vermeiden\n"
|
||||
"Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "aktuelle Platte drucken"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Objektkoordinaten"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Weltkoordinaten"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Verschieben (relativ)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Rotation (absolut)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Teile Koordinaten"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Cloud-Synchronisationskonflikt: Dieses Profil hat eine neuere Version in OrcaCloud.\n"
|
||||
#~ "Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Cloud-Synchronisationskonflikt: Ein Profil mit diesem Namen existiert bereits in OrcaCloud.\n"
|
||||
#~ "Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
#~ "Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Cloud-Synchronisationskonflikt: Ein Profil mit demselben Namen wurde zuvor aus der Cloud gelöscht.\n"
|
||||
#~ "Delete löscht Ihr lokales Profil. Force Push überschreibt es mit Ihrem lokalen Profil."
|
||||
|
||||
#~ 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 ""
|
||||
#~ "Cloud-Synchronisationskonflikt: Es gab einen unerwarteten oder nicht identifizierten Profilkonflikt.\n"
|
||||
#~ "Pull lädt die Cloud-Kopie herunter. Force Push überschreibt sie mit Ihrem lokalen Profil."
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Adaptives PA für Überhänge aktivieren (experimentell)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
#~ msgstr ""
|
||||
#~ "Aktivieren Sie adaptives PA auch für Überhänge sowie bei Flussänderungen innerhalb desselben Features. Dies ist eine experimentelle Option, da sie bei ungenau eingestelltem PA-Profil zu Uniformitätsproblemen auf den äußeren Oberflächen vor und nach Überhängen führen kann.\n"
|
||||
#~ "Nicht kompatibel mit Prusa-Druckern, da diese pausieren, um PA-Änderungen zu verarbeiten, was zu Verzögerungen und Defekten führt."
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Pressure Advance für Brücken"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Pressure Advance-Wert für Brücken. Auf 0 setzen, um zu deaktivieren.\n"
|
||||
#~ "\n"
|
||||
#~ "Ein niedrigerer PA-Wert beim Drucken von Brücken hilft, das Auftreten einer leichten Unterextrusion unmittelbar nach Brücken zu reduzieren. Dies wird durch den Druckabfall in der Düse beim Drucken in der Luft verursacht, und ein niedrigerer PA hilft, dem entgegenzuwirken."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Filament-Synchronisierungsoptionen"
|
||||
|
||||
@@ -21754,6 +21576,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "Abwählen"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Skalieren"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "Z-Höhe einhalten"
|
||||
|
||||
@@ -22719,210 +22545,3 @@ msgstr ""
|
||||
#~ msgstr ""
|
||||
#~ "Stil und Form der Stützstruktur. Bei normalem Stützen führt die Projektion in ein regelmäßiges Raster zu stabileren Stützen (Standardeinstellung), während eng anliegende Stütztürme Material sparen und die Narbenbildung am Objekt verringern.\n"
|
||||
#~ "Bei Baumstützen führt der schlanke Stil zu einer aggressiveren Zusammenführung der Äste und spart viel Material (Standard), während der Hybridmodus bei großen überhängenden Flächen eine ähnliche Struktur wie bei normalen Stützstrukturen erzeugt."
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Abnormales Hotend"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Verfügbare Düsen"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Bettmasse der Y-Achse"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Achtung: Das Mischen von Düsendurchmessern in einem Druck wird nicht unterstützt. Wenn die ausgewählte Größe nur auf einem Extruder verfügbar ist, wird der Druck mit einem einzigen Extruder durchgeführt."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Während des Hotend-Upgrades bewegt sich der Werkzeugkopf. Greifen Sie nicht in die Kammer."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Aktivieren Sie diese Option, wenn der Drucker einen Kühlungsfilter unterstützt"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Fehler: Beide Düsenanzahlen können nicht auf Null gesetzt werden."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Fehler: Die Anzahl der Düsen darf %d nicht überschreiten."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Extruderwechsel"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Hotend-Wechsel"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Hotend-Wechselzeit"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Die Hotend-Informationen sind möglicherweise ungenau. Möchten Sie das Hotend erneut auslesen? (Die Hotend-Informationen können sich während des Ausschaltvorgangs ändern)."
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Ich bestätige alle"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Induktions-Hotend-Magazin"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Maximale Kraft der Y-Achse"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Düsenhandbuch"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Düsenauswahl"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Bitte überprüfen Sie, ob der erforderliche Düsendurchmesser und die Durchflussrate mit den aktuell angezeigten Werten übereinstimmen."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Bitte Düsenanzahl einstellen"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Vorheiztemperatur-Delta"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Der Reinigungsturm ist für den Düsenwechsel erforderlich. Ohne Reinigungsturm können Fehler im Modell auftreten. Möchten Sie den Reinigungsturm wirklich deaktivieren?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Alle neu auslesen"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Hotends werden ausgelesen, bitte warten."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Aktualisiere %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Düsenstatus synchronisieren"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU-High-Flow"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Temperatur-Delta, das während des Vorheizens vor dem Werkzeugwechsel angewendet wird."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "Die maximal zulässige gedruckte Masse"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "Die maximal zulässige gedruckte Masse auf einer Platte"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Die maximal zulässige Ausgangskraft der Y-Achse"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Das Hotend befindet sich in einem abnormalen Zustand und ist derzeit nicht verfügbar. Bitte gehen Sie zu „Gerät -> Upgrade“, um die Firmware zu aktualisieren."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Die Maschinenbett-Massenlast der Y-Achse"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Die maximale Volumengeschwindigkeit für das Rammen vor einem Hotend-Wechsel, wobei -1 die Verwendung der maximalen Volumengeschwindigkeit bedeutet."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Die maximale Volumengeschwindigkeit für das Rammen vor dem Extruderwechsel, wobei -1 die Verwendung der maximalen Volumengeschwindigkeit bedeutet."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "Der Werkzeugkopf und das Hotend-Magazin können sich bewegen. Bitte halten Sie Ihre Hände von der Kammer fern."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Das Materialvolumen, das erforderlich ist, um den Extruder für einen Hotend-Wechsel am Turm vorzubereiten."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Zeit, um das Hotend zu wechseln."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Um ein Auslaufen zu verhindern, wird die Düsentemperatur während des Rammens gekühlt. Hinweis: Es wird nur ein Abkühlbefehl und die Aktivierung des Lüfters ausgelöst, das Erreichen der Zieltemperatur ist nicht garantiert. 0 bedeutet deaktiviert."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Um ein Austreten von Material zu verhindern, wird die Düsentemperatur während des Rammens abgekühlt. Daher muss die Rammzeit länger sein als die Abkühlzeit. 0 bedeutet deaktiviert."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Um ein Nachtropfen zu verhindern, führt die Düse nach Abschluss des Rammvorgangs für eine bestimmte Zeit eine Rückwärtsbewegung aus. Die Einstellung definiert die Verfahrzeit."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Unbekannte Düse erkannt. Aktualisieren Sie, um die Informationen zu erfassen (nicht aktualisierte Düsen werden beim Slicen übersprungen)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Unbekannte Düse erkannt. Aktualisieren Sie, um die Informationen zu erfassen (nicht aktualisierte Düsen werden beim Slicen ausgeschlossen). Überprüfen Sie den Düsendurchmesser und die Durchflussrate anhand der angezeigten Werte."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Kühlungsfilter verwenden"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Beim Wechseln des Hotends wird empfohlen, eine bestimmte Länge des Filaments aus der ursprünglichen Düse zu extrudieren. Dies hilft, das Auslaufen der Düse zu minimieren."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Wenn dieser Rückzugswert geändert wird, wird er als die Filamentmenge verwendet, die vor dem Wechsel des Hotends im Hotend zurückgezogen wird."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "Ihr Drucker verfügt über verschiedene Düsen. Bitte wählen Sie eine Düse für diesen Druck aus."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "Länge beim Wechseln des Hotends"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Dynamische Düsen sind auf der aktuellen Platte zugewiesen. Die Auswahl des Hotends wird nicht unterstützt."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Hotend-Magazin"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Hotend-Status ist abnormal, derzeit nicht verfügbar. Bitte aktualisieren Sie die Firmware und versuchen Sie es erneut."
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Hotend-Informationen"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotends im Magazin"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Zur Upgrade-Seite springen"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Hinweis: Die Hotend-Nummer auf dem %s ist an den Halter gebunden. Wenn das Hotend in einen neuen Halter bewegt wird, wird seine Nummer automatisch aktualisiert."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "Düsen-ID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Düseninformationen müssen ausgelesen werden"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Bitte warten"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Drucken mit der aktuellen Düse kann zu %0.2f g zusätzlichem Abfall führen."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Angehoben"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Alle auslesen"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Wird ausgelesen "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Reihe A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Reihe B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Läuft..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Filament & Hotends auswählen"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Standardfluss"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Werkzeugkopf"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Werkzeugkopf"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Nutzungszeit: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: \n"
|
||||
@@ -321,7 +321,6 @@ msgstr ""
|
||||
msgid "Optimize orientation"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr ""
|
||||
|
||||
@@ -331,7 +330,6 @@ msgstr ""
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
|
||||
@@ -365,9 +363,6 @@ msgstr ""
|
||||
msgid "Object operations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Scale"
|
||||
msgstr ""
|
||||
|
||||
msgid "Volume operations"
|
||||
msgstr ""
|
||||
|
||||
@@ -389,32 +384,25 @@ msgstr ""
|
||||
msgid "Reset rotation"
|
||||
msgstr ""
|
||||
|
||||
msgid "World"
|
||||
msgid "Object coordinates"
|
||||
msgstr ""
|
||||
|
||||
msgid "Object"
|
||||
msgid "World coordinates"
|
||||
msgstr ""
|
||||
|
||||
msgid "Part"
|
||||
msgstr ""
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr ""
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgid "Part coordinates"
|
||||
msgstr ""
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
@@ -520,6 +508,12 @@ msgstr ""
|
||||
msgid "Spacing"
|
||||
msgstr ""
|
||||
|
||||
msgid "Part"
|
||||
msgstr ""
|
||||
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1822,30 +1816,23 @@ msgstr ""
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr ""
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1854,12 +1841,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1927,8 +1908,7 @@ msgstr ""
|
||||
msgid "Sync user presets"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2138,9 +2118,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3503,7 +3480,6 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Navigation"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
@@ -4786,7 +4762,6 @@ msgstr ""
|
||||
msgid "Color change"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
@@ -4942,15 +4917,11 @@ msgstr ""
|
||||
msgid "Align to Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
@@ -5029,9 +5000,6 @@ msgstr ""
|
||||
msgid "Outline"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5074,7 +5042,7 @@ msgstr ""
|
||||
msgid "Size:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr ""
|
||||
|
||||
@@ -5267,10 +5235,6 @@ msgstr ""
|
||||
msgid "Export G-code file"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr ""
|
||||
|
||||
@@ -7697,35 +7661,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -7738,12 +7673,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr ""
|
||||
|
||||
@@ -11763,18 +11692,6 @@ msgstr ""
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr ""
|
||||
|
||||
@@ -11927,25 +11844,21 @@ msgid ""
|
||||
"3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
@@ -12302,22 +12215,6 @@ msgstr ""
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr ""
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr ""
|
||||
|
||||
@@ -13934,9 +13831,6 @@ msgstr ""
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
msgid "Random"
|
||||
msgstr ""
|
||||
|
||||
@@ -14887,14 +14781,6 @@ msgstr ""
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr ""
|
||||
|
||||
@@ -18083,12 +17969,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Guislain Cyril, Thomas Lété\n"
|
||||
@@ -324,7 +324,6 @@ msgstr "Gizmo-Pivoter"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optimiser l'orientation"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Redimensionner"
|
||||
|
||||
@@ -334,9 +333,8 @@ msgstr "Gizmo-Redimensionner"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Erreur : Veuillez d'abord fermer tous les menus de la barre d'outils"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "dans"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -368,9 +366,6 @@ msgstr "Rapports d'échelle"
|
||||
msgid "Object operations"
|
||||
msgstr "Opérations sur les objets"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Redimensionner"
|
||||
|
||||
msgid "Volume operations"
|
||||
msgstr "Opérations sur les volumes"
|
||||
|
||||
@@ -392,33 +387,26 @@ msgstr "Réinitialiser la position"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Réinitialiser la rotation"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Coordonnées de l’objet"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objet"
|
||||
msgid "World coordinates"
|
||||
msgstr "Coordonnées"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Pièce"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Translation (relative)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Réinitialiser la rotation actuelle à la valeur lors de l'ouverture de l'outil de rotation."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Rotation (absolue)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Réinitialiser la rotation actuelle à zéro."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Redimensionner"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Coordonnées de la pièce"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -523,6 +511,12 @@ msgstr "Espacement"
|
||||
msgid "Spacing"
|
||||
msgstr "Espacement"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Pièce"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objet"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1861,32 +1855,33 @@ msgstr "Ouvrir un projet"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "La version de OrcaSlicer est trop ancienne et doit être mise à jour vers la dernière version afin qu’il puisse être utilisé normalement."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Conflit de synchronisation cloud : ce préréglage a une version plus récente dans OrcaCloud.\n"
|
||||
"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Conflit de synchronisation cloud : un préréglage de ce nom existe déjà dans OrcaCloud.\n"
|
||||
"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"Conflit de synchronisation cloud : un préréglage du même nom a été précédemment supprimé du cloud.\n"
|
||||
"Supprimer effacera votre préréglage local. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
"Conflit de synchronisation cloud : un conflit de préréglage inattendu ou non identifié s’est produit.\n"
|
||||
"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -1895,12 +1890,6 @@ msgstr ""
|
||||
"Forcer l’envoi écrasera la copie du cloud avec vos modifications locales du préréglage.\n"
|
||||
"Voulez-vous continuer ?"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr "Résoudre le conflit de synchronisation cloud"
|
||||
|
||||
@@ -1980,9 +1969,8 @@ msgstr "Le nombre de préréglages utilisateur mis en cache dans le nuage a dép
|
||||
msgid "Sync user presets"
|
||||
msgstr "Synchroniser les réglages prédéfinis de l’utilisateur"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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 "Le contenu du préréglage est trop volumineux pour être synchronisé avec le cloud (dépasse 1 Mo). Veuillez réduire la taille du préréglage en supprimant des configurations personnalisées, ou l’utiliser uniquement en local."
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2191,9 +2179,6 @@ msgstr "Cube Orca"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "OrcaSliced Combo"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Test de tolérance Orca"
|
||||
|
||||
@@ -3577,7 +3562,6 @@ msgstr "Calibrage terminé. Veuillez trouver la ligne d'extrusion la plus unifor
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
msgctxt "Navigation"
|
||||
msgid "Back"
|
||||
msgstr "Arrière"
|
||||
|
||||
@@ -4925,7 +4909,6 @@ msgstr "Changements d’outil"
|
||||
msgid "Color change"
|
||||
msgstr "Changement de couleur"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Imprimer"
|
||||
|
||||
@@ -5085,15 +5068,11 @@ msgstr "Éviter la région de calibration de l'extrusion"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Aligner sur l’axe Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Arrière"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Gauche"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Droite"
|
||||
|
||||
@@ -5172,9 +5151,6 @@ msgstr "Surplombs"
|
||||
msgid "Outline"
|
||||
msgstr "Contour"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr "Vue réaliste"
|
||||
|
||||
@@ -5217,7 +5193,7 @@ msgstr "Volume :"
|
||||
msgid "Size:"
|
||||
msgstr "Taille :"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Des conflits de chemins G-code ont été trouvés au niveau de la couche %d, z = %.2lfmm. Veuillez séparer davantage les objets en conflit (%s <-> %s)."
|
||||
|
||||
@@ -5416,10 +5392,6 @@ msgstr "Imprimer le plateau"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Exporter le fichier G-code"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Imprimer"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exporter le fichier découpé du plateau"
|
||||
|
||||
@@ -7910,35 +7882,6 @@ msgstr "Afficher les options lors de l'importation d'un fichier STEP"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Si activé, une boîte de dialogue de paramètres apparaîtra lors de l'importation d'un fichier STEP."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Niveau de qualité pour l'exportation Draco"
|
||||
|
||||
@@ -7954,12 +7897,6 @@ msgstr ""
|
||||
"0 = compression sans perte (la géométrie est préservée en pleine précision). Les valeurs avec perte valides vont de 8 à 30.\n"
|
||||
"Des valeurs plus basses produisent des fichiers plus petits mais perdent plus de détails géométriques ; des valeurs plus élevées préservent plus de détails au prix de fichiers plus volumineux."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Préréglage"
|
||||
|
||||
@@ -12292,18 +12229,6 @@ msgstr "Seuil des petits périmètres"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Cela définit le seuil pour une petite longueur de périmètre. Le seuil par défaut est de 0 mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Ordre d’impression des parois"
|
||||
|
||||
@@ -12489,26 +12414,27 @@ msgstr ""
|
||||
"2. Notez la valeur optimale de PA pour chaque vitesse de débit volumétrique et accélération. Vous pouvez trouver le numéro de débit en sélectionnant le débit dans le menu déroulant du schéma de couleurs et en déplaçant le curseur horizontal sur les lignes du schéma PA. Le chiffre doit être visible en bas de la page. La valeur idéale du PA devrait diminuer au fur et à mesure que le débit volumétrique augmente. Si ce n’est pas le cas, vérifiez que votre extrudeur fonctionne correctement. Plus vous imprimez lentement et avec peu d’accélération, plus la plage des valeurs PA acceptables est grande. Si aucune différence n’est visible, utilisez la valeur PA du test le plus rapide.\n"
|
||||
"3 Entrez les triplets de valeurs PA, de débit et d’accélérations dans la zone de texte ici et sauvegardez votre profil de filament."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Activation de l’avance de pression adaptative pour les surplombs (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
"Activez le PA adaptatif pour les surplombs ainsi que lorsque le débit change au sein d’une même structure. Il s’agit d’une option expérimentale : si le profil de PA n’est pas réglé avec précision, elle provoquera des problèmes d’uniformité sur les surfaces externes avant et après les surplombs.\n"
|
||||
"Incompatible avec les imprimantes Prusa, car elles marquent une pause pour traiter les changements de PA, ce qui cause des retards et des défauts."
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Avance de pression pour les ponts"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Valeur de l’avance de pression pour les ponts. Régler à 0 pour désactiver.\n"
|
||||
"\n"
|
||||
" Une valeur PA plus faible lors de l’impression de ponts permet de réduire l’apparition d’une légère sous-extrusion immédiatement après les ponts. Ce phénomène est dû à la chute de pression dans la buse lors de l’impression dans l’air et une valeur PA plus faible permet d’y remédier."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Largeur de ligne par défaut si les autres largeurs de ligne sont fixées à 0. Si elle est exprimée en %, elle sera calculée sur le diamètre de la buse."
|
||||
@@ -12880,22 +12806,6 @@ msgstr "Direction du remplissage"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Angle pour le motif de remplissage, qui contrôle le début ou la direction principale de la ligne"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Densité de remplissage"
|
||||
|
||||
@@ -13112,12 +13022,7 @@ msgid ""
|
||||
"If \"Full fan speed at layer\" is also set, the fan ramps smoothly from this value on the first layer up to your target by the chosen layer.\n"
|
||||
"Only available when \"No cooling for the first\" is 0.\n"
|
||||
"Set to -1 to disable it."
|
||||
msgstr ""
|
||||
"Définit une vitesse de ventilateur exacte pour la première couche, remplaçant tous les autres réglages de refroidissement. Utile pour protéger les pièces de tête d’impression imprimées en 3D (par exemple les conduits ABS/ASA de type Voron) d’un plateau chaud. Un léger flux d’air refroidit les conduits, sans recourir au refroidissement complet qui, dans certaines conditions, peut nuire à l’adhérence de la première couche.\n"
|
||||
"À partir de la deuxième couche, le refroidissement normal reprend.\n"
|
||||
"Si « Ventilateur à pleine vitesse à la couche » est également défini, le ventilateur monte progressivement de cette valeur sur la première couche jusqu’à votre cible à la couche choisie.\n"
|
||||
"Disponible uniquement lorsque « Pas de refroidissement pour » est à 0.\n"
|
||||
"Réglez sur -1 pour le désactiver."
|
||||
msgstr "Définit une vitesse de ventilateur exacte pour la première couche, remplaçant tous les autres réglages de refroidissement. Utile pour protéger les pièces de tête d’impression imprimées en 3D (par exemple les conduits ABS/ASA de type Voron) d’un plateau chaud. Un léger flux d’air refroidit les conduits, sans recourir au refroidissement complet qui, dans certaines conditions, peut nuire à l’adhérence de la première couche.\nÀ partir de la deuxième couche, le refroidissement normal reprend.\nSi « Ventilateur à pleine vitesse à la couche » est également défini, le ventilateur monte progressivement de cette valeur sur la première couche jusqu’à votre cible à la couche choisie.\nDisponible uniquement lorsque « Pas de refroidissement pour » est à 0.\nRéglez sur -1 pour le désactiver."
|
||||
|
||||
msgid "Support interface fan speed"
|
||||
msgstr "Vitesse du ventilateur"
|
||||
@@ -14646,9 +14551,6 @@ msgstr "Alignée"
|
||||
msgid "Aligned back"
|
||||
msgstr "Aligné à l'arrière"
|
||||
|
||||
msgid "Back"
|
||||
msgstr "Arrière"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Aléatoire"
|
||||
|
||||
@@ -15674,14 +15576,6 @@ msgstr "Torsion des trous polygones"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Faites pivoter le trou polygone à chaque couche."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Vignette G-code"
|
||||
|
||||
@@ -18157,9 +18051,7 @@ msgstr "Choisissez où enregistrer le fichier JSON exporté"
|
||||
msgid ""
|
||||
"Export failed\n"
|
||||
"Please check write permissions or file in use by another application"
|
||||
msgstr ""
|
||||
"Échec de l’exportation\n"
|
||||
"Veuillez vérifier les autorisations d’écriture ou si le fichier est utilisé par une autre application"
|
||||
msgstr "Échec de l’exportation\nVeuillez vérifier les autorisations d’écriture ou si le fichier est utilisé par une autre application"
|
||||
|
||||
msgid "Choose where to save the exported ZIP file"
|
||||
msgstr "Choisissez où enregistrer le fichier ZIP exporté"
|
||||
@@ -19011,12 +18903,6 @@ msgstr "Nombre de facettes triangulaires"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Calcul en cours, veuillez patienter…"
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr "Paquet de préréglages"
|
||||
|
||||
@@ -19418,80 +19304,6 @@ msgstr ""
|
||||
"Éviter la déformation\n"
|
||||
"Saviez-vous que lors de l’impression de matériaux susceptibles de se déformer, tels que l’ABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Imprimer"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "dans"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Coordonnées de l’objet"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Coordonnées"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Translation (relative)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Rotation (absolue)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Coordonnées de la pièce"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Conflit de synchronisation cloud : ce préréglage a une version plus récente dans OrcaCloud.\n"
|
||||
#~ "Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Conflit de synchronisation cloud : un préréglage de ce nom existe déjà dans OrcaCloud.\n"
|
||||
#~ "Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
#~ "Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "Conflit de synchronisation cloud : un préréglage du même nom a été précédemment supprimé du cloud.\n"
|
||||
#~ "Supprimer effacera votre préréglage local. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "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 ""
|
||||
#~ "Conflit de synchronisation cloud : un conflit de préréglage inattendu ou non identifié s’est produit.\n"
|
||||
#~ "Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local."
|
||||
|
||||
#~ msgid "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 "Le contenu du préréglage est trop volumineux pour être synchronisé avec le cloud (dépasse 1 Mo). Veuillez réduire la taille du préréglage en supprimant des configurations personnalisées, ou l’utiliser uniquement en local."
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Activation de l’avance de pression adaptative pour les surplombs (beta)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
#~ msgstr ""
|
||||
#~ "Activez le PA adaptatif pour les surplombs ainsi que lorsque le débit change au sein d’une même structure. Il s’agit d’une option expérimentale : si le profil de PA n’est pas réglé avec précision, elle provoquera des problèmes d’uniformité sur les surfaces externes avant et après les surplombs.\n"
|
||||
#~ "Incompatible avec les imprimantes Prusa, car elles marquent une pause pour traiter les changements de PA, ce qui cause des retards et des défauts."
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Avance de pression pour les ponts"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Valeur de l’avance de pression pour les ponts. Régler à 0 pour désactiver.\n"
|
||||
#~ "\n"
|
||||
#~ " Une valeur PA plus faible lors de l’impression de ponts permet de réduire l’apparition d’une légère sous-extrusion immédiatement après les ponts. Ce phénomène est dû à la chute de pression dans la buse lors de l’impression dans l’air et une valeur PA plus faible permet d’y remédier."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Options de synchronisation des filaments"
|
||||
|
||||
@@ -21131,6 +20943,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "Désélectionner"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Redimensionner"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "Exécution du décalage en Z"
|
||||
|
||||
@@ -22080,210 +21896,3 @@ msgstr ""
|
||||
#~ "Veuillez saisir des valeurs valides :\n"
|
||||
#~ "Début > 10 intervalle >= 0\n"
|
||||
#~ "Fin > Début + Intervalle"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Hotend Anormal"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Buses Disponibles"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Masse du plateau de l'axe Y"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Attention : Le mélange de diamètres de buses dans une même impression n'est pas pris en charge. Si la taille sélectionnée se trouve uniquement sur un extrudeur, l'impression mono-extrudeur sera appliquée."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Pendant la mise à niveau du hotend, la tête d’outil va se déplacer. Ne mettez pas vos mains dans la chambre."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Activez cette option si l'imprimante prend en charge le filtre de refroidissement"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Erreur : impossible de définir le nombre de buses à zéro."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Erreur : Le nombre de buses ne peut pas dépasser %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Changement d'extrudeur"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Changement de Hotend"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Temps de changement du Hotend"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Les informations du Hotend peuvent être inexactes. Souhaitez-vous relire le Hotend ? (Les informations du Hotend peuvent changer lors de la coupure d'alimentation)."
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Hybride"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Tout confirmer"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Rack Hotend Induction"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Force maximale de l'axe Y"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Manuel de Buse"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Sélection de Buse"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Veuillez confirmer si le diamètre de la buse requis et le débit correspondent aux valeurs actuellement affichées."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Veuillez définir le nombre de buses"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Écart de température de préchauffage"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Une tour d'amorçage est requise pour le changement de buse. Il peut y avoir des défauts sur le modèle sans cette tour. Êtes-vous sûr de vouloir désactiver la tour d'amorçage ?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Relire tout"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Lecture des hotends, veuillez patienter."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Actualisation %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Synchroniser Buse"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Écart de température appliqué lors du préchauffage avant un changement d'outil."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "Masse maximale imprimée autorisée"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "Masse maximale imprimée autorisée sur une plaque"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Force de sortie maximale autorisée sur l'axe Y"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Cet hotend est dans un état anormal et est actuellement indisponible. Veuillez aller dans \"Appareil -> Mise à jour\" pour mettre à jour le firmware."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Charge massique du plateau de la machine sur l'axe Y"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "La vitesse volumétrique maximale pour l'éperonnage avant un changement de Hotend, où -1 signifie utiliser la vitesse volumétrique maximale."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "La vitesse volumétrique maximale pour l'éperonnage avant le changement d'extrudeuse, où -1 signifie utiliser la vitesse volumétrique maximale."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "La tête d'outil et le rack hotend peuvent se déplacer. Veuillez garder vos mains hors de la chambre."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Le volume de matériau nécessaire pour amorcer l'extrudeur lors d'un changement de hotend sur la tourelle."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Il est temps de changer le Hotend."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Pour éviter les coulures, la température de la buse sera refroidie pendant l'éperonnage. Remarque : seule une commande de refroidissement et l'activation du ventilateur sont déclenchées, l'obtention de la température cible n'est pas garantie. 0 signifie désactivé."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Pour éviter tout suintement, la température de la buse sera réduite pendant l'éperonnage. Par conséquent, le temps d'éperonnage doit être supérieur au temps de refroidissement. 0 signifie désactivé."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Pour éviter le suintement, la buse effectue un mouvement inverse pendant un certain temps après la fin de l'éperonnage. Le réglage définit le temps de déplacement."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Buse inconnue détectée. Actualisez pour mettre à jour (les buses non actualisées seront ignorées lors de la découpe)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Buse inconnue détectée. Actualisez pour mettre à jour les informations (les buses non actualisées seront exclues lors du découpage). Vérifiez le diamètre de la buse et le débit par rapport aux valeurs affichées."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Utiliser le filtre de refroidissement"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Lors du remplacement du hotend, il est recommandé d'extruder une certaine longueur de filament à partir de la buse d'origine. Cela permet de minimiser la bavure de la buse."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Lorsque cette valeur de rétraction est modifiée, elle sera utilisée comme la quantité de filament rétractée à l'intérieur du hotend avant de changer de hotend."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "Votre imprimante est équipée de différentes buses . Veuillez sélectionner une buse pour cette impression."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "longueur lors du changement de hotend"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Les buses dynamiques sont attribuées sur la plaque actuelle. La sélection du hotend n'est pas prise en charge."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Rack Hotends"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "État du hotend anormal, il est indisponible pour le moment. Veuillez mettre à jour le firmware et réessayer."
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Infos Hotends"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotends sur le Rack"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Aller à la page de Mise à jour"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Remarque : Le numéro du hotend sur le %s est lié au support. Lorsque le hotend est déplacé vers un nouveau support, son numéro sera mis à jour automatiquement."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "ID de Buse"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Les informations de la buse doivent être lues"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Veuillez patienter"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Imprimer avec la buse actuelle peut générer %0.2f g de déchets supplémentaires."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Soulevée"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Tout Lire"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Lecture "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Rang A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Rang B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "En cours..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Sélectionnez Filament && Hotends"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Débit Standard"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Tête d'Outil"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Tête d'Outil"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Temps d'Usage: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -324,7 +324,6 @@ msgstr "Gizmo-Forgatás"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Orientáció optimalizálása"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Átméretezés"
|
||||
|
||||
@@ -334,9 +333,8 @@ msgstr "Gizmo-Átméretezés"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Hiba: Kérlek, először zárd be az összes eszköztár menüt"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -369,9 +367,6 @@ msgstr "Méretarányok"
|
||||
msgid "Object operations"
|
||||
msgstr "Objektum műveletek"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Átméretezés"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Térfogat műveletek"
|
||||
@@ -399,33 +394,26 @@ msgstr "Pozíció visszaállítása"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Forgatás visszaállítása"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Objektum koordináták"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objektum"
|
||||
msgid "World coordinates"
|
||||
msgstr "Világkoordináták"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Tárgy"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Eltolás (relatív)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Az aktuális forgatás visszaállítása a forgatás eszköz megnyitásakor érvényes értékre."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Forgatás (abszolút)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Az aktuális forgatás visszaállítása valódi nullára."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Átméretezés"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Alkatrész koordináták"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -530,6 +518,12 @@ msgstr "Rés"
|
||||
msgid "Spacing"
|
||||
msgstr "Térköz"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Tárgy"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objektum"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1873,30 +1867,23 @@ msgstr "Projekt megnyitása"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "A Orca Slicer ezen verziója túl régi és a legfrissebb verzióra kell frissíteni, mielőtt rendesen használható lenne"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1905,12 +1892,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1990,9 +1971,8 @@ msgstr "A felhőben tárolt felhasználói beállítások száma elérte a limit
|
||||
msgid "Sync user presets"
|
||||
msgstr "Felhasználói beállítások szinkronizálása"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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 "Az beállítás tartalom túl nagy a cloud-al való szinkronizáláshoz (több mint 1 MB). Csökkentsd a beállítás méretet az egyéni konfigurációk eltávolításával, vagy használd csak helyileg."
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2213,9 +2193,6 @@ msgstr "Orca kocka"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca tolerancia teszt"
|
||||
|
||||
@@ -3653,7 +3630,7 @@ msgstr "A kalibrálás befejeződött. Kérlek, válaszd ki az alábbi képen l
|
||||
msgid "Save"
|
||||
msgstr "Mentés"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Hátul"
|
||||
|
||||
@@ -5034,7 +5011,6 @@ msgstr "Szerszámváltások"
|
||||
msgid "Color change"
|
||||
msgstr "Színváltás"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Nyomtatás"
|
||||
|
||||
@@ -5198,15 +5174,11 @@ msgstr "Extrudáláskalibráció környékének elkerülése"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Igazítás az Y-tengelyhez"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Hátul"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Bal"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Jobb"
|
||||
|
||||
@@ -5285,9 +5257,6 @@ msgstr "Túlnyúlások"
|
||||
msgid "Outline"
|
||||
msgstr "Körvonal"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5331,7 +5300,7 @@ msgstr "Térfogat:"
|
||||
msgid "Size:"
|
||||
msgstr "Méret:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "G-kód útvonalütközés található a(z) %d. rétegen, Z = %.2lfmm. Helyezd távolabb egymástól az ütköző objektumokat (%s <-> %s)."
|
||||
|
||||
@@ -5534,10 +5503,6 @@ msgstr "Nyomtatótálca"
|
||||
msgid "Export G-code file"
|
||||
msgstr "G-kód fájl exportálása"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Nyomtatás"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Szeletelt tálca exportálása"
|
||||
|
||||
@@ -8075,35 +8040,6 @@ msgstr "Beállítások megjelenítése STEP fájl importálásakor"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Ha engedélyezve van, STEP fájl importálásakor paraméterbeállítási párbeszédablak jelenik meg."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Minőségi szint Draco exporthoz"
|
||||
|
||||
@@ -8119,12 +8055,6 @@ msgstr ""
|
||||
"0 = veszteségmentes tömörítés (a geometria teljes pontossággal megmarad). Az érvényes veszteséges értékek 8 és 30 között vannak.\n"
|
||||
"Az alacsonyabb értékek kisebb fájlokat eredményeznek, de több geometriai részlet vész el; a magasabb értékek több részletet őriznek meg nagyobb fájlméret árán."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Beállítás"
|
||||
|
||||
@@ -12485,18 +12415,6 @@ msgstr "Kis kerületek küszöbértéke"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "A kis peremek hosszának küszöbértékét határozza meg. Az alapértelmezett érték 0 mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Falak nyomtatási sorrendje"
|
||||
|
||||
@@ -12685,26 +12603,25 @@ msgstr ""
|
||||
"2. Jegyezd fel az optimális PA értéket minden volumetrikus áramlási sebességhez és gyorsuláshoz. Az áramlási számot úgy találhatod meg, hogy a színséma legördülő menüben az áramlást választod, majd a vízszintes csúszkát a PA mintavonalak fölé mozgatod. A számnak az oldal alján kell megjelenjen. Az ideális PA értéknek csökkennie kell a volumetrikus áramlás növekedésével. Ha nem így van, ellenőrizd, hogy az extrudered megfelelően működik-e. Minél lassabban és kisebb gyorsulással nyomtatsz, annál nagyobb az elfogadható PA értékek tartománya. Ha nincs látható különbség, használd a gyorsabb tesztből származó PA értéket\n"
|
||||
"3. Add meg a PA értékek, az áramlás és a gyorsulás hármasait az itt található szövegmezőben, majd mentsd el a filamentprofilt."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Adaptív nyomáselőtolás engedélyezése túlnyúlásokhoz (béta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Nyomáselőtolás hidakhoz"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Nyomáselőtolási érték hidakhoz. A kikapcsoláshoz állítsd 0-ra.\n"
|
||||
"\n"
|
||||
"Hidak nyomtatásakor az alacsonyabb PA érték segít csökkenteni a hidak után közvetlenül jelentkező enyhe alulextrudálás megjelenését. Ezt az okozza, hogy a levegőbe nyomtatás során nyomásesés lép fel a fúvókában, amit az alacsonyabb PA részben ellensúlyoz."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Alapértelmezett vonalszélesség, ha a többi vonalszélesség 0-ra van állítva. Ha százalékban van megadva, a fúvókaátmérő alapján lesz kiszámítva."
|
||||
@@ -13087,22 +13004,6 @@ msgstr "Tömör kitöltés iránya"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "A tömör kitöltési minta szöge, amely a vonalak kezdő- vagy fő irányát szabályozza."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Kitöltés sűrűsége"
|
||||
|
||||
@@ -14897,10 +14798,6 @@ msgstr "Igazított"
|
||||
msgid "Aligned back"
|
||||
msgstr "Hátulra igazítva"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Hátul"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Véletlenszerû"
|
||||
|
||||
@@ -15960,14 +15857,6 @@ msgstr "Sokszögelt lyuk elforgatása"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "A sokszögelt lyuk forgatása rétegenként."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-kód miniatűrök"
|
||||
|
||||
@@ -19319,12 +19208,6 @@ msgstr "Háromszögfelületek száma"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Számítás folyamatban, kérlek várj..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19733,45 +19616,6 @@ msgstr ""
|
||||
"Kunkorodás elkerülése\n"
|
||||
"Tudtad, hogy a kunkorodásra hajlamos anyagok (például ABS) nyomtatásakor a tárgyasztal hőmérsékletének növelése csökkentheti a kunkorodás valószínűségét?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Nyomtatás"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Objektum koordináták"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Világkoordináták"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Eltolás (relatív)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Forgatás (abszolút)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Alkatrész koordináták"
|
||||
|
||||
#~ 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 "Az beállítás tartalom túl nagy a cloud-al való szinkronizáláshoz (több mint 1 MB). Csökkentsd a beállítás méretet az egyéni konfigurációk eltávolításával, vagy használd csak helyileg."
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Adaptív nyomáselőtolás engedélyezése túlnyúlásokhoz (béta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Nyomáselőtolás hidakhoz"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Nyomáselőtolási érték hidakhoz. A kikapcsoláshoz állítsd 0-ra.\n"
|
||||
#~ "\n"
|
||||
#~ "Hidak nyomtatásakor az alacsonyabb PA érték segít csökkenteni a hidak után közvetlenül jelentkező enyhe alulextrudálás megjelenését. Ezt az okozza, hogy a levegőbe nyomtatás során nyomásesés lép fel a fúvókában, amit az alacsonyabb PA részben ellensúlyoz."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Filament szinkronizálási opciók"
|
||||
|
||||
@@ -20355,213 +20199,3 @@ msgstr ""
|
||||
|
||||
#~ 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 "Bekapcsolva az extrudálási áramlást az illesztett érték (a vonalszélesség és rétegmagasság alapján számolva) és a felhasználó által megadott maximális áramlás közül a kisebbik korlátozza. Kikapcsolva csak a felhasználó által megadott maximális áramlás érvényesül."
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Rendellenes hotend"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Elérhető fúvókák"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Az Y tengely asztaltömege"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Figyelem: Nem lehetséges a fúvókaátmérők keverése egyetlen nyomtatás során. Ha a kiválasztott méret csak egy extruderen van, akkor az egy extruderes nyomtatás lesz kényszerítve."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "A hotend felismerése során a szerszámfej mozogni fog. Ne nyúlj be a kamrába."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Engedélyezd a beállítást, ha a nyomtató támogatja a hűtőszűrőt"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Hiba: Nem lehet mindkét fúvóka számát nullára állítani."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Hiba: A fúvóka száma nem haladhatja meg a(z) %d értéket."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Extruderváltás"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Hotendváltás"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Hotendváltás ideje"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "A hotendinformációk pontatlanok lehetnek. Szeretnéd újra beolvasni a hotendet? (A hotendinformáció kikapcsolt állapotban megváltozhat)."
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Hibrid"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Összes megerősítése"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Indukciós hotendtartó"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Az Y tengely maximális ereje"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Fúvóka kiválasztás"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Kérjük, ellenőrizd, hogy a szükséges fúvókaátmérő és áramlási sebesség megegyezik-e a kijelzőn lévővel."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Kérjük, állítsd be a fúvókaszámot"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Előmelegítési hőmérséklet delta"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "A fúvókacsere miatt szükség van a törlőtoronyra. Nélküle előfordulhatnak hibák a nyomtatott tárgyon. Biztos, hogy kikapcsolod a törlőtornyot?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Összes újraolvasása"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "A hotendek beolvasása folyamatban van, kérjük várj."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Frissítés %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Fúvókaállapot szinkronizálása"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU nagy áramlású"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Hőmérséklet-különbség alkalmazása az eszközcsere előtti előmelegítés során."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "A megengedett maximális nyomtatott tömeg"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "A megengedett maximális nyomtatott tömeg egy lemezen"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Az Y tengely megengedett maximális kimeneti ereje"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "A hotend állapota rendellenes, és jelenleg nem elérhető. Kérjük, lépj az „Eszköz -> Frissítés“ oldalra a firmware frissítéséhez."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Az Y tengely gépasztaltömeg-terhelése"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "A hotendváltás előtti betolás maximális áramlási sebessége, ahol -1 a maximális sebesség használatát jelenti."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Az extruderváltás előtti betolás maximális áramlási sebessége, ahol -1 a maximális sebesség használatát jelenti."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "Előfordulhat, hogy a szerszámfej és a hotendtartó megmozdul. Kérjük, ne nyúlj a kamrába."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Az extruder átöblítéséhez szükséges anyagmennyiség a hotend cseréjekor."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "A hotendváltás ideje."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "A szivárgás megakadályozása érdekében a fúvóka a betolás során lehűl. Megjegyzés: csak a hűtési parancs és a ventilátor bekapcsolása kerül elküldésre, a célhőmérséklet elérése nem garantált. A 0 letiltást jelent."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "A szivárgás elkerülése érdekében a fúvóka lehűl betolás közben. Ezért a betolási időnek hosszabbnak kell lennie, mint a lehűlési időnek. A 0 kikapcsolja ezt az opciót."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "A szivárgás elkerülése érdekében a fúvóka a betolás befejezése után egy bizonyos ideig visszafelé mozog. A beállítás határozza meg a mozgás idejét."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Ismeretlen fúvóka érzékelve. Frissítsd az adatokat (a nem frissített fúvókákat nem használjuk a szeleteléskor)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Ismeretlen fúvóka érzékelve. Frissítsd az adatokat (a nem frissített fúvókákat nem használjuk a szeleteléskor). Hasonlítsd össze a fúvóka átmérőjét és a térfogatáramot a megjelenített értékekkel."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Hűtőszűrő használata"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "A hotend cseréjekor ajánlott egy bizonyos hosszúságú filamentet extrudálni az eredeti fúvókából. Ez segít minimalizálni a fúvóka szivárgását."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Ha ezt a visszahúzási értéket módosítod, akkor ezt az értéket használja a nyomtató a filament hotend belsejéből történő visszahúzásakor, mielőtt hotendet cserélne."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "A nyomtatóban különböző fúvókák vannak. Kérjük, válassz egy fúvókát a nyomtatáshoz."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "hossz hotendcsere esetén"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "A dinamikus fúvókák a jelenlegi tálcához vannak kiosztva. A hotend kiválasztása nem támogatott."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Hotendtartó"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "A hotend állapota nem megfelelő, jelenleg nem kérdezhető le. Frissítsd a firmware-t, és próbáld újra."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "Hotendek"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Hotendek adatai"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotendek a tartón"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Ugrás a frissítés oldalra"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Megjegyzés: A hotend száma a tartóhoz van rendelve ezen: %s. Amikor a hotendet áthelyezed egy új tartóra, a száma automatikusan frissül."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "Fúvókaazonosító"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "A fúvókainformációkat be kell olvasni"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Kérjük, várj"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "A jelenlegi fúvókával történő nyomtatás %0.2f g többlethulladékot eredményezhet."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Felemelve"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Összes beolvasása"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Beolvasás "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "„A“ sor"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "„B“ sor"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Futtatás..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Válassz filamentet és hotendet"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Normál áramlás"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Szerszámfej"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Szerszámfej"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Felhasznált idő: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "Strumento di rotazione"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Ottimizza orientamento"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Ridimensiona"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "Strumento di ridimensionamento"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Errore: chiudi prima tutti i menu della barra degli strumenti"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "Rapporti di scala"
|
||||
msgid "Object operations"
|
||||
msgstr "Operazioni sugli oggetti"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Ridimensiona"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Operazioni volume"
|
||||
@@ -402,33 +397,26 @@ msgstr "Ripristina posizione"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Reimposta rotazione"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Coordinate oggetto"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Oggetto"
|
||||
msgid "World coordinates"
|
||||
msgstr "Coordinate reali"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Parte"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Trasla (relativo)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Reimposta la rotazione corrente al valore di apertura dello strumento."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Ruota (assoluto)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Reimposta la rotazione corrente a zero reale."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Ridimensiona"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Coordinate della parte"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr ""
|
||||
msgid "Spacing"
|
||||
msgstr "Spaziatura"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Parte"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Oggetto"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1875,30 +1869,23 @@ msgstr "Apri progetto"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "La versione di OrcaSlicer è obsoleta. Devi aggiornarla all'ultima versione prima di poter utilizzare normalmente il programma."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1907,12 +1894,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1992,9 +1973,8 @@ msgstr "Il numero di profili utente memorizzati nel cloud ha superato il limite
|
||||
msgid "Sync user presets"
|
||||
msgstr "Sincronizza profili utente"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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 "Il contenuto del profilo è troppo grande per essere sincronizzato con il cloud (supera 1 MB). Si prega di ridurre le dimensioni del profilo rimuovendo le configurazioni personalizzate oppure utilizzarlo solo in locale."
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2215,9 +2195,6 @@ msgstr "Cubo di Orca"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Test di tolleranza di OrcaSlicer"
|
||||
|
||||
@@ -3654,7 +3631,7 @@ msgstr "Calibrazione completata. Trova la linea di estrusione più uniforme sul
|
||||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Posteriore"
|
||||
|
||||
@@ -5035,7 +5012,6 @@ msgstr "Cambi testina"
|
||||
msgid "Color change"
|
||||
msgstr "Cambio colore"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Stampa"
|
||||
|
||||
@@ -5199,15 +5175,11 @@ msgstr "Evitare la regione di calibrazione dell'estrusione"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Allinea all'asse Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Posteriore"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Sinistra"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Destra"
|
||||
|
||||
@@ -5286,9 +5258,6 @@ msgstr "Sporgenze"
|
||||
msgid "Outline"
|
||||
msgstr "Contorno"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5332,7 +5301,7 @@ msgstr ""
|
||||
msgid "Size:"
|
||||
msgstr "Dimensione:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Sono stati trovati conflitti di percorsi nel G-code sullo strato %d, Z = %.2lfmm. Si prega di separare gli oggetti in conflitto (%s <-> %s)."
|
||||
|
||||
@@ -5535,10 +5504,6 @@ msgstr "Piatto di stampa"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Esporta file G-code"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Stampa"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Esporta il file del piatto elaborato"
|
||||
|
||||
@@ -8082,35 +8047,6 @@ msgstr "Mostra opzioni durante l'importazione di file STEP"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Se abilitato, una finestra di dialogo per le impostazioni dei parametri apparirà durante l'importazione di file STEP."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Livello di qualità per l'esportazione Draco"
|
||||
|
||||
@@ -8126,12 +8062,6 @@ msgstr ""
|
||||
"0 = compressione senza perdita (la geometria viene preservata a piena precisione). I valori con perdita validi vanno da 8 a 30.\n"
|
||||
"Valori più bassi producono file più piccoli ma perdono più dettagli geometrici; valori più alti preservano più dettagli a costo di file più grandi."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Profilo"
|
||||
|
||||
@@ -12468,18 +12398,6 @@ msgstr "Soglia perimetri piccoli"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Imposta la soglia per la lunghezza dei perimetri piccoli. La soglia predefinita è 0 mm."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Ordine stampa pareti"
|
||||
|
||||
@@ -12668,26 +12586,25 @@ msgstr ""
|
||||
"2. Prendi nota del valore AP ottimale per ogni portata volumetrica e accelerazione. Puoi trovare il numero relativo alla portata volumetrica dal menu a discesa dello schema di colori e spostando il cursore orizzontale sulle linee del modello AP. Il numero dovrebbe essere visibile nella parte inferiore della pagina. Il valore AP ideale dovrebbe decrescere all'aumentare della portata volumetrica. In caso contrario, verifica che l'estrusore funzioni correttamente. Più lentamente e con meno accelerazione stampi, più ampio è l'intervallo di valori AP accettabili. Se non è visibile alcuna differenza, usa il valore AP dal test più veloce\n"
|
||||
"3. Inserisci le triplette dei valori di anticipo di pressione, portata e accelerazione nella casella di testo qui e salva il tuo profilo di filamento."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Abilita anticipo di pressione adattiva per sporgenze (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Anticipo di pressione per ponti"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Valore di anticipo di pressione per i ponti. Impostare su 0 per disabilitare.\n"
|
||||
"\n"
|
||||
"Un valore AP più basso durante la stampa di ponti aiuta a ridurre la comparsa di una leggera sottoestrusione subito dopo l'estrusione dei ponti. Ciò è causato dalla caduta di pressione nell'ugello durante la stampa in aria e un anticipo di pressione più basso aiuta a contrastarla."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Larghezza di linea predefinita se le altre larghezze di linea sono impostate su 0. Se espresso come una %, verrà calcolato sul diametro del ugello."
|
||||
@@ -13070,22 +12987,6 @@ msgstr "Direzione riempimento solido"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Angolo per il motivo del riempimento solido, che controlla l'inizio o la direzione principale delle linee."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Densità riempimento sparso"
|
||||
|
||||
@@ -14871,10 +14772,6 @@ msgstr "Allineato"
|
||||
msgid "Aligned back"
|
||||
msgstr "Allineato dietro"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Posteriore"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Casuale"
|
||||
|
||||
@@ -15927,14 +15824,6 @@ msgstr "Torsione poliforo"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Ruota il poliforo in ogni strato."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Miniature G-code"
|
||||
|
||||
@@ -19302,12 +19191,6 @@ msgstr "Numero di facce triangolari"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Calcolo in corso, attendere..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19713,45 +19596,6 @@ msgstr ""
|
||||
"Evita le deformazioni\n"
|
||||
"Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Stampa"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Coordinate oggetto"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Coordinate reali"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Trasla (relativo)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Ruota (assoluto)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Coordinate della parte"
|
||||
|
||||
#~ 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 "Il contenuto del profilo è troppo grande per essere sincronizzato con il cloud (supera 1 MB). Si prega di ridurre le dimensioni del profilo rimuovendo le configurazioni personalizzate oppure utilizzarlo solo in locale."
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Abilita anticipo di pressione adattiva per sporgenze (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Anticipo di pressione per ponti"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Valore di anticipo di pressione per i ponti. Impostare su 0 per disabilitare.\n"
|
||||
#~ "\n"
|
||||
#~ "Un valore AP più basso durante la stampa di ponti aiuta a ridurre la comparsa di una leggera sottoestrusione subito dopo l'estrusione dei ponti. Ciò è causato dalla caduta di pressione nell'ugello durante la stampa in aria e un anticipo di pressione più basso aiuta a contrastarla."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Opzioni sincronizzazione filamento"
|
||||
|
||||
@@ -21232,6 +21076,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "Deseleziona"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Ridimensiona"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "Applicazione dell'ascensore Z"
|
||||
|
||||
@@ -21936,216 +21784,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Do not recommend bed temperature of other layer to be lower than initial layer for more than this threshold. Too low bed temperature of other layer may cause the model broken free from build plate"
|
||||
#~ msgstr "Non è consigliabile che la temperatura del piano degli altri layer sia inferiore a quella del primo layer di oltre questa soglia. Una temperatura del piano troppo bassa degli altri layer può causare il distacco dell'oggetto dal piatto."
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Hotend Anomalo"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Nozzle disponibili"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Massa del piano lungo l'asse Y"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Attenzione: L'uso di diametri nozzle differenti in una sola stampa non è supportata. Se la dimensione selezionata è disponibile solo su un estrusore, verrà forzata la stampa con un solo estrusore."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Durante l'aggiornamento dell'hotend, la testa di stampa si muoverà. Non inserire la mano nella camera."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Abilita questa opzione se la stampante supporta il filtro di raffreddamento."
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Errore: Impossibile impostare il numero di nozzle su zero."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Errore: il numero di nozzle non può superare %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Cambio dell'estrusore"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Cambio Hotend"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Tempo cambio Hotend"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Le informazioni sull'Hotend potrebbero non essere accurate. Vuoi rileggere l'Hotend? (Le informazioni sull'Hotend potrebbero cambiare durante lo spegnimento)."
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Ibrido"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Confermo tutto"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Rack Hotend a Induzione"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Forza massima dell'asse Y"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Manuale nozzle"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Selezione Nozzle"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Verifica se il diametro del nozzle richiesto eil flusso corrispondono ai valori attualmente visualizzati."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Imposta il numero di nozzle"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Differenza di temperatura di preriscaldamento"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "La torre di spurgo è necessaria per la sostituzione del nozzle. Senza la prime tower potrebbero esserci dei difetti sul modello. Sei sicuro di voler disabilitare la torre di spurgo?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Rileggi tutto"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Lettura degli hotend in corso, attendi."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Aggiornamento %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Sync Nozzle"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU Alto FLusso"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Differenza di temperatura applicata durante il preriscaldamento prima del cambio utensile."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "La massima massa stampata consentita"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "La massima massa di stampa consentita su un piatto"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "La forza di uscita massima consentita dell'asse Y"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Questo hotend presenta un’anomalia ed è attualmente non disponibile. Vai su 'Dispositivo -> Aggiorna' per aggiornare il firmware."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Il carico di massa del piano della macchina sull'asse Y"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "La velocità volumetrica massima per l'urto prima di una sostituzione del Hotend, dove -1 indica l'utilizzo della velocità volumetrica massima."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "La velocità volumetrica massima per l'urto prima del cambio dell'estrusore, dove -1 indica l'utilizzo della velocità volumetrica massima."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "La testa di stampa e il supporto hotend potrebbero muoversi. Tieni le mani lontane dalla camera."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Volume di materiale necessario per innescare l'estrusore in vista di una sostituzione dell'hotend sulla torre."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "È ora di sostituire l'hotend."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Per prevenire la trasudazione, la temperatura del nozzle verrà raffreddata durante la pressatura. Nota: viene attivato solo un comando di raffreddamento e la ventola, non è garantito il raggiungimento della temperatura target. 0 significa disabilitato."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Per evitare fuoriuscite di materiale, la temperatura del nozzle verrà abbassata durante il ramming. Pertanto, il tempo di ramming deve essere superiore al tempo di raffreddamento. 0 indica che la funzione è disattivata."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Per evitare trasudamento, il nozzle eseguirà un movimento con percorso inverso per un certo periodo dopo il completamento della battuta. L'impostazione definisce il tempo di percorrenza."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Nozzle sconosciuto rilevato. Effettua un refresh per aggiornare (i nozzle non aggiornati verranno saltati durante l'elaborazione)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Nozzle sconosciuto rilevato. Effettua un refresh per aggiornare le informazioni (i nozzle non aggiornati saranno esclusi durante l'elaborazione). Verifica il diametro del nozzle e il flusso rispetto ai valori mostrati."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Usa filtro raffreddamento"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Quando si cambia l'hotend, è consigliato estrudere una certa lunghezza di filamento dall nozzle originale. Questo aiuta a ridurre al minimo la trasudazione dal nozzle."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Quando questo valore di retrazione viene modificato, verrà utilizzato come quantità di filamento retratto all'interno del hotend prima di cambiare hotend."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "La tua stampante dispone di diversi nozzle installati. Seleziona un nozzle per questa stampa."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "lunghezza quando si cambia hotend"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "I Nozzle Dinamici sono assegnati al piatto corrente. La selezione dell’hotend non è supportata."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Rack Hotend"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Stato hotend anomalo, al momento non disponibile. Aggiorna il firmware e riprova."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "Hotend"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Informazioni Hotend"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotend sul Rack"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Vai alla pagina dell'aggiornamento"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Nota: Il numero del hotend su %s è collegato al supporto. Quando un hotend viene spostato su un nuovo supporto, il suo numero verrà aggiornato automaticamente."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "ID Nozzle"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "È necessario leggere le informazioni sul nozzle"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Attendi prego"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "La stampa con l'attuale nozzle potrebbe generare un %0.2f g extra di scarto."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Sollevato"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Leggi Tutto"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Lettura "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Fila A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Fila B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "In Corso..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Seleziona Filamento e Hotend"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Flusso standard"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Testa di stampa"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Testa di stampa"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Tempo Utilizzo: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "ギズモ-回転"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "向きを最適化"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "スケール"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "ギズモ-縮尺"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "エラー: ツールバーを閉じてください"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "に"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "倍率"
|
||||
msgid "Object operations"
|
||||
msgstr "オブジェクト操作"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "スケール"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "操作"
|
||||
@@ -402,33 +397,26 @@ msgstr "位置をリセット"
|
||||
msgid "Reset rotation"
|
||||
msgstr "回転をリセット"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "オブジェクト座標"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "OBJ"
|
||||
msgid "World coordinates"
|
||||
msgstr "空間座標"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "パーツ"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "移動(相対)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "回転ツールを開いた時の値にリセットします。"
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "回転(絶対)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "現在の回転を0にリセットします。"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "スケール"
|
||||
msgid "Part coordinates"
|
||||
msgstr "パーツ座標"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr "ギャップ"
|
||||
msgid "Spacing"
|
||||
msgstr "間隔"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "パーツ"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "OBJ"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1874,30 +1868,23 @@ msgstr "プロジェクトを開く"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "現在のOrca Slicerはバージョンが古いため使用できません、アップデートしてください。"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1906,12 +1893,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1986,8 +1967,7 @@ msgstr "クラウドにキャッシュされたユーザープリセット数が
|
||||
msgid "Sync user presets"
|
||||
msgstr "ユーザープリセットを同期"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2209,9 +2189,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca公差テスト"
|
||||
|
||||
@@ -3637,7 +3614,7 @@ msgstr "キャリブレーションが完了しました。下の写真のよう
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
@@ -5008,7 +4985,6 @@ msgstr "ツールチェンジ"
|
||||
msgid "Color change"
|
||||
msgstr "色変更"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "造形する"
|
||||
|
||||
@@ -5172,15 +5148,11 @@ msgstr "押出しキャリブレーション領域を避ける"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Y軸に整列"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "左"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "右"
|
||||
|
||||
@@ -5259,9 +5231,6 @@ msgstr "オーバーハング"
|
||||
msgid "Outline"
|
||||
msgstr "アウトライン"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5305,7 +5274,7 @@ msgstr "ボリューム"
|
||||
msgid "Size:"
|
||||
msgstr "サイズ:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "レイヤー%d、Z = %.2lfmmでG-codeパスの衝突が検出されました。衝突するオブジェクトをもっと離してください(%s <-> %s)。"
|
||||
|
||||
@@ -5502,10 +5471,6 @@ msgstr "造形開始"
|
||||
msgid "Export G-code file"
|
||||
msgstr "G-codeをエクスポート"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "造形する"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "エクスポート"
|
||||
|
||||
@@ -8040,35 +8005,6 @@ msgstr "STEPファイルインポート時にオプションを表示"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "有効にすると、STEPファイルインポート時にパラメータ設定ダイアログが表示されます。"
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Dracoエクスポートの品質レベル"
|
||||
|
||||
@@ -8084,12 +8020,6 @@ msgstr ""
|
||||
"0 = 可逆圧縮(ジオメトリは完全な精度で保持されます)。有効な非可逆値の範囲は8〜30です。\n"
|
||||
"低い値はファイルサイズが小さくなりますがジオメトリの詳細が失われます。高い値はファイルサイズが大きくなりますがより多くの詳細が保持されます。"
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "プリセット"
|
||||
|
||||
@@ -12271,18 +12201,6 @@ msgstr "小さな外周のしきい値"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "壁の印刷順序"
|
||||
|
||||
@@ -12438,25 +12356,21 @@ msgid ""
|
||||
"3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
@@ -12831,22 +12745,6 @@ msgstr ""
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr ""
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "充填密度"
|
||||
|
||||
@@ -14519,10 +14417,6 @@ msgstr "整列"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "ランダム"
|
||||
|
||||
@@ -15516,14 +15410,6 @@ msgstr ""
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Gコードのサムネイル"
|
||||
|
||||
@@ -18793,12 +18679,6 @@ msgstr "三角面の数"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "計算中、お待ちください..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19181,27 +19061,6 @@ msgstr ""
|
||||
"反りを避ける\n"
|
||||
"ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "造形する"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "に"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "オブジェクト座標"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "空間座標"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "移動(相対)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "回転(絶対)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "パーツ座標"
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "フィラメント同期オプション"
|
||||
|
||||
@@ -20130,6 +19989,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "選択解除"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "スケール"
|
||||
|
||||
#~ msgid "Z-hop when retract"
|
||||
#~ msgstr "リトラクト時にZ方向調整"
|
||||
|
||||
@@ -20483,216 +20346,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Orient the model"
|
||||
#~ msgstr "モデルの向きを調整"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "異常なホットエンド"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "利用可能なノズル"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Y軸のベッド質量"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "注意:1つの造形でノズル径の混在はサポートされていません。選択したサイズが片方の押出機にしかない場合は、単一押出機での造形が強制されます。"
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "ホットエンドのアップグレード中にツールヘッドが動きます。チャンバー内に手を入れないでください。"
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "プリンターが冷却フィルターに対応している場合は有効にする"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "エラー:両方のノズル数を0に設定することはできません。"
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "エラー:ノズル数は%dを超えることはできません。"
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "押出機の変更"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "ホットエンドの変更"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "ホットエンド交換時間"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "ホットエンドの情報が正確でない可能性があります。再読み込みしますか?(電源オフ時に情報が変更される場合があります)"
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "ハイブリッド"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "すべて確認しました"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "誘導式ホットエンドラック"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Y軸の最大力"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "ノズルマニュアル"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "ノズル選択"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "必要なノズル径と流量が、現在表示されている値と一致しているかご確認ください。"
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "ノズル数を設定してください"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "予熱温度差"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "ノズルの切り替えにはプライムタワーが必要です。無効にするとモデルに欠陥が生じる可能性があります。本当にプライムタワーを無効にしますか?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "すべて再読み込み"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "ホットエンドを読み取り中です。しばらくお待ちください。"
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "更新中 %d/%d…"
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "ノズル状態を同期"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPUハイフロー"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "工具交換前の予熱中に適用される温度差。"
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "印刷可能な最大質量"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "プレートに印刷できる最大質量"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Y軸の許容最大出力"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "ホットエンドが異常な状態のため、現在使用できません。「デバイス -> アップグレード」からファームウェアをアップデートしてください。"
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Y軸のマシンベッド質量"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "ホットエンド変更前のラミングにおける最大体積流量です。-1 を設定すると、最大体積流量が使用されます。"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "押出機切り替え前のラミングにおける最大体積流量です。-1 を設定すると、最大体積流量が使用されます。"
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "ツールヘッドおよびホットエンドラックが動く可能性があります。チャンバー内に手を入れないでください。"
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "ホットエンド変更を伴う場合に、プライムタワー上で押出機を初期化するために必要な材料量です。"
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "ホットエンドの切り替えにかかる時間です。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "ノズルの垂れを防ぐため、ラミング中にノズル温度を冷却します。注:冷却指示とファンの作動のみが行われ、目標温度に達することは保証されません。0を設定すると無効になります。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "糸引きを防ぐため、ラム動作中にノズル温度が冷却されます。そのため、ラム動作時間は冷却時間より長く設定する必要があります。0を指定すると、この機能は無効になります。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "糸引きを防ぐために、ラム動作の完了後にノズルが一定時間逆方向へ移動します。この設定では、その移動時間を定義します。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "不明なノズルが検出されました。情報を更新してください(未更新のノズルはスライスから除外されます)。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "不明なノズルが検出されました。情報を更新してください(更新されていないノズルはスライス時に除外されます)。ノズル径と流量が表示と一致しているかご確認ください。"
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "冷却フィルターを使用"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "ホットエンドを切り替える際、元のノズルから一定量のフィラメントを押し出すことを推奨します。これにより、ノズルの垂れを最小限に抑えられます。"
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "このリトラクション値を変更すると、ホットエンドを切り替える前にノズル内で引き戻すフィラメントの長さとして使用されます。"
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "プリンターには異なるノズルが取り付けられています。この造形に使用するノズルを選択してください。"
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "ノズル切替時のリトラクト長さ"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "現在のプレートではダイナミックノズルが割り当てられています。ホットエンドの手動選択はできません。"
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "ホットエンドラック"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "ホットエンドの状態が異常のため、現在使用できません。ファームウェアを更新してから再度お試しください。"
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "ホットエンド"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "ホットエンド情報"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "ラック上のホットエンド"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "アップグレードページに移動"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "注:%s のホットエンド番号はホルダーに紐づいています。ホットエンドを新しいホルダーに移動すると、その番号は自動的に更新されます。"
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "ノズルID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "ノズル情報を読み取る必要があります"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "お待ちください"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "現在のノズルで造形すると、約%0.2fgのフィラメントが無駄になる可能性があります。"
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "上昇した"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "すべて読み取り"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "読み取り中"
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "A列"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "B列"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "実行中..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "フィラメントとホットエンドを選択"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "標準フロー"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "ツールヘッド"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "ツールヘッド"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "使用時間: %s"
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
|
||||
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -331,7 +331,6 @@ msgstr "변형도구 - 회전"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "방향 최적화"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "배율"
|
||||
|
||||
@@ -341,9 +340,8 @@ msgstr "변형도구 - 배율"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "오류: 먼저 모든 도구 모음 메뉴를 닫으십시오."
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "인치"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -376,9 +374,6 @@ msgstr "배율비"
|
||||
msgid "Object operations"
|
||||
msgstr "객체 작업"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "배율"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "용량 작업"
|
||||
@@ -406,33 +401,26 @@ msgstr "위치 초기화"
|
||||
msgid "Reset rotation"
|
||||
msgstr "회전 재설정"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "객체 좌표"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "객체"
|
||||
msgid "World coordinates"
|
||||
msgstr "영역 좌표"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "부품"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "이동(상대)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "회전 도구를 열었을 때의 값으로 현재 회전을 초기화합니다."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "회전 (절대)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "현재 회전을 0으로 초기화합니다."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "배율"
|
||||
msgid "Part coordinates"
|
||||
msgstr "파트 좌표"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -537,6 +525,12 @@ msgstr "간격"
|
||||
msgid "Spacing"
|
||||
msgstr "간격"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "부품"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "객체"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1880,30 +1874,23 @@ msgstr "프로젝트 열기"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Orca Slicer의 버전이 너무 낮아 최신 버전으로 업데이트해야 정상적으로 사용 가능합니다"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1912,12 +1899,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1992,8 +1973,7 @@ msgstr "클라우드에 캐시된 사용자 사전 설정 수가 상한을 초
|
||||
msgid "Sync user presets"
|
||||
msgstr "사용자 사전 설정 동기화"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2216,9 +2196,6 @@ msgstr "Orca 큐브"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca 공차 테스트"
|
||||
|
||||
@@ -3652,7 +3629,7 @@ msgstr "교정이 완료되었습니다. 당신의 고온 베드에서 아래
|
||||
msgid "Save"
|
||||
msgstr "저장"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "뒷면"
|
||||
|
||||
@@ -5034,7 +5011,6 @@ msgstr ""
|
||||
msgid "Color change"
|
||||
msgstr "색 변경"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "출력"
|
||||
|
||||
@@ -5198,15 +5174,11 @@ msgstr "압출 교정 영역을 피하세요"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Y축에 정렬"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "뒷면"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "왼쪽"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "오른쪽"
|
||||
|
||||
@@ -5285,9 +5257,6 @@ msgstr "오버행"
|
||||
msgid "Outline"
|
||||
msgstr "외곽선"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5331,7 +5300,7 @@ msgstr "용량:"
|
||||
msgid "Size:"
|
||||
msgstr "크기:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "레이어 %d, Z = %.2lf mm에서 Gcode 경로 충돌이 발견되었습니다. 충돌하는 객체를 더 멀리 분리하세요 (%s <-> %s)."
|
||||
|
||||
@@ -5530,10 +5499,6 @@ msgstr "플레이트 출력"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Gcode 파일 내보내기"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "출력"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "플레이트 슬라이스 파일 내보내기"
|
||||
|
||||
@@ -8067,35 +8032,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8108,12 +8044,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "사전 설정"
|
||||
|
||||
@@ -12394,18 +12324,6 @@ msgstr "작은 둘레 임계값"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "작은 둘레 길이에 대한 임계값을 설정합니다. 기본 임계값은 0mm입니다"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "벽 출력 순서"
|
||||
|
||||
@@ -12590,26 +12508,25 @@ msgstr ""
|
||||
"2. 각 압출 유속 및 가속도에 대한 최적의 PA 값을 기록해 두십시오. 색상 구성표 드롭다운에서 흐름을 선택하고 PA 패턴 라인 위로 수평 슬라이더를 이동하여 흐름 번호를 찾을 수 있습니다. 페이지 하단에 번호가 표시되어야 합니다. 이상적인 PA 값은 압출 압출량이 높을수록 감소해야 합니다. 그렇지 않은 경우 압출기가 올바르게 작동하는지 확인하십시오. 출력 속도가 느리고 가속도가 낮을수록 허용되는 PA 값의 범위는 더 커집니다. 차이가 보이지 않으면 더 빠른 테스트의 PA 값을 사용하십시오.\n"
|
||||
"3. 여기 텍스트 상자에 PA 값, 흐름 및 가속도의 세 가지 값을 입력하고 필라멘트 프로필을 저장하세요."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "오버행에 대한 적응형 PA 활성화(베타)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "브릿지를 위한 PA"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"브릿지의 PA 값입니다. 비활성화하려면 0으로 설정합니다.\n"
|
||||
"\n"
|
||||
" 브릿지를 프린팅할 때 PA 값이 낮으면 브릿지 직후에 약간의 언더 압출이 나타나는 것을 줄이는 데 도움이 됩니다. 이는 공중에서 출력할 때 노즐의 압력 강하로 인해 발생하며 PA가 낮을수록 이를 방지하는 데 도움이 됩니다."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "다른 선 너비가 0으로 설정된 경우 기본 선 너비입니다. %로 입력 시 노즐 직경에 대한 비율로 계산됩니다."
|
||||
@@ -12985,22 +12902,6 @@ msgstr "꽉찬 채우기 방향"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "선의 시작 또는 기본 방향을 제어하는 솔리드 채우기 패턴의 각도"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "드문 채우기 밀도"
|
||||
|
||||
@@ -14737,10 +14638,6 @@ msgstr "정렬"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "뒷면"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "무작위"
|
||||
|
||||
@@ -15785,14 +15682,6 @@ msgstr "폴리홀 회전"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "레이어마다 폴리홀을 회전시킵니다."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Gcode 미리보기"
|
||||
|
||||
@@ -19138,12 +19027,6 @@ msgstr "삼각형 패싯 수"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "계산 중, 잠시만 기다려주세요..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19549,42 +19432,6 @@ msgstr ""
|
||||
"뒤틀림 방지\n"
|
||||
"ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "출력"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "인치"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "객체 좌표"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "영역 좌표"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "이동(상대)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "회전 (절대)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "파트 좌표"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "오버행에 대한 적응형 PA 활성화(베타)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "브릿지를 위한 PA"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "브릿지의 PA 값입니다. 비활성화하려면 0으로 설정합니다.\n"
|
||||
#~ "\n"
|
||||
#~ " 브릿지를 프린팅할 때 PA 값이 낮으면 브릿지 직후에 약간의 언더 압출이 나타나는 것을 줄이는 데 도움이 됩니다. 이는 공중에서 출력할 때 노즐의 압력 강하로 인해 발생하며 PA가 낮을수록 이를 방지하는 데 도움이 됩니다."
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "시점 컨트롤 설정"
|
||||
|
||||
@@ -21043,6 +20890,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "선택 취소"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "규모"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "강제 Z 올리기"
|
||||
|
||||
@@ -21885,216 +21736,3 @@ msgstr ""
|
||||
#~ "유효한 값을 입력하십시오:\n"
|
||||
#~ "시작 > 10 단계 >= 0\n"
|
||||
#~ "끝 > 시작 + 단계)"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "비정상 핫엔드"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "사용 가능한 노즐"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Y축의 베드 질량"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "주의: 한 번에 여러 노즐 직경을 혼합하여 출력하는 것은 지원되지 않습니다. 선택한 크기가 압출기 하나에만 있는 경우, 단일 압출기 출력이 적용됩니다."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "핫엔드 업그레이드 중에 툴헤드가 움직일 것입니다. 챔버 내부에 손을 넣지 마십시오."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "프린터가 냉각 필터를 지원하는 경우 이 기능을 활성화하세요."
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "오류: 노즐 수를 둘 다 0으로 설정할 수 없습니다."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "오류: 노즐 수는 %d을 초과할 수 없습니다."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "압출기 교체"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "핫엔드 교체"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "핫엔드 교체 시간"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "핫엔드 정보가 부정확할 수 있습니다. 핫엔드를 다시 읽어 보시겠습니까? (핫엔드 정보는 전원이 꺼지는 동안 변경될 수 있습니다.)"
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "하이브리드"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "모두 확인합니다"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "인덕션 핫엔드 랙"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Y축의 최대 힘"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "노즐 설명서"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "노즐 선택"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "필요한 노즐 직경과 유량이 현재 표시된 값과 일치하는지 확인하세요."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "노즐 수를 설정하세요"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "예열 온도 차이"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "노즐 교체를 위해 프라임 타워가 필요합니다. 프라임 타워가 없으면 모델에 결함이 있을 수 있습니다. 프라임 타워를 비활성화하시겠습니까?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "모두 다시 읽기"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "핫엔드를 읽는 중입니다, 잠시 기다려 주십시오."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "새로 고침 %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "노즐 상태 동기화"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU 고유량"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "도구 교체 전 예열 과정에서 적용되는 온도 차이입니다."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "허용되는 최대 출력 질량"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "플레이트에 허용되는 최대 출력 질량"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Y축의 허용 최대 출력 힘"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "이 핫엔드에 이상 상태가 발생하여 현재 사용할 수 없습니다. '장치 -> 업그레이드'로 이동하여 펌웨어를 업그레이드해 주세요."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Y축 장비 베드 질량 하중"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "핫엔드 교체 전에 적용되는 충돌의 최대 체적 속도이며, 여기서 -1은 최대 체적 속도를 사용함을 의미합니다."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "압출기 교체 전 충돌을 위한 최대 체적 속도이며, 여기서 -1은 최대 체적 속도를 사용함을 의미합니다."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "툴헤드와 핫엔드 랙이 움직일 수 있습니다. 챔버에 손을 대지 마십시오."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "타워에서 핫엔드를 교체하기 위해 압출기를 준비하는 데 필요한 재료 부피."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "핫엔드를 교체할 시간입니다."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "누수 방지를 위해 충돌 중 노즐 온도가 낮아집니다. 참고: 냉각 명령과 팬 작동만 실행되며, 목표 온도 도달은 보장되지 않습니다. 0은 비활성화를 의미합니다."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "흘러내림을 방지하기 위해 래밍하는 동안 노즐 온도가 냉각됩니다. 따라서 래밍 시간은 쿨다운 시간보다 길어야 합니다. 0은 비활성화를 의미합니다."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "흘러내림을 방지하기 위해 노즐은 래밍이 완료된 후 일정 시간 동안 역방향 이동을 수행합니다. 이 설정은 이동 시간을 정의합니다."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "알 수 없는 노즐이 감지되었습니다. 새로 고침하여 업데이트하세요(새로 고침되지 않은 노즐은 슬라이싱 시 건너뜁니다)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "알 수 없는 노즐이 감지되었습니다. 정보를 업데이트하려면 새로 고침하세요(새로 고침되지 않은 노즐은 슬라이싱 과정에서 제외됩니다). 표시된 값과 노즐 직경 및 유량을 확인하세요."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "냉각 필터 사용"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "핫엔드를 교체할 때는 원래 노즐에서 일정 길이의 필라멘트를 압출하는 것이 좋습니다. 이렇게 하면 노즐 흘러내림을 최소화할 수 있습니다."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "이 수축 값이 수정되면 핫엔드를 변경하기 전에 핫엔드 내부로 수축되는 필라멘트 양으로 사용됩니다."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "프린터에 여러 개의 노즐이 설치되어 있습니다. 이 출력에 맞는 노즐을 선택하세요."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "핫엔드 교체 시 길이"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "다이내믹 노즐은 현재 플레이트에 할당됩니다. 핫엔드 선택은 지원되지 않습니다."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "핫엔드 랙"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "핫엔드 상태 비정상, 현재 사용할 수 없습니다. 펌웨어를 업그레이드한 후 다시 시도해 주세요."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "핫엔드"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "핫엔드 정보"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "랙의 핫엔드"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "업그레이드 페이지로 이동"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "참고: %s의 핫엔드 번호는 홀더에 연결되어 있습니다. 핫엔드를 새 홀더로 옮기면 번호가 자동으로 업데이트됩니다."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "노즐 ID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "노즐 정보를 읽어야 합니다"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "잠시 기다려 주세요"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "현재 노즐로 출력하면 약 %0.2fg의 낭비물이 발생할 수 있습니다."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "상승함"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "모두 읽기"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "읽는 중 "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "A열"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "B열"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "실행 중..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "필라멘트 및 핫엔드"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "표준 유량"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "툴헤드"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "툴헤드"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "사용 시간: %s"
|
||||
|
||||
@@ -41,23 +41,12 @@ src/slic3r/GUI/DeviceCore/DevMapping.h
|
||||
src/slic3r/GUI/DeviceCore/DevMapping.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRack.h
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevUtil.h
|
||||
src/slic3r/GUI/DeviceCore/DevUtil.cpp
|
||||
src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h
|
||||
src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp
|
||||
src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h
|
||||
src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
|
||||
@@ -108,7 +97,6 @@ src/slic3r/GUI/Widgets/FilamentLoad.cpp
|
||||
src/slic3r/GUI/Widgets/TempInput.cpp
|
||||
src/slic3r/GUI/Widgets/CheckList.cpp
|
||||
src/slic3r/GUI/Widgets/SwitchButton.cpp
|
||||
src/slic3r/GUI/Widgets/MultiNozzleSync.cpp
|
||||
src/slic3r/GUI/ImGuiWrapper.cpp
|
||||
src/slic3r/GUI/Jobs/ArrangeJob.cpp
|
||||
src/slic3r/GUI/Jobs/OrientJob.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "Roteren"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Oriëntatie optimaliseren"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Schalen"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "Verschalen"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Fout: sluit eerst alle openstaande hulpmiddelmenu's"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "Schaalverhoudingen"
|
||||
msgid "Object operations"
|
||||
msgstr "Objectbewerkingen"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Schalen"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Volumebewerkingen"
|
||||
@@ -402,33 +397,26 @@ msgstr "Positie herstellen"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Reset rotatie"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Objectcoördinaten"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Voorwerp"
|
||||
msgid "World coordinates"
|
||||
msgstr "Wereldcoördinaten"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Onderdeel"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr ""
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Schalen"
|
||||
msgid "Part coordinates"
|
||||
msgstr ""
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr "Kloof"
|
||||
msgid "Spacing"
|
||||
msgstr "Uitlijning"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Onderdeel"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Voorwerp"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1858,30 +1852,23 @@ msgstr "Project openen"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "De versie van Orca Slicer is te oud en dient te worden bijgewerkt naar de nieuwste versie voordat deze normaal kan worden gebruikt"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1890,12 +1877,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1963,8 +1944,7 @@ msgstr "Het aantal gebruikersvoorinstellingen dat in de cloud is opgeslagen, hee
|
||||
msgid "Sync user presets"
|
||||
msgstr "Synchroniseer gebruikersvoorinstellingen"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2186,9 +2166,6 @@ msgstr "Orca-kubus"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3619,7 +3596,7 @@ msgstr "Kalibratie voltooid. Zoek de meest uniforme extrusielijn op uw hotbed, z
|
||||
msgid "Save"
|
||||
msgstr "Bewaar"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Achterzijde"
|
||||
|
||||
@@ -4979,7 +4956,6 @@ msgstr "Toolwisselingen"
|
||||
msgid "Color change"
|
||||
msgstr "Kleur veranderen"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
@@ -5138,15 +5114,11 @@ msgstr "Vermijd het extrusie kalibratie gebied"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Uitlijnen op Y-as"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Achterzijde"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Links"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Rechts"
|
||||
|
||||
@@ -5225,9 +5197,6 @@ msgstr "Overhangen"
|
||||
msgid "Outline"
|
||||
msgstr "Omtrek"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5271,7 +5240,7 @@ msgstr ""
|
||||
msgid "Size:"
|
||||
msgstr "Maat:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr ""
|
||||
|
||||
@@ -5470,10 +5439,6 @@ msgstr "Printplaat"
|
||||
msgid "Export G-code file"
|
||||
msgstr "G-codebestand exporteren"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exporteer plate sliced bestand"
|
||||
|
||||
@@ -7984,35 +7949,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8025,12 +7961,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Voorinstelling"
|
||||
|
||||
@@ -12203,18 +12133,6 @@ msgstr ""
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Dit stelt de drempel voor kleine omtreklengte in. De standaarddrempel is 0 mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr ""
|
||||
|
||||
@@ -12370,25 +12288,21 @@ msgid ""
|
||||
"3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
@@ -12756,22 +12670,6 @@ msgstr ""
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr ""
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Vulling percentage"
|
||||
|
||||
@@ -14444,10 +14342,6 @@ msgstr "Uitgelijnd"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Achterzijde"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Willekeurig"
|
||||
|
||||
@@ -15444,14 +15338,6 @@ msgstr ""
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-code miniaturen"
|
||||
|
||||
@@ -18725,12 +18611,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19136,15 +19016,6 @@ msgstr ""
|
||||
"Kromtrekken voorkomen\n"
|
||||
"Wist je dat bij het printen van materialen die gevoelig zijn voor kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het warmtebed de kans op kromtrekken kan verkleinen?"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Objectcoördinaten"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Wereldcoördinaten"
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "Besturing instellingen weergeven"
|
||||
|
||||
@@ -20342,6 +20213,10 @@ msgstr ""
|
||||
#~ msgid "Thick bridges"
|
||||
#~ msgstr "Dikke bruggen"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Schalen"
|
||||
|
||||
#~ msgid "Z-hop when retract"
|
||||
#~ msgstr "Z-hop tijdens terugtrekken (retraction)"
|
||||
|
||||
@@ -20731,213 +20606,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Orient the model"
|
||||
#~ msgstr "Oriënteer het model"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Abnormale hot-end"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Beschikbare nozzles"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Bedmassa van de Y-as"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Waarschuwing: Het combineren van nozzle-diameters in één print wordt niet ondersteund. Als de geselecteerde maat slechts op één extruder aanwezig is, wordt het printen met een enkele extruder afgedwongen."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Tijdens de hot-end upgrade beweegt de printkop. Steek uw hand niet in de kamer."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Schakel dit in als de printer koelingsfilter ondersteunt"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Fout: Kan niet beide nozzles op nul instellen."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Fout: Het aantal nozzles mag niet meer zijn dan %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Extruder wisselen"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Hot-end vervangen"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Tijd voor hot-end wisseling"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Hot-end informatie kan onnauwkeurig zijn. Wilt u de hot-end opnieuw uitlezen? (Hot-end informatie kan veranderen tijdens het uitschakelen)."
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Hybride"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Ik bevestig alles"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Inductie Hot-end rek"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Maximale kracht van de Y-as"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Handleiding nozzle"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Nozzle selectie"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Bevestigt u of de vereiste nozzle diameter en doorvoersnelheid overeenkomen met de momenteel weergegeven waarden."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Stel het aantal nozzles in"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Voorverwarmingstemperatuurverschil"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Prime tower is vereist voor het wisselen van de nozzle. Er kunnen fouten in het model zitten zonder prime tower. Weet je zeker dat je prime tower wilt uitschakelen?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Alles opnieuw lezen"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "De hotends worden gelezen. Even geduld."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Vernieuwen %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Synchroniseer nozzlestatus"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Temperatuurverschil toegepast tijdens het voorverwarmen vóór het wisselen van gereedschap."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "De maximaal toegestane printmassa"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "De maximaal toegestane printmassa op een plaat"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "De maximaal toegestane uitgangskracht van de Y-as"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "De hot-end bevindt zich in een abnormale staat en is momenteel niet beschikbaar. Ga naar 'Apparaat -> Upgrade' om de firmware bij te werken."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "De massabelasting van het machinebed op de Y-as"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "De maximale volumetrische snelheid voor het rammen vóór een hot-end wissel, waarbij -1 betekent dat de maximale volumetrische snelheid wordt gebruikt."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "De maximale volumetrische snelheid voor het rammen vóór extruderwissel, waarbij -1 betekent dat de maximale volumetrische snelheid wordt gebruikt."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "De printkop en het hot-endrek kunnen bewegen. Houd uw handen uit de buurt van de kamer."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Het volume materiaal dat nodig is om de extruder te primen voor een hot-end wissel op de toren."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Tijd om de hot-end te vervangen."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Om druipen te voorkomen, wordt de nozzle-temperatuur tijdens het rammen afgekoeld. Opmerking: alleen een koelcommando en ventilatoractivatie worden geactiveerd, het bereiken van de doeldtemperatuur wordt niet gegarandeerd. 0 betekent uitgeschakeld."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Om doorsijpelen te voorkomen, wordt de temperatuur van de nozzle afgekoeld tijdens het rammen. Daarom moet de rammingtijd groter zijn dan de afkoeltijd. 0 betekent uitgeschakeld."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Om doorsijpelen te voorkomen, zal de nozzle na het rammen gedurende een bepaalde tijd een omgekeerde beweging uitvoeren. De instelling bepaalt de rijtijd."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Onbekende nozzle gedetecteerd. Vernieuw om bij te werken (niet-vernieuwde mondstukken worden overgeslagen bij het slicen)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Onbekende nozzle gedetecteerd. Vernieuw om informatie bij te werken (niet-vernieuwde nozzles worden tijdens het slicen uitgesloten). Controleer nozzle diameter en debiet tegen de weergegeven waarden."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Gebruik koelfilter"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Als u de hot-end verwisselt, is het aan te raden om een bepaalde lengte filament uit de oorspronkelijke nozzle te extruderen. Dit helpt het druipen van de nozzle te minimaliseren."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Wanneer deze terugtrekwaarde wordt aangepast, wordt deze gebruikt als de hoeveelheid filament die binnen de hot-end wordt teruggetrokken voordat de hot-ends worden verwisseld."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "Uw printer heeft verschillende nozzles. Selecteer een spuitmondje voor deze print."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "lengte bij het verwisselen van de hot-end"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Dynamische nozzles zijn toegewezen op de huidige plaat. Het selecteren van een hotend wordt niet ondersteund."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Hot-end rek"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Hotendstatus abnormaal, momenteel niet beschikbaar. Werk de firmware bij en probeer het opnieuw."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "Hot-ends"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Hot-end Informatie"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hot-ends op rek"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Ga naar de upgradepagina"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Opmerking: Het nummer van de hot-end op de %s is gekoppeld aan de houder. Wanneer de hot-end naar een nieuwe houder wordt verplaatst, wordt het nummer automatisch bijgewerkt."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "Nozzle-ID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Nozzle-informatie moet worden uitgelezen"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Even geduld"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Printen met de huidige nozzle kan een extra %0.2f g afval opleveren."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Verhoogd"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Alles lezen"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Lezen "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Rij A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Rij B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Bezig met uitvoeren..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Selecteer Filament && hot-ends"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Standaardstroom"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Printkop"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Printkop"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Gebruikte tijd: %s"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -329,7 +329,6 @@ msgstr "Uchwyt-Obróć"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optymalizuj orientację"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Skaluj"
|
||||
|
||||
@@ -339,9 +338,8 @@ msgstr "Uchwyt-Skaluj"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Błąd: Proszę najpierw zamknąć wszystkie paski narzędziowe"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "cal"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -374,9 +372,6 @@ msgstr "Współczynniki skali"
|
||||
msgid "Object operations"
|
||||
msgstr "Operacje na obiekcie"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Skaluj"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Operacje na objętości"
|
||||
@@ -404,33 +399,26 @@ msgstr "Zresetuj pozycję"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Zresetuj obrót"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Koordynaty obiektu"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Obiekt"
|
||||
msgid "World coordinates"
|
||||
msgstr "Współrzędne"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Część"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Przesunięcie równoległe (Względne)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Zresetuj bieżący obrót do wartości ustawionej przy otwarciu narzędzia obrotu."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Obrót (bezwzględny)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Zresetuj bieżący obrót do wartości zerowej."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Skaluj"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Koordynaty części"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -535,6 +523,12 @@ msgstr "Szczelina"
|
||||
msgid "Spacing"
|
||||
msgstr "Rozstaw"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Część"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Obiekt"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1881,30 +1875,23 @@ msgstr "Otwórz projekt"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Wersja Orca Slicer jest przestarzała i musi zostać uaktualniona do najnowszej wersji, aby działać normalnie"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1913,12 +1900,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1986,8 +1967,7 @@ msgstr "Liczba zapisanych w chmurze ustawień użytkownika przekroczyła maksyma
|
||||
msgid "Sync user presets"
|
||||
msgstr "Synchronizuj ustawienia użytkownika"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2209,9 +2189,6 @@ msgstr "Sześcian Orca"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Test tolerancji Orca"
|
||||
|
||||
@@ -3657,7 +3634,7 @@ msgstr "Kalibracja zakończona. Proszę znaleźć na płycie roboczej, linie eks
|
||||
msgid "Save"
|
||||
msgstr "Zapisz"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Tył"
|
||||
|
||||
@@ -5031,7 +5008,6 @@ msgstr "Zmiany narzędzi"
|
||||
msgid "Color change"
|
||||
msgstr "Zmiana koloru"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Drukuj"
|
||||
|
||||
@@ -5195,15 +5171,11 @@ msgstr "Unikaj obszaru kalibracji ekstruzji"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Wyrównaj do osi Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Tył"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Lewy"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Prawy"
|
||||
|
||||
@@ -5282,9 +5254,6 @@ msgstr "Nawisy"
|
||||
msgid "Outline"
|
||||
msgstr "kontur"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5328,7 +5297,7 @@ msgstr "Objętość:"
|
||||
msgid "Size:"
|
||||
msgstr "Rozmiar:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Wykryto konflikty ścieżek G-code na warstwie %d, Z = %.2lfmm. Proszę oddalić od siebie obiekty będące w konflikcie (%s <-> %s)."
|
||||
|
||||
@@ -5531,10 +5500,6 @@ msgstr "Drukuj aktualną płytę"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Eksportuj plik G-code"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Drukuj"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Eksportuj plik pociętej płyty"
|
||||
|
||||
@@ -8077,35 +8042,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8118,12 +8054,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Profil"
|
||||
|
||||
@@ -12413,18 +12343,6 @@ msgstr "Próg małego obrysu"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "To ustawia próg długości małych obrysów. Domyślny próg to 0 mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Kolejność drukowania ścian"
|
||||
|
||||
@@ -12605,26 +12523,25 @@ msgstr ""
|
||||
"2. Zwróć uwagę na optymalną wartość PA dla każdej wolumetrycznej prędkości przepływu i przyspieszenia. Możesz znaleźć numer przepływu, wybierając przepływ z rozwijanego schematu kolorów i przesuwając poziomy suwak nad liniami wzoru PA. Numer powinien być widoczny na dole strony. Idealna wartość PA powinna maleć, im większy jest przepływ objętościowy. Jeśli tak nie jest, potwierdź, że ekstruder działa poprawnie. Im wolniej i z mniejszym przyspieszeniu drukujesz, tym jest większy zakres dopuszczalnych wartości PA. Jeśli różnica nie jest widoczna, należy użyć wartości PA z szybszego testu.\n"
|
||||
"3. Wprowadź trójki wartości PA, przepływu i przyspieszenia w polu tekstowym tutaj i zapisz swój profil filamentu."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Włącz adaptacyjny wzrost ciśnienia dla nawisów (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Wzrost ciśnienia (PA) dla mostów"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Wartość wzrostu ciśnienia dla mostów. Ustaw na 0, aby wyłączyć.\n"
|
||||
"\n"
|
||||
"Niższa wartość PA podczas drukowania mostów pomaga zredukować widoczność lekkiego niedoboru materiału, który może wystąpić bezpośrednio po ich wydruku. Jest to spowodowane spadkiem ciśnienia w dyszy podczas drukowania w powietrzu, a niższy PA pomaga temu przeciwdziałać."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Domyślna szerokość linii, jeśli inne szerokości linii są ustawione na 0. Jeśli wyrażona w %, zostanie obliczona na podstawie średnicy dyszy."
|
||||
@@ -13000,22 +12917,6 @@ msgstr "Kierunek wzoru pełnego wypełnienia"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Kąt wyznaczający główny kierunek linii dla wzoru pełnego wypełnienia"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Gęstość wypełnienia"
|
||||
|
||||
@@ -14755,10 +14656,6 @@ msgstr "Wyrównany"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Tył"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Losowo"
|
||||
|
||||
@@ -15801,14 +15698,6 @@ msgstr "Skręt poliotworu"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Obracaj poliotwor co warstwę."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Miniatury G-code"
|
||||
|
||||
@@ -19149,12 +19038,6 @@ msgstr "Liczba trójkątnych faset"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Obliczanie, proszę czekać..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19563,42 +19446,6 @@ msgstr ""
|
||||
"Unikaj odkształceń\n"
|
||||
"Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Drukuj"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "cal"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Koordynaty obiektu"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Współrzędne"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Przesunięcie równoległe (Względne)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Obrót (bezwzględny)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Koordynaty części"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Włącz adaptacyjny wzrost ciśnienia dla nawisów (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Wzrost ciśnienia (PA) dla mostów"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Wartość wzrostu ciśnienia dla mostów. Ustaw na 0, aby wyłączyć.\n"
|
||||
#~ "\n"
|
||||
#~ "Niższa wartość PA podczas drukowania mostów pomaga zredukować widoczność lekkiego niedoboru materiału, który może wystąpić bezpośrednio po ich wydruku. Jest to spowodowane spadkiem ciśnienia w dyszy podczas drukowania w powietrzu, a niższy PA pomaga temu przeciwdziałać."
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "Ustawienia kontrolowania widoku"
|
||||
|
||||
@@ -21024,6 +20871,10 @@ msgstr ""
|
||||
#~ msgid "Unselect"
|
||||
#~ msgstr "Odznacz"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Skala"
|
||||
|
||||
#~ msgid "Lift Z Enforcement"
|
||||
#~ msgstr "Wymuszenie podniesienia osi Z"
|
||||
|
||||
@@ -22689,216 +22540,3 @@ msgstr ""
|
||||
#~ "Proszę podać poprawne wartości:\n"
|
||||
#~ "start > 10 kroków >= 0\n"
|
||||
#~ "koniec > start + krok)"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Nieprawidłowy hotend"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Dostępne dysze"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Masa stołu dla osi Y"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Uwaga: Mieszanie średnic dysz w jednym wydruku nie jest obsługiwane. Jeśli wybrany rozmiar jest dostępny tylko na jednym ekstruderze, zostanie wymuszony druk jednym ekstruderem."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Podczas aktualizacji hotendu, głowica będzie się poruszać. Nie wkładaj rąk do komory."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Włącz tę opcję, jeśli drukarka może korzystać z filtra przy chłodzeniu."
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Błąd: Nie można ustawić liczby obu dysz na zero."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Błąd: Liczba dysz nie może przekraczać %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Zmiana ekstrudera"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Zmiana hotendu"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Czas zmiany hotendu"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Informacje o hotendzie mogą być niedokładne. Czy chcesz ponownie odczytać dane o hotendzie? (Informacje o hotendzie mogły się zmienić podczas wyłączenia zasilania)."
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "Hybryda"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Potwierdzam wszystko"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Indukcyjny uchwyt na hotendy"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Maksymalna siła na osi Y"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Instrukcja dyszy"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Wybór dyszy"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Sprawdź, czy wymagana średnica dyszy i natężenie przepływu odpowiadają aktualnie wyświetlanym wartościom."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Proszę ustawić liczbę dysz"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Delta temperatur podgrzewania wstępnego"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Wieża czyszcząca jest wymagana do wymiany dyszy. Brak wieży czyszczącej może spowodować wystąpienie wad na modelu. Czy na pewno chcesz ją wyłączyć?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Odczytaj ponownie wszystko"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Odczytywanie hotendów, proszę czekać."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Odśwież %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Synchronizuj status dyszy"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU wysoki przepływ"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Delta temperatur stosowana podczas podgrzewania wstępnego przed wymianą narzędzia."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "Dopuszczalna maksymalna masa wydruku"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "Maksymalna dopuszczalna masa nadruku na płycie"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Dopuszczalna maksymalna siła wyjściowa na osi Y"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Hotend jest w nieprawidłowym stanie i jest obecnie niedostępny. Przejdź do \"Urządzenie -> Aktualizacja\" w celu aktualizacji firmware"
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Obciążenie masowe stołu maszyny na osi Y"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Maksymalna prędkość przepływu dla wyciskania przed zmianą hotendu, gdzie -1 oznacza użycie prędkości maksymalnej."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Maksymalna prędkość przepływu dla wyciskania, gdzie -1 oznacza użycie prędkości maksymalnej."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "Głowica i uchwyt na hotendy mogą się poruszać. Proszę trzymać ręce z dala od komory."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Objętość materiału wymagana do oczyszczania ekstrudera na wieży przed zmianą hotendu."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Czas na zmianę hotendu."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "Aby zapobiec wyciekom, temperatura dyszy będzie obniżana podczas wyciskania. Uwaga: wywoływane jest jedynie polecenie chłodzenia i aktywacja wentylatora, osiągnięcie docelowej temperatury nie jest gwarantowane. Wartość 0 oznacza wyłączenie."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Aby zapobiec wyciekaniu, temperatura dyszy zostanie zmniejszona podczas wyciskania. Dlatego, czas wyciskania musi być większy niż czas schładzania. 0 oznacza wyłączony."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Aby zapobiec wyciekaniu filamentu, dysza wykona ruch wsteczny przez określony czas po zakończeniu wyciskania materiału. Ustawienie określa czas tego ruchu."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Wykryto nieznaną dyszę. Odśwież, aby zaktualizować (nieodświeżone dysze zostaną pominięte podczas cięcia)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Wykryto nieznaną dyszę. Odśwież informacje (dysze nieodświeżone zostaną pominięte podczas cięcia). Sprawdź średnicę dyszy oraz przepływ względem wyświetlanych wartości."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Użyj filtra przy chłodzeniu"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "Podczas zmiany hotendu zaleca się ekstruzję określonej długości filamentu z oryginalnej dyszy. Pomaga to zminimalizować wyciek filamentu z dyszy."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "Po modyfikacji tej wartości retrakcji będzie ona używana jako ilość cofniętego filamentu wewnątrz hotendu przed każdą jego zmianą."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "W Twojej drukarce są zainstalowane różne dysze. Wybierz dyszę do tego wydruku."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "długość przy zmianie hotendu"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Dysze dynamiczne zostały przydzielane do bieżącej płyty. Wybór hotendu nie jest obsługiwany."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Uchwyt na hotendy"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Stan hotendu jest nieprawidłowy i obecnie nie jest dostępny. Proszę zaktualizować firmware i spróbować ponownie."
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "Hotendy"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Informacje o hotendach"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotendy w uchwycie"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Przejdź do strony aktualizacji"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Uwaga: Numer hotendu na %s jest powiązany z uchwytem. Po przeniesieniu hotendu na nowy uchwyt jego numer zostanie automatycznie zaktualizowany."
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "Identyfikator dyszy"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Należy odczytać informacje o dyszy"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Proszę czekać"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Drukowanie przy użyciu obecnej dyszy może powodować powstanie dodatkowych %0.2f g odpadów."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Podniesiony"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Odczytaj wszystko"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Odczyt "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Rząd A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Rząd B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Uruchamianie..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Wybierz filament i hotendy"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Przepływ standardowy"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Głowica"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Głowica"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Czas użycia: %s"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer V2.5.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2026-02-25 13:38+0300\n"
|
||||
"Last-Translator: Felix14_v2\n"
|
||||
"Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg <andylg@yandex.ru>\n"
|
||||
@@ -337,7 +337,6 @@ msgstr "Инструмент вращения"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Оптимизация положения модели"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
|
||||
@@ -347,9 +346,8 @@ msgstr "Инструмент изменения размера"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Ошибка: сначала закройте текущий инструмент."
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "дюйм"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "мм"
|
||||
@@ -381,9 +379,6 @@ msgstr "Коэф. масштаба"
|
||||
msgid "Object operations"
|
||||
msgstr "Операции с моделями"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
|
||||
msgid "Volume operations"
|
||||
msgstr "Булевы операции с телами"
|
||||
|
||||
@@ -405,33 +400,26 @@ msgstr "Сброс позиции"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Сброс вращения"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Относительно модели"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Модель"
|
||||
msgid "World coordinates"
|
||||
msgstr "Относительно стола"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Часть"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Перемещение (относительное)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Сбросить последние изменения ориентации"
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Поворот"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Сбросить ориентацию до изначальной"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Относительно части"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -539,6 +527,12 @@ msgstr "Зазор"
|
||||
msgid "Spacing"
|
||||
msgstr "Отступ"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Часть"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Модель"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1913,30 +1907,23 @@ msgstr "Открыть проект"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Слишком старая версия Orca Slicer. Для корректной работы обновите программу до последней версии."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1945,12 +1932,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -2026,8 +2007,7 @@ msgstr "Количество пользовательских профилей,
|
||||
msgid "Sync user presets"
|
||||
msgstr "Синхронизировать пользовательские профили"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2237,9 +2217,6 @@ msgstr "Куб Orca"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "Нарезанная Orca"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Тест точности Orca"
|
||||
|
||||
@@ -3665,9 +3642,9 @@ msgstr "Калибровка завершена. Теперь найдите н
|
||||
msgid "Save"
|
||||
msgstr "Сохранить"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# Используется в нескольких местах: в 2 местах в значении расположения (шва и камеры), в одном – на кнопке "назад" (калибровка бамбу)
|
||||
msgid "Back"
|
||||
msgstr "Назад"
|
||||
msgstr "Сзади"
|
||||
|
||||
msgid "Example"
|
||||
msgstr "Пример"
|
||||
@@ -5073,7 +5050,6 @@ msgstr "Смена инструмента"
|
||||
msgid "Color change"
|
||||
msgstr "Смена цвета"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Печать"
|
||||
|
||||
@@ -5236,15 +5212,11 @@ msgstr "Избегать зону калибровки экструзии"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Выравнивать по оси Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Сзади"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Слева"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Справа"
|
||||
|
||||
@@ -5327,9 +5299,6 @@ msgstr "Нависания"
|
||||
msgid "Outline"
|
||||
msgstr "Обводка выбранного"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5372,7 +5341,7 @@ msgstr "Объём:"
|
||||
msgid "Size:"
|
||||
msgstr "Размер:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "В G-коде на %d слое (z = %.2lf мм) обнаружен конфликт путей. Пожалуйста, разместите конфликтующие модели дальше друг от друга (%s <-> %s)."
|
||||
|
||||
@@ -5602,10 +5571,6 @@ msgstr "Распечатать стол"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Экспорт в G-код"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Печать"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Экспорт стола в файл проекта"
|
||||
|
||||
@@ -8152,35 +8117,6 @@ msgstr "Показывать настройки импорта STEP"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Если включено, во время импорта STEP файла появится диалоговое окно настроек параметров импорта."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Качество при экспорте в DRC"
|
||||
|
||||
@@ -8196,12 +8132,6 @@ msgstr ""
|
||||
"Чем меньше глубина, тем ниже качество и размер файла. Допустимый диапазон – от 8 до 30.\n"
|
||||
"0 – сжатие без потерь (представление с максимальной точностью)."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Профиль"
|
||||
|
||||
@@ -12579,18 +12509,6 @@ msgstr "Порог коротких периметров"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Пороговое значение (радиус) для расчёта длины коротких периметров (по формуле длины окружности). Значение по умолчанию – 0 мм."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Порядок печати периметров"
|
||||
|
||||
@@ -12800,26 +12718,27 @@ msgstr ""
|
||||
"\n"
|
||||
"3. Проверьте порядок введённых значений (PA, расход, ускорения) и сохраните профиль материала."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
# Тут речь о коэффициенте PA (адаптивный коэффициент PA), а не об адаптивном
|
||||
# алгоритме
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Адаптивный PA на нависаниях (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Коэффициент PA на мостах"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Коэффициент Pressure Advance для мостов. Установите значение 0, если хотите отключить функцию.\n"
|
||||
"\n"
|
||||
"Более низкое значение PA при печати мостов помогает уменьшить появление небольшой недоэкструзии сразу после мостов. Это вызвано падением давления в сопле при печати в воздухе, и более низкое значение PA помогает предотвратить это."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Стандартная ширина линии для отключённых (установленных на 0) значений ниже. Можно указать процент от диаметра сопла."
|
||||
@@ -13206,22 +13125,6 @@ msgstr "Угол шаблона сплошного заполнения"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Угол ориентации шаблона сплошного заполнения, который определяет начало или основное направление линий."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Плотность заполнения"
|
||||
|
||||
@@ -15103,10 +15006,6 @@ msgstr "В углах"
|
||||
msgid "Aligned back"
|
||||
msgstr "В углах сзади"
|
||||
|
||||
# Используется в нескольких местах: в 2 местах в значении расположения (шва и камеры), в одном – на кнопке "назад" (калибровка бамбу)
|
||||
msgid "Back"
|
||||
msgstr "Сзади"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Случайная"
|
||||
|
||||
@@ -16260,14 +16159,6 @@ msgstr "Скручивание многогранника"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Вращение многогранного отверстия на каждом слое."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Эскизы в G-коде"
|
||||
|
||||
@@ -19703,12 +19594,6 @@ msgstr "Количество треугольников"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Расчёт, подождите..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -20117,44 +20002,6 @@ msgstr ""
|
||||
"Предотвращение коробления материала\n"
|
||||
"Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Печать"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "дюйм"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Относительно модели"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Относительно стола"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Перемещение (относительное)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Поворот"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Относительно части"
|
||||
|
||||
# Тут речь о коэффициенте PA (адаптивный коэффициент PA), а не об адаптивном
|
||||
# алгоритме
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Адаптивный PA на нависаниях (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Коэффициент PA на мостах"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Коэффициент Pressure Advance для мостов. Установите значение 0, если хотите отключить функцию.\n"
|
||||
#~ "\n"
|
||||
#~ "Более низкое значение PA при печати мостов помогает уменьшить появление небольшой недоэкструзии сразу после мостов. Это вызвано падением давления в сопле при печати в воздухе, и более низкое значение PA помогает предотвратить это."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Настройки синхронизации"
|
||||
|
||||
@@ -21861,9 +21708,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Right click to reset value to system default."
|
||||
#~ msgstr "Правая кнопка мыши - сброс значения до системного по умолчанию."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Для предотвращения подтекания материала, температура сопла будет снижена во время рэмминга. Поэтому время рэмминга должно быть больше времени охлаждения. 0 значит отключено."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Чтобы материал не подтекал, материал после рэмминга немного отъезжает назад. Этот параметр задаёт время движения в обратном направлении."
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -324,7 +324,6 @@ msgstr ""
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Optimisera placering"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Skala"
|
||||
|
||||
@@ -334,9 +333,8 @@ msgstr ""
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "FEL: Stäng alla verktygsmenyer först"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "i"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -369,9 +367,6 @@ msgstr "Skalnings förhållande"
|
||||
msgid "Object operations"
|
||||
msgstr "Objekt Åtgärder"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Skala"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Volym Åtgärder"
|
||||
@@ -398,33 +393,26 @@ msgstr "Återställ Position"
|
||||
msgid "Reset rotation"
|
||||
msgstr ""
|
||||
|
||||
msgid "World"
|
||||
msgid "Object coordinates"
|
||||
msgstr ""
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
msgid "World coordinates"
|
||||
msgstr "Världskoordinater"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Del"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr ""
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Skala"
|
||||
msgid "Part coordinates"
|
||||
msgstr ""
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -529,6 +517,12 @@ msgstr "Glipa"
|
||||
msgid "Spacing"
|
||||
msgstr "Mellanrum"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Del"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1847,30 +1841,23 @@ msgstr "Öppna Projekt"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Versionen av Orca Slicer är för låg och behöver uppdateras till den senaste versionen innan den kan användas normalt"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1879,12 +1866,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1952,8 +1933,7 @@ msgstr "Antalet användar inställningar som cachats i molnet har överskridit d
|
||||
msgid "Sync user presets"
|
||||
msgstr "Synkronisera användar inställningar"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2175,9 +2155,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3611,7 +3588,7 @@ msgstr "Kalibreringen klar. Vänligen hitta den mest enhetliga extruderingslinje
|
||||
msgid "Save"
|
||||
msgstr "Spara"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Tillbaka"
|
||||
|
||||
@@ -4969,7 +4946,6 @@ msgstr ""
|
||||
msgid "Color change"
|
||||
msgstr "Färg byte"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Skriv ut"
|
||||
|
||||
@@ -5129,15 +5105,11 @@ msgstr "Undvik kalibrerings området"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Justera mot Y-axeln"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Tillbaka"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Vänster"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Höger"
|
||||
|
||||
@@ -5216,9 +5188,6 @@ msgstr ""
|
||||
msgid "Outline"
|
||||
msgstr "Kontur"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5262,7 +5231,7 @@ msgstr "Volym:"
|
||||
msgid "Size:"
|
||||
msgstr "Storlek:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr ""
|
||||
|
||||
@@ -5461,10 +5430,6 @@ msgstr "Skriv ut byggplattan"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Exportera G-kod filen"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Skriv ut"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Exportera byggplattans beredda fil"
|
||||
|
||||
@@ -7973,35 +7938,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8014,12 +7950,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Förinställd"
|
||||
|
||||
@@ -12177,18 +12107,6 @@ msgstr ""
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Detta ställer in tröskelvärdet för liten perimeterlängd. Standardgränsen är 0mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr ""
|
||||
|
||||
@@ -12344,25 +12262,21 @@ msgid ""
|
||||
"3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
@@ -12729,22 +12643,6 @@ msgstr ""
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr ""
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Sparsam ifyllnads densitet"
|
||||
|
||||
@@ -14417,10 +14315,6 @@ msgstr "Linjerad"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Tillbaka"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Slumpmässig"
|
||||
|
||||
@@ -15415,14 +15309,6 @@ msgstr ""
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr ""
|
||||
|
||||
@@ -18692,12 +18578,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19076,15 +18956,6 @@ msgstr ""
|
||||
"Undvik vridning\n"
|
||||
"Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Skriv ut"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "i"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Världskoordinater"
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "Kontroll inställningar"
|
||||
|
||||
@@ -20252,6 +20123,10 @@ msgstr ""
|
||||
#~ msgid "Thick bridges"
|
||||
#~ msgstr "Tjocka bridges"
|
||||
|
||||
#~ msgctxt "Verb"
|
||||
#~ msgid "Scale"
|
||||
#~ msgstr "Skala"
|
||||
|
||||
#~ msgid "Z-hop when retract"
|
||||
#~ msgstr "Z-hopp vid retraktion"
|
||||
|
||||
@@ -20693,207 +20568,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Orient the model"
|
||||
#~ msgstr "Orientera modellen"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "Onormal Hotend"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "Tillgängliga nozzle"
|
||||
|
||||
msgid "Bed mass of the Y axis"
|
||||
msgstr "Y-axelns bäddmassa"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "Varning: Blandning av nozzle diametrar i en utskrift stöds inte. Om den valda storleken bara är på en extruder kommer singel extruder utskrift att utföras."
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "Under hotend uppgraderingen kommer verktygshuvudet att röra sig. Stoppa inte in något i kammaren."
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "Aktivera detta om printern stöder kylfilter"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "Fel: Kan inte ställa in båda nozzle till noll."
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "Fel: Antal nozzle får inte överskrida %d."
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "Extruder byte"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "Byte av hotend"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "Tid för byte av hotend"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "Informationen om hotend kan vara felaktig. Vill du läsa av hotend igen? (Informationen om hotend kan ändras vid avstängning)."
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "Jag bekräftar allt"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "Induktion Hotend Ställning"
|
||||
|
||||
msgid "Maximum force of the Y axis"
|
||||
msgstr "Maximal kraft för Y-axeln"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "Nozzle manual"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "Val av nozzle"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "Bekräfta om den önskade nozzle diametern och flödes hastigheten matchar de värden som visas just nu."
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "Ange antal nozzle"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "Förvärmningstemperaturdelta"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "Prime tower krävs för nozzle byte. Det kan bli brister på modellen utan prime tower. Är du säker på att du vill inaktivera prime tower?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "Läs om allt"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "Läser av hotends, vänta."
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "Uppdatera %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "Synkronisera nozzle status"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU Hög Flöde"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "Temperaturdelta tillämpad under förvärmning före verktygsbyte."
|
||||
|
||||
msgid "The allowed max printed mass"
|
||||
msgstr "Den maximalt tillåtna tryckta massan"
|
||||
|
||||
msgid "The allowed max printed mass on a plate"
|
||||
msgstr "Den maximalt tillåtna tryckta massan på en platta"
|
||||
|
||||
msgid "The allowed maximum output force of Y axis"
|
||||
msgstr "Den maximalt tillåtna utgående kraften för Y-axeln"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "Hotend är i ett onormalt tillstånd och är inte tillgängligt. Gå till 'Enhet -> Uppgradera' för att uppgradera firmware."
|
||||
|
||||
msgid "The machine bed mass load of Y axis"
|
||||
msgstr "Maskinbäddens massbelastning på Y-axeln"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Den maximala volymetriska hastigheten för ramning före ett hotend byte, där -1 innebär att den maximala volymetriska hastigheten används."
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "Den maximala volymetriska hastigheten för ramning före extruder byte, där -1 innebär att den maximala volymetriska hastigheten används."
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "Verktygs huvudet och hotend stället kan röra sig. Håll händerna borta från kammaren."
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "Volymen av material som krävs för att prima extrudern för en hotend förändring på tower."
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "Dags att byta hotend."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "För att förhindra läckage kyls nozzle temperatur ner under ramningen. Obs: endast ett nedkylnings kommando och fläktaktivering utlöses, det är inte garanterat att måltemperaturen uppnås. 0 betyder inaktiverad."
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "För att förhindra ooze ur nozzle kyls nozzle temperatur under ramning. Ramningstiden måste därför vara längre än nedkylningstiden. 0 betyder avaktiverad."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "För att förhindra oozing ur nozzle görs en bakåtriktad rörelse under en viss period efter att ramningen är klar. Inställningen definierar rörelse tiden."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "Okänd nozzle upptäckt. Uppdatera för att uppdatera (ej uppdaterad nozzle kommer att hoppas över i beredning)."
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "Okänd nozzle upptäckt. Uppdatera för att uppdatera info (ej uppdaterad nozzle kommer att uteslutas under beredning). Verifiera nozzle diameter och flödes hastighet mot visade värden."
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "Använd kylfilter"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "När du byter hotend, rekommenderas det att extrudera en viss längd av filament från det ursprungliga nozzle. Detta hjälper till att minimera nozzle läckage."
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "När detta indragnings värde ändras, kommer det att användas som mängden indraget filament inuti hotend innan du byter hotend."
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "Din printer har olika nozzle installerade. Välj en nozzle för denna utskrift."
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "längd vid byte av hotend"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "Dynamiska nozzles är tilldelade på den aktuella plattan. Val av hotend stöds inte."
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "Hotend Ställning"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "Hotend status onormal, ej tillgänglig för närvarande. Uppgradera firmware och försök igen."
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "Hotend Information"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "Hotends på ställning"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "Gå till uppgraderings sidan"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "Obs: Hotend numret på %s är kopplat till hållaren. När hotend flyttas till en ny hållare uppdateras dess nummer automatiskt."
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "Nozzle information måste läsas"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "Vänligen vänta"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "Utskrift med det aktuell nozzle kan ge extra %0.2fg avfall."
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "Upphöjd"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "Läs allt"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "Läser "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "Rad A"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "Rad B"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "Kör..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "Välj Filament && Hotends"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "Standard flöde"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "Verktygshuvud"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "Verktygshuvud"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "Använd tid: %s"
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2026-06-19 13:40+0700\n"
|
||||
"Last-Translator: Icezaza\n"
|
||||
"Language-Team: Thai\n"
|
||||
@@ -324,7 +324,6 @@ msgstr "Gizmo-หมุน"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "ปรับการวางแนวให้เหมาะสม"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "ปรับขนาด"
|
||||
|
||||
@@ -334,9 +333,8 @@ msgstr "Gizmo-ขนาด"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "ข้อผิดพลาด: โปรดปิดเมนูแถบเครื่องมือทั้งหมดก่อน"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "นิ้ว"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "มม."
|
||||
@@ -368,9 +366,6 @@ msgstr "อัตราส่วนการปรับขนาด"
|
||||
msgid "Object operations"
|
||||
msgstr "การทำงานกับวัตถุ"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "ปรับขนาด"
|
||||
|
||||
msgid "Volume operations"
|
||||
msgstr "การทำงานกับวอลลุ่ม"
|
||||
|
||||
@@ -392,33 +387,26 @@ msgstr "รีเซ็ตตำแหน่ง"
|
||||
msgid "Reset rotation"
|
||||
msgstr "รีเซ็ตการหมุน"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "พิกัดวัตถุ"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "วัตถุ"
|
||||
msgid "World coordinates"
|
||||
msgstr "พิกัดโลก"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "ชิ้นส่วน"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "เลื่อนตำแหน่ง (แบบสัมพันธ์)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "รีเซ็ตการหมุนปัจจุบันเป็นค่าเมื่อเปิดเครื่องมือการหมุน"
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "หมุน (สัมบูรณ์)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "รีเซ็ตการหมุนปัจจุบันให้เป็นศูนย์จริง"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "ปรับขนาด"
|
||||
msgid "Part coordinates"
|
||||
msgstr "พิกัดส่วน"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -523,6 +511,12 @@ msgstr "ช่องว่าง"
|
||||
msgid "Spacing"
|
||||
msgstr "ระยะห่าง"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "ชิ้นส่วน"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "วัตถุ"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1856,32 +1850,33 @@ msgstr "เปิดโปรเจกต์"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Orca Slicer เวอร์ชันต่ำเกินไปและจำเป็นต้องอัปเดตเป็นเวอร์ชันล่าสุดก่อนจึงจะสามารถใช้งานได้ตามปกติ"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"ความขัดแย้งในการซิงก์ Cloud: ค่าที่ตั้งไว้ล่วงหน้านี้มีเวอร์ชันใหม่กว่าใน Orca Cloud\n"
|
||||
"ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"ความขัดแย้งในการซิงก์ Cloud: มีค่าที่ตั้งไว้ล่วงหน้าชื่อนี้อยู่ใน Orca Cloud แล้ว\n"
|
||||
"ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"ความขัดแย้งในการซิงก์ Cloud: ค่าที่ตั้งไว้ล่วงหน้าชื่อเดียวกันเคยถูกลบจากคลาวด์แล้ว\n"
|
||||
"ลบจะลบค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
"ความขัดแย้งในการซิงก์ Cloud: พบความขัดแย้งของค่าที่ตั้งไว้ล่วงหน้าที่ไม่คาดคิดหรือระบุไม่ได้\n"
|
||||
"ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -1890,12 +1885,6 @@ msgstr ""
|
||||
"การบังคับส่งจะเขียนทับสำเนาบนคลาวด์ด้วยการเปลี่ยนแปลงค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ\n"
|
||||
"คุณต้องการดำเนินการต่อหรือไม่?"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr "แก้ไขความขัดแย้งการซิงค์คลาวด์"
|
||||
|
||||
@@ -1975,9 +1964,8 @@ msgstr "จำนวนค่าที่ตั้งไว้ล่วงหน
|
||||
msgid "Sync user presets"
|
||||
msgstr "ซิงค์การตั้งค่าล่วงหน้าของผู้ใช้"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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) โปรดลดขนาดที่กำหนดไว้ล่วงหน้าโดยการลบการกำหนดค่าที่กำหนดเองออกหรือใช้เฉพาะในเครื่องเท่านั้น"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2186,9 +2174,6 @@ msgstr "ออร์ก้าคิวบ์"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "OrcaSliced Combo"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "การทดสอบค่าความเผื่อ Orca"
|
||||
|
||||
@@ -3567,7 +3552,6 @@ msgstr "การสอบเทียบเสร็จสิ้น โปร
|
||||
msgid "Save"
|
||||
msgstr "บันทึก"
|
||||
|
||||
msgctxt "Navigation"
|
||||
msgid "Back"
|
||||
msgstr "กลับ"
|
||||
|
||||
@@ -4916,7 +4900,6 @@ msgstr "การเปลี่ยนแปลงเครื่องมือ
|
||||
msgid "Color change"
|
||||
msgstr "เปลี่ยนสี"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "พิมพ์"
|
||||
|
||||
@@ -5076,15 +5059,11 @@ msgstr "หลีกเลี่ยงบริเวณการสอบเท
|
||||
msgid "Align to Y axis"
|
||||
msgstr "จัดแนวตามแกน Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "กลับ"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "ซ้าย"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "ขวา"
|
||||
|
||||
@@ -5163,9 +5142,6 @@ msgstr "ส่วนยื่น"
|
||||
msgid "Outline"
|
||||
msgstr "เส้นขอบ"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr "มุมมองสมจริง"
|
||||
|
||||
@@ -5208,7 +5184,7 @@ msgstr "ปริมาณ:"
|
||||
msgid "Size:"
|
||||
msgstr "ขนาด:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "พบความขัดแย้งของเส้นทางรหัส G ที่เลเยอร์ %d, Z = %.2lfmm โปรดแยกวัตถุที่ขัดแย้งกันให้ไกลออกไป (%s <-> %s)"
|
||||
|
||||
@@ -5407,10 +5383,6 @@ msgstr "พิมพ์ฐานพิมพ์"
|
||||
msgid "Export G-code file"
|
||||
msgstr "ส่งออกไฟล์ G-code"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "พิมพ์"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "ส่งออกไฟล์แผ่นสไลซ์บาง ๆ"
|
||||
|
||||
@@ -7891,35 +7863,6 @@ msgstr "แสดงตัวเลือกเมื่อนำเข้าไ
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "หากเปิดใช้งาน กล่องโต้ตอบการตั้งค่าพารามิเตอร์จะปรากฏขึ้นระหว่างการนำเข้าไฟล์ STEP"
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "ระดับคุณภาพสำหรับการส่งออกของ Draco"
|
||||
|
||||
@@ -7935,12 +7878,6 @@ msgstr ""
|
||||
"0 = การบีบอัดแบบไม่สูญเสีย (รูปทรงเรขาคณิตจะถูกรักษาไว้อย่างแม่นยำเต็มที่) ค่าการสูญเสียที่ถูกต้องมีตั้งแต่ 8 ถึง 30\n"
|
||||
"ค่าที่ต่ำกว่าจะทำให้ไฟล์มีขนาดเล็กลง แต่สูญเสียรายละเอียดทางเรขาคณิตมากขึ้น ค่าที่สูงกว่าจะรักษารายละเอียดได้มากขึ้นโดยที่ไฟล์มีขนาดใหญ่กว่า"
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "พรีเซ็ต"
|
||||
|
||||
@@ -12262,18 +12199,6 @@ msgstr "เกณฑ์ขอบเขตขนาดเล็ก"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "นี่เป็นการกำหนดเกณฑ์สำหรับความยาวเส้นรอบวงเล็กน้อย เกณฑ์เริ่มต้นคือ 0 มม."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "สั่งพิมพ์ผนัง"
|
||||
|
||||
@@ -12458,26 +12383,27 @@ msgstr ""
|
||||
"2. จดบันทึกค่า PA ที่เหมาะสมที่สุดสำหรับความเร็วการไหลและความเร่งตามปริมาตรแต่ละรายการ คุณสามารถค้นหาหมายเลขโฟลว์ได้โดยเลือกโฟลว์จากรายการสีแบบเลื่อนลง และเลื่อนแถบเลื่อนแนวนอนไปเหนือเส้นรูปแบบ PA หมายเลขควรปรากฏที่ด้านล่างของหน้า ค่า PA ในอุดมคติควรลดลงตามอัตราการไหลตามปริมาตรที่สูงขึ้น หากไม่เป็นเช่นนั้น ให้ยืนยันว่าชุดดันเส้นของคุณทำงานอย่างถูกต้อง ยิ่งคุณพิมพ์ช้าลงและเร่งความเร็วน้อยลง ช่วงของค่า PA ที่ยอมรับได้ก็จะยิ่งมากขึ้นเท่านั้น หากไม่เห็นความแตกต่าง ให้ใช้ค่า PA จากการทดสอบที่เร็วกว่า\n"
|
||||
"3. ป้อนค่า PA, การไหล และความเร่งสามเท่าในกล่องข้อความที่นี่ และบันทึกโปรไฟล์เส้นพลาสติกของคุณ"
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "เปิดใช้งานการปรับPressure Advanceสำหรับระยะยื่น (เบต้า)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
"เปิดใช้งาน PA แบบปรับตัวสำหรับส่วนยื่นและเมื่ออัตราการไหลเปลี่ยนภายในฟีเจอร์เดียวกัน เป็นตัวเลือกทดลอง หากโปรไฟล์ PA ไม่แม่นยำ จะทำให้ผิวด้านนอกไม่สม่ำเสมอก่อนและหลังส่วนยื่น\n"
|
||||
"ไม่รองรับเครื่องพิมพ์ Prusa เพราะจะหยุดชั่วคราวเพื่อประมวลผลการเปลี่ยน PA ทำให้เกิดความล่าช้าและข้อบกพร่อง"
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "แรงดันล่วงหน้า (Pressure Advance)สำหรับสะพาน"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"ค่าPressure Advanceสำหรับสะพาน ตั้งค่าเป็น 0 เพื่อปิดใช้งาน\n"
|
||||
"\n"
|
||||
"ค่า PA ที่ต่ำลงเมื่อพิมพ์บริดจ์จะช่วยลดลักษณะที่ปรากฏเล็กน้อยจากการอัดขึ้นรูปทันทีหลังจากบริดจ์ สาเหตุนี้เกิดจากแรงดันตกในหัวฉีดเมื่อพิมพ์ในอากาศ และค่า PA ที่ต่ำกว่าจะช่วยแก้ปัญหานี้ได้"
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "ความกว้างของเส้นเริ่มต้นหากความกว้างของเส้นอื่นตั้งค่าเป็น 0 หากแสดงเป็น % ระบบจะคำนวณตามเส้นผ่านศูนย์กลางของหัวฉีด"
|
||||
@@ -12849,22 +12775,6 @@ msgstr "ทิศทางไส้ในแบบทึบ"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "มุมสำหรับรูปแบบไส้ในแบบทึบ ซึ่งควบคุมจุดเริ่มต้นหรือทิศทางหลักของเส้น"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "ความหนาแน่นไส้ในแบบโปร่ง"
|
||||
|
||||
@@ -14609,9 +14519,6 @@ msgstr "จัดตำแหน่ง"
|
||||
msgid "Aligned back"
|
||||
msgstr "จัดแนวกลับ"
|
||||
|
||||
msgid "Back"
|
||||
msgstr "กลับ"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "สุ่ม"
|
||||
|
||||
@@ -15628,14 +15535,6 @@ msgstr "บิดรูหลายรู"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "หมุนโพลีโฮลทุกชั้น"
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "ภาพขนาดย่อ G-code"
|
||||
|
||||
@@ -18959,12 +18858,6 @@ msgstr "จำนวนด้านสามเหลี่ยม"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "กำลังคำนวณ โปรดรอสักครู่..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr "ชุดค่าที่ตั้งไว้ล่วงหน้า"
|
||||
|
||||
@@ -19366,80 +19259,6 @@ msgstr ""
|
||||
"หลีกเลี่ยงการบิดเบี้ยว\n"
|
||||
"คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "พิมพ์"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "นิ้ว"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "พิกัดวัตถุ"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "พิกัดโลก"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "เลื่อนตำแหน่ง (แบบสัมพันธ์)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "หมุน (สัมบูรณ์)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "พิกัดส่วน"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "ความขัดแย้งในการซิงก์ Cloud: ค่าที่ตั้งไว้ล่วงหน้านี้มีเวอร์ชันใหม่กว่าใน Orca Cloud\n"
|
||||
#~ "ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "ความขัดแย้งในการซิงก์ Cloud: มีค่าที่ตั้งไว้ล่วงหน้าชื่อนี้อยู่ใน Orca Cloud แล้ว\n"
|
||||
#~ "ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
#~ "Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "ความขัดแย้งในการซิงก์ Cloud: ค่าที่ตั้งไว้ล่วงหน้าชื่อเดียวกันเคยถูกลบจากคลาวด์แล้ว\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 ""
|
||||
#~ "ความขัดแย้งในการซิงก์ Cloud: พบความขัดแย้งของค่าที่ตั้งไว้ล่วงหน้าที่ไม่คาดคิดหรือระบุไม่ได้\n"
|
||||
#~ "ดึงข้อมูลจะดาวน์โหลดสำเนาจากคลาวด์ บังคับส่งจะเขียนทับด้วยค่าที่ตั้งไว้ล่วงหน้าในเครื่องของคุณ"
|
||||
|
||||
#~ 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) โปรดลดขนาดที่กำหนดไว้ล่วงหน้าโดยการลบการกำหนดค่าที่กำหนดเองออกหรือใช้เฉพาะในเครื่องเท่านั้น"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "เปิดใช้งานการปรับPressure Advanceสำหรับระยะยื่น (เบต้า)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
#~ msgstr ""
|
||||
#~ "เปิดใช้งาน PA แบบปรับตัวสำหรับส่วนยื่นและเมื่ออัตราการไหลเปลี่ยนภายในฟีเจอร์เดียวกัน เป็นตัวเลือกทดลอง หากโปรไฟล์ PA ไม่แม่นยำ จะทำให้ผิวด้านนอกไม่สม่ำเสมอก่อนและหลังส่วนยื่น\n"
|
||||
#~ "ไม่รองรับเครื่องพิมพ์ Prusa เพราะจะหยุดชั่วคราวเพื่อประมวลผลการเปลี่ยน PA ทำให้เกิดความล่าช้าและข้อบกพร่อง"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "แรงดันล่วงหน้า (Pressure Advance)สำหรับสะพาน"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "ค่าPressure Advanceสำหรับสะพาน ตั้งค่าเป็น 0 เพื่อปิดใช้งาน\n"
|
||||
#~ "\n"
|
||||
#~ "ค่า PA ที่ต่ำลงเมื่อพิมพ์บริดจ์จะช่วยลดลักษณะที่ปรากฏเล็กน้อยจากการอัดขึ้นรูปทันทีหลังจากบริดจ์ สาเหตุนี้เกิดจากแรงดันตกในหัวฉีดเมื่อพิมพ์ในอากาศ และค่า PA ที่ต่ำกว่าจะช่วยแก้ปัญหานี้ได้"
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "ตัวเลือกการซิงค์ฟิลาเมนต์"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2026-04-08 23:59+0300\n"
|
||||
"Last-Translator: GlauTech\n"
|
||||
"Language-Team: \n"
|
||||
@@ -327,7 +327,6 @@ msgstr "Gizmo-Döndür"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Yönü optimize edin"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Ölçeklendir"
|
||||
|
||||
@@ -337,9 +336,8 @@ msgstr "Gizmo-Ölçeklendir"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Hata: Lütfen önce tüm araç çubuğu menülerini kapatın"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -372,9 +370,6 @@ msgstr "Ölçek oranları"
|
||||
msgid "Object operations"
|
||||
msgstr "Nesne İşlemleri"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Ölçeklendir"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Hacim İşlemleri"
|
||||
@@ -402,33 +397,26 @@ msgstr "Konumu Sıfırla"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Döndürmeyi sıfırla"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Nesne koordinatları"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Nesne"
|
||||
msgid "World coordinates"
|
||||
msgstr "Dünya koordinatları"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Parça"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "Çevir(Göreceli)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Döndürme aracını açtığınızda mevcut döndürme değerini sıfırlayın."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Döndür (mutlak)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Mevcut dönüşü gerçek sıfırlara sıfırla."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Ölçeklendir"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Parça koordinatları"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -533,6 +521,12 @@ msgstr "Boşluk"
|
||||
msgid "Spacing"
|
||||
msgstr "Boşluk"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Parça"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Nesne"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1877,30 +1871,23 @@ msgstr "Projeyi Aç"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Orca Slicer'ın sürümü çok düşük ve normal şekilde kullanılabilmesi için en son sürüme güncellenmesi gerekiyor."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1909,12 +1896,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1989,8 +1970,7 @@ msgstr "Bulutta önbelleğe alınan kullanıcı ön ayarlarının sayısı üst
|
||||
msgid "Sync user presets"
|
||||
msgstr "Kullanıcı ön ayarlarını senkronize edin"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2212,9 +2192,6 @@ msgstr "Orca Küpü"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca tolerans testi"
|
||||
|
||||
@@ -3652,7 +3629,7 @@ msgstr "Kalibrasyon tamamlandı. Lütfen sıcak yatağınızdaki en düzgün eks
|
||||
msgid "Save"
|
||||
msgstr "Kaydet"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Arka"
|
||||
|
||||
@@ -5035,7 +5012,6 @@ msgstr "Takım değişiklikleri"
|
||||
msgid "Color change"
|
||||
msgstr "Renk değişimi"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Yazdır"
|
||||
|
||||
@@ -5199,15 +5175,11 @@ msgstr "Ekstrüzyon kalibrasyon bölgesinden kaçın"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Y eksenine hizala"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Arka"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Sol"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Sağ"
|
||||
|
||||
@@ -5286,9 +5258,6 @@ msgstr "Çıkıntılar"
|
||||
msgid "Outline"
|
||||
msgstr "Taslak"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5332,7 +5301,7 @@ msgstr "Hacim:"
|
||||
msgid "Size:"
|
||||
msgstr "Boyut:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "%d katmanında gcode yollarında çakışmalar bulundu, Z = %.2lfmm. Lütfen çakışan nesneleri daha uzağa ayırın (%s <-> %s)."
|
||||
|
||||
@@ -5535,10 +5504,6 @@ msgstr "Plakayı Yazdır"
|
||||
msgid "Export G-code file"
|
||||
msgstr "G-kod dosyasını dışa aktar"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Yazdır"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Dilimlenmiş plaka dosyasını dışa aktar"
|
||||
|
||||
@@ -8075,35 +8040,6 @@ msgstr "STEP dosyasını içe aktarırken seçenekleri göster"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Etkinleştirilirse, STEP dosyası içe aktarılırken bir parametre ayarları iletişim kutusu görüntülenir."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Draco dışa aktarımı için kalite düzeyi"
|
||||
|
||||
@@ -8119,12 +8055,6 @@ msgstr ""
|
||||
"0 = kayıpsız sıkıştırma (geometri tam hassasiyetle korunur). Geçerli kayıplı değerler 8 ile 30 arasında değişir.\n"
|
||||
"Daha düşük değerler daha küçük dosyalar oluşturur ancak daha fazla geometrik ayrıntıyı kaybeder; daha yüksek değerler, daha büyük dosyalar pahasına daha fazla ayrıntıyı korur."
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Ön ayar"
|
||||
|
||||
@@ -12437,18 +12367,6 @@ msgstr "Küçük çevre (perimeter) eşiği"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Bu, küçük çevre uzunluğu için eşiği belirler. Varsayılan eşik 0 mm'dir."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Duvar baskı sırası"
|
||||
|
||||
@@ -12632,26 +12550,25 @@ msgstr ""
|
||||
"2. Her hacimsel akış hızı ve ivme için en uygun PA değerini not edin. Renk şeması açılır menüsünden akışı seçerek ve yatay kaydırıcıyı PA desen çizgileri üzerinde hareket ettirerek akış numarasını bulabilirsiniz. Numara sayfanın altında görünmelidir. İdeal PA değeri hacimsel akış ne kadar yüksek olursa o kadar azalmalıdır. Değilse, ekstruderinizin doğru şekilde çalıştığını doğrulayın. Ne kadar yavaş ve daha az ivmeyle yazdırırsanız, kabul edilebilir PA değerleri aralığı o kadar geniş olur. Hiçbir fark görünmüyorsa, daha hızlı olan testteki PA değerini kullanın.\n"
|
||||
"3. Buradaki metin kutusuna PA değerleri, Akış ve Hızlanma üçlüsünü girin ve filament profilinizi kaydedin."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Çıkıntılar için uyarlanabilir basınç ilerlemesini etkinleştirin (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Köprüler için basınç ilerlemesi"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Köprüler için basınç ilerleme değeri. Devre dışı bırakmak için 0’a ayarlayın.\n"
|
||||
"\n"
|
||||
" Köprüleri yazdırırken daha düşük bir basınç değeri, köprülerden hemen sonra hafif ekstrüzyon görünümünün azaltılmasına yardımcı olur. Bunun nedeni, havada yazdırma sırasında nozuldaki basınç düşüşüdür ve daha düşük bir basınç, bunu önlemeye yardımcı olur."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Diğer çizgi genişlikleri 0'a ayarlanmışsa varsayılan çizgi genişliği. % olarak ifade edilirse nozul çapı üzerinden hesaplanacaktır."
|
||||
@@ -13034,22 +12951,6 @@ msgstr "Katı dolgu yönü"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Hattın başlangıcını veya ana yönünü kontrol eden katı dolgu deseni açısı."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Dolgu yoğunluğu"
|
||||
|
||||
@@ -14793,10 +14694,6 @@ msgstr "Hizalı"
|
||||
msgid "Aligned back"
|
||||
msgstr "Arkaya hizalı"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Arka"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Rastgele"
|
||||
|
||||
@@ -15849,14 +15746,6 @@ msgstr "Çokgen delik eğrisi"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Çokgeni her katmanda döndürün."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-code önizleme resimleri"
|
||||
|
||||
@@ -19220,12 +19109,6 @@ msgstr "Üçgen yüzeylerin sayısı"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Hesaplanıyor, lütfen bekleyin..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19631,42 +19514,6 @@ msgstr ""
|
||||
"Eğilmeyi önleyin\n"
|
||||
"ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Yazdır"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Nesne koordinatları"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Dünya koordinatları"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "Çevir(Göreceli)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Döndür (mutlak)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Parça koordinatları"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Çıkıntılar için uyarlanabilir basınç ilerlemesini etkinleştirin (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Köprüler için basınç ilerlemesi"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Köprüler için basınç ilerleme değeri. Devre dışı bırakmak için 0’a ayarlayın.\n"
|
||||
#~ "\n"
|
||||
#~ " Köprüleri yazdırırken daha düşük bir basınç değeri, köprülerden hemen sonra hafif ekstrüzyon görünümünün azaltılmasına yardımcı olur. Bunun nedeni, havada yazdırma sırasında nozuldaki basınç düşüşüdür ve daha düşük bir basınç, bunu önlemeye yardımcı olur."
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "Filament Senkronizasyon Seçenekleri"
|
||||
|
||||
@@ -20160,9 +20007,3 @@ 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 "Sıcaklık farkı çok büyük olan birden fazla filament aynı anda basılamaz. Aksi takdirde ekstruder ve nozul baskı sırasında tıkanabilir veya zarar görebilir"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "Sızıntıyı önlemek için, nozul sıcaklığı tokmaklama sırasında soğutulacaktır. Bu nedenle, sıkıştırma süresi soğuma süresinden büyük olmalıdır. 0 devre dışı anlamına gelir."
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "Sızmayı önlemek için nozul, sıkıştırma tamamlandıktan sonra belirli bir süre boyunca ters hareket hareketi gerçekleştirecektir. Ayar, hareket süresini tanımlar."
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: orcaslicerua\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2025-03-07 09:30+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Ukrainian\n"
|
||||
@@ -332,7 +332,6 @@ msgstr "Gizmo обертання"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Оптимізувати орієнтацію"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
|
||||
@@ -342,9 +341,8 @@ msgstr "Gizmo масштабування"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Помилка: будь ласка, спочатку закрийте все меню панелі інструментів"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "в"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "мм"
|
||||
@@ -377,9 +375,6 @@ msgstr "Коефіцієнти масштабування"
|
||||
msgid "Object operations"
|
||||
msgstr "Операції з об'єктами"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Операції з об’ємом"
|
||||
@@ -407,33 +402,26 @@ msgstr "Скинути позицію"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Скинути обертання"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Координати об'єкта"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Об'єкт"
|
||||
msgid "World coordinates"
|
||||
msgstr "Глобальні координати"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Частина"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Скинути поточне обертання до значення при відкритті інструмента обертання."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Обертання (абсолютне)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Скинути поточне обертання до нульових значень."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Масштаб"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Координати частини"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -538,6 +526,12 @@ msgstr "Проміжок"
|
||||
msgid "Spacing"
|
||||
msgstr "Відстань"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Частина"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Об'єкт"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1884,30 +1878,23 @@ msgstr "Відкрити проєкт"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Версія студії Bambu надто низька, її необхідно оновити до останньоїверсії, перш ніж її можна буде використовувати у звичайному режимі"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1916,12 +1903,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1989,8 +1970,7 @@ msgstr "Кількість налаштувань користувача, збе
|
||||
msgid "Sync user presets"
|
||||
msgstr "Синхронізувати налаштування користувача"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2212,9 +2192,6 @@ msgstr "Orca Куб"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Тест на допуски ORCA"
|
||||
|
||||
@@ -3668,7 +3645,7 @@ msgstr "Калібрування завершено. Тепер знайдіть
|
||||
msgid "Save"
|
||||
msgstr "Зберегти"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Ззаду"
|
||||
|
||||
@@ -5038,7 +5015,6 @@ msgstr "Зміна інструменту"
|
||||
msgid "Color change"
|
||||
msgstr "Зміна кольору"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "Друк"
|
||||
|
||||
@@ -5200,15 +5176,11 @@ msgstr "Уникайте області калібрування екструз
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Розташувати вздовж осі Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Ззаду"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Ліво"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Право"
|
||||
|
||||
@@ -5287,9 +5259,6 @@ msgstr "Нависання"
|
||||
msgid "Outline"
|
||||
msgstr "Контур"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5334,7 +5303,7 @@ msgid "Size:"
|
||||
msgstr "Розмір:"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr ""
|
||||
"Виявлено конфлікти шляхів gcode на рівні %d, Z = %.2lf мм. Будь ласка \n"
|
||||
@@ -5536,10 +5505,6 @@ msgstr "Друкувати пластину"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Експорт файлу G-коду"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "Друк"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Експортувати файл нарізки пластини"
|
||||
|
||||
@@ -8089,35 +8054,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8130,12 +8066,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Шаблон"
|
||||
|
||||
@@ -12420,18 +12350,6 @@ msgstr "Поріг малих периметрів"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "При цьому встановлюється поріг для невеликої довжини периметра. Порігове за замовчуванням - 0 мм"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Послідовність друку стінок"
|
||||
|
||||
@@ -12619,26 +12537,25 @@ msgstr ""
|
||||
"2. Запишіть оптимальне значення PA для кожної об'ємної швидкості подачі та прискорення. Ви можете знайти значення подачі, вибравши \"Flow\" у випадаючому списку колірної схеми та пересуваючи горизонтальний повзунок по лініях шаблону PA. Значення повинне відображатися внизу сторінки. Ідеальне значення PA має зменшуватися зі збільшенням об'ємної швидкості подачі. Якщо це не так, переконайтеся, що ваш екструдер працює коректно. Чим повільніше друкуєте і з меншим прискоренням, тим ширший діапазон допустимих значень PA. Якщо різниця не помітна, використовуйте значення PA із швидшого тесту.\n"
|
||||
"3. Введіть трійки значень PA, Flow і Acceleration у це текстове поле та збережіть профіль філамента."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Увімкнути адаптивне випередження тиску для нависань (бета)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Випередження тиску для мостів"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Значення випередження тиску для мостів. Встановіть 0, щоб вимкнути.\n"
|
||||
"\n"
|
||||
"Нижче значення випередження тиску при друкуванні мостів допомагає зменшити прояви незначної недоекструзії одразу після друку мостів. Це спричинено падінням тиску в соплі під час друку в повітрі, і зменшене значення випередження тиску допомагає це компенсувати."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Ширина лінії за замовчуванням, якщо інші ширини ліній встановлено на 0. Якщо виражено у %, вона буде розрахована за діаметром сопла."
|
||||
@@ -13016,22 +12933,6 @@ msgstr "Напрямок cуцільного заповнення"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Кут шаблону суцільного заповнення, який контролює початок або основний напрямок лінії"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Щільність часткового заповнення"
|
||||
|
||||
@@ -14770,10 +14671,6 @@ msgstr "Вирівняне"
|
||||
msgid "Aligned back"
|
||||
msgstr ""
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Ззаду"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Випадкове"
|
||||
|
||||
@@ -15822,14 +15719,6 @@ msgstr "Скручування полігонів"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Повертайте полігон кожен шар."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Мініатюри G-code"
|
||||
|
||||
@@ -19164,12 +19053,6 @@ msgstr "Кількість трикутних граней"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "Розрахунок, будь ласка, зачекайте…"
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19575,39 +19458,6 @@ msgstr ""
|
||||
"Уникнення деформації\n"
|
||||
"Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури гарячого ліжка може зменшити ймовірність деформації?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "Друк"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "в"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Координати об'єкта"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Глобальні координати"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Обертання (абсолютне)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Координати частини"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Увімкнути адаптивне випередження тиску для нависань (бета)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Випередження тиску для мостів"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Значення випередження тиску для мостів. Встановіть 0, щоб вимкнути.\n"
|
||||
#~ "\n"
|
||||
#~ "Нижче значення випередження тиску при друкуванні мостів допомагає зменшити прояви незначної недоекструзії одразу після друку мостів. Це спричинено падінням тиску в соплі під час друку в повітрі, і зменшене значення випередження тиску допомагає це компенсувати."
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "Перегляд параметрів керування"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: hainguyen.ts13@gmail.com\n"
|
||||
@@ -328,7 +328,6 @@ msgstr "Gizmo - Xoay"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "Tối ưu định hướng"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "Tỷ lệ"
|
||||
|
||||
@@ -338,9 +337,8 @@ msgstr "Gizmo - Tỷ lệ"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "Lỗi: Vui lòng đóng tất cả menu thanh công cụ trước"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "in"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -373,9 +371,6 @@ msgstr "Tỷ lệ co giãn"
|
||||
msgid "Object operations"
|
||||
msgstr "Thao tác vật thể"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "Tỷ lệ"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "Thao tác thể tích"
|
||||
@@ -403,33 +398,26 @@ msgstr "Đặt lại vị trí"
|
||||
msgid "Reset rotation"
|
||||
msgstr "Đặt lại xoay"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "Tọa độ vật thể"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Vật thể"
|
||||
msgid "World coordinates"
|
||||
msgstr "Tọa độ thế giới"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Phần"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgid "Translate(Relative)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "Đặt lại xoay hiện tại về giá trị khi mở công cụ xoay."
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "Xoay (tuyệt đối)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "Đặt lại xoay hiện tại về số không thực."
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "Tỷ lệ"
|
||||
msgid "Part coordinates"
|
||||
msgstr "Tọa độ phần"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -534,6 +522,12 @@ msgstr ""
|
||||
msgid "Spacing"
|
||||
msgstr "Khoảng cách"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "Phần"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "Vật thể"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1877,30 +1871,23 @@ msgstr "Mở dự án"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Phiên bản Orca Slicer quá cũ và cần được cập nhật lên phiên bản mới nhất trước khi có thể sử dụng bình thường."
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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 ""
|
||||
|
||||
@@ -1909,12 +1896,6 @@ msgid ""
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr ""
|
||||
|
||||
@@ -1982,8 +1963,7 @@ msgstr "Số lượng preset người dùng đã lưu trong cloud vượt quá g
|
||||
msgid "Sync user presets"
|
||||
msgstr "Đồng bộ preset người dùng"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
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 ""
|
||||
|
||||
#, c-format, boost-format
|
||||
@@ -2204,9 +2184,6 @@ msgstr ""
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr ""
|
||||
|
||||
@@ -3638,7 +3615,7 @@ msgstr "Hiệu chỉnh hoàn tất. Vui lòng tìm đường đùn đồng đề
|
||||
msgid "Save"
|
||||
msgstr "Lưu"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Sau"
|
||||
|
||||
@@ -5009,7 +4986,6 @@ msgstr ""
|
||||
msgid "Color change"
|
||||
msgstr "Đổi màu"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "In"
|
||||
|
||||
@@ -5171,15 +5147,11 @@ msgstr "Tránh vùng hiệu chỉnh đùn"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "Căn theo trục Y"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "Sau"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "Trái"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "Phải"
|
||||
|
||||
@@ -5258,9 +5230,6 @@ msgstr "Phần nhô"
|
||||
msgid "Outline"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr ""
|
||||
|
||||
@@ -5304,7 +5273,7 @@ msgstr "Thể tích:"
|
||||
msgid "Size:"
|
||||
msgstr "Kích thước:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "Đã tìm thấy xung đột đường đi G-code tại lớp %d, Z = %.2lfmm. Vui lòng tách các vật thể xung đột ra xa hơn (%s <-> %s)."
|
||||
|
||||
@@ -5503,10 +5472,6 @@ msgstr "In plate"
|
||||
msgid "Export G-code file"
|
||||
msgstr "Xuất file G-code"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "In"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "Xuất file plate đã slice"
|
||||
|
||||
@@ -8027,35 +7992,6 @@ msgstr ""
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "Nếu được bật, hộp thoại cài đặt tham số sẽ xuất hiện trong quá trình nhập file STEP."
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr ""
|
||||
|
||||
@@ -8068,12 +8004,6 @@ msgid ""
|
||||
"Lower values produce smaller files but lose more geometric detail; higher values preserve more detail at the cost of larger files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "Cài đặt sẵn"
|
||||
|
||||
@@ -12333,18 +12263,6 @@ msgstr "Ngưỡng chu vi nhỏ"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "Điều này đặt ngưỡng cho độ dài chu vi nhỏ. Ngưỡng mặc định là 0mm."
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "Thứ tự in thành"
|
||||
|
||||
@@ -12529,26 +12447,25 @@ msgstr ""
|
||||
"2. Ghi chú giá trị PA tối ưu cho mỗi tốc độ lưu lượng thể tích và gia tốc. Bạn có thể tìm số lưu lượng bằng cách chọn lưu lượng từ menu thả xuống sơ đồ màu và di chuyển thanh trượt ngang qua các đường mẫu PA. Số nên hiển thị ở cuối trang. Giá trị PA lý tưởng nên giảm xuống khi lưu lượng thể tích càng cao. Nếu không, hãy xác nhận rằng extruder của bạn đang hoạt động chính xác. Càng chậm và với gia tốc ít hơn bạn in, phạm vi giá trị PA chấp nhận được càng lớn. Nếu không thấy sự khác biệt, hãy sử dụng giá trị PA từ kiểm tra nhanh hơn\n"
|
||||
"3. Nhập bộ ba giá trị PA, Lưu lượng và Gia tốc vào hộp văn bản ở đây và lưu hồ sơ filament của bạn."
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "Bật áp suất nâng cao thích ứng cho phần nhô (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "Áp suất nâng cao cho cầu"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"Giá trị áp suất nâng cao cho cầu. Đặt thành 0 để tắt.\n"
|
||||
"\n"
|
||||
"Giá trị PA thấp hơn khi in cầu giúp giảm sự xuất hiện của đùn thiếu nhỏ ngay sau cầu. Điều này được gây ra bởi áp suất giảm trong đầu phun khi in trong không khí và PA thấp hơn giúp chống lại điều này."
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "Độ rộng đường mặc định nếu độ rộng đường khác được đặt thành 0. Nếu được biểu thị dưới dạng %, nó sẽ được tính trên đường kính đầu phun."
|
||||
@@ -12928,22 +12845,6 @@ msgstr "Hướng infill đặc"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "Góc cho mẫu infill đặc, điều khiển hướng bắt đầu hoặc chính của đường."
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "Mật độ infill thưa"
|
||||
|
||||
@@ -14685,10 +14586,6 @@ msgstr "Căn chỉnh"
|
||||
msgid "Aligned back"
|
||||
msgstr "Căn chỉnh sau"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "Sau"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "Ngẫu nhiên"
|
||||
|
||||
@@ -15737,14 +15634,6 @@ msgstr "Xoắn polyhole"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "Xoay polyhole mỗi lớp."
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "Hình thu nhỏ G-code"
|
||||
|
||||
@@ -19085,12 +18974,6 @@ msgstr ""
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr ""
|
||||
|
||||
@@ -19496,39 +19379,6 @@ msgstr ""
|
||||
"Tránh cong vênh\n"
|
||||
"Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "In"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "in"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "Tọa độ vật thể"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "Tọa độ thế giới"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "Xoay (tuyệt đối)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "Tọa độ phần"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "Bật áp suất nâng cao thích ứng cho phần nhô (beta)"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "Áp suất nâng cao cho cầu"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr ""
|
||||
#~ "Giá trị áp suất nâng cao cho cầu. Đặt thành 0 để tắt.\n"
|
||||
#~ "\n"
|
||||
#~ "Giá trị PA thấp hơn khi in cầu giúp giảm sự xuất hiện của đùn thiếu nhỏ ngay sau cầu. Điều này được gây ra bởi áp suất giảm trong đầu phun khi in trong không khí và PA thấp hơn giúp chống lại điều này."
|
||||
|
||||
#~ msgid "View control settings"
|
||||
#~ msgstr "Cài đặt điều khiển chế độ xem"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Slic3rPE\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
|
||||
"Last-Translator: Handle <mail@bysb.net>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -330,7 +330,6 @@ msgstr "Gizmo-旋转"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "优化朝向"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "缩放"
|
||||
|
||||
@@ -340,9 +339,8 @@ msgstr "缩放工具"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "错误:请先关闭所有工具栏菜单"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "在"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -375,9 +373,6 @@ msgstr "缩放比例"
|
||||
msgid "Object operations"
|
||||
msgstr "对象操作"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "缩放"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "零件操作"
|
||||
@@ -405,33 +400,26 @@ msgstr "重置位置"
|
||||
msgid "Reset rotation"
|
||||
msgstr "重置旋转"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "物体坐标"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "对象"
|
||||
msgid "World coordinates"
|
||||
msgstr "世界坐标"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "零件"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "转换(相对)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "重置当前旋转为打开旋转工具时的值"
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "旋转(绝对)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "重置当前旋转为真实零位"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "缩放"
|
||||
msgid "Part coordinates"
|
||||
msgstr "零件坐标"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -536,6 +524,12 @@ msgstr "间隙"
|
||||
msgid "Spacing"
|
||||
msgstr "间距"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "零件"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "对象"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1875,32 +1869,33 @@ msgstr "打开项目"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "此逆戟鲸切片器的版本过低,需更新至最新版本方可正常使用"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"云同步冲突:此预设在 OrcaCloud 中存在更新的版本。\n"
|
||||
"拉取将下载云端副本。强制推送将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"云同步冲突:OrcaCloud 中已存在同名预设。\n"
|
||||
"拉取将下载云端副本。强制推送将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"云同步冲突:之前已从云端删除了同名预设。\n"
|
||||
"“删除”将删除您的本地预设。“强制推送”将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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"
|
||||
"“拉取”将下载云端副本。“强制推送”将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -1909,12 +1904,6 @@ msgstr ""
|
||||
"强制推送将用您本地的预设更改覆盖云端副本。\n"
|
||||
"是否继续?"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr "解决云同步冲突"
|
||||
|
||||
@@ -1994,9 +1983,8 @@ msgstr "云端缓存的用户预设数量已超过上限,新创建的用户预
|
||||
msgid "Sync user presets"
|
||||
msgstr "同步用户预设"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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)。请通过移除自定义配置来缩减预设大小,或仅在本地使用。"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2217,9 +2205,6 @@ msgstr "Orca方块"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "OrcaSliced 复合模型"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca误差测试"
|
||||
|
||||
@@ -3647,7 +3632,7 @@ msgstr "校准完成。如下图中的示例,请在您的热床上找到最均
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
@@ -5022,7 +5007,6 @@ msgstr "工具更换"
|
||||
msgid "Color change"
|
||||
msgstr "颜色更换"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "打印"
|
||||
|
||||
@@ -5187,15 +5171,11 @@ msgstr "避开挤出校准区域"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "对齐到Y轴"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "左"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "右"
|
||||
|
||||
@@ -5274,9 +5254,6 @@ msgstr "悬垂"
|
||||
msgid "Outline"
|
||||
msgstr "轮廓线"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr "写实渲染"
|
||||
|
||||
@@ -5320,7 +5297,7 @@ msgstr "体积:"
|
||||
msgid "Size:"
|
||||
msgstr "尺寸:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "发现G-code路径在层%d,高度为%.2lf mm处有冲突。请将有冲突的对象分离得更远(%s <-> %s)。"
|
||||
|
||||
@@ -5523,10 +5500,6 @@ msgstr "打印单盘"
|
||||
msgid "Export G-code file"
|
||||
msgstr "导出G-code文件"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "打印"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "导出单盘切片文件"
|
||||
|
||||
@@ -8042,35 +8015,6 @@ msgstr "显示STEP网格参数设置对话框"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "如果启用,在导入STEP文件时将出现参数设置对话框"
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Draco 导出的模型质量"
|
||||
|
||||
@@ -8086,12 +8030,6 @@ msgstr ""
|
||||
"0 = 无损压缩(以全精度保留几何形状)。有效有损值范围为 8 到 30。\n"
|
||||
"较低的值会生成较小的文件,但会丢失更多的几何细节;较高的值可保留更多细节,但代价是文件较大。"
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "预设"
|
||||
|
||||
@@ -12497,18 +12435,6 @@ msgstr "微小部位周长阈值"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "这将设置微小部位周长的阈值。默认阈值为0mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "墙顺序"
|
||||
|
||||
@@ -12689,26 +12615,24 @@ msgstr ""
|
||||
"2. 记下每个体积流速和加速度的最佳 PA 值。您可以通过从配色方案下拉列表中选择流量并将水平滑块移动到 PA 图案线上来找到流量编号。该数字应该在页面底部可见。理想的 PA 值应该随着体积流量的增加而减小。如果不是,请确认您的挤出机运行正常。打印速度越慢且加速度越小,可接受的 PA 值范围就越大。如果没有明显差异,请使用更快测试中的 PA 值\n"
|
||||
"3. 在此处的文本框中输入 PA 值、流量和加速度的三元组并保存耗材丝配置文件"
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "为悬垂启用自适应压力提前(试验)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
"针对悬垂以及同一特征内的流量变化启用自适应 PA。这是一个实验性选项,因为如果未准确设置 PA 配置文件,将导致悬垂前后外表面出现均匀性问题。\n"
|
||||
"与 Prusa 打印机不兼容,因为它们会暂停以处理 PA 变化,从而导致延迟和瑕疵。"
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "为搭桥启用压力提前"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr "桥梁的压力提前值。设置为 0 以禁用。 打印桥接时较低的 PA 值有助于减少桥接后立即出现的轻微挤压不足现象。这是由在空气中打印时喷嘴中的压力下降引起的,较低的 PA 有助于抵消这种情况。"
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "当线宽设置为0时走线的默认线宽。如果以%表示,它将基于喷嘴直径来计算。"
|
||||
@@ -13104,22 +13028,6 @@ msgstr "实心填充方向"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "实心填充图案的角度,决定走线的开始或整体方向。"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "稀疏填充密度"
|
||||
|
||||
@@ -14913,10 +14821,6 @@ msgstr "对齐"
|
||||
msgid "Aligned back"
|
||||
msgstr "背部对齐"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "随机"
|
||||
|
||||
@@ -15973,14 +15877,6 @@ msgstr "扭曲多边型孔"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "按层旋转多边形孔。"
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-code缩略图尺寸"
|
||||
|
||||
@@ -19342,12 +19238,6 @@ msgstr "三角面片数量"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "正在计算,请稍候..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr "预设包"
|
||||
|
||||
@@ -19758,77 +19648,6 @@ msgstr ""
|
||||
"避免翘曲\n"
|
||||
"您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "打印"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "在"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "物体坐标"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "世界坐标"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "转换(相对)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "旋转(绝对)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "零件坐标"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "云同步冲突:此预设在 OrcaCloud 中存在更新的版本。\n"
|
||||
#~ "拉取将下载云端副本。强制推送将用您的本地预设覆盖它。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "云同步冲突:OrcaCloud 中已存在同名预设。\n"
|
||||
#~ "拉取将下载云端副本。强制推送将用您的本地预设覆盖它。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
#~ "Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "云同步冲突:之前已从云端删除了同名预设。\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"
|
||||
#~ "“拉取”将下载云端副本。“强制推送”将用您的本地预设覆盖它。"
|
||||
|
||||
#~ 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)。请通过移除自定义配置来缩减预设大小,或仅在本地使用。"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "为悬垂启用自适应压力提前(试验)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
#~ msgstr ""
|
||||
#~ "针对悬垂以及同一特征内的流量变化启用自适应 PA。这是一个实验性选项,因为如果未准确设置 PA 配置文件,将导致悬垂前后外表面出现均匀性问题。\n"
|
||||
#~ "与 Prusa 打印机不兼容,因为它们会暂停以处理 PA 变化,从而导致延迟和瑕疵。"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "为搭桥启用压力提前"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr "桥梁的压力提前值。设置为 0 以禁用。 打印桥接时较低的 PA 值有助于减少桥接后立即出现的轻微挤压不足现象。这是由在空气中打印时喷嘴中的压力下降引起的,较低的 PA 有助于抵消这种情况。"
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "耗材丝同步选项"
|
||||
|
||||
@@ -20444,189 +20263,3 @@ msgstr ""
|
||||
#, c-format, boost-format
|
||||
#~ msgid "The selected preset: %s is not found."
|
||||
#~ msgstr "未找到所选预设:%s。"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "热端异常"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "可用喷嘴"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "注意:不支持在打印中混用不同直径的喷嘴。如果所选尺寸仅存在于一个挤出机上,将强制使用单挤出机打印。"
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "在热端升级过程中,工具头会移动。请勿将手伸入机箱内。"
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "开启该功能后,当腔温过高时,会自动关闭过滤以提高冷却效果"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "错误:无法将两个喷嘴数量都设置为零。"
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "错误:喷嘴数量不可以超过%d。"
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "挤出机更换"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "热端更换"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "热端更换时间"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "热端信息可能不准确。是否重新读取热端?(断电期间热端信息可能会发生变化)。"
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "混合"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "确认无误"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "感应热端架"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "喷嘴选择"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "请核对喷嘴直径和流量是否与显示值一致。"
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "请设置喷嘴数量"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "切换喷嘴需要擦料塔,否则打印件上可能会有瑕疵。您确定要关闭擦料塔吗?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "重新读取全部"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "正在读取热端信息,请稍候。"
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "刷新 %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "同步喷嘴状态"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU高流量"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "热端状态异常,当前不可用。请前往“设备 -> 升级”升级固件。"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "热端更换前的最大预冲刷体积速度,其中 -1 表示使用最大体积速度。"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "换出挤出机前的最大预冲刷体积速度,-1 表示使用最大体积速度。"
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "工具头和热端架可能会运动,请勿将手伸入机箱。"
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "换热端所需的擦料塔上的清理量。"
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "热端更换时间。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "为防止溢料,预冲刷过程中喷嘴温度会降低。注意:仅触发冷却指令并启动风扇,不保证达到目标温度。0 表示禁用。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "为了防止溢料,预冲刷时会降低喷嘴温度。因此,预冲刷时间必须大于冷却时间。0 表示禁用。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "为了防止溢料,预冲刷完成后,喷嘴会进行一段时间的反向空驶。该设置用于定义空驶时间。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "检测到未知喷嘴。请刷新以更新信息(未刷新的喷嘴将在切片时被排除)。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "检测到未知喷嘴。请刷新以更新信息(未刷新的喷嘴将在切片时被排除)。请核对喷嘴直径和流量是否与显示值一致。"
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "开启冷却过滤"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "更换热端时,建议从原热端中挤出一定长度的耗材丝。这有助于最大限度地减少喷嘴漏料。"
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "当修改此回抽数值时,将用于热端内在更换热端前回抽的耗材量。"
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "您的打印机安装了不同的喷嘴。请选择一个喷嘴进行本次打印。"
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "换热端时回抽量"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "当前盘存在动态分配喷嘴,不支持修改。"
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "热端挂架"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "热端状态异常,目前不可用。请升级固件后重试。"
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "热端"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "热端信息"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "热端&挂架"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "跳转至升级页面"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "注意:%s上的热端编号与刀架绑定。当热端移动至新刀架时,其编号会自动更新。"
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "喷嘴 ID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "需要读取喷嘴信息"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "请稍候"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "使用当前喷嘴打印可能会产生额外 %0.2f 克废料。"
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "已升起"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "读取全部"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "读取中 "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "A排"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "B排"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "运行中..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "选择材料预设和喷头"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "标准流量"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "工具头"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "工具头"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "使用时间: %s"
|
||||
|
||||
@@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
|
||||
"POT-Creation-Date: 2026-07-03 14:43+0200\n"
|
||||
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
|
||||
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -333,7 +333,6 @@ msgstr "Gizmo-旋轉"
|
||||
msgid "Optimize orientation"
|
||||
msgstr "最佳化方向"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Scale"
|
||||
msgstr "縮放"
|
||||
|
||||
@@ -343,9 +342,8 @@ msgstr "Gizmo 比例"
|
||||
msgid "Error: Please close all toolbar menus first"
|
||||
msgstr "錯誤:請先關閉所有工具欄選單"
|
||||
|
||||
msgctxt "inches"
|
||||
msgid "in"
|
||||
msgstr ""
|
||||
msgstr "在"
|
||||
|
||||
msgid "mm"
|
||||
msgstr "mm"
|
||||
@@ -378,9 +376,6 @@ msgstr "縮放比例"
|
||||
msgid "Object operations"
|
||||
msgstr "物件操作"
|
||||
|
||||
msgid "Scale"
|
||||
msgstr "縮放"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Volume operations"
|
||||
msgstr "零件操作"
|
||||
@@ -408,33 +403,26 @@ msgstr "重設位置"
|
||||
msgid "Reset rotation"
|
||||
msgstr "重設旋轉"
|
||||
|
||||
msgid "World"
|
||||
msgstr ""
|
||||
msgid "Object coordinates"
|
||||
msgstr "物件座標"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "物件"
|
||||
msgid "World coordinates"
|
||||
msgstr "世界座標"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "零件"
|
||||
|
||||
msgid "Relative"
|
||||
msgstr ""
|
||||
|
||||
msgid "Coordinate system used for transform actions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Absolute"
|
||||
msgstr ""
|
||||
msgid "Translate(Relative)"
|
||||
msgstr "平移(相對)"
|
||||
|
||||
msgid "Reset current rotation to the value when open the rotation tool."
|
||||
msgstr "重設旋轉角度為開啟旋轉工具時的狀態。"
|
||||
|
||||
msgid "Rotate (absolute)"
|
||||
msgstr "旋轉(絕對)"
|
||||
|
||||
msgid "Reset current rotation to real zeros."
|
||||
msgstr "將旋轉角度歸零"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Scale"
|
||||
msgstr "縮放"
|
||||
msgid "Part coordinates"
|
||||
msgstr "零件座標"
|
||||
|
||||
#. TRN - Input label. Be short as possible
|
||||
msgid "Size"
|
||||
@@ -539,6 +527,12 @@ msgstr "間隙"
|
||||
msgid "Spacing"
|
||||
msgstr "間距"
|
||||
|
||||
msgid "Part"
|
||||
msgstr "零件"
|
||||
|
||||
msgid "Object"
|
||||
msgstr "物件"
|
||||
|
||||
msgid ""
|
||||
"Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane"
|
||||
@@ -1877,32 +1871,33 @@ msgstr "打開專案"
|
||||
msgid "The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."
|
||||
msgstr "Orca Slicer 版本過舊,需要更新到最新版本才能正常使用"
|
||||
|
||||
msgid "Cloud sync conflict:"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Cloud sync conflict for preset \"%s\":"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This preset has a newer version in OrcaCloud.\n"
|
||||
"Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"雲端同步衝突:此預設在 OrcaCloud 中有較新的版本。\n"
|
||||
"拉取會下載雲端副本。強制推送會以您的本機預設覆寫雲端版本。"
|
||||
|
||||
msgid ""
|
||||
"A preset with this name already exists in OrcaCloud.\n"
|
||||
"Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"雲端同步衝突:OrcaCloud 中已有同名的預設。\n"
|
||||
"拉取會下載雲端副本。強制推送會以您的本機預設覆寫它。"
|
||||
|
||||
msgid ""
|
||||
"A preset with the same name was previously deleted from the cloud.\n"
|
||||
"Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
msgstr ""
|
||||
"雲端同步衝突:先前已從雲端刪除同名的預設。\n"
|
||||
"「刪除」將刪除您的本機預設。「強制推送」會以您的本機預設覆寫它。"
|
||||
|
||||
msgid ""
|
||||
"There was an unexpected or unidentified preset conflict.\n"
|
||||
"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"
|
||||
"拉取會下載雲端副本。強制推送會以您的本機預設覆寫它。"
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -1911,12 +1906,6 @@ msgstr ""
|
||||
"強制推送會以您本機的預設變更覆寫雲端副本。\n"
|
||||
"您要繼續嗎?"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n"
|
||||
"Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resolve cloud sync conflict"
|
||||
msgstr "解決雲端同步衝突"
|
||||
|
||||
@@ -1996,9 +1985,8 @@ msgstr "雲端儲存的使用者預設數量已超過上限,新的使用者預
|
||||
msgid "Sync user presets"
|
||||
msgstr "同步使用者預設"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."
|
||||
msgstr ""
|
||||
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)。請移除自訂設定以減少預設大小,或僅在本機使用。"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -2219,9 +2207,6 @@ msgstr "Orca 立方體"
|
||||
msgid "OrcaSliced Combo"
|
||||
msgstr "OrcaSliced 複合模型"
|
||||
|
||||
msgid "Orca Badge"
|
||||
msgstr ""
|
||||
|
||||
msgid "Orca Tolerance Test"
|
||||
msgstr "Orca 誤差測試"
|
||||
|
||||
@@ -3658,7 +3643,7 @@ msgstr "校正完成。如下圖中的範例,請在您的熱床上找到最均
|
||||
msgid "Save"
|
||||
msgstr "儲存"
|
||||
|
||||
msgctxt "Navigation"
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
@@ -5064,7 +5049,6 @@ msgstr "取代工具"
|
||||
msgid "Color change"
|
||||
msgstr "顏色更換"
|
||||
|
||||
msgctxt "Noun"
|
||||
msgid "Print"
|
||||
msgstr "列印"
|
||||
|
||||
@@ -5229,15 +5213,11 @@ msgstr "避開擠出校正區域"
|
||||
msgid "Align to Y axis"
|
||||
msgstr "與 Y 軸對齊"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Left"
|
||||
msgstr "左"
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgctxt "Camera"
|
||||
msgid "Right"
|
||||
msgstr "右"
|
||||
|
||||
@@ -5316,9 +5296,6 @@ msgstr "懸空"
|
||||
msgid "Outline"
|
||||
msgstr "輪廓線"
|
||||
|
||||
msgid "Wireframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Realistic View"
|
||||
msgstr "擬真檢視"
|
||||
|
||||
@@ -5362,7 +5339,7 @@ msgstr "體積:"
|
||||
msgid "Size:"
|
||||
msgstr "尺寸:"
|
||||
|
||||
#, c-format, boost-format
|
||||
#, boost-format
|
||||
msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)."
|
||||
msgstr "發現 G-code 路徑在 %d 層,Z = %.2lf mm 處的衝突。請將有衝突的物件分離得更遠(%s <-> %s)。"
|
||||
|
||||
@@ -5566,10 +5543,6 @@ msgstr "列印單一列印板"
|
||||
msgid "Export G-code file"
|
||||
msgstr "匯出 G-code 檔案"
|
||||
|
||||
msgctxt "Verb"
|
||||
msgid "Print"
|
||||
msgstr "列印"
|
||||
|
||||
msgid "Export plate sliced file"
|
||||
msgstr "匯出單一列印板切片檔案"
|
||||
|
||||
@@ -8104,35 +8077,6 @@ msgstr "顯示 STEP 網格參數設定視窗。"
|
||||
msgid "If enabled, a parameter settings dialog will appear during STEP file import."
|
||||
msgstr "啟用後,匯入 STEP 檔案時會顯示參數設定視窗。"
|
||||
|
||||
msgid "STEP importing: linear deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Linear deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.003 mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: angle deflection"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Angle deflection used when meshing imported STEP files.\n"
|
||||
"Smaller values produce higher-quality meshes but increase processing time.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: 0.5."
|
||||
msgstr ""
|
||||
|
||||
msgid "STEP importing: Split into multiple objects"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n"
|
||||
"Used as the default in the import dialog, or directly when the import dialog is disabled.\n"
|
||||
"Default: disabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality level for Draco export"
|
||||
msgstr "Draco 匯出品質等級"
|
||||
|
||||
@@ -8148,12 +8092,6 @@ msgstr ""
|
||||
"0 = 無損壓縮(幾何資料以完整精度保留)。有效的有損值範圍為 8 至 30。\n"
|
||||
"較低的值會產生較小的檔案但損失更多幾何細節;較高的值會保留更多細節但檔案較大。"
|
||||
|
||||
msgid "Store full source file paths in projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset"
|
||||
msgstr "預設"
|
||||
|
||||
@@ -12563,18 +12501,6 @@ msgstr "微小部位周長臨界值"
|
||||
msgid "This sets the threshold for small perimeter length. Default threshold is 0mm."
|
||||
msgstr "這設定了微小部位周長的臨界值。 預設臨界值是 0mm"
|
||||
|
||||
msgid "Small support perimeters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto."
|
||||
msgstr ""
|
||||
|
||||
msgid "Small support perimeters threshold"
|
||||
msgstr ""
|
||||
|
||||
msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm."
|
||||
msgstr ""
|
||||
|
||||
msgid "Walls printing order"
|
||||
msgstr "牆列印順序"
|
||||
|
||||
@@ -12757,26 +12683,24 @@ msgstr ""
|
||||
"2. 記錄每個體積流速和加速度的最佳壓力補償 (PA) 值。您可以通過從顏色方案下拉選單中選擇流量,並將水平滑桿移動到 PA 測試線的圖案來找到流量數值。該數值應顯示在頁面底部。理想的 PA 值應隨著體積流速的增加而減小。如果不是,請檢查您的擠出機是否正常工作。當列印速度較慢且加速度較低時,可接受的 PA 值範圍會更大。如果看不出差異,請採用最快測試的 PA 值。\n"
|
||||
"3. 將 PA 值、流量和加速度的三組資料輸入到此文字框中,然後保存您的線材設定檔"
|
||||
|
||||
msgid "Enable adaptive pressure advance within features (beta)"
|
||||
msgstr ""
|
||||
msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
msgstr "啟用懸挑自適應壓力補償 (beta)"
|
||||
|
||||
msgid ""
|
||||
"Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n"
|
||||
"\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n"
|
||||
"\n"
|
||||
"This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues."
|
||||
"Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
"Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
msgstr ""
|
||||
"針對懸空以及同一特徵內的流量變化啟用自適應壓力補償 (PA)。這是一個實驗性選項,因為若 PA 設定檔設定不準確,將會導致懸空前後的外表面出現均勻性問題。\n"
|
||||
"與 Prusa 印表機不相容,因為它們會暫停以處理 PA 變更,進而導致延遲與瑕疵。"
|
||||
|
||||
msgid "Static pressure advance for bridges"
|
||||
msgstr ""
|
||||
msgid "Pressure advance for bridges"
|
||||
msgstr "橋接的壓力補償"
|
||||
|
||||
msgid ""
|
||||
"Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n"
|
||||
"equivalent walls (using adaptive settings if enabled).\n"
|
||||
"Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
"\n"
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr ""
|
||||
"A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
msgstr "橋接的壓力補償值。設為 0 以停用此功能。降低橋接時的壓力補償值有助於減少橋接結束後立即出現的輕微欠擠出現象。這種現象是由於在空中列印時噴嘴內壓力下降引起的,而降低壓力補償值有助於抵消這一影響。"
|
||||
|
||||
msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter."
|
||||
msgstr "當線寬設定為 0 時走線的預設線寬。如果以 % 表示,將以噴嘴直徑為基準來計算。"
|
||||
@@ -13158,22 +13082,6 @@ msgstr "實心填充方向"
|
||||
msgid "Angle for solid infill pattern, which controls the start or main direction of line."
|
||||
msgstr "實心填充圖案的角度設定,用於決定線條的起始方向或主要列印方向"
|
||||
|
||||
msgid "Top layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the top solid infill and ironing lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom layer direction"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Fixed angle for the bottom solid infill lines.\n"
|
||||
"Set to -1 to follow the default solid infill direction."
|
||||
msgstr ""
|
||||
|
||||
msgid "Sparse infill density"
|
||||
msgstr "稀疏填充密度"
|
||||
|
||||
@@ -14974,10 +14882,6 @@ msgstr "對齊"
|
||||
msgid "Aligned back"
|
||||
msgstr "背部對齊"
|
||||
|
||||
# TODO: Review, changed by lang refactor. PR 14254
|
||||
msgid "Back"
|
||||
msgstr "背面"
|
||||
|
||||
msgid "Random"
|
||||
msgstr "隨機"
|
||||
|
||||
@@ -16020,14 +15924,6 @@ msgstr "扭曲多邊形孔"
|
||||
msgid "Rotate the polyhole every layer."
|
||||
msgstr "依層旋轉多邊形孔。"
|
||||
|
||||
msgid "Maximum Polyhole edge count"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Maximum number of polyhole edges\n"
|
||||
"This setting limits the amount of edges a polyhole can have"
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code thumbnails"
|
||||
msgstr "G-code 縮圖"
|
||||
|
||||
@@ -19392,12 +19288,6 @@ msgstr "三角面片數量"
|
||||
msgid "Calculating, please wait..."
|
||||
msgstr "正在計算,請稍候..."
|
||||
|
||||
msgid "Save these settings as default"
|
||||
msgstr ""
|
||||
|
||||
msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)."
|
||||
msgstr ""
|
||||
|
||||
msgid "PresetBundle"
|
||||
msgstr "設定檔組"
|
||||
|
||||
@@ -19829,77 +19719,6 @@ msgstr ""
|
||||
"您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度\n"
|
||||
"可以降低翹曲的機率。"
|
||||
|
||||
#~ msgid "Print"
|
||||
#~ msgstr "列印"
|
||||
|
||||
#~ msgid "in"
|
||||
#~ msgstr "在"
|
||||
|
||||
#~ msgid "Object coordinates"
|
||||
#~ msgstr "物件座標"
|
||||
|
||||
#~ msgid "World coordinates"
|
||||
#~ msgstr "世界座標"
|
||||
|
||||
#~ msgid "Translate(Relative)"
|
||||
#~ msgstr "平移(相對)"
|
||||
|
||||
#~ msgid "Rotate (absolute)"
|
||||
#~ msgstr "旋轉(絕對)"
|
||||
|
||||
#~ msgid "Part coordinates"
|
||||
#~ msgstr "零件座標"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: this preset has a newer version in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "雲端同步衝突:此預設在 OrcaCloud 中有較新的版本。\n"
|
||||
#~ "拉取會下載雲端副本。強制推送會以您的本機預設覆寫雲端版本。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with this name already exists in OrcaCloud.\n"
|
||||
#~ "Pull downloads the cloud copy. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "雲端同步衝突:OrcaCloud 中已有同名的預設。\n"
|
||||
#~ "拉取會下載雲端副本。強制推送會以您的本機預設覆寫它。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cloud sync conflict: a preset with the same name was previously deleted from the cloud.\n"
|
||||
#~ "Delete will delete your local preset. Force push overwrites it with your local preset."
|
||||
#~ msgstr ""
|
||||
#~ "雲端同步衝突:先前已從雲端刪除同名的預設。\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"
|
||||
#~ "拉取會下載雲端副本。強制推送會以您的本機預設覆寫它。"
|
||||
|
||||
#~ 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)。請移除自訂設定以減少預設大小,或僅在本機使用。"
|
||||
|
||||
#~ msgid "Enable adaptive pressure advance for overhangs (beta)"
|
||||
#~ msgstr "啟用懸挑自適應壓力補償 (beta)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enable adaptive PA for overhangs as well as when flow changes within the same feature. This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"
|
||||
#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects."
|
||||
#~ msgstr ""
|
||||
#~ "針對懸空以及同一特徵內的流量變化啟用自適應壓力補償 (PA)。這是一個實驗性選項,因為若 PA 設定檔設定不準確,將會導致懸空前後的外表面出現均勻性問題。\n"
|
||||
#~ "與 Prusa 印表機不相容,因為它們會暫停以處理 PA 變更,進而導致延遲與瑕疵。"
|
||||
|
||||
#~ msgid "Pressure advance for bridges"
|
||||
#~ msgstr "橋接的壓力補償"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Pressure advance value for bridges. Set to 0 to disable.\n"
|
||||
#~ "\n"
|
||||
#~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this."
|
||||
#~ msgstr "橋接的壓力補償值。設為 0 以停用此功能。降低橋接時的壓力補償值有助於減少橋接結束後立即出現的輕微欠擠出現象。這種現象是由於在空中列印時噴嘴內壓力下降引起的,而降低壓力補償值有助於抵消這一影響。"
|
||||
|
||||
#~ msgid "Filament Sync Options"
|
||||
#~ msgstr "線材同步選項"
|
||||
|
||||
@@ -20456,198 +20275,3 @@ msgstr ""
|
||||
#, c-format, boost-format
|
||||
#~ msgid "The selected preset: %s is not found."
|
||||
#~ msgstr "找不到所選的預設:%s"
|
||||
|
||||
msgid "Abnormal Hotend"
|
||||
msgstr "熱端異常"
|
||||
|
||||
msgid "Available Nozzles"
|
||||
msgstr "可用噴嘴"
|
||||
|
||||
msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced."
|
||||
msgstr "注意:不支援在列印中混用不同直徑的噴嘴。如果所選尺寸僅存在於一個擠出機上,將強制使用單擠出機列印。"
|
||||
|
||||
msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber."
|
||||
msgstr "在熱端升級過程中,工具頭會移動。請勿將手伸入機箱內。"
|
||||
|
||||
msgid "Enable this if printer support cooling filter"
|
||||
msgstr "開啟該功能後,當腔溫過高時,會自動關閉過濾以提高冷卻效果"
|
||||
|
||||
msgid "Error: Can not set both nozzle count to zero."
|
||||
msgstr "錯誤:無法將兩個噴嘴數量都設定為零。"
|
||||
|
||||
msgid "Error: Nozzle count can not exceed %d."
|
||||
msgstr "錯誤:噴嘴數量不可以超過%d。"
|
||||
|
||||
msgid "Extruder change"
|
||||
msgstr "擠出機更換"
|
||||
|
||||
msgid "Hotend change"
|
||||
msgstr "熱端更換"
|
||||
|
||||
msgid "Hotend change time"
|
||||
msgstr "熱端更換時間"
|
||||
|
||||
msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)."
|
||||
msgstr "熱端資訊可能不準確。是否重新讀取熱端?(斷電期間熱端資訊可能會發生變化)。"
|
||||
|
||||
msgid "Hybrid"
|
||||
msgstr "混合"
|
||||
|
||||
msgid "I confirm all"
|
||||
msgstr "確認無誤"
|
||||
|
||||
msgid "Induction Hotend Rack"
|
||||
msgstr "感應熱端架"
|
||||
|
||||
msgid "Nozzle Manual"
|
||||
msgstr "噴嘴手動"
|
||||
|
||||
msgid "Nozzle Selection"
|
||||
msgstr "噴嘴選擇"
|
||||
|
||||
msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values."
|
||||
msgstr "請核對噴嘴直徑和流量是否與顯示值一致。"
|
||||
|
||||
msgid "Please set nozzle count"
|
||||
msgstr "請設定噴嘴數量"
|
||||
|
||||
msgid "Preheat temperature delta"
|
||||
msgstr "預熱溫度差"
|
||||
|
||||
msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"
|
||||
msgstr "切換噴嘴需要擦料塔,否則列印件上可能會有瑕疵。您確定要關閉擦料塔嗎?"
|
||||
|
||||
msgid "Re-read all"
|
||||
msgstr "重新讀取全部"
|
||||
|
||||
msgid "Reading the hotends, please wait."
|
||||
msgstr "正在讀取熱端資訊,請稍候。"
|
||||
|
||||
msgid "Refresh %d/%d..."
|
||||
msgstr "重新整理 %d/%d..."
|
||||
|
||||
msgid "Sync Nozzle status"
|
||||
msgstr "同步噴嘴狀態"
|
||||
|
||||
msgid "TPU High Flow"
|
||||
msgstr "TPU高流量"
|
||||
|
||||
msgid "Temperature delta applied during pre-heating before tool change."
|
||||
msgstr "工具切換前預熱期間套用的溫度差。"
|
||||
|
||||
msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware."
|
||||
msgstr "熱端狀態異常,當前不可用。請前往“裝置 -> 升級”升級韌體。"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "熱端更換前的最大預沖刷體積速度,其中 -1 表示使用最大體積速度。"
|
||||
|
||||
msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."
|
||||
msgstr "換出擠出機前的最大預沖刷體積速度,-1 表示使用最大體積速度。"
|
||||
|
||||
msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber."
|
||||
msgstr "工具頭和熱端架可能會運動,請勿將手伸入機箱。"
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr "換熱端所需的擦料塔上的清理量。"
|
||||
|
||||
msgid "Time to change hotend."
|
||||
msgstr "熱端更換時間。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."
|
||||
msgstr "為防止溢料,預沖刷過程中噴嘴溫度會降低。注意:僅觸發冷卻指令並啟動風扇,不保證達到目標溫度。0 表示禁用。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."
|
||||
msgstr "為了防止溢料,預沖刷時會降低噴嘴溫度。因此,預沖刷時間必須大於冷卻時間。0 表示禁用。"
|
||||
|
||||
msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time."
|
||||
msgstr "為了防止溢料,預沖刷完成後,噴嘴會進行一段時間的反向空駛。該設定用於定義空駛時間。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)."
|
||||
msgstr "檢測到未知噴嘴。請重新整理以更新資訊(未重新整理的噴嘴將在切片時被排除)。"
|
||||
|
||||
msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values."
|
||||
msgstr "檢測到未知噴嘴。請重新整理以更新資訊(未重新整理的噴嘴將在切片時被排除)。請核對噴嘴直徑和流量是否與顯示值一致。"
|
||||
|
||||
msgid "Use cooling filter"
|
||||
msgstr "開啟冷卻過濾"
|
||||
|
||||
msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."
|
||||
msgstr "更換熱端時,建議從原熱端中擠出一定長度的耗材絲。這有助於最大限度地減少噴嘴漏料。"
|
||||
|
||||
msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends."
|
||||
msgstr "當修改此回抽數值時,將用於熱端內在更換熱端前回抽的耗材量。"
|
||||
|
||||
msgid "Your printer has different nozzles installed. Please select a nozzle for this print."
|
||||
msgstr "您的印表機安裝了不同的噴嘴。請選擇一個噴嘴進行本次列印。"
|
||||
|
||||
msgid "length when change hotend"
|
||||
msgstr "換熱端時回抽量"
|
||||
|
||||
msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported."
|
||||
msgstr "當前盤存在動態分配噴嘴,不支援修改。"
|
||||
|
||||
msgid "Hotend Rack"
|
||||
msgstr "熱端掛架"
|
||||
|
||||
msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again."
|
||||
msgstr "熱端狀態異常,目前不可用。請升級韌體後重試。"
|
||||
|
||||
msgid "Hotends"
|
||||
msgstr "熱端"
|
||||
|
||||
msgid "Hotends Info"
|
||||
msgstr "熱端資訊"
|
||||
|
||||
msgid "Hotends on Rack"
|
||||
msgstr "熱端&掛架"
|
||||
|
||||
msgid "Jump to the upgrade page"
|
||||
msgstr "跳轉至升級頁面"
|
||||
|
||||
msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."
|
||||
msgstr "注意:%s上的熱端編號與刀架繫結。當熱端移動至新刀架時,其編號會自動更新。"
|
||||
|
||||
msgid "Nozzle ID"
|
||||
msgstr "噴嘴 ID"
|
||||
|
||||
msgid "Nozzle information needs to be read"
|
||||
msgstr "需要讀取噴嘴資訊"
|
||||
|
||||
msgid "Please wait"
|
||||
msgstr "請稍候"
|
||||
|
||||
msgid "Printing with the current nozzle may produce an extra %0.2f g of waste."
|
||||
msgstr "使用當前噴嘴列印可能會產生額外 %0.2f 克廢料。"
|
||||
|
||||
msgid "Raised"
|
||||
msgstr "已升起"
|
||||
|
||||
msgid "Read All"
|
||||
msgstr "讀取全部"
|
||||
|
||||
msgid "Reading "
|
||||
msgstr "讀取中 "
|
||||
|
||||
msgid "Row A"
|
||||
msgstr "A排"
|
||||
|
||||
msgid "Row B"
|
||||
msgstr "B排"
|
||||
|
||||
msgid "Running..."
|
||||
msgstr "執行中..."
|
||||
|
||||
msgid "Select Filament && Hotends"
|
||||
msgstr "選擇材料預設和噴頭"
|
||||
|
||||
msgid "Standard Flow"
|
||||
msgstr "標準流量"
|
||||
|
||||
msgid "ToolHead"
|
||||
msgstr "工具頭"
|
||||
|
||||
msgid "Toolhead"
|
||||
msgstr "工具頭"
|
||||
|
||||
msgid "Used Time: %s"
|
||||
msgstr "使用時間: %s"
|
||||
|
||||
Binary file not shown.
BIN
resources/handy_models/OrcaSliced.drc
Normal file
BIN
resources/handy_models/OrcaSliced.drc
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 128 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 126 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user