Compare commits
320 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ee6b85605a | |||
| 045cfed6a7 | |||
| 5f60d78658 | |||
| 646eb97eaf | |||
| 2cf8df2ef6 | |||
| 0096e694dd | |||
| c29bd18190 | |||
| 8e9e270027 | |||
| 1b927421f6 | |||
| 8d22b3a41a | |||
| edcf02c0d4 | |||
| b85d5a665c | |||
| a232df7751 | |||
| 4757c3cee6 | |||
| 736f334301 | |||
| e721004f62 | |||
| 88d87729d4 | |||
| c7597ea66f | |||
| f3389c3af7 | |||
| a0a52f6657 | |||
| cc9787f80e | |||
| 8e80d98610 | |||
| f8a8114843 | |||
| 98bfe1af9c | |||
| ffbf9836cc | |||
| 806adb6c46 | |||
| 250ed2f266 | |||
| 56f07a5598 | |||
| dfdad35d08 | |||
| 1cef0d83df | |||
| a99c57ffc7 | |||
| cdffdcbbef | |||
| 4f05716f69 | |||
| f0567d6a48 | |||
| 6e9ffe83d2 | |||
| 2647ec51fc | |||
| 23587433e2 | |||
| 0414de7b98 | |||
| 295bd0e165 | |||
| 0b34d3590d | |||
| aedbf0b1d4 | |||
| a13e0e0ceb | |||
| 6f05c19c42 | |||
| db0c25522e | |||
| e6c999bbcd | |||
| 180a725c0e | |||
| 4ba6a9744b | |||
| ae998906ff | |||
| 634f0a2308 | |||
| 306b78ce16 | |||
| 678da425da | |||
| fc499441e2 | |||
| 1cf5f83924 | |||
| 6a465abee9 | |||
| 89a3e89d62 | |||
| 58c0fc396f | |||
| 0952686c1b | |||
| 64b506dccf | |||
| 61195235d8 | |||
| 6241decaf9 | |||
| 3288adf3dd | |||
| 5b53a1354a | |||
| 579dddaea0 | |||
| 9052b69e81 | |||
| 2c5d875ab7 | |||
| 04efc68578 | |||
| 0e137b947f | |||
| 97a24941d2 | |||
| c2a19bf375 | |||
| e40d7aaee7 | |||
| 2b18b68307 | |||
| b9ae8814d4 | |||
| f3a4c62240 | |||
| dbf38d84ef | |||
| f913a2a459 | |||
| f504c82216 | |||
| df18823d0a | |||
| 0396b2d00a | |||
| b1c132bc9a | |||
| 71b3a70254 | |||
| bcdecd19f4 | |||
| 3b3f860adc | |||
| f0d5666a74 | |||
| f1c2f67d63 | |||
| 32900556e0 | |||
| bf14bf3678 | |||
| f0a5fc5016 | |||
| ad1652683b | |||
| 0d778e074b | |||
| 0b2d51d301 | |||
| bf7979d4a7 | |||
| 5439bfc0b5 | |||
| c2ea096abb | |||
| 085853315d | |||
| 332f96c26a | |||
| 56e752c182 | |||
| 014ccf5ff4 | |||
| ab309f2219 | |||
| 6c9afc6f7e | |||
| aff8106205 | |||
| 8ced905843 | |||
| 21340ba019 | |||
| 8b25fa0ae4 | |||
| c0b0369aa2 | |||
| 44a9f9ee42 | |||
| f331a0740b | |||
| 12636b67be | |||
| 9f5ac92faa | |||
| 6e39efd4ac | |||
| 3c40edd12a | |||
| 81b620d7aa | |||
| 9af2ae9a0f | |||
| 1754318df7 | |||
| f273195144 | |||
| 247a77e1b1 | |||
| ce4212a33a | |||
| 522bd95254 | |||
| b0b1e6832e | |||
| 3cb9aa07b5 | |||
| 60f6836ab7 | |||
| 43f0438fbb | |||
| ded10b52da | |||
| 4bc5bdc791 | |||
| 1baaebd3ef | |||
| 97e467f2d1 | |||
| 665ff84495 | |||
| 07b3b92703 | |||
| ddf56e1246 | |||
| 0ddbe87935 | |||
| 19dc8b6881 | |||
| 3e2e229dd1 | |||
| c8d9a4bfdd | |||
| 6c764dce06 | |||
| 655e771455 | |||
| 15f74b7981 | |||
| 9b607f6f1f | |||
| ab67126eec | |||
| 3b8cbc4e22 | |||
| f59f6698f1 | |||
| bd1525dcfb | |||
| 1e5eb1e3b8 | |||
| a1483d63c1 | |||
| 491687d4c1 | |||
| 66bd64cc5e | |||
| f9146cdd58 | |||
| 23e7ac767e | |||
| 3ac7a196c9 | |||
| 202e713cf1 | |||
| 63923da2ca | |||
| 7e22aed739 | |||
| 966b10e731 | |||
| 99eda4cd1b | |||
| 47292bb2bd | |||
| 37dc878f31 | |||
| 7da02460d8 | |||
| f73f4da665 | |||
| ef5985f841 | |||
| 71bb4f7c98 | |||
| 92af4a21c8 | |||
| 5d6c5bab39 | |||
| 8251be9c06 | |||
| 3d744cc8a2 | |||
| 1447bc772a | |||
| 7b24a1dc1e | |||
| d95f40ac88 | |||
| 82ac9a6b03 | |||
| 6ab46b6488 | |||
| 991082fbaf | |||
| 4d338ba2eb | |||
| 94b399e98f | |||
| 5aa41703f7 | |||
| d9aa73b597 | |||
| 6e4e94a8a8 | |||
| ae2a5b2c0d | |||
| 81cbcef31c | |||
| e3d9090e6c | |||
| b8e93270b4 | |||
| ef628d1c86 | |||
| d93b1cb282 | |||
| a66a517c40 | |||
| f3ee34d372 | |||
| c94d1e9894 | |||
| 46a2d6b53c | |||
| c9935007e8 | |||
| 7b9d37c787 | |||
| aa1fe28ddf | |||
| 8f1b456275 | |||
| 8a6a064d37 | |||
| f35f3197c3 | |||
| 78499f44af | |||
| 5b5201f1a6 | |||
| f28ff15ffb | |||
| 4f8bbec9fb | |||
| 77ebf1326c | |||
| fdc95337cf | |||
| 0e053e5e61 | |||
| 6bbb4276c0 | |||
| 6d641c87c4 | |||
| 553f5fb9b8 | |||
| 88dd699715 | |||
| c092e0551b | |||
| c320dc421c | |||
| 0f489a5777 | |||
| 3df709be63 | |||
| 875ac2ce49 | |||
| 698275874f | |||
| 0d4470cd8c | |||
| 5dfc3481c1 | |||
| b596bfc730 | |||
| d11d268597 | |||
| 4b0ba62c69 | |||
| 313d2bdb41 | |||
| 079f6e61e6 | |||
| 4a781b8cd8 | |||
| 5b0eb08473 | |||
| 3e62553d9c | |||
| 87206f20c8 | |||
| 5a24d4095a | |||
| d4fb5538e6 | |||
| f6393ef211 | |||
| 355b486595 | |||
| 2356a63aea | |||
| 57c0121cb3 | |||
| 9b97e06f71 | |||
| 9c5a636987 | |||
| 18b00a4192 | |||
| 988caa83fc | |||
| 18dc05c83d | |||
| 5cf18ba8c3 | |||
| 9454afe13a | |||
| 70d39bb4f3 | |||
| a4fd998539 | |||
| 1c673e38c7 | |||
| b43712cdb0 | |||
| 184d4720be | |||
| f08623be3c | |||
| 31218b1451 | |||
| cb34eef6aa | |||
| b9e9521128 | |||
| e59a2bcf80 | |||
| 6fcdca1bb7 | |||
| a985b8ee17 | |||
| c857f2fe70 | |||
| 9416e975e0 | |||
| 5f11d92458 | |||
| 97550dc37e | |||
| 4456e0470a | |||
| 561336aab6 | |||
| 82b38f5bae | |||
| 43a22bed46 | |||
| cd12d9d8e7 | |||
| 15e3245180 | |||
| 730dc5f6c3 | |||
| 3cdc68aaf1 | |||
| e3c08471b6 | |||
| a7048f41ab | |||
| 1c0001af8e | |||
| 8b1ee94296 | |||
| 791abbd9b1 | |||
| 6255a10e80 | |||
| d05a114241 | |||
| 6ebfe91661 | |||
| d0b357d532 | |||
| cc047a29c1 | |||
| 32c8b23199 | |||
| 21366ec47e | |||
| 699d730151 | |||
| a4274f9b59 | |||
| d6d6c7d9ee | |||
| 5bd85dded6 | |||
| e5ef3bad02 | |||
| 9df8837d43 | |||
| 409ab1ed45 | |||
| 5e03fe2f4b | |||
| 37a586dd61 | |||
| a79f40a711 | |||
| b5728f284b | |||
| 5965439a15 | |||
| 586a358ed4 | |||
| 7770f8982d | |||
| 72ad6383ef | |||
| 0537623a75 | |||
| 65d288227e | |||
| fedb3bcdb1 | |||
| 097b8b7550 | |||
| af7ca3a8a2 | |||
| 27ddb725c7 | |||
| a06bdf5cfc | |||
| 33fdcdb3a0 | |||
| c07ab5f8f9 | |||
| fea32f8aac | |||
| 4927214976 | |||
| b621819c0c | |||
| ec552a5300 | |||
| e0cc740cc3 | |||
| 5de48e916d | |||
| 80af7bbe3e | |||
| 191e983423 | |||
| 2b9445b049 | |||
| 7ddf48ca16 | |||
| d2f6848377 | |||
| 0b6d6fecd8 | |||
| fa691707c2 | |||
| b9a55c74e2 | |||
| 2bb9c81069 | |||
| cedb51b8ea | |||
| 66d13059dd | |||
| 800ea40c0d | |||
| 20442eecd3 | |||
| 22d1cd7032 | |||
| 6a0dc18655 | |||
| e006dbf1af | |||
| 8241a750fa | |||
| 41779cf7bb | |||
| b01b9689c8 | |||
| 4426da6f5d | |||
| 5ead82e627 | |||
| c29b0d2f13 | |||
| 480fd8d517 | |||
| 4c09fa5355 |
@@ -84,6 +84,8 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| docs/book/src/generated/tool-preview.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/tool-preview.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| assets/fonts/liberation-sans/LiberationSans-Regular.ttf | Red Hat, Inc. (Liberation Fonts 2.x; digitized data Google) | https://github.com/liberationfonts (Debian fonts-liberation), unmodified; licence text in assets/fonts/liberation-sans/OFL.txt; used for sketch Text outlines | SIL OFL 1.1 |
|
||||
| assets/fonts/biz-udp-gothic/BIZUDPGothic-Regular.ttf | The BIZ UDGothic Project Authors | https://github.com/googlefonts/morisawa-biz-ud-gothic (Google Fonts), unmodified; licence text in assets/fonts/biz-udp-gothic/OFL.txt; used for web UI Japanese font | SIL OFL 1.1 |
|
||||
| assets/fonts/craft-ui-sc/CraftUI-SC.otf | Adobe / Google Inc. (Noto Sans SC); SolidCraft subset | https://github.com/notofonts/noto-cjk Sans/SubsetOTF/SC Regular, glyph-subset for assets/locales/zh.json and renamed Craft UI SC (OFL reserved-name); licence text in assets/fonts/craft-ui-sc/OFL.txt; web UI Simplified Chinese | SIL OFL 1.1 |
|
||||
| assets/fonts/craft-ui-tc/CraftUI-TC.otf | Adobe / Google Inc. (Noto Sans TC); SolidCraft subset | https://github.com/notofonts/noto-cjk Sans/SubsetOTF/TC Regular, glyph-subset for assets/locales/zh-TW.json and renamed Craft UI TC (OFL reserved-name); licence text in assets/fonts/craft-ui-tc/OFL.txt; web UI Traditional Chinese | SIL OFL 1.1 |
|
||||
| tests/step-conformance/cone_point.step | step-conformance contributors | generated from formulas by https://github.com/dan335/step-conformance (corpus/generated, 96f30bb); import regression fixture | CC0-1.0 |
|
||||
| tests/step-conformance/cone_point_vertex.step | step-conformance contributors | generated from formulas by https://github.com/dan335/step-conformance (corpus/generated, 96f30bb); import regression fixture | CC0-1.0 |
|
||||
| tests/step-conformance/cylinder.step | step-conformance contributors | generated from formulas by https://github.com/dan335/step-conformance (corpus/generated, 96f30bb); import regression fixture | CC0-1.0 |
|
||||
@@ -125,6 +127,8 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/appearances/library.rs | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/appearances/opaque_finishes.rs | SolidCraft contributors | original illustrative opaque finish values; no external dataset, textures or measured engineering data | MIT OR Apache-2.0 |
|
||||
| assets/fonts/biz-udp-gothic/OFL.txt | The BIZ UDGothic Project Authors | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/fonts/craft-ui-sc/OFL.txt | Adobe / Google Inc. (Noto CJK); SolidCraft header | Accompanying OFL for CraftUI-SC.otf | SIL OFL 1.1 |
|
||||
| assets/fonts/craft-ui-tc/OFL.txt | Adobe / Google Inc. (Noto CJK); SolidCraft header | Accompanying OFL for CraftUI-TC.otf | SIL OFL 1.1 |
|
||||
| assets/fonts/ibm-plex-mono/OFL.txt | IBM Corp. | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/fonts/ibm-plex-sans/OFL.txt | IBM Corp. | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/fonts/liberation-sans/OFL.txt | Red Hat, Inc.; Liberation Fonts contributors | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
@@ -609,6 +613,27 @@ Original SolidCraft drawings, Open for owner review; no runtime assignments.
|
||||
| assets/icons/ui/design/svg/model/timeline_stop.svg | SolidCraft contributors | Original history playback icon; canonical grey_cube base and original action cue | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/flat/status_pin.svg | SolidCraft contributors | Original analytic pin icon for persistent viewport results | MIT OR Apache-2.0 |
|
||||
| assets/locales/pending/render-wear.json | SolidCraft contributors | Original UI labels and translations | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/equation_curve.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/locales/pending/sketch-recent-snap.json | SolidCraft contributors | Original preference messages for the recent centre and midpoint snap | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_horizontal.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_vertical.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_angle.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_parallel.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_perpendicular.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_tangent_external.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_tangent_at.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_tangent_two.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/construction_line_bisector.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-circle.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-circle.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-flower.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-flower.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-involute.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-involute.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-line.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-line.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-parabola.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-parabola.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-spiral.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-spiral.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| docs/book/src/generated/equation-wave.png | SolidCraft contributors | rendered by `cargo xtask book` (`solidcraft-cli snapshot docs/book/scripts/equation-wave.json`; gitignored) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/print_face.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/locales/fi.json | SolidCraft contributors | Original Finnish translation of SolidCraft's English catalog, AI-assisted (Claude Code) clean-room from the English and not yet reviewed line by line by a native speaker; no commercial CAD text used | MIT OR Apache-2.0 |
|
||||
|
||||
## Code adapted from sibling projects
|
||||
|
||||
@@ -668,6 +693,7 @@ copied into SolidCraft.
|
||||
|
||||
| Directory | Source | Licence | Changes |
|
||||
|---|---|---|---|
|
||||
| vendor/accesskit_macos | accesskit_macos 0.26.3, https://github.com/AccessKit/accesskit (The AccessKit contributors) | MIT OR Apache-2.0 | the subclassing adapter and its tests from 0.27.2: dropping the adapter keeps AppKit's key-value observers (vendor/README.md) |
|
||||
| vendor/truck-meshalgo | truck-meshalgo 0.4.0, https://github.com/ricosjp/truck (RICOS Co. Ltd.) | Apache-2.0 | meshing: bounded parameter searches, collapsed-boundary projection, subdivision and provisional fixed-grid previews (vendor/README.md) |
|
||||
| vendor/truck-stepio | truck-stepio 0.3.0, https://github.com/ricosjp/truck (RICOS Co. Ltd.) | Apache-2.0 | STEP writer: intersection-curve surfaces written at unique ids (vendor/README.md) |
|
||||
| vendor/truck-shapeops | truck-shapeops 0.4.0, https://github.com/ricosjp/truck (RICOS Co. Ltd.) | Apache-2.0 | robust meshing and nearest-parameter fallback in booleans; degenerate intersection-curve rejection; face and edge history of booleans; trace macro; corner choice at vertices several intersection curves end on; reuse of an operand's meshes (vendor/README.md) |
|
||||
|
||||
@@ -60,8 +60,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "accesskit_macos"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_consumer 0.38.0",
|
||||
@@ -4210,7 +4208,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"block2 0.6.2",
|
||||
"eframe",
|
||||
@@ -4242,15 +4240,16 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"winit",
|
||||
"x11rb",
|
||||
"zbus 5.19.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-3dx-client"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-cli"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4262,7 +4261,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-derive"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4271,7 +4270,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-doc"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -4288,7 +4287,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-engine"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4309,7 +4308,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-geom"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4318,7 +4317,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-gpu"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4338,7 +4337,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-io"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"cadmpeg-core",
|
||||
"cadmpeg-ir",
|
||||
@@ -4362,7 +4361,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-kernel"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"proptest",
|
||||
@@ -4382,7 +4381,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-mcp"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"solidcraft-engine",
|
||||
@@ -4391,7 +4390,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-render"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"moxcms",
|
||||
@@ -4405,7 +4404,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-sketch"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"harfrust",
|
||||
"serde",
|
||||
@@ -4418,14 +4417,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-space-mouse"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-ui-egui"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
@@ -4455,7 +4454,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-web"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
@@ -5998,7 +5997,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"serde",
|
||||
|
||||
@@ -5,7 +5,7 @@ members = ["crates/*", "apps/*", "xtask"]
|
||||
exclude = ["vendor"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
rust-version = "1.95"
|
||||
@@ -165,6 +165,9 @@ egui-wgpu = { path = "vendor/egui-wgpu" }
|
||||
# winit 0.30 never binds and eframe 0.36 still requires winit 0.30.
|
||||
winit = { path = "vendor/winit" }
|
||||
|
||||
# macOS: dropping the accessibility adapter leaves AppKit's key-value observers intact (#7535).
|
||||
accesskit_macos = { path = "vendor/accesskit_macos" }
|
||||
|
||||
# Mutation testing (cargo-mutants, docs/mutation-testing.md): the ci profile with incremental
|
||||
# builds, since every mutant rebuilds the crates above the one it changes.
|
||||
[profile.mutants]
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/296178?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-296178" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/296178/daily" alt="tangency-labs%2Fsolidcraft | Trendshift" width="250" height="55"/></a>
|
||||
<a href="https://trendshift.io/repositories/296178?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-296178" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/296178/daily?language=Rust" alt="tangency-labs%2Fsolidcraft | Trendshift (Rust)" width="250" height="55"/></a>
|
||||
<a href="https://trendshift.io/repositories/296178?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-296178" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/296178/daily" alt="tangency-labs%2Fsolidcraft | Trendshift" width="250" height="55"/></a>
|
||||
<a href="https://trendshift.io/repositories/296178?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-296178" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/296178/daily?language=Rust" alt="tangency-labs%2Fsolidcraft | Trendshift (Rust)" width="250" height="55"/></a>
|
||||
</p>
|
||||
|
||||

|
||||
@@ -98,7 +98,7 @@ More commands, the Windows cross-build and the browser build are in [docs/buildi
|
||||
runs its own design session, or with `--connect` it drives the running app so you can watch.
|
||||
Claude Code: `claude mcp add solidcraft -- solidcraft-cli mcp`. If a terminal doesn't find
|
||||
`solidcraft-cli` (older Windows installers don't put it on `PATH`), give its full path (by default
|
||||
`"C:\Program Files\SolidCraft\solidcraft-cli.exe"`). Tools, access rules and an example session:
|
||||
`"C:\\Program Files\\SolidCraft\\solidcraft-cli.exe"`). Tools, access rules and an example session:
|
||||
[docs/mcp.md](docs/mcp.md).
|
||||
|
||||
## Scripts
|
||||
@@ -150,3 +150,4 @@ Tinkercad are trademarks of their respective owners, named only to describe comp
|
||||
[linux-appimage]: https://github.com/tangency-labs/solidcraft/releases/latest/download/solidcraft-linux-x86_64.AppImage
|
||||
[snap-store]: https://snapcraft.io/solidcraft
|
||||
[web-app]: https://solidcraft.io/app
|
||||
|
||||
|
||||
@@ -16799,6 +16799,14 @@ Bundled fonts (SIL Open Font License, Version 1.1)
|
||||
Copyright 2022 The BIZ UDGothic Project Authors (https://github.com/googlefonts/morisawa-biz-ud-mincho)
|
||||
Source: https://github.com/googlefonts/morisawa-biz-ud-gothic
|
||||
|
||||
- CraftUI-SC.otf (assets/fonts/craft-ui-sc/CraftUI-SC.otf)
|
||||
Copyright 2014-2021 Adobe / Google Inc. (Noto Sans SC subset for SolidCraft web zh)
|
||||
Source: https://github.com/notofonts/noto-cjk (Sans SubsetOTF/SC)
|
||||
|
||||
- CraftUI-TC.otf (assets/fonts/craft-ui-tc/CraftUI-TC.otf)
|
||||
Copyright 2014-2021 Adobe / Google Inc. (Noto Sans TC subset for SolidCraft web zh-TW)
|
||||
Source: https://github.com/notofonts/noto-cjk (Sans SubsetOTF/TC)
|
||||
|
||||
- IBMPlexSans-Variable.ttf (assets/fonts/ibm-plex-sans/IBMPlexSans-Variable.ttf)
|
||||
Copyright 2017 IBM Corp. with Reserved Font Name "Plex"
|
||||
Source: https://github.com/IBM/plex
|
||||
|
||||
@@ -66,7 +66,7 @@ fn run() -> Result<(), String> {
|
||||
let mut session = Session::default();
|
||||
eprintln!("Generating original CAD scene from {recipe_path}");
|
||||
let generation_start = Instant::now();
|
||||
let (commands, command_timings) = session.run_script_timed(&recipe, false).map_err(|e| e.to_string())?;
|
||||
let (commands, command_timings) = session.run_script_timed(&recipe, false, &mut |_, _| {}).map_err(|e| e.to_string())?;
|
||||
let generation_seconds = generation_start.elapsed().as_secs_f64();
|
||||
let design_path = output.with_extension(solidcraft_engine::io::DESIGN_EXT);
|
||||
session.execute("file.save_as", &json!({"path":design_path})).map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//!
|
||||
//! ```text
|
||||
//! solidcraft-cli run <script.json|design.sc|part.step|mesh.3mf> [--in design|part.step|mesh.3mf] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]
|
||||
//! [--param-check off|warn|strict]
|
||||
//! solidcraft-cli eval <script.json|design.sc|part.step> [--in design.sc|part.step] [--json-out FILE] (alias: inspect) measurements as JSON
|
||||
//! solidcraft-cli script <design.sc> [--out script.json] the design's history as a command script
|
||||
//! solidcraft-cli bench-open <design.sc | part.step> [--parse-only] [--save OUT.sc] [--display LEVEL [--edit NAME EXPR]] [--ops script.json] loading timings as JSON lines
|
||||
@@ -57,7 +58,7 @@ struct Command {
|
||||
}
|
||||
|
||||
/// `run`'s lines in the usage.
|
||||
const USAGE_RUN: &str = " solidcraft-cli run <script.json|design.sc|part.step> [--in design.sc|part.step] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]\n solidcraft-cli run --in <design.sc|part.step> [--out FILE]...\n (a timeline feature that fails fails the run and nothing is written; --allow-errors writes anyway)\n (--timings prints {timings: [{index, command, ms}], total_ms} for a script, with --results its results too;\n --profile adds each command's profile: {boolean_ms, tessellate_ms, other_ms}, the kernel's share)\n";
|
||||
const USAGE_RUN: &str = " solidcraft-cli run <script.json|design.sc|part.step> [--in design.sc|part.step] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]\n [--param-check off|warn|strict]\n solidcraft-cli run --in <design.sc|part.step> [--out FILE]...\n (a timeline feature that fails fails the run and nothing is written; --allow-errors writes anyway)\n (--param-check checks each step against its command's contract: warn reports on stderr, strict stops the run)\n (--timings prints {timings: [{index, command, ms}], total_ms} for a script, with --results its results too;\n --profile adds each command's profile: {boolean_ms, tessellate_ms, other_ms}, the kernel's share)\n";
|
||||
/// `eval`'s lines in the usage.
|
||||
const USAGE_EVAL: &str = " solidcraft-cli eval <script.json|design.sc|part.step> [--in design.sc|part.step] [--json-out FILE] (alias: inspect)\n solidcraft-cli eval --in <script.json|design.sc|part.step> [--json-out FILE]\n (with both inputs, runs the positional script on --in before measuring; does not automatically save the modified design)\n (--json-out FILE writes the JSON that run (with --results, else the measurement) and eval print to FILE instead of stdout,\n as plain UTF-8: a shell's > can re-encode it, e.g. Windows PowerShell adds a byte-order mark)\n";
|
||||
/// `script`'s lines in the usage.
|
||||
@@ -299,18 +300,36 @@ fn load_checked(path: &str, check: solidcraft_engine::schema::ParamCheck) -> Res
|
||||
s.execute("doc.open", &json!({"path": path})).map_err(|e| e.to_string())?;
|
||||
} else {
|
||||
let script = if v.get("features").is_some() && v.get("commands").is_none() { recipe::to_script(&v)? } else { v };
|
||||
// Warn level: each step's `param_warnings` as it completes, even when a later step fails
|
||||
// (stderr, so stdout stays the caller's).
|
||||
let mut warn = |step: usize, r: &Value| {
|
||||
for w in r.get("param_warnings").and_then(Value::as_array).into_iter().flatten() {
|
||||
eprintln!("{path}: step {}: {}", step + 1, w.as_str().unwrap_or_default());
|
||||
}
|
||||
};
|
||||
s.run_script_each(&script, &mut warn).map_err(|e| e.to_string())?;
|
||||
run_script_warning(&mut s, path, &script)?;
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Run `script`, read from `path`, on `s`. At the warn level each step's `param_warnings` go to
|
||||
/// stderr as the step completes, even when a later step fails (stdout stays the caller's).
|
||||
fn run_script_warning(s: &mut Session, path: &str, script: &Value) -> Result<Vec<Value>, String> {
|
||||
s.run_script_each(script, &mut |step, r| print_param_warnings(path, step, r)).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Step `step`'s `param_warnings` on stderr, one per line, named after the script at `path`.
|
||||
fn print_param_warnings(path: &str, step: usize, r: &Value) {
|
||||
for w in r.get("param_warnings").and_then(Value::as_array).into_iter().flatten() {
|
||||
eprintln!("{path}: step {}: {}", step + 1, w.as_str().unwrap_or_default());
|
||||
}
|
||||
}
|
||||
|
||||
/// `--param-check off|warn|strict`: how calls that break a command's parameter contract are
|
||||
/// treated (docs/mcp.md); off when the option isn't given.
|
||||
fn parse_param_check(cmd: &str, args: &[String]) -> Result<solidcraft_engine::schema::ParamCheck, String> {
|
||||
match flag(args, "--param-check") {
|
||||
None if args.iter().any(|a| a == "--param-check") => Err(format!("{cmd}: --param-check wants off, warn or strict")),
|
||||
None => Ok(solidcraft_engine::schema::ParamCheck::Off),
|
||||
Some(v) => {
|
||||
solidcraft_engine::schema::ParamCheck::parse(v).ok_or_else(|| format!("{cmd}: --param-check wants off, warn or strict, not `{v}`"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flag<'a>(args: &'a [String], name: &str) -> Option<&'a str> {
|
||||
args.iter().position(|a| a == name).and_then(|i| args.get(i + 1)).map(String::as_str)
|
||||
}
|
||||
@@ -367,7 +386,15 @@ fn print_json(v: &Value, file: Option<&str>) -> Result<(), String> {
|
||||
fn cmd_run(args: &[String]) -> Result<(), String> {
|
||||
install_renderer();
|
||||
let json_out = json_out(args)?;
|
||||
known_args("run", args, &["--in", "--out", "--save", "--json-out"], &["--quiet", "--results", "--timings", "--profile", "--allow-errors"], true)?;
|
||||
// Before the option check, so a bare `--param-check` gets the words `mcp` uses.
|
||||
let check = parse_param_check("run", args)?;
|
||||
known_args(
|
||||
"run",
|
||||
args,
|
||||
&["--in", "--out", "--save", "--json-out", "--param-check"],
|
||||
&["--quiet", "--results", "--timings", "--profile", "--allow-errors"],
|
||||
true,
|
||||
)?;
|
||||
let base = flag(args, "--in");
|
||||
let path = positional(args);
|
||||
if path.is_none() && base.is_none() {
|
||||
@@ -380,23 +407,25 @@ fn cmd_run(args: &[String]) -> Result<(), String> {
|
||||
let (mut s, results) = if want_results || timings {
|
||||
// Collect every command's result or time (scripts only), then process requested files too.
|
||||
let mut s = match base {
|
||||
Some(b) => load(b)?,
|
||||
Some(b) => load_checked(b, check)?,
|
||||
None => Session::default(),
|
||||
};
|
||||
s.param_check = check;
|
||||
let needs = if want_results { "--results needs a script" } else { "--timings needs a script" };
|
||||
let v = read_json(path.ok_or(needs)?)?;
|
||||
let script = path.ok_or(needs)?;
|
||||
let v = read_json(script)?;
|
||||
let out = if timings {
|
||||
let (r, mut t) = s.run_script_timed(&v, profile).map_err(|e| e.to_string())?;
|
||||
let (r, mut t) = s.run_script_timed(&v, profile, &mut |step, r| print_param_warnings(script, step, r)).map_err(|e| e.to_string())?;
|
||||
if want_results && let Some(o) = t.as_object_mut() {
|
||||
o.insert("results".into(), Value::Array(r));
|
||||
}
|
||||
t
|
||||
} else {
|
||||
Value::Array(s.run_script(&v).map_err(|e| e.to_string())?)
|
||||
Value::Array(run_script_warning(&mut s, script, &v)?)
|
||||
};
|
||||
(s, Some(out))
|
||||
} else {
|
||||
(open(base, path)?, None)
|
||||
(open(base, path, check)?, None)
|
||||
};
|
||||
// A feature that fails leaves the bodies as they were before it (a parameter change can
|
||||
// break a feature without failing the command that made it): writing them would hand out
|
||||
@@ -421,16 +450,16 @@ fn cmd_run(args: &[String]) -> Result<(), String> {
|
||||
}
|
||||
|
||||
/// The session `run`, `eval` and `snapshot` start from: `--in` (a design or STEP file) with the
|
||||
/// positional script run on top of it, or either one alone.
|
||||
fn open(base: Option<&str>, path: Option<&String>) -> Result<Session, String> {
|
||||
/// positional script run on top of it, or either one alone, with scripts run at `check`.
|
||||
fn open(base: Option<&str>, path: Option<&String>, check: solidcraft_engine::schema::ParamCheck) -> Result<Session, String> {
|
||||
match (base, path) {
|
||||
(Some(b), Some(p)) => {
|
||||
let mut s = load(b)?;
|
||||
s.run_script(&read_json(p)?).map_err(|e| e.to_string())?;
|
||||
let mut s = load_checked(b, check)?;
|
||||
run_script_warning(&mut s, p, &read_json(p)?)?;
|
||||
Ok(s)
|
||||
}
|
||||
(Some(b), None) => load(b),
|
||||
(None, Some(p)) => load(p),
|
||||
(Some(b), None) => load_checked(b, check),
|
||||
(None, Some(p)) => load_checked(p, check),
|
||||
(None, None) => Err(usage()),
|
||||
}
|
||||
}
|
||||
@@ -473,7 +502,7 @@ fn timeline_ok(s: &Session) -> Result<(), String> {
|
||||
fn cmd_eval(args: &[String]) -> Result<(), String> {
|
||||
let json_out = json_out(args)?;
|
||||
known_args("eval", args, &["--in", "--json-out"], &[], true)?;
|
||||
let mut s = open(flag(args, "--in"), positional(args))?;
|
||||
let mut s = open(flag(args, "--in"), positional(args), solidcraft_engine::schema::ParamCheck::Off)?;
|
||||
let m = s.execute("inspect.measure", &json!({})).map_err(|e| e.to_string())?;
|
||||
let d = s.execute("document.inspect", &json!({})).map_err(|e| e.to_string())?;
|
||||
let out = json!({
|
||||
@@ -567,7 +596,7 @@ fn cmd_snapshot(args: &[String]) -> Result<(), String> {
|
||||
Some(x) => x.parse().ok().filter(|n| (16..=8192).contains(n)).ok_or_else(|| format!("{name} must be 16 to 8192 pixels, not `{x}`")),
|
||||
};
|
||||
let (w, h) = (size("--width", 1280)?, size("--height", 800)?);
|
||||
let mut s = open(flag(args, "--in"), positional(args))?;
|
||||
let mut s = open(flag(args, "--in"), positional(args), solidcraft_engine::schema::ParamCheck::Off)?;
|
||||
// How the bodies are drawn and where the model is cut, through the commands the app's
|
||||
// Appearance dialog and Section Analysis run (`preview`).
|
||||
preview::apply(&mut s, &flags(args, "--body"), &flags(args, "--tool"), flag(args, "--section"))?;
|
||||
@@ -691,17 +720,8 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
eprintln!("solidcraft mcp: the design's folder is left out because {why}; add it with --allow-path if you mean it");
|
||||
}
|
||||
}
|
||||
// How a headless session treats calls that break a command's parameter contract (docs/mcp.md).
|
||||
let param_check = match flag(args, "--param-check") {
|
||||
None if args.iter().any(|a| a == "--param-check") => return Err("mcp: --param-check wants off, warn or strict".into()),
|
||||
None => solidcraft_engine::schema::ParamCheck::Off,
|
||||
Some(v) => {
|
||||
solidcraft_engine::schema::ParamCheck::parse(v).ok_or_else(|| format!("mcp: --param-check wants off, warn or strict, not `{v}`"))?
|
||||
}
|
||||
};
|
||||
if param_check != solidcraft_engine::schema::ParamCheck::Off && flag(args, "--connect").is_some() {
|
||||
eprintln!("solidcraft mcp: --param-check applies to headless sessions; calls to the app are not checked yet");
|
||||
}
|
||||
// How calls that break a command's parameter contract are treated, headless or bridged.
|
||||
let param_check = parse_param_check("mcp", args)?;
|
||||
let backend: Box<dyn solidcraft_mcp::Backend> = match (flag(args, "--connect"), flag(args, "--in")) {
|
||||
(Some(_), Some(_)) => return Err("mcp: use either --connect or --in, not both".into()),
|
||||
(Some(addr), None) => {
|
||||
@@ -709,7 +729,7 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
return Err(format!("mcp: --connect wants HOST:PORT, such as 127.0.0.1:7878, not `{addr}`"));
|
||||
};
|
||||
// Serve without the app too: the tools connect once it runs, and say it isn't until then.
|
||||
let mut remote = solidcraft_mcp::Remote::new(addr, flag(args, "--token"));
|
||||
let mut remote = solidcraft_mcp::Remote::new(addr, flag(args, "--token")).with_param_check(param_check);
|
||||
if let Err(e) = remote.try_connect() {
|
||||
eprintln!(
|
||||
"solidcraft mcp: no SolidCraft app at {addr} yet ({e}); start it with `solidcraft --control {port}` \
|
||||
@@ -729,7 +749,8 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
let auto = !args.iter().any(|a| a == "--headless");
|
||||
if auto && let Some(port) = discover_app() {
|
||||
eprintln!("solidcraft mcp: bridged to the running app at 127.0.0.1:{port} (--headless starts a session of its own)");
|
||||
return serve_mcp(Box::new(solidcraft_mcp::Remote::new(&format!("127.0.0.1:{port}"), flag(args, "--token"))), scope);
|
||||
let remote = solidcraft_mcp::Remote::new(&format!("127.0.0.1:{port}"), flag(args, "--token")).with_param_check(param_check);
|
||||
return serve_mcp(Box::new(remote), scope);
|
||||
}
|
||||
let mut headless = solidcraft_mcp::Headless::default();
|
||||
headless.session.param_check = param_check;
|
||||
|
||||
@@ -288,3 +288,47 @@ fn undoing_an_edit_after_opening_reuses_the_saved_results() {
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let _ = std::fs::remove_file(format!("{}.bak", path.display()));
|
||||
}
|
||||
|
||||
/// A design saved before body names were pinned (#6403) pins them as it opens, as its first
|
||||
/// command would, and opening it is no change. That command pinned them as part of itself, so
|
||||
/// undoing it went back to the unpinned design, which no evaluated result matched: the first
|
||||
/// undo after opening from the command line evaluated every feature again (82-93 s in a
|
||||
/// 5,484-feature design); `doc.open` pinned them after opening, which marked the design changed.
|
||||
#[test]
|
||||
fn a_design_saved_before_names_were_pinned_opens_pinned_and_unchanged() {
|
||||
let plate = solidcraft_engine::sample::samples().into_iter().find(|s| s.name == "Sample Plate").unwrap();
|
||||
let mut built = Session::default();
|
||||
for c in (plate.script)()["commands"].as_array().unwrap() {
|
||||
built.execute(c["command"].as_str().unwrap(), &c["params"]).unwrap();
|
||||
}
|
||||
let mut doc = built.design().into_owned();
|
||||
for f in &mut doc.features {
|
||||
f.body_names.clear();
|
||||
}
|
||||
doc.reserved_body_names.clear();
|
||||
let unpinned = Session::new(doc);
|
||||
let design = unpinned.design();
|
||||
let saved = unpinned.model.saved(&design).unwrap();
|
||||
let bytes = solidcraft_engine::io::write_design_container_with_cache(&design, solidcraft_engine::io::DesignCompression::Fast, None, Some(&saved))
|
||||
.unwrap();
|
||||
let path = temp("unpinned");
|
||||
std::fs::write(&path, &bytes).unwrap();
|
||||
let file = path.to_string_lossy().to_string();
|
||||
// As the command line opens a design (`load`), and as the app does (`doc.open`).
|
||||
let (doc, saved) = solidcraft_engine::io::read_design_file(&file, None::<fn(solidcraft_engine::io::DesignPreview)>).unwrap();
|
||||
for (how, mut s) in [("opened_at", Session::opened_at(doc, saved.as_ref(), Some(&file))), ("doc.open", open(&path))] {
|
||||
assert_eq!(s.model.last_recomputed, 0, "{how}: taken from the file");
|
||||
assert!(s.doc.features.iter().any(|f| !f.body_names.is_empty()), "{how}: the names are pinned");
|
||||
assert!(!s.is_dirty(), "{how}: opening is no change");
|
||||
let read: Vec<Arc<ModelState>> = s.model.results.iter().map(|r| r.state.clone()).collect();
|
||||
s.execute("solid.box", &json!({"length": 3, "width": 3, "height": 3, "operation": "new"})).unwrap();
|
||||
// As in a large design, whose evaluation cache keeps only a few results: undo finds the
|
||||
// results in the model itself or evaluates them again.
|
||||
*s.model.cache.lock().unwrap() = Default::default();
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert_eq!(s.model.last_recomputed, 0, "{how}: the first undo evaluates nothing");
|
||||
assert!(s.model.results.iter().zip(&read).all(|(r, st)| Arc::ptr_eq(&r.state, st)), "{how}: the states read from the file");
|
||||
assert!(!s.is_dirty(), "{how}: undone to the design as opened");
|
||||
}
|
||||
let _ = std::fs::remove_file(&path);
|
||||
}
|
||||
|
||||
@@ -496,6 +496,78 @@ fn timings_and_profile_report_each_command() {
|
||||
assert!(String::from_utf8_lossy(&output.stderr).contains("--timings needs a script"));
|
||||
}
|
||||
|
||||
/// #6921: `--param-check` checks a script's steps against their contracts on every path `run`
|
||||
/// takes (a script alone, on an `--in` design or script, with `--results`, `--timings` or
|
||||
/// `--profile`), and a warning reaches stderr even when a later step fails.
|
||||
#[test]
|
||||
fn param_check_reaches_every_script_run_takes() {
|
||||
let dir = Scratch::new();
|
||||
let typo = dir.0.join("typo.json");
|
||||
let step = json!({"command": "solid.box", "params": {"length": 2, "width": 3, "height": 4, "operaton": "new"}});
|
||||
std::fs::write(&typo, json!({"commands": [step.clone()]}).to_string()).unwrap();
|
||||
let base = dir.0.join("base.solidcraft");
|
||||
json_output(cli().arg("run").arg(dir.script()).arg("--save").arg(&base).output().unwrap());
|
||||
let saved = dir.0.join("saved.solidcraft");
|
||||
let start = dir.script();
|
||||
let (typo, base, saved_arg, start) = (typo.to_str().unwrap(), base.to_str().unwrap(), saved.to_str().unwrap(), start.to_str().unwrap());
|
||||
let paths = [&[][..], &["--in", base], &["--in", start], &["--results"], &["--timings"], &["--timings", "--profile"]];
|
||||
let run = |level: Option<&str>, extra: &[&str]| {
|
||||
std::fs::remove_file(&saved).ok();
|
||||
let check = level.map(|l| ["--param-check", l]).into_iter().flatten();
|
||||
cli().args(["run", typo, "--save", saved_arg]).args(check).args(extra).output().unwrap()
|
||||
};
|
||||
|
||||
// Off, the default: the step runs as it always has, without a word.
|
||||
let off = run(None, &[]);
|
||||
assert!(off.status.success() && !String::from_utf8_lossy(&off.stderr).contains("operaton"), "{off:?}");
|
||||
assert_eq!(body_count(&saved), 1);
|
||||
|
||||
// Warn: each path runs the step, saves, and reports it on stderr; `--results` keeps it too.
|
||||
for extra in paths {
|
||||
let output = run(Some("warn"), extra);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(output.status.success(), "{extra:?}: {stderr}");
|
||||
assert!(stderr.contains("step 1: unknown key `operaton`; did you mean `operation`?"), "{extra:?}: {stderr}");
|
||||
assert!(saved.exists(), "{extra:?}");
|
||||
if extra == ["--results"] {
|
||||
let results: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
assert!(results[0]["param_warnings"][0].as_str().is_some_and(|w| w.contains("operaton")), "{results}");
|
||||
}
|
||||
}
|
||||
|
||||
// Strict: on each path the run stops at the step, and nothing is written.
|
||||
for extra in paths {
|
||||
let output = run(Some("strict"), extra);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert_eq!(output.status.code(), Some(1), "{extra:?}: {stderr}");
|
||||
assert!(stderr.contains("unknown key `operaton`"), "{extra:?}: {stderr}");
|
||||
assert!(!saved.exists(), "{extra:?}");
|
||||
}
|
||||
|
||||
// Warn, with a later step that fails: the run fails, and the first step's warning is still
|
||||
// reported, timed or not.
|
||||
let failing = dir.0.join("failing.json");
|
||||
let fail = json!({"command": "solid.extrude", "params": {"sketch": "Nope"}});
|
||||
std::fs::write(&failing, json!({"commands": [step, fail]}).to_string()).unwrap();
|
||||
for extra in [&[][..], &["--timings"]] {
|
||||
let output = cli().arg("run").arg(&failing).args(["--param-check", "warn"]).args(extra).output().unwrap();
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert_eq!(output.status.code(), Some(1), "{extra:?}: {stderr}");
|
||||
assert!(stderr.contains("step 1: unknown key `operaton`") && stderr.contains("no sketch `Nope`"), "{extra:?}: {stderr}");
|
||||
}
|
||||
|
||||
// A level it doesn't know and a missing value fail.
|
||||
for (bad, says) in [
|
||||
(&["--param-check", "loud"][..], "--param-check wants off, warn or strict, not `loud`"),
|
||||
(&["--param-check"], "run: --param-check wants off, warn or strict"),
|
||||
] {
|
||||
let output = cli().args(["run", typo]).args(bad).output().unwrap();
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert_eq!(output.status.code(), Some(1), "{bad:?}: {stderr}");
|
||||
assert!(stderr.contains(says), "{bad:?}: {stderr}");
|
||||
}
|
||||
}
|
||||
|
||||
fn render_setup_script(dir: &Scratch, job: Value) -> PathBuf {
|
||||
let path = dir.0.join("render.json");
|
||||
std::fs::write(
|
||||
|
||||
@@ -34,7 +34,7 @@ serde_json = { workspace = true }
|
||||
web-sys = { version = "0.3", features = [
|
||||
"Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement", "Location", "Navigator", "StorageManager",
|
||||
"FileSystemHandle", "FileSystemDirectoryHandle", "FileSystemFileHandle", "FileSystemGetFileOptions", "FileSystemWritableFileStream",
|
||||
"WritableStream", "File", "FileList", "Blob", "BlobPropertyBag", "Url", "HtmlAnchorElement", "HtmlInputElement", "Storage",
|
||||
"WritableStream", "File", "FileList", "Blob", "BlobPropertyBag", "Url", "HtmlAnchorElement", "HtmlInputElement", "Storage", "StorageEvent",
|
||||
"IdbFactory", "IdbDatabase", "IdbObjectStore", "IdbOpenDbRequest", "IdbRequest", "IdbTransaction", "IdbTransactionMode",
|
||||
"Headers", "ReadableStream", "ReadableStreamDefaultReader",
|
||||
"BeforeUnloadEvent", "Event", "EventTarget", "KeyboardEvent", "Response", "FormData", "RequestInit", "MediaQueryList", "Gamepad", "Performance",
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
<link data-trunk rel="rust" data-bin="solidcraft-web" data-wasm-opt="z" data-weak-refs />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/BIZUDPGothic-Regular.ttf" data-target-path="fonts" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/OFL.txt" data-target-path="fonts" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/craft-ui-sc/CraftUI-SC.otf" data-target-path="fonts" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/craft-ui-sc/OFL.txt" data-target-path="fonts/craft-ui-sc" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/craft-ui-tc/CraftUI-TC.otf" data-target-path="fonts" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/craft-ui-tc/OFL.txt" data-target-path="fonts/craft-ui-tc" />
|
||||
<link data-trunk rel="css" href="../../assets/styles/web/loading.css" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/styles/web/loading-logo.svg" />
|
||||
<!-- Installable as an app (manifest.webmanifest); the icons are the Linux exports of the app mark. -->
|
||||
|
||||
@@ -119,6 +119,43 @@ fn closes_design(key: &str, command: bool, shift: bool, alt: bool, design_shown:
|
||||
design_shown && command && !shift && !alt && key.eq_ignore_ascii_case("w")
|
||||
}
|
||||
|
||||
/// The settings a tab last wrote to the browser's storage, or loaded from another tab (#8644).
|
||||
/// Every open tab of the app shares that storage, and eframe saves each tab's whole copy every
|
||||
/// 30 s and when the page loses focus, so a tab still holding old settings put them back over a
|
||||
/// change made in another. A change is now written in the frame it is made, and the other tabs
|
||||
/// load it ([`settings_written`]).
|
||||
#[cfg(any(target_arch = "wasm32", test))]
|
||||
#[derive(Default, Debug)]
|
||||
struct PrefsWriter {
|
||||
written: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "wasm32", test))]
|
||||
impl PrefsWriter {
|
||||
/// `prefs` if they are not the settings written or loaded last (they count as written from
|
||||
/// now on).
|
||||
fn take(&mut self, prefs: String) -> Option<String> {
|
||||
if self.written.as_deref() == Some(prefs.as_str()) {
|
||||
return None;
|
||||
}
|
||||
self.written = Some(prefs.clone());
|
||||
Some(prefs)
|
||||
}
|
||||
|
||||
/// The settings the tab holds after loading another tab's: the tab doesn't write them back.
|
||||
fn loaded(&mut self, prefs: String) {
|
||||
self.written = Some(prefs);
|
||||
}
|
||||
}
|
||||
|
||||
/// The settings another tab wrote, from a `storage` event (the browser sends one to every other
|
||||
/// tab of the page when one tab writes). Other keys, and settings taken away (clearing the site's
|
||||
/// data), leave this tab's settings as they are.
|
||||
#[cfg(any(target_arch = "wasm32", test))]
|
||||
fn settings_written(key: Option<&str>, value: Option<String>) -> Option<String> {
|
||||
value.filter(|_| key == Some(solidcraft_ui_egui::prefs::STORAGE_KEY))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod web {
|
||||
use std::rc::Rc;
|
||||
@@ -217,9 +254,29 @@ mod web {
|
||||
on_key.forget();
|
||||
}
|
||||
|
||||
const JAPANESE_FONT_PATH: &str = "./fonts/BIZUDPGothic-Regular.ttf";
|
||||
/// Settings another tab wrote, waiting for this tab's next frame (#8644).
|
||||
type PrefsInbox = Rc<std::cell::Cell<Option<String>>>;
|
||||
|
||||
type FontLoadResult = Rc<std::cell::RefCell<Option<Result<Vec<u8>, String>>>>;
|
||||
/// Settings another tab of the app writes go to `inbox`, and this tab draws a frame, which
|
||||
/// loads them.
|
||||
fn hear_settings_from_other_tabs(window: &web_sys::Window, ctx: &egui::Context, inbox: PrefsInbox) {
|
||||
let ctx = ctx.clone();
|
||||
let on_storage = wasm_bindgen::closure::Closure::<dyn FnMut(web_sys::StorageEvent)>::new(move |e: web_sys::StorageEvent| {
|
||||
if let Some(prefs) = crate::settings_written(e.key().as_deref(), e.new_value()) {
|
||||
inbox.set(Some(prefs));
|
||||
ctx.request_repaint();
|
||||
}
|
||||
});
|
||||
let _ = window.add_event_listener_with_callback("storage", on_storage.as_ref().unchecked_ref());
|
||||
// The listener lives as long as the page.
|
||||
on_storage.forget();
|
||||
}
|
||||
|
||||
const JAPANESE_FONT_PATH: &str = "./fonts/BIZUDPGothic-Regular.ttf";
|
||||
const CHINESE_SC_FONT_PATH: &str = "./fonts/CraftUI-SC.otf";
|
||||
const CHINESE_TC_FONT_PATH: &str = "./fonts/CraftUI-TC.otf";
|
||||
|
||||
type FontLoadResult = Rc<std::cell::RefCell<Option<Result<(String, Vec<u8>), String>>>>;
|
||||
|
||||
struct Shell {
|
||||
app: SolveApp,
|
||||
@@ -237,18 +294,63 @@ mod web {
|
||||
rename_focus: bool,
|
||||
/// The start page's recent designs were filled from the stored ones.
|
||||
recents_synced: bool,
|
||||
/// On-demand CJK font: fetched only when a CJK language is selected.
|
||||
/// On-demand script fonts: fetched only when a CJK language is selected.
|
||||
font: solidcraft_ui_egui::fonts::CjkFontLoader,
|
||||
font_result: FontLoadResult,
|
||||
/// The fetched CJK font's bytes: kept so a language change can re-order the fallbacks.
|
||||
/// The fetched Japanese font's bytes: kept so a language change can re-order the fallbacks.
|
||||
cjk_bytes: Option<Vec<u8>>,
|
||||
/// The fetched Chinese font's bytes (Simplified or Traditional for this session).
|
||||
chinese_bytes: Option<Vec<u8>>,
|
||||
/// Which Chinese face `chinese_bytes` is: `"zh"` or `"zh-TW"`.
|
||||
chinese_kind: Option<&'static str>,
|
||||
/// Kind requested by the in-flight fetch (`"ja"`, `"zh"`, or `"zh-TW"`).
|
||||
font_fetch_kind: Option<&'static str>,
|
||||
/// The language the fonts were last set up for (a CJK UI leads with the CJK face).
|
||||
font_language: String,
|
||||
space_mouse: SpaceMouse,
|
||||
wheel_gestures: solidcraft_ui_egui::WebWheelGestures,
|
||||
/// The settings this tab wrote or loaded last, and those another tab wrote since (#8644).
|
||||
prefs_writer: crate::PrefsWriter,
|
||||
other_tab_prefs: PrefsInbox,
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
/// The settings as they are kept between visits: with the user's own language, not a
|
||||
/// session-only English fallback.
|
||||
fn persisted_prefs(&mut self) -> String {
|
||||
let saved = self.font.persisted_language(&self.app.preferences.language).to_owned();
|
||||
let live = std::mem::replace(&mut self.app.preferences.language, saved);
|
||||
let prefs = self.app.prefs();
|
||||
self.app.preferences.language = live;
|
||||
prefs
|
||||
}
|
||||
|
||||
/// A settings change goes to the browser's storage in the frame it is made, and from
|
||||
/// there to the other open tabs (#8644). Input is what changes settings, so a frame
|
||||
/// without any is skipped; eframe's own save still catches anything else.
|
||||
fn store_prefs(&mut self, ctx: &egui::Context) {
|
||||
if !self.launch.persists() || ctx.input(|i| i.events.is_empty()) {
|
||||
return;
|
||||
}
|
||||
let prefs = self.persisted_prefs();
|
||||
let Some(prefs) = self.prefs_writer.take(prefs) else { return };
|
||||
let stored =
|
||||
web_sys::window().and_then(|w| w.local_storage().ok().flatten()).map(|s| s.set_item(solidcraft_ui_egui::prefs::STORAGE_KEY, &prefs));
|
||||
if !matches!(stored, Some(Ok(()))) {
|
||||
log::warn!("settings: the browser's storage did not take them; they are saved again later");
|
||||
self.prefs_writer = crate::PrefsWriter::default();
|
||||
}
|
||||
}
|
||||
|
||||
/// Settings another tab wrote replace this tab's, so this tab's own saves keep them
|
||||
/// instead of putting its older copy back (#8644).
|
||||
fn load_other_tabs_prefs(&mut self) {
|
||||
let Some(prefs) = self.other_tab_prefs.take() else { return };
|
||||
self.app.load_prefs(&prefs);
|
||||
let held = self.persisted_prefs();
|
||||
self.prefs_writer.loaded(held);
|
||||
}
|
||||
|
||||
/// Files from the computer, writes to store, messages and the autosave.
|
||||
fn files_tick(&mut self, ctx: &egui::Context) {
|
||||
if !self.launch.persists() {
|
||||
@@ -580,32 +682,60 @@ mod web {
|
||||
files::autosave(&self.files, None);
|
||||
}
|
||||
|
||||
/// Fetch and install the CJK font when a CJK language is selected. If that fails, this
|
||||
/// Whether the shell already has the on-demand face the live language needs.
|
||||
fn script_font_ready(&self) -> bool {
|
||||
match solidcraft_ui_egui::fonts::web_script_font_kind(&self.app.preferences.language) {
|
||||
Some("zh") => self.chinese_bytes.is_some() && self.chinese_kind == Some("zh"),
|
||||
Some("zh-TW") => self.chinese_bytes.is_some() && self.chinese_kind == Some("zh-TW"),
|
||||
Some("ja") => self.cjk_bytes.is_some(),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch and install a script font when a CJK language is selected. If that fails, this
|
||||
/// session falls back to English (no tofu); the saved language preference is kept.
|
||||
fn tick_font(&mut self, ctx: &egui::Context) {
|
||||
let done = self.font_result.borrow_mut().take();
|
||||
if let Some(res) = done {
|
||||
let kind = self.font_fetch_kind.take();
|
||||
let installed = match res {
|
||||
Ok(bytes) => {
|
||||
self.cjk_bytes = Some(bytes);
|
||||
Ok((path, bytes)) => {
|
||||
match kind {
|
||||
Some("zh") => {
|
||||
self.chinese_bytes = Some(bytes);
|
||||
self.chinese_kind = Some("zh");
|
||||
}
|
||||
Some("zh-TW") => {
|
||||
self.chinese_bytes = Some(bytes);
|
||||
self.chinese_kind = Some("zh-TW");
|
||||
}
|
||||
_ => {
|
||||
self.cjk_bytes = Some(bytes);
|
||||
}
|
||||
}
|
||||
log::info!("loaded web script font from {path}");
|
||||
true
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("failed to fetch CJK font from {JAPANESE_FONT_PATH}: {err}");
|
||||
let path = match kind {
|
||||
Some("zh") => CHINESE_SC_FONT_PATH,
|
||||
Some("zh-TW") => CHINESE_TC_FONT_PATH,
|
||||
_ => JAPANESE_FONT_PATH,
|
||||
};
|
||||
log::warn!("failed to fetch script font from {path}: {err}");
|
||||
false
|
||||
}
|
||||
};
|
||||
if installed {
|
||||
log::info!("loaded web CJK font from {JAPANESE_FONT_PATH}");
|
||||
} else if solidcraft_ui_egui::fonts::needs_cjk_font(&self.app.preferences.language) {
|
||||
log::warn!("CJK font unavailable; showing English for this session");
|
||||
if !installed && solidcraft_ui_egui::fonts::needs_cjk_font(&self.app.preferences.language) {
|
||||
log::warn!("script font unavailable; showing English for this session");
|
||||
}
|
||||
self.font.finished(installed, &mut self.app.preferences.language);
|
||||
self.apply_fonts(ctx);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
if self.font.tick(&mut self.app.preferences.language) {
|
||||
self.fetch_font(ctx);
|
||||
let ready = self.script_font_ready();
|
||||
if self.font.tick(&mut self.app.preferences.language, ready) {
|
||||
self.fetch_font(ctx, solidcraft_ui_egui::fonts::web_script_font_kind(&self.app.preferences.language).unwrap_or("ja"));
|
||||
}
|
||||
// The CJK face leads only a CJK UI: its Cyrillic glyphs are full-width, so switching
|
||||
// to Ukrainian (or English) must put the Latin face back in front.
|
||||
@@ -614,31 +744,42 @@ mod web {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set up the UI fonts for the live language, keeping the fetched CJK font as a fallback
|
||||
/// (it leads only for a CJK UI, see [`solidcraft_ui_egui::fonts::install_cjk_font_for`]).
|
||||
/// Set up the UI fonts for the live language, keeping fetched script fonts as fallbacks
|
||||
/// (Chinese leads a Chinese UI; see [`solidcraft_ui_egui::fonts::install_web_script_fonts`]).
|
||||
fn apply_fonts(&mut self, ctx: &egui::Context) {
|
||||
match self.cjk_bytes.clone() {
|
||||
Some(bytes) => {
|
||||
solidcraft_ui_egui::fonts::install_cjk_font_for(ctx, bytes, &self.app.preferences.language);
|
||||
}
|
||||
None => solidcraft_ui_egui::fonts::setup_fonts(ctx),
|
||||
if self.cjk_bytes.is_none() && self.chinese_bytes.is_none() {
|
||||
solidcraft_ui_egui::fonts::setup_fonts(ctx);
|
||||
} else {
|
||||
solidcraft_ui_egui::fonts::install_web_script_fonts(
|
||||
ctx,
|
||||
self.cjk_bytes.clone(),
|
||||
self.chinese_bytes.clone(),
|
||||
&self.app.preferences.language,
|
||||
);
|
||||
}
|
||||
self.font_language.clone_from(&self.app.preferences.language);
|
||||
}
|
||||
|
||||
/// CJK text on screen with no CJK font yet (an English UI showing a Japanese name):
|
||||
/// fetch the font, so the text does not stay tofu (#720).
|
||||
/// CJK text on screen with no Japanese font yet (an English UI showing a Japanese name):
|
||||
/// fetch the Japanese font, so the text does not stay tofu (#720).
|
||||
fn watch_text_for_font(&mut self, ctx: &egui::Context) {
|
||||
if self.font.watching_text() && solidcraft_ui_egui::fonts::painted_cjk(ctx) && self.font.text_needs_font() {
|
||||
self.fetch_font(ctx);
|
||||
self.fetch_font(ctx, "ja");
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_font(&self, ctx: &egui::Context) {
|
||||
fn fetch_font(&mut self, ctx: &egui::Context, kind: &'static str) {
|
||||
let path = match kind {
|
||||
"zh" => CHINESE_SC_FONT_PATH,
|
||||
"zh-TW" => CHINESE_TC_FONT_PATH,
|
||||
_ => JAPANESE_FONT_PATH,
|
||||
};
|
||||
self.font_fetch_kind = Some(kind);
|
||||
let slot = self.font_result.clone();
|
||||
let ctx = ctx.clone();
|
||||
let path = path.to_owned();
|
||||
wasm_bindgen_futures::spawn_local(async move {
|
||||
let res = fetch_font_bytes(JAPANESE_FONT_PATH).await;
|
||||
let res = fetch_font_bytes(&path).await.map(|bytes| (path, bytes));
|
||||
*slot.borrow_mut() = Some(res);
|
||||
ctx.request_repaint();
|
||||
});
|
||||
@@ -647,6 +788,8 @@ mod web {
|
||||
|
||||
impl eframe::App for Shell {
|
||||
fn logic(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
// First: a language another tab chose fetches its font this frame.
|
||||
self.load_other_tabs_prefs();
|
||||
self.tick_font(ctx);
|
||||
self.app.logic(ctx);
|
||||
self.api.poll();
|
||||
@@ -689,6 +832,7 @@ mod web {
|
||||
self.recovery_prompt(&ctx);
|
||||
}
|
||||
self.watch_text_for_font(&ctx);
|
||||
self.store_prefs(&ctx);
|
||||
}
|
||||
fn persist_egui_memory(&self) -> bool {
|
||||
self.launch.persists()
|
||||
@@ -697,11 +841,8 @@ mod web {
|
||||
if !self.launch.persists() {
|
||||
return;
|
||||
}
|
||||
// Persist the user's own language, not a session-only English fallback.
|
||||
let saved = self.font.persisted_language(&self.app.preferences.language).to_owned();
|
||||
let live = std::mem::replace(&mut self.app.preferences.language, saved);
|
||||
storage.set_string(solidcraft_ui_egui::prefs::STORAGE_KEY, self.app.prefs());
|
||||
self.app.preferences.language = live;
|
||||
let prefs = self.persisted_prefs();
|
||||
storage.set_string(solidcraft_ui_egui::prefs::STORAGE_KEY, prefs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,6 +963,12 @@ mod web {
|
||||
let (sender, receiver) = std::sync::mpsc::channel();
|
||||
let mut app = SolveApp::new(Session::default(), services).with_control(receiver);
|
||||
app.embedded = launch.embed;
|
||||
// Listening before reading: settings another tab writes from now on are
|
||||
// newer than those read here.
|
||||
let other_tab_prefs = PrefsInbox::default();
|
||||
if launch.persists() {
|
||||
hear_settings_from_other_tabs(&window, &cc.egui_ctx, other_tab_prefs.clone());
|
||||
}
|
||||
if launch.persists() && let Some(p) = cc.storage.and_then(|s| solidcraft_ui_egui::prefs::stored(|k| s.get_string(k))) {
|
||||
app.load_prefs(&p);
|
||||
}
|
||||
@@ -862,9 +1009,14 @@ mod web {
|
||||
font: Default::default(),
|
||||
font_result: Rc::new(std::cell::RefCell::new(None)),
|
||||
cjk_bytes: None,
|
||||
chinese_bytes: None,
|
||||
chinese_kind: None,
|
||||
font_fetch_kind: None,
|
||||
font_language,
|
||||
space_mouse: SpaceMouse::default(),
|
||||
wheel_gestures: solidcraft_ui_egui::WebWheelGestures::default(),
|
||||
prefs_writer: crate::PrefsWriter::default(),
|
||||
other_tab_prefs,
|
||||
}))
|
||||
}),
|
||||
)
|
||||
@@ -1001,4 +1153,28 @@ mod tests {
|
||||
assert!(!closes_design("w", false, false, false, true));
|
||||
assert!(!closes_design("s", true, false, false, true));
|
||||
}
|
||||
|
||||
/// A tab writes its settings when they change, and not again while they stay the same; the
|
||||
/// settings it loaded from another tab aren't written back (#8644).
|
||||
#[test]
|
||||
fn changed_settings_are_written_once_and_loaded_ones_not_at_all() {
|
||||
let mut writer = PrefsWriter::default();
|
||||
assert_eq!(writer.take(r#"{"a":1}"#.into()).as_deref(), Some(r#"{"a":1}"#), "the first settings are written");
|
||||
assert_eq!(writer.take(r#"{"a":1}"#.into()), None, "the same settings are not written again");
|
||||
assert_eq!(writer.take(r#"{"a":2}"#.into()).as_deref(), Some(r#"{"a":2}"#), "a change is written at once");
|
||||
writer.loaded(r#"{"a":3}"#.into());
|
||||
assert_eq!(writer.take(r#"{"a":3}"#.into()), None, "settings from another tab are not written back");
|
||||
assert_eq!(writer.take(r#"{"a":4}"#.into()).as_deref(), Some(r#"{"a":4}"#), "this tab's next change is written");
|
||||
}
|
||||
|
||||
/// Only the settings another tab wrote are loaded: not other keys, and not settings taken
|
||||
/// away by clearing the site's data (#8644).
|
||||
#[test]
|
||||
fn only_settings_another_tab_wrote_are_loaded() {
|
||||
let key = solidcraft_ui_egui::prefs::STORAGE_KEY;
|
||||
assert_eq!(settings_written(Some(key), Some("{}".into())).as_deref(), Some("{}"));
|
||||
assert_eq!(settings_written(Some("solidcraft.webgl"), Some("1".into())), None);
|
||||
assert_eq!(settings_written(Some(key), None), None, "removed settings leave this tab's");
|
||||
assert_eq!(settings_written(None, None), None, "clearing all storage leaves this tab's settings");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,5 +104,10 @@ winit = { version = "0.30", default-features = false, features = ["x11"] }
|
||||
raw-window-handle = "0.6"
|
||||
x11rb = { version = "0.13", default-features = false }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
# The desktop's dark or light preference through the XDG Desktop Portal (src/desktop_theme.rs,
|
||||
# #7944); already in the tree through eframe's accessibility support (accesskit_unix).
|
||||
zbus = { version = "5", default-features = false, features = ["async-io", "blocking-api"] }
|
||||
|
||||
[build-dependencies]
|
||||
embed-resource = "3.0.11"
|
||||
|
||||
@@ -413,11 +413,37 @@ impl Lines {
|
||||
}
|
||||
}
|
||||
|
||||
/// A subscribed connection's seat on the watch: it leaves exactly once, whichever thread sees
|
||||
/// the connection's end first — the connection's own thread at the end of the stream, or the
|
||||
/// events thread at the first write a closed client refuses. The seat used to wait for the
|
||||
/// events thread alone, and that thread only leaves its wait when the design moves, so the
|
||||
/// count could outlive the connection by a second or more (#8315).
|
||||
struct Seat(Mutex<Option<Subscriber>>);
|
||||
|
||||
impl Seat {
|
||||
fn new(counted: Subscriber) -> Self {
|
||||
Seat(Mutex::new(Some(counted)))
|
||||
}
|
||||
|
||||
/// Leave the watch now: the seat goes once, whoever gets here first.
|
||||
fn release(&self) {
|
||||
let counted = self.0.lock().unwrap_or_else(PoisonError::into_inner).take();
|
||||
drop(counted);
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Seat {
|
||||
fn drop(&mut self) {
|
||||
self.release();
|
||||
}
|
||||
}
|
||||
|
||||
/// A connection's `control.subscribe` (#6985): its `design.changed` lines, sent from a thread of
|
||||
/// their own until the connection ends.
|
||||
struct Subscription {
|
||||
lines: Arc<Lines>,
|
||||
stop: Arc<AtomicBool>,
|
||||
seat: Arc<Seat>,
|
||||
}
|
||||
|
||||
impl Subscription {
|
||||
@@ -433,15 +459,17 @@ impl Subscription {
|
||||
) -> Option<(Self, std::io::Result<()>)> {
|
||||
let lines = Arc::new(Lines { socket: out.try_clone().ok()?, turn: Mutex::new(()) });
|
||||
let stop = Arc::new(AtomicBool::new(false));
|
||||
let seat = Arc::new(Seat::new(counted));
|
||||
let first = lines.turn.lock().unwrap_or_else(PoisonError::into_inner);
|
||||
let (l, s) = (lines.clone(), stop.clone());
|
||||
let (l, s, watch_seat) = (lines.clone(), stop.clone(), Arc::clone(&seat));
|
||||
// The connection's seat on the watch rides the events thread: it leaves when the thread
|
||||
// does, so the next failed write to a closed client retires it even while the connection's
|
||||
// own thread is slow to see the end of the stream (#7226).
|
||||
std::thread::Builder::new().stack_size(64 * 1024).spawn(move || send_events(design, &l, &s, seen, counted)).ok()?;
|
||||
// own thread is slow to see the end of the stream (#7226). The connection's own thread
|
||||
// leaves it too, so a closed connection stops counting at once (#8315).
|
||||
std::thread::Builder::new().stack_size(64 * 1024).spawn(move || send_events(design, &l, &s, seen, watch_seat)).ok()?;
|
||||
let sent = send(&mut &lines.socket, reply);
|
||||
drop(first);
|
||||
Some((Subscription { lines, stop }, sent))
|
||||
Some((Subscription { lines, stop, seat }, sent))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,6 +482,9 @@ fn design_of(reply: &Value) -> Option<(String, u64)> {
|
||||
impl Drop for Subscription {
|
||||
fn drop(&mut self) {
|
||||
self.stop.store(true, Ordering::Relaxed);
|
||||
// The seat on the watch goes now: the connection is over, and nothing counts it any more
|
||||
// (#8315).
|
||||
self.seat.release();
|
||||
// The socket closes now, not when the thread next looks; a line blocked on a client that
|
||||
// stopped reading ends too.
|
||||
let _ = self.lines.socket.shutdown(std::net::Shutdown::Both);
|
||||
@@ -461,10 +492,10 @@ impl Drop for Subscription {
|
||||
}
|
||||
|
||||
/// The `design.changed` lines of a subscribed connection, each time the design differs from the
|
||||
/// last one it was told of (`seen`), until `stop`. Owns the connection's seat on the watch
|
||||
/// (`counted`), so the seat leaves exactly when this thread does: on `stop`, or on the first
|
||||
/// write a closed client refuses (#7226).
|
||||
fn send_events(design: &DesignWatch, lines: &Lines, stop: &AtomicBool, mut seen: (String, u64), _counted: Subscriber) {
|
||||
/// last one it was told of (`seen`), until `stop`. Holds the connection's seat on the watch
|
||||
/// (`seat`), which it leaves when the thread ends: on `stop`, or on the first write a closed
|
||||
/// client refuses (#7226).
|
||||
fn send_events(design: &DesignWatch, lines: &Lines, stop: &AtomicBool, mut seen: (String, u64), seat: Arc<Seat>) {
|
||||
while !stop.load(Ordering::Relaxed) {
|
||||
let Some(now) = design.wait(&seen, stop, Duration::from_secs(1)).filter(|now| *now != seen) else { continue };
|
||||
if lines.send(&json!({"event": "design.changed", "params": {"document_id": now.0, "revision": now.1}})).is_err() {
|
||||
@@ -473,6 +504,17 @@ fn send_events(design: &DesignWatch, lines: &Lines, stop: &AtomicBool, mut seen:
|
||||
seen = now;
|
||||
std::thread::sleep(EVENT_GAP);
|
||||
}
|
||||
// The client is gone: it is not counted on the watch any more, whatever the connection's own
|
||||
// thread still has to notice (#8315).
|
||||
seat.release();
|
||||
}
|
||||
|
||||
/// What this app's control channel does beyond the methods every version has, for a client to
|
||||
/// find out before it relies on it (an older app answers `control.capabilities` with "unknown
|
||||
/// method"). `param_check`: the levels `engine.execute`, `engine.batch` and `engine.script` take
|
||||
/// as a request's own parameter check (#9184).
|
||||
fn capabilities() -> Value {
|
||||
json!({"param_check": solidcraft_engine::schema::ParamCheck::ALL.map(|l| l.name())})
|
||||
}
|
||||
|
||||
/// Write `reply` on the connection: through its subscription once it has one.
|
||||
@@ -535,15 +577,20 @@ fn serve_with(
|
||||
let id = msg.get("id").cloned().unwrap_or(Value::Null);
|
||||
let method = msg.get("method").and_then(Value::as_str).unwrap_or("").to_string();
|
||||
let params = msg.get("params").cloned().unwrap_or(json!({}));
|
||||
// A request that timed out may have finished since (#1618). `control.running` only
|
||||
// looks, so it leaves that reply where it is.
|
||||
let late = pending.as_ref().filter(|_| method != "control.running").and_then(|p| match p.reply.try_recv() {
|
||||
// A request that timed out may have finished since (#1618). `control.running` and
|
||||
// `control.capabilities` only look, so they leave that reply where it is.
|
||||
let late = pending.as_ref().filter(|_| !matches!(method.as_str(), "control.running" | "control.capabilities")).and_then(|p| match p
|
||||
.reply
|
||||
.try_recv()
|
||||
{
|
||||
Ok(reply) => Some(reply),
|
||||
Err(TryRecvError::Disconnected) => Some(json!({"ok": false, "error": "the app ended the request without a reply"})),
|
||||
Err(TryRecvError::Empty) => None,
|
||||
});
|
||||
let mut r = if method == "control.running" {
|
||||
json!({"ok": true, "result": running.result(connection)})
|
||||
} else if method == "control.capabilities" {
|
||||
json!({"ok": true, "result": capabilities()})
|
||||
} else if method == "control.pending" {
|
||||
match (pending.take(), late) {
|
||||
(None, _) => json!({"ok": true, "result": {"pending": null}}),
|
||||
@@ -750,6 +797,9 @@ mod tests {
|
||||
let mut watcher = open();
|
||||
let (r, rows) = running(&mut watcher, &|_| true);
|
||||
assert!(r["ok"] == true && rows.is_empty(), "idle: {r}");
|
||||
// What the app's control channel does beyond the methods every version has (#9184).
|
||||
let r = watcher(json!({"id": 0, "method": "control.capabilities", "token": token}));
|
||||
assert_eq!((&r["ok"], &r["result"]["param_check"]), (&json!(true), &json!(["off", "warn", "strict"])), "{r}");
|
||||
|
||||
let mut export = open();
|
||||
let path = "/private/part.step";
|
||||
@@ -781,6 +831,9 @@ mod tests {
|
||||
let own: Vec<&Value> = r["result"]["running"].as_array().unwrap().iter().filter(|row| row["self"] == true).collect();
|
||||
assert_eq!(own.len(), 1, "{r}");
|
||||
assert_eq!(own[0]["command"], "file.export", "{r}");
|
||||
// So may it ask what the app can do: answered at once, not refused as busy.
|
||||
let r = export(json!({"id": 8, "method": "control.capabilities"}));
|
||||
assert_eq!(r["result"]["param_check"], json!(["off", "warn", "strict"]), "{r}");
|
||||
|
||||
gate_tx.send(()).unwrap();
|
||||
assert_eq!(queued.join().unwrap()["result"], "engine.batch");
|
||||
@@ -886,6 +939,58 @@ mod tests {
|
||||
assert!(!WATCH.subscribed());
|
||||
}
|
||||
|
||||
/// #8315: a closed connection leaves the watch at once. The seat of a subscribed connection
|
||||
/// goes when the connection's own thread sees the end of the stream, not only when the
|
||||
/// events thread notices: that thread waits for the design to move, so a connection that
|
||||
/// closed while the design stood still kept the watch counting it for a second or more.
|
||||
#[test]
|
||||
fn a_closed_connection_leaves_the_watch_at_once() {
|
||||
static RUNNING: Running = Running::new();
|
||||
static WATCH: DesignWatch = DesignWatch::new();
|
||||
let token = "0123456789abcdef0123456789abcdef";
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let (tx, rx) = channel::<ControlRequest>();
|
||||
// The window names the design once and then leaves it alone: nothing moves it, so the
|
||||
// events thread has nothing to write and only the end of the connection can retire it.
|
||||
std::thread::spawn(move || {
|
||||
for req in rx {
|
||||
if req.method == "control.subscribe" {
|
||||
WATCH.publish("d-1", 3);
|
||||
let _ = req.reply.send(json!({"ok": true, "result": {"document_id": "d-1", "revision": 3}}));
|
||||
} else {
|
||||
let _ = req.reply.send(json!({"ok": true, "result": req.method}));
|
||||
}
|
||||
}
|
||||
});
|
||||
std::thread::spawn(move || {
|
||||
for stream in listener.incoming().flatten() {
|
||||
let tx = tx.clone();
|
||||
std::thread::spawn(move || serve_with(stream, token, tx, egui::Context::default(), false, WAITS, &RUNNING, &WATCH));
|
||||
}
|
||||
});
|
||||
let s = TcpStream::connect(addr).unwrap();
|
||||
s.set_read_timeout(Some(Duration::from_secs(10))).unwrap();
|
||||
let mut out = s.try_clone().unwrap();
|
||||
let mut lines = BufReader::new(s);
|
||||
writeln!(out, "{}", json!({"id": 1, "method": "control.subscribe", "token": token})).unwrap();
|
||||
let mut l = String::new();
|
||||
lines.read_line(&mut l).unwrap();
|
||||
let reply: Value = serde_json::from_str(&l).unwrap();
|
||||
assert!(reply["ok"] == true, "{reply}");
|
||||
assert!(WATCH.subscribed(), "the connection is subscribed");
|
||||
// Let the events thread settle into its wait: the design stands still, so it has nothing
|
||||
// to write, and only the end of the connection can retire it.
|
||||
std::thread::sleep(Duration::from_millis(200));
|
||||
// The client goes away without asking anything else.
|
||||
drop((out, lines));
|
||||
let deadline = Instant::now() + Duration::from_millis(400);
|
||||
while WATCH.subscribed() && Instant::now() < deadline {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
assert!(!WATCH.subscribed(), "a closed connection is not counted on the watch");
|
||||
}
|
||||
|
||||
/// A timed-out request that only reads is not said to "still apply", nor is one that only
|
||||
/// writes a file (an export, #1989); a change is, by name.
|
||||
#[test]
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
//! Linux: the desktop's dark or light preference, for Theme: System (#7944).
|
||||
//!
|
||||
//! The window toolkit does not pass it on everywhere: on GNOME (Wayland, or X11 through XWayland)
|
||||
//! the window never learns it, nor when it changes, so the app kept its colours. This reads the
|
||||
//! freedesktop setting through the XDG Desktop Portal's Settings interface on the session bus
|
||||
//! (`org.freedesktop.appearance color-scheme`, then GNOME's `color-scheme` and `gtk-theme`), the
|
||||
//! same setting other applications follow, and inside a Flatpak too. It runs on a thread of its
|
||||
//! own: the first reading, then the portal's `SettingChanged` signal; where the signal can't be
|
||||
//! had, a reading every few seconds. Without a portal it asks `gsettings` instead, on the same
|
||||
//! thread. The window reads the last answer with an atomic load
|
||||
//! (`solidcraft_ui_egui::Services::desktop_dark`), and the decision from the raw values is
|
||||
//! `solidcraft_ui_egui::prefs::desktop_prefers_dark`.
|
||||
|
||||
use std::io::Read;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU8, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
use zbus::zvariant::{OwnedValue, Value};
|
||||
|
||||
const UNKNOWN: u8 = 0;
|
||||
const DARK: u8 = 1;
|
||||
const LIGHT: u8 = 2;
|
||||
|
||||
/// How often to read again where the portal's change signal is not available.
|
||||
const POLL: Duration = Duration::from_secs(5);
|
||||
/// How long one `gsettings` reading may take before it is given up.
|
||||
const GSETTINGS_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
|
||||
const PORTAL: &str = "org.freedesktop.portal.Desktop";
|
||||
const PORTAL_PATH: &str = "/org/freedesktop/portal/desktop";
|
||||
const SETTINGS: &str = "org.freedesktop.portal.Settings";
|
||||
const APPEARANCE: &str = "org.freedesktop.appearance";
|
||||
const GNOME: &str = "org.gnome.desktop.interface";
|
||||
|
||||
/// Start following the desktop's preference; the closure answers the latest reading (`None`
|
||||
/// until there is one, or when the desktop says nothing).
|
||||
pub fn start(ctx: &egui::Context) -> Box<dyn Fn() -> Option<bool>> {
|
||||
let state = Arc::new(AtomicU8::new(UNKNOWN));
|
||||
let (thread_state, ctx) = (state.clone(), ctx.clone());
|
||||
if let Err(e) = std::thread::Builder::new().name("desktop-theme".into()).spawn(move || follow(&thread_state, &ctx)) {
|
||||
log::warn!("desktop theme: no thread to follow it: {e}");
|
||||
}
|
||||
Box::new(move || match state.load(Ordering::Relaxed) {
|
||||
DARK => Some(true),
|
||||
LIGHT => Some(false),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Keep `state` on the desktop's preference, asking for a frame whenever it changes.
|
||||
fn follow(state: &AtomicU8, ctx: &egui::Context) {
|
||||
let publish = |dark: Option<bool>| {
|
||||
let code = match dark {
|
||||
Some(true) => DARK,
|
||||
Some(false) => LIGHT,
|
||||
None => UNKNOWN,
|
||||
};
|
||||
if state.swap(code, Ordering::Relaxed) != code {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
};
|
||||
let portal = match portal() {
|
||||
Ok(p) => Some(p),
|
||||
Err(e) => {
|
||||
log::info!("desktop theme: no settings portal ({e}); asking gsettings");
|
||||
None
|
||||
}
|
||||
};
|
||||
// The portal first; gsettings where there is none or it says nothing (its backend missing).
|
||||
let read = |portal: Option<&zbus::blocking::Proxy<'static>>| portal.and_then(read_portal).or_else(read_gsettings);
|
||||
let from_portal = portal.as_ref().and_then(read_portal);
|
||||
let first = from_portal.or_else(read_gsettings);
|
||||
publish(first);
|
||||
// Wait for the portal's signal only when the portal answers: else the reading is gsettings',
|
||||
// which only a new reading notices.
|
||||
if let Some(p) = portal.as_ref().filter(|_| from_portal.is_some()) {
|
||||
match p.receive_signal("SettingChanged") {
|
||||
Ok(changes) => {
|
||||
for message in changes {
|
||||
if relevant(&message) {
|
||||
publish(read(Some(p)));
|
||||
}
|
||||
}
|
||||
log::info!("desktop theme: the portal's change signal ended; reading every few seconds");
|
||||
}
|
||||
Err(e) => log::info!("desktop theme: no change signal ({e}); reading every few seconds"),
|
||||
}
|
||||
} else if portal.is_none() && first.is_none() && !gsettings_available() {
|
||||
// Neither the portal nor gsettings: nothing to follow; the window toolkit's theme stays.
|
||||
return;
|
||||
}
|
||||
loop {
|
||||
std::thread::sleep(POLL);
|
||||
publish(read(portal.as_ref()));
|
||||
}
|
||||
}
|
||||
|
||||
/// The portal's Settings interface on the session bus.
|
||||
fn portal() -> zbus::Result<zbus::blocking::Proxy<'static>> {
|
||||
let connection = zbus::blocking::Connection::session()?;
|
||||
zbus::blocking::Proxy::new(&connection, PORTAL, PORTAL_PATH, SETTINGS)
|
||||
}
|
||||
|
||||
/// One reading through the portal.
|
||||
fn read_portal(portal: &zbus::blocking::Proxy<'static>) -> Option<bool> {
|
||||
let appearance = read_setting(portal, APPEARANCE, "color-scheme").and_then(|v| as_u32(&v));
|
||||
// The GNOME settings only matter when the freedesktop one has no preference.
|
||||
if matches!(appearance, Some(1 | 2)) {
|
||||
return solidcraft_ui_egui::prefs::desktop_prefers_dark(appearance, None, None);
|
||||
}
|
||||
let gnome = read_setting(portal, GNOME, "color-scheme").and_then(|v| as_string(&v));
|
||||
let gtk_theme = read_setting(portal, GNOME, "gtk-theme").and_then(|v| as_string(&v));
|
||||
solidcraft_ui_egui::prefs::desktop_prefers_dark(appearance, gnome.as_deref(), gtk_theme.as_deref())
|
||||
}
|
||||
|
||||
/// A setting through `ReadOne` (portal version 2), else the older `Read`.
|
||||
fn read_setting(portal: &zbus::blocking::Proxy<'static>, namespace: &str, key: &str) -> Option<OwnedValue> {
|
||||
let one: zbus::Result<OwnedValue> = portal.call("ReadOne", &(namespace, key));
|
||||
one.or_else(|_| -> zbus::Result<OwnedValue> { portal.call("Read", &(namespace, key)) }).ok()
|
||||
}
|
||||
|
||||
/// Whether a `SettingChanged` signal is about a setting the preference is read from.
|
||||
fn relevant(message: &zbus::Message) -> bool {
|
||||
let body = message.body();
|
||||
let Ok((namespace, key, _)) = body.deserialize::<(String, String, OwnedValue)>() else { return false };
|
||||
matches!((namespace.as_str(), key.as_str()), (APPEARANCE, "color-scheme") | (GNOME, "color-scheme" | "gtk-theme"))
|
||||
}
|
||||
|
||||
/// The value inside the variants `Read` wraps it in (a portal answers one or two deep).
|
||||
fn unwrap_variants<'v, 'a>(value: &'v Value<'a>) -> &'v Value<'a> {
|
||||
let mut value = value;
|
||||
for _ in 0..4 {
|
||||
match value {
|
||||
Value::Value(inner) => value = &**inner,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
fn as_u32(value: &Value<'_>) -> Option<u32> {
|
||||
match unwrap_variants(value) {
|
||||
Value::U32(n) => Some(*n),
|
||||
Value::I32(n) => u32::try_from(*n).ok(),
|
||||
Value::U8(n) => Some(u32::from(*n)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_string(value: &Value<'_>) -> Option<String> {
|
||||
match unwrap_variants(value) {
|
||||
Value::Str(s) => Some(s.as_str().to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Without a portal: GNOME's settings through `gsettings` (`None` when it is not there).
|
||||
fn read_gsettings() -> Option<bool> {
|
||||
let gnome = gsettings("color-scheme");
|
||||
let gtk_theme = gsettings("gtk-theme");
|
||||
solidcraft_ui_egui::prefs::desktop_prefers_dark(None, gnome.as_deref(), gtk_theme.as_deref())
|
||||
}
|
||||
|
||||
fn gsettings_available() -> bool {
|
||||
gsettings("gtk-theme").is_some()
|
||||
}
|
||||
|
||||
/// `gsettings get org.gnome.desktop.interface <key>`, its quoted answer, or `None` when the
|
||||
/// program is missing, fails or does not answer in time.
|
||||
fn gsettings(key: &str) -> Option<String> {
|
||||
let mut child = std::process::Command::new("gsettings")
|
||||
.args(["get", GNOME, key])
|
||||
.stdin(std::process::Stdio::null())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.spawn()
|
||||
.ok()?;
|
||||
let started = std::time::Instant::now();
|
||||
loop {
|
||||
match child.try_wait() {
|
||||
Ok(Some(status)) if status.success() => break,
|
||||
Ok(None) if started.elapsed() < GSETTINGS_TIMEOUT => std::thread::sleep(Duration::from_millis(20)),
|
||||
_ => {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut out = String::new();
|
||||
child.stdout.take()?.take(4096).read_to_string(&mut out).ok()?;
|
||||
let value = out.trim().trim_matches('\'').to_string();
|
||||
(!value.is_empty()).then_some(value)
|
||||
}
|
||||
@@ -5,12 +5,25 @@
|
||||
//! for recovery as a forced quit does, and starts again ([`restart`]), and the new start says what
|
||||
//! happened ([`note`]). A device lost again soon after such a restart starts the next one on the
|
||||
//! software renderer, which doesn't depend on the graphics driver.
|
||||
//!
|
||||
//! The old process ends without tearing down its GPU objects ([`end`]): on a lost NVIDIA device
|
||||
//! destroying the window's swap chain busy-waits in the driver and never returns (#9044).
|
||||
|
||||
use crate::startup;
|
||||
|
||||
/// Set on the start after a lost device: when the device was lost (seconds since 1970).
|
||||
pub const LOST_ENV: &str = "SOLIDCRAFT_DEVICE_LOST";
|
||||
|
||||
/// Set on the start after a lost device: why it was lost, as wgpu said it. The old process's
|
||||
/// session journal, which recorded it, is gone by then.
|
||||
pub const REASON_ENV: &str = "SOLIDCRAFT_DEVICE_LOST_REASON";
|
||||
|
||||
/// The longest reason passed on ([`REASON_ENV`]) and shown, in characters.
|
||||
const REASON_CHARS: usize = 300;
|
||||
|
||||
/// How long the process may take to end ([`end`]) before it is aborted.
|
||||
const END_GRACE: std::time::Duration = std::time::Duration::from_secs(3);
|
||||
|
||||
/// A loss this recent (seconds) counts for the start after it: its note, and a second loss
|
||||
/// within it starts on the software renderer. Inherited by later starts, an older stamp is
|
||||
/// ignored.
|
||||
@@ -32,27 +45,54 @@ pub fn restart_on_software(after_recent_loss: bool, cpu_renderer: bool) -> bool
|
||||
after_recent_loss || cpu_renderer
|
||||
}
|
||||
|
||||
/// `reason` on one line, at most [`REASON_CHARS`] long; None when there is nothing to say.
|
||||
pub fn reason(reason: Option<&str>) -> Option<String> {
|
||||
let line = reason?.split_whitespace().collect::<Vec<_>>().join(" ");
|
||||
(!line.is_empty()).then(|| line.chars().take(REASON_CHARS).collect())
|
||||
}
|
||||
|
||||
/// What the start after a lost device tells the user, `software` when it runs on the software
|
||||
/// renderer.
|
||||
pub fn note(software: bool) -> String {
|
||||
/// renderer, with what the driver reported ([`REASON_ENV`]).
|
||||
pub fn note(software: bool, reason: Option<&str>) -> String {
|
||||
let mut note = String::from(
|
||||
"The graphics device was reset (the graphics driver stopped responding), so SolidCraft closed and started again. Unsaved changes were kept for recovery.",
|
||||
);
|
||||
if software {
|
||||
note.push_str(" This start uses software rendering, which doesn't depend on the graphics driver.");
|
||||
}
|
||||
if let Some(reason) = self::reason(reason) {
|
||||
note.push_str(&format!(" The graphics driver reported: {reason}"));
|
||||
}
|
||||
note
|
||||
}
|
||||
|
||||
/// Start SolidCraft again with the same arguments, the loss stamped at `lost_at`, on the software
|
||||
/// renderer when `software`.
|
||||
pub fn restart(software: bool, lost_at: u64) {
|
||||
let Ok(exe) = std::env::current_exe() else { return };
|
||||
/// The command that starts `exe` again with `args`, the loss stamped at `lost_at` and its
|
||||
/// `reason`, on the software renderer when `software`.
|
||||
fn command(
|
||||
exe: std::path::PathBuf,
|
||||
args: impl IntoIterator<Item = std::ffi::OsString>,
|
||||
software: bool,
|
||||
lost_at: u64,
|
||||
reason: &str,
|
||||
) -> std::process::Command {
|
||||
let mut command = std::process::Command::new(exe);
|
||||
command.args(std::env::args_os().skip(1)).env(LOST_ENV, lost_at.to_string());
|
||||
command.args(args).env(LOST_ENV, lost_at.to_string());
|
||||
match self::reason(Some(reason)) {
|
||||
Some(reason) => command.env(REASON_ENV, reason),
|
||||
// Not one inherited from an earlier loss.
|
||||
None => command.env_remove(REASON_ENV),
|
||||
};
|
||||
if software {
|
||||
command.env(startup::RENDERER_ENV, "cpu");
|
||||
}
|
||||
command
|
||||
}
|
||||
|
||||
/// Start SolidCraft again with the same arguments, the loss stamped at `lost_at` and its `reason`,
|
||||
/// on the software renderer when `software`.
|
||||
pub fn restart(software: bool, lost_at: u64, reason: &str) {
|
||||
let Ok(exe) = std::env::current_exe() else { return };
|
||||
let mut command = command(exe, std::env::args_os().skip(1), software, lost_at, reason);
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
@@ -64,6 +104,23 @@ pub fn restart(software: bool, lost_at: u64) {
|
||||
}
|
||||
}
|
||||
|
||||
/// End the process now, without tearing down what is left on the lost device: the window's swap
|
||||
/// chain, the viewport's buffers and pipelines. On NVIDIA's Vulkan driver destroying the swap
|
||||
/// chain of a lost device busy-waits forever, which left the old window frozen at 100% of a core
|
||||
/// beside the new one (#9044). Should the exit itself get stuck in a library's exit handler, the
|
||||
/// process is aborted after [`END_GRACE`].
|
||||
pub fn end() -> ! {
|
||||
let watchdog = std::thread::Builder::new().name("solidcraft-exit".into()).spawn(|| {
|
||||
std::thread::sleep(END_GRACE);
|
||||
eprintln!("SolidCraft graphics: still closing after the device was lost; aborting");
|
||||
std::process::abort();
|
||||
});
|
||||
if let Err(e) = watchdog {
|
||||
log::warn!("graphics: no exit watchdog: {e}");
|
||||
}
|
||||
std::process::exit(0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Only a recent, well-formed stamp counts: a later start that inherited it says nothing.
|
||||
@@ -84,8 +141,34 @@ mod tests {
|
||||
assert!(!super::restart_on_software(false, false));
|
||||
assert!(super::restart_on_software(true, false));
|
||||
assert!(super::restart_on_software(false, true));
|
||||
assert!(super::note(true).contains("software rendering"));
|
||||
assert!(!super::note(false).contains("software rendering"));
|
||||
assert!(super::note(false).contains("kept for recovery"));
|
||||
assert!(super::note(true, None).contains("software rendering"));
|
||||
assert!(!super::note(false, None).contains("software rendering"));
|
||||
assert!(super::note(false, None).contains("kept for recovery"));
|
||||
}
|
||||
|
||||
/// The start after a loss is told why (#9044): the old process's journal held the reason, and
|
||||
/// it is deleted as that process closes.
|
||||
#[test]
|
||||
fn the_next_start_is_told_why_the_device_was_lost() {
|
||||
let exe = std::path::PathBuf::from("solidcraft");
|
||||
let args = ["--control".into(), "7979".into()];
|
||||
let command = super::command(exe.clone(), args, true, 1_000, "Lost: Device lost\n (vkQueueSubmit)");
|
||||
let env = |command: &std::process::Command, name: &str| {
|
||||
command.get_envs().find(|(k, _)| *k == name).map(|(_, v)| v.map(|v| v.to_string_lossy().into_owned()))
|
||||
};
|
||||
assert_eq!(env(&command, super::LOST_ENV), Some(Some("1000".into())));
|
||||
assert_eq!(env(&command, super::REASON_ENV), Some(Some("Lost: Device lost (vkQueueSubmit)".into())), "on one line");
|
||||
assert_eq!(env(&command, crate::startup::RENDERER_ENV), Some(Some("cpu".into())));
|
||||
assert_eq!(command.get_args().collect::<Vec<_>>(), ["--control", "7979"]);
|
||||
// No reason: none inherited from an earlier loss either.
|
||||
let command = super::command(exe, Vec::new(), false, 1_000, " ");
|
||||
assert_eq!(env(&command, super::REASON_ENV), Some(None));
|
||||
assert_eq!(env(&command, crate::startup::RENDERER_ENV), None);
|
||||
|
||||
let note = super::note(false, Some("Lost: Device lost"));
|
||||
assert!(note.ends_with("The graphics driver reported: Lost: Device lost"), "{note}");
|
||||
assert!(!super::note(false, Some(" \n ")).contains("reported"));
|
||||
let long = "x".repeat(1_000);
|
||||
assert_eq!(super::reason(Some(&long)).map(|r| r.chars().count()), Some(300));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
mod app_icon;
|
||||
mod come_forward;
|
||||
mod control_server;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod desktop_theme;
|
||||
mod device_lost;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod native_crash;
|
||||
@@ -202,13 +204,29 @@ impl eframe::App for App {
|
||||
}
|
||||
solidcraft_ui_egui::recovery_ui::close(&mut self.solve);
|
||||
solidcraft_ui_egui::open_elsewhere::close(&mut self.solve);
|
||||
// Before a restart below starts the next instance, which would otherwise get nothing from
|
||||
// the 3D mouse driver (`solidcraft_3dx_client::stop`).
|
||||
// Before a restart (`Drop for App`) starts the next instance, which would otherwise get
|
||||
// nothing from the 3D mouse driver (`solidcraft_3dx_client::stop`).
|
||||
#[cfg(target_os = "macos")]
|
||||
solidcraft_3dx_client::stop();
|
||||
solidcraft_engine::crash::end_session();
|
||||
if let Some(lost_at) = self.gpu.as_ref().and_then(|g| g.lost_at) {
|
||||
device_lost::restart(self.gpu.as_ref().is_some_and(|g| g.restart_on_software), lost_at);
|
||||
// The next start (after a lost device, or into an update) begins once the app is dropped
|
||||
// (`Drop for App`), when the settings are on disk.
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for App {
|
||||
/// eframe drops its settings storage first, which waits for `app.ron` to be written, then the
|
||||
/// app, then the window and its GPU surface. So the next start begins here: started from
|
||||
/// `on_exit`, it read `app.ron` while the old process was still writing it, found it
|
||||
/// unreadable and moved it aside, resetting every setting (#9044).
|
||||
fn drop(&mut self) {
|
||||
if let Some(gpu) = &self.gpu
|
||||
&& let Some(lost_at) = gpu.lost_at
|
||||
{
|
||||
device_lost::restart(gpu.restart_on_software, lost_at, &gpu.reason);
|
||||
// The window's GPU surface is still to be dropped, and on a lost device that may
|
||||
// never return (#9044).
|
||||
device_lost::end();
|
||||
}
|
||||
// An update asked to restart into the new version or to run its installer.
|
||||
if let Some((program, args)) = solidcraft_ui_egui::update::take_launch(&mut self.solve) {
|
||||
@@ -236,6 +254,8 @@ struct LostWatch {
|
||||
restart_on_software: bool,
|
||||
/// When the loss was seen: the app is closing to start again.
|
||||
lost_at: Option<u64>,
|
||||
/// Why, as wgpu said it: passed to the next start ([`device_lost::REASON_ENV`]).
|
||||
reason: String,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@@ -249,6 +269,7 @@ impl App {
|
||||
eprintln!("SolidCraft graphics: the device was lost ({reason}); starting again");
|
||||
solidcraft_engine::crash::phase(&format!("graphics device lost: {reason}"));
|
||||
gpu.lost_at = Some(device_lost::now_secs());
|
||||
gpu.reason = reason;
|
||||
self.solve.quit_requested = true;
|
||||
}
|
||||
}
|
||||
@@ -422,6 +443,12 @@ fn services(cc: &eframe::CreationContext<'_>, folder: &DialogFolder) -> Services
|
||||
graphics_adapters: Vec::new(),
|
||||
graphics_path: graphics_path().map(|p| p.to_string_lossy().to_string()),
|
||||
window_system: window_system_now(),
|
||||
// Linux: the desktop's dark or light setting, which the window is not told on every
|
||||
// desktop (#7944). Windows and macOS: the window's own theme.
|
||||
#[cfg(target_os = "linux")]
|
||||
desktop_dark: Some(desktop_theme::start(&cc.egui_ctx)),
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
desktop_dark: None,
|
||||
http_get: Some(std::sync::Arc::new(http_get)),
|
||||
http_download: Some(std::sync::Arc::new(http_download)),
|
||||
// Already an installed app: only the browser build offers to install.
|
||||
@@ -750,6 +777,16 @@ fn main() -> eframe::Result {
|
||||
#[cfg(target_os = "macos")]
|
||||
objc2_foundation::NSProcessInfo::processInfo().setProcessName(objc2_foundation::ns_string!("SolidCraft"));
|
||||
mark("main");
|
||||
// On OCLP-patched Macs, wgpu picks a Metal Shading Language standard that the system's
|
||||
// compiler refuses (`invalid value 'metal3.2'`), because the patched OS reports a newer
|
||||
// macOS version than the GPU's Metal compiler supports. Re-launching with
|
||||
// SYSTEM_VERSION_COMPAT=1 makes the OS report the real (older) version so wgpu selects
|
||||
// a standard the compiler accepts. The variable must be set before the process starts, so
|
||||
// we detect OCLP here and re-exec immediately, before any macOS framework call (#3080, #4605).
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Err(e) = startup::relaunch_with_version_compat() {
|
||||
log::warn!("startup: OCLP check failed (continuing normally): {e}");
|
||||
}
|
||||
// Validate before legacy adoption, crash markers or any user preference read.
|
||||
let settings = settings_dir().map_err(|error| eframe::Error::AppCreation(error.into()))?;
|
||||
if std::env::var_os("SOLIDCRAFT_SETTINGS_DIR").is_none() {
|
||||
@@ -821,7 +858,11 @@ fn main() -> eframe::Result {
|
||||
// The launch before this one closed because its graphics device was lost (`App::watch_device`).
|
||||
let after_loss = device_lost::recent(std::env::var(device_lost::LOST_ENV).ok().as_deref(), device_lost::now_secs());
|
||||
if after_loss {
|
||||
notes.push(device_lost::note(cpu_renderer));
|
||||
let reason = std::env::var(device_lost::REASON_ENV).ok();
|
||||
if let Some(reason) = device_lost::reason(reason.as_deref()) {
|
||||
log::warn!("graphics: the last launch lost its device ({reason})");
|
||||
}
|
||||
notes.push(device_lost::note(cpu_renderer, reason.as_deref()));
|
||||
}
|
||||
if safe_mode {
|
||||
notes.push("Safe mode: default settings (yours are kept for the next normal start), no recovery offer, software rendering.".into());
|
||||
@@ -961,6 +1002,7 @@ fn main() -> eframe::Result {
|
||||
lost: rs.device_lost.clone(),
|
||||
restart_on_software: device_lost::restart_on_software(after_loss, cpu_renderer),
|
||||
lost_at: None,
|
||||
reason: String::new(),
|
||||
});
|
||||
if !safe_mode {
|
||||
app.preferences.graphics_adapter =
|
||||
@@ -1016,6 +1058,10 @@ fn main() -> eframe::Result {
|
||||
app.session.doc_mut().name = "Sample Plate".into();
|
||||
app.session.mark_saved();
|
||||
app.session.undo.clear();
|
||||
// Built straight into the session, so nothing asked for a fit: frame it at the
|
||||
// home view as any opened design is (#9195). The fit waits for the first layout.
|
||||
app.cam.set_view(solidcraft_engine::render::StandardView::Iso);
|
||||
app.fit_view();
|
||||
}
|
||||
// Lock files next to open designs: a design open on another computer says so (#5467),
|
||||
// the files given at launch included.
|
||||
@@ -1099,12 +1145,13 @@ fn main() -> eframe::Result {
|
||||
}
|
||||
|
||||
/// egui-wgpu is about to start a step of getting the graphics device and the window's surface up:
|
||||
/// the crash journal keeps it, and the adapter once it is picked.
|
||||
/// the crash journal keeps it until the app runs (a window opened later goes through the same
|
||||
/// steps), and the adapter once it is picked.
|
||||
fn startup_step(step: &'static str, detail: &str) {
|
||||
if step == eframe::egui_wgpu::STEP_ADAPTER_CHOSEN {
|
||||
solidcraft_engine::crash::set_environment(&format!("Renderer: {detail}"));
|
||||
}
|
||||
solidcraft_engine::crash::phase(step);
|
||||
solidcraft_engine::crash::startup_step(step);
|
||||
}
|
||||
|
||||
/// The renderer settings: with `cpu`, the software adapter (WARP, lavapipe, llvmpipe). The
|
||||
|
||||
@@ -101,6 +101,7 @@ impl NativeMenu {
|
||||
])?;
|
||||
for (action, label) in [
|
||||
("docs", "Documentation"),
|
||||
("updates", app.tr("update.check_for_updates")),
|
||||
("shortcuts", "Keyboard Shortcuts"),
|
||||
("messages", "Messages\u{2026}"),
|
||||
("report", "Report an Issue\u{2026}"),
|
||||
|
||||
@@ -292,6 +292,71 @@ pub fn window_instance_flags(flags: eframe::wgpu::InstanceFlags, intel_mac: bool
|
||||
if intel_mac && env.map(str::trim).is_none_or(str::is_empty) { flags - eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL } else { flags }
|
||||
}
|
||||
|
||||
/// The environment variable that makes the macOS compatibility shim report an older OS
|
||||
/// version to wgpu's Metal backend. On OCLP-patched machines the Metal compiler accepts
|
||||
/// only up to the MSL standard of the original GPU, not the one the patched OS reports,
|
||||
/// so wgpu picks a standard that the compiler refuses (`invalid value 'metal3.2'`).
|
||||
/// Setting this variable before the process starts causes the OS to report the older
|
||||
/// version and wgpu selects a supported MSL standard (#3080, #4605).
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const SYSTEM_VERSION_COMPAT_ENV: &str = "SYSTEM_VERSION_COMPAT";
|
||||
|
||||
/// The NVRAM variable that OpenCore Legacy Patcher writes on every OCLP-booted system.
|
||||
/// Its presence is the primary signal that `SYSTEM_VERSION_COMPAT=1` is needed.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const OCLP_NVRAM_KEY: &str = "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version";
|
||||
|
||||
/// `true` if the OCLP NVRAM key is present on this system.
|
||||
///
|
||||
/// Runs `nvram <key>` and treats exit 0 as present. Any error (missing binary,
|
||||
/// permission denied, key absent) returns `false` — this is a best-effort probe.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn oclp_nvram_present() -> bool {
|
||||
std::process::Command::new("nvram").arg(OCLP_NVRAM_KEY).output().map(|o| o.status.success()).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Whether to re-launch with `SYSTEM_VERSION_COMPAT=1`: it is not set yet and OCLP shows through
|
||||
/// the NVRAM key. The probe runs only when it is needed, so a re-launched process (variable
|
||||
/// set) never starts `nvram`.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn compat_wanted(compat_set: bool, nvram: impl FnOnce() -> bool) -> bool {
|
||||
!compat_set && nvram()
|
||||
}
|
||||
|
||||
/// If this process is running under OCLP and `SYSTEM_VERSION_COMPAT` has not been set,
|
||||
/// re-launch the current binary with `SYSTEM_VERSION_COMPAT=1` added to the environment,
|
||||
/// then exit with the child's status code.
|
||||
///
|
||||
/// `SYSTEM_VERSION_COMPAT=1` must be present **before** the process starts: setting it
|
||||
/// with `std::env::set_var` inside `main` is too late because the macOS frameworks have
|
||||
/// already queried the OS version by then. Re-launching is the only safe approach that
|
||||
/// works without `unsafe` (a true `execve` replacement would require it).
|
||||
///
|
||||
/// Returns `Ok(false)` immediately when:
|
||||
/// - `SYSTEM_VERSION_COMPAT` is already set (re-launched process, no loop), or
|
||||
/// - the OCLP NVRAM key is absent.
|
||||
///
|
||||
/// Returns `Err` only when `std::env::current_exe()` fails or the child process cannot
|
||||
/// be spawned; the caller should log the error and continue normally.
|
||||
///
|
||||
/// Never returns `Ok(true)`: a successful re-launch exits the current process.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn relaunch_with_version_compat() -> Result<bool, String> {
|
||||
// A set variable means this is the re-launched process: no loop.
|
||||
if !compat_wanted(std::env::var_os(SYSTEM_VERSION_COMPAT_ENV).is_some(), oclp_nvram_present) {
|
||||
return Ok(false);
|
||||
}
|
||||
log::info!("startup: OCLP detected; re-launching with {}=1", SYSTEM_VERSION_COMPAT_ENV);
|
||||
eprintln!("SolidCraft: OCLP detected; re-launching with {}=1", SYSTEM_VERSION_COMPAT_ENV);
|
||||
let exe = std::env::current_exe().map_err(|e| format!("could not find own executable: {e}"))?;
|
||||
let status = std::process::Command::new(&exe)
|
||||
.args(std::env::args_os().skip(1))
|
||||
.env(SYSTEM_VERSION_COMPAT_ENV, "1")
|
||||
.status()
|
||||
.map_err(|e| format!("could not re-launch with {}: {e}", SYSTEM_VERSION_COMPAT_ENV))?;
|
||||
std::process::exit(status.code().unwrap_or(1));
|
||||
}
|
||||
|
||||
/// Windows with OpenGL: the window keeps the system title bar (#2063). The window without OS
|
||||
/// decorations keeps its caption style while having no frame, and some OpenGL drivers (older
|
||||
/// Intel HD/UHD) then show the picture a caption's height lower than the window, so it no longer
|
||||
@@ -414,6 +479,27 @@ mod tests {
|
||||
assert_eq!(window_instance_flags(on, false, None), on);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn oclp_relaunch_needs_the_signal_and_no_compat_variable() {
|
||||
use super::compat_wanted;
|
||||
let probed = std::cell::Cell::new(false);
|
||||
let probe = |found: bool| {
|
||||
let probed = &probed;
|
||||
move || {
|
||||
probed.set(true);
|
||||
found
|
||||
}
|
||||
};
|
||||
// The re-launched process has the variable: no probe, no second re-launch.
|
||||
assert!(!compat_wanted(true, probe(true)));
|
||||
assert!(!probed.get());
|
||||
// The OCLP NVRAM key is the signal.
|
||||
assert!(compat_wanted(false, probe(true)));
|
||||
// No signal: an ordinary Mac starts as it is.
|
||||
assert!(!compat_wanted(false, probe(false)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switches_read_from_the_environment() {
|
||||
assert!(env_on(Some("1")) && env_on(Some("yes")) && !env_on(Some("0")) && !env_on(Some(" ")) && !env_on(None) && !env_on(Some("false")));
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'.
|
||||
Copyright 2014-2021 Google Inc. with Reserved Font Name 'Noto'.
|
||||
Subset for SolidCraft web UI (glyphs used by the zh locale); renamed Craft UI SC (no Reserved Font Name).
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License,
|
||||
Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font
|
||||
creation efforts of academic and linguistic communities, and to
|
||||
provide a free and open framework in which fonts may be shared and
|
||||
improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply to
|
||||
any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software
|
||||
components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to,
|
||||
deleting, or substituting -- in part or in whole -- any of the
|
||||
components of the Original Version, by changing formats or by porting
|
||||
the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed,
|
||||
modify, redistribute, and sell modified and unmodified copies of the
|
||||
Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in
|
||||
Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the
|
||||
corresponding Copyright Holder. This restriction only applies to the
|
||||
primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created using
|
||||
the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,96 @@
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'.
|
||||
Copyright 2014-2021 Google Inc. with Reserved Font Name 'Noto'.
|
||||
Subset for SolidCraft web UI (glyphs used by the zh-TW locale); renamed Craft UI TC (no Reserved Font Name).
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License,
|
||||
Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font
|
||||
creation efforts of academic and linguistic communities, and to
|
||||
provide a free and open framework in which fonts may be shared and
|
||||
improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply to
|
||||
any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software
|
||||
components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to,
|
||||
deleting, or substituting -- in part or in whole -- any of the
|
||||
components of the Original Version, by changing formats or by porting
|
||||
the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed,
|
||||
modify, redistribute, and sell modified and unmodified copies of the
|
||||
Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in
|
||||
Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the
|
||||
corresponding Copyright Holder. This restriction only applies to the
|
||||
primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created using
|
||||
the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -188,7 +188,7 @@ surface = [
|
||||
sketch = [
|
||||
"arc3", "arc_center", "arc_slot", "arc_slot_center", "arc_tangent",
|
||||
"blend", "circle", "circle2", "circle3", "circle_tt",
|
||||
"circle_ttt", "conic", "constrainer", "dimension", "ellipse",
|
||||
"circle_ttt", "conic", "constrainer", "dimension", "ellipse", "equation_curve",
|
||||
"extend", "finish", "fit_section", "include",
|
||||
"intersect", "intersection_curve", "iso_curve", "line", "line_mid",
|
||||
"offset", "offset_two_sides", "offset_symmetric", "point", "polygon", "polygon_circumscribed", "polygon_edge",
|
||||
@@ -204,7 +204,10 @@ constraint = [
|
||||
"c_polygon", "c_smooth", "c_symmetry", "c_tangent",
|
||||
]
|
||||
construction = [
|
||||
"centerline", "construction", "infinite",
|
||||
"centerline", "construction", "construction_line", "construction_line_angle",
|
||||
"construction_line_bisector", "construction_line_horizontal", "construction_line_parallel",
|
||||
"construction_line_perpendicular", "construction_line_tangent_at", "construction_line_tangent_external",
|
||||
"construction_line_tangent_two", "construction_line_vertical", "infinite",
|
||||
]
|
||||
mesh = [
|
||||
"mesh_body",
|
||||
|
||||
@@ -70,6 +70,16 @@ configuration_table false
|
||||
conic false
|
||||
constrainer false
|
||||
construction false
|
||||
construction_line false
|
||||
construction_line_angle false
|
||||
construction_line_bisector false
|
||||
construction_line_horizontal false
|
||||
construction_line_parallel false
|
||||
construction_line_perpendicular false
|
||||
construction_line_tangent_at false
|
||||
construction_line_tangent_external false
|
||||
construction_line_tangent_two false
|
||||
construction_line_vertical false
|
||||
contact_all false
|
||||
contact_new false
|
||||
contact_off false
|
||||
@@ -95,6 +105,7 @@ edit false
|
||||
ellipse false
|
||||
emboss false
|
||||
environment_map false
|
||||
equation_curve false
|
||||
error false
|
||||
explode false
|
||||
export false
|
||||
@@ -190,6 +201,7 @@ polygon false
|
||||
polygon_circumscribed false
|
||||
polygon_edge false
|
||||
presspull false
|
||||
print_face false
|
||||
project false
|
||||
project_surface false
|
||||
rack_pinion false
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Construction line through two points</title>
|
||||
<path d="M8 52L56 12" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round" stroke-dasharray="10 5"/>
|
||||
<circle cx="20" cy="42" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="20" cy="42" r="3.4" fill="#236ead"/>
|
||||
<circle cx="44" cy="22" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="44" cy="22" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 472 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Construction line at an angle</title>
|
||||
<path d="M10.26 48.66L58.26 48.66" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M28.65 33.23A24 24 0 0 1 34.26 48.66" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M10.26 48.66L54.26 11.66" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="10.26" cy="48.66" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="10.26" cy="48.66" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 646 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Angle bisector</title>
|
||||
<path d="M13.92 12.18L9.92 52.17L54.92 44.17" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M12.11 30.29A22 22 0 0 1 31.58 48.33" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M9.92 52.17L47.3 11.83" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 526 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Horizontal construction line</title>
|
||||
<path d="M8 32L56 32" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round" stroke-dasharray="10 5"/>
|
||||
<circle cx="32" cy="32" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="32" cy="32" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 362 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Parallel construction line</title>
|
||||
<path d="M9 37L41 9" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M23 55L55 27" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round" stroke-dasharray="10 5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 380 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Perpendicular construction line</title>
|
||||
<path d="M8 44L56 44" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 8L32 56" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 34L42 34L42 44" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 490 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Tangent at a curve point</title>
|
||||
<circle cx="32" cy="34.26" r="17" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M8 17.26L56 17.26" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="17.26" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="32" cy="17.26" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 480 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Tangent through an external point</title>
|
||||
<circle cx="21.74" cy="38.77" r="14" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M53.6 8.23L28.55 55.9" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="51.74" cy="11.77" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="51.74" cy="11.77" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 502 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Common tangent to two curves</title>
|
||||
<circle cx="20" cy="33.59" r="12" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="46" cy="33.59" r="8" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M6 19.27L58 27.36" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 509 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Vertical construction line</title>
|
||||
<path d="M32 8L32 56" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round" stroke-dasharray="10 5"/>
|
||||
<circle cx="32" cy="32" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="32" cy="32" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 360 B |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Equation curve</title>
|
||||
<path d="M12 8L12 56M6 32L58 32" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M12 32C15.42 24.83 18.72 18 22.5 18C26.28 18 29.58 24.83 33 32C36.42 39.17 39.72 46 43.5 46C47.28 46 50.58 39.17 54 32" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="32" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="12" cy="32" r="3.4" fill="#236ead"/>
|
||||
<circle cx="54" cy="32" r="5.8" fill="#ffffff"/>
|
||||
<circle cx="54" cy="32" r="3.4" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 666 B |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Print Face</title>
|
||||
<path d="M9.72 26.17L4.5 20.95L4.5 40.85L9.72 46.07Z" fill="#b8c3cf"/>
|
||||
<path d="M9.72 26.17L4.5 20.95L4.5 40.85L9.72 46.07Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.77 23.15L9.72 26.17L9.72 46.07L18.77 43.05Z" fill="#328bd3"/>
|
||||
<path d="M18.77 23.15L9.72 26.17L9.72 46.07L18.77 43.05Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M13.55 17.93L18.77 23.15L9.72 26.17L4.5 20.95Z" fill="#e2e8ef"/>
|
||||
<path d="M13.55 17.93L18.77 23.15L9.72 26.17L4.5 20.95Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M50.45 37.54L38.27 25.35L38.27 33.88L50.45 46.07Z" fill="#b8c3cf"/>
|
||||
<path d="M50.45 37.54L38.27 25.35L38.27 33.88L50.45 46.07Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M59.5 34.53L50.45 37.54L50.45 46.07L59.5 43.05Z" fill="#8e9faf"/>
|
||||
<path d="M59.5 34.53L50.45 37.54L50.45 46.07L59.5 43.05Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M47.31 22.34L59.5 34.53L50.45 37.54L38.27 25.35Z" fill="#e2e8ef"/>
|
||||
<path d="M47.31 22.34L59.5 34.53L50.45 37.54L38.27 25.35Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M50.45 46.07L38.27 33.88" fill="none" stroke="#236ead" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M59.5 43.05L50.45 46.07" fill="none" stroke="#236ead" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M24.17 34.2L28.31 34.2" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M35.31 34.2L27.31 38.7L27.31 29.7Z" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "سطح مزج",
|
||||
"BOUNDARY SURFACE": "سطح حدودي",
|
||||
"BROWSER": "المستعرض",
|
||||
"Back to the original order": "العودة إلى الترتيب الأصلي",
|
||||
"Ball": "كروي",
|
||||
"Bar": "قضيب",
|
||||
"Base Center": "مركز القاعدة",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "الحواف",
|
||||
"Edit": "تعديل",
|
||||
"Edit Profile Sketch": "تعديل رسم المقطع",
|
||||
"Edit shortcuts": "تعديل الاختصارات",
|
||||
"Enable rule": "تفعيل القاعدة",
|
||||
"Enabled": "مفعّل",
|
||||
"End Radius": "نصف القطر النهائي",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "نصف القطر",
|
||||
"Radius Fit": "ملاءمة نصف القطر",
|
||||
"Ratio": "النسبة",
|
||||
"Read-only list: shortcuts can't be changed here.": "قائمة للقراءة فقط: لا يمكن تغيير الاختصارات هنا.",
|
||||
"Reattach selected face": "إعادة ربط الوجه المحدد",
|
||||
"Recover": "استعادة",
|
||||
"Recover unsaved design?": "استعادة التصميم غير المحفوظ؟",
|
||||
@@ -593,6 +596,8 @@
|
||||
"Snap to face and edge centres": "الالتقاط إلى مراكز الأوجه والحواف",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "لا يستطيع SolidCraft إرسال التقارير مباشرةً. أرسلها على GitHub؛ لا حاجة إلى رمز وصول في التطبيق.",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "أُغلق SolidCraft قبل حفظ هذه التصاميم. يمكن فتح آخر حفظ تلقائي لها.",
|
||||
"Sort A to Z": "فرز تصاعدي",
|
||||
"Sort Z to A": "فرز تنازلي",
|
||||
"Spacing 2 must be a non-zero number": "يجب أن يكون التباعد 2 عددًا غير صفري",
|
||||
"Spacing must be a non-zero number": "يجب أن يكون التباعد عددًا غير صفري",
|
||||
"Specialise": "تخصيص",
|
||||
@@ -730,7 +735,7 @@
|
||||
"a picked edge is gone": "الحافة المحددة لم تعد موجودة",
|
||||
"a picked edge's body is gone": "جسم الحافة المحددة لم يعد موجودًا",
|
||||
"add a key for a joint first": "أضف أولًا مفتاحًا لمفصل",
|
||||
"ai.connected_toast": "أصبح SolidCraft متاحًا في {clients}. أعد تشغيلها لاستخدامه (الإعدادات > المساعد).",
|
||||
"ai.connected_toast": "أصبح SolidCraft متاحًا في {clients}. أعد تشغيلها لاستخدامه (التفضيلات > المساعد).",
|
||||
"ai.prefs.allow_control": "السماح لوكلاء الذكاء الاصطناعي بالاتصال (قناة التحكم / MCP)",
|
||||
"ai.prefs.allow_control_note": "يفتح قناة تحكم على هذا الحاسوب فقط (127.0.0.1، المنفذ 27878 أو أول منفذ متاح بعده). على البرنامج الذي يتصل أن يقدّم أيضًا رمزًا سريًا لا يقرؤه إلا حساب المستخدم الخاص بك، ويُنشأ من جديد عند كل تشغيل. يُطبّق في المرة القادمة التي يبدأ فيها SolidCraft. عند الإيقاف: لا شيء يستمع ما لم تشغّل SolidCraft مع --control.",
|
||||
"ai.prefs.availability": "عناصر تحكم المساعد",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "عند الوجه",
|
||||
"bom.group_children": "الأجزاء الفرعية في صف الجزء الأصلي",
|
||||
"browser.body_name": "جسم {number}",
|
||||
"browser.calibrate_click_a": "انقر على الصورة لتحديد النقطة A، أو اكتب إحداثياتها.",
|
||||
"browser.calibrate_click_b": "انقر على الصورة لتحديد النقطة B، أو اكتب إحداثياتها.",
|
||||
"browser.calibrate_title": "معايرة: {name}",
|
||||
"browser.capture_many": "تم تحريك {count} مكوّنات دون تثبيت مواضعها.",
|
||||
"browser.capture_note": "التثبيت يحتفظ بالموضع الجديد، والإرجاع يعيده كما كان.",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "التقاط المظهر",
|
||||
"cmd.appearance_replace": "استبدال المظهر",
|
||||
"cmd.assembly_bom": "قائمة المواد",
|
||||
"cmd.body.print_face": "وجه الطباعة",
|
||||
"cmd.body_rename": "إعادة تسمية الجسم",
|
||||
"cmd.browser_collapse_all": "طي الكل",
|
||||
"cmd.browser_expand_all": "توسيع الكل",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "نقل عناصر المستعرض",
|
||||
"cmd.browser_order": "ترتيب عناصر المستعرض",
|
||||
"cmd.browser_rename_group": "إعادة تسمية المجموعة",
|
||||
"cmd.browser_reparent": "نقل إلى مكوّن",
|
||||
"cmd.browser_ungroup": "فك التجميع",
|
||||
"cmd.browser_visibility": "إظهار/إخفاء",
|
||||
"cmd.canvas_calibrate": "معايرة اللوحة",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "خصائص القطعة",
|
||||
"cmd.component_metadata_set": "تغيير خصائص القطعة",
|
||||
"cmd.component_move_bodies": "نقل الأجسام إلى مكوّن",
|
||||
"cmd.component_move_features": "نقل الميزات إلى مكوّن",
|
||||
"cmd.component_move_sketches": "نقل الرسومات إلى مكوّن",
|
||||
"cmd.component_paste_from_design": "لصق من تصميم آخر",
|
||||
"cmd.component_paste_new": "لصق كجديد",
|
||||
"cmd.component_properties": "الخصائص الفيزيائية للمكوّن",
|
||||
"cmd.component_relink": "إعادة ربط المصدر",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "تصيير صورة",
|
||||
"cmd.render_status": "تقدّم التصيير",
|
||||
"cmd.select_clear": "مسح التحديد",
|
||||
"cmd.settings_profile_apply": "تطبيق ملف تعريف الإعدادات",
|
||||
"cmd.settings_profile_delete": "حذف ملف تعريف الإعدادات",
|
||||
"cmd.settings_profile_export": "تصدير ملف تعريف الإعدادات",
|
||||
"cmd.settings_profile_import": "استيراد ملف تعريف الإعدادات",
|
||||
"cmd.settings_profile_list": "ملفات تعريف الإعدادات",
|
||||
"cmd.settings_profile_rename": "إعادة تسمية ملف تعريف الإعدادات",
|
||||
"cmd.settings_profile_save": "حفظ ملف تعريف الإعدادات",
|
||||
"cmd.sheet_convert": "تحويل إلى صفائح معدنية",
|
||||
"cmd.sheet_export_bend_table": "تصدير جدول الثني",
|
||||
"cmd.sheet_export_dxf": "تصدير النمط المسطح بصيغة DXF",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "إعادة الطي",
|
||||
"cmd.sheet_rules": "قائمة قواعد الصفائح المعدنية",
|
||||
"cmd.sheet_unfold": "فرد",
|
||||
"cmd.sketch.construction_line": "خط إنشائي",
|
||||
"cmd.sketch.construction_line.angle": "خط إنشائي بزاوية",
|
||||
"cmd.sketch.construction_line.bisector": "منصف الزاوية",
|
||||
"cmd.sketch.construction_line.horizontal": "خط إنشائي أفقي",
|
||||
"cmd.sketch.construction_line.parallel": "خط إنشائي موازٍ",
|
||||
"cmd.sketch.construction_line.perpendicular": "خط إنشائي عمودي",
|
||||
"cmd.sketch.construction_line.tangent_at": "مماس عند نقطة على المنحنى",
|
||||
"cmd.sketch.construction_line.tangent_external": "مماس يمر بنقطة خارجية",
|
||||
"cmd.sketch.construction_line.tangent_two": "مماس مشترك",
|
||||
"cmd.sketch.construction_line.vertical": "خط إنشائي رأسي",
|
||||
"cmd.sketch_arc3d": "قوس ثلاثي الأبعاد",
|
||||
"cmd.sketch_arc_center_point": "قوس بنقطة مركز",
|
||||
"cmd.sketch_arc_tangent": "قوس مماسي",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "حجم الرسمة",
|
||||
"cmd.sketch_edit": "تعديل الرسم",
|
||||
"cmd.sketch_edit_text": "تعديل النص",
|
||||
"cmd.sketch_equation_curve": "منحنى معادلة",
|
||||
"cmd.sketch_equation_curve_edit": "تحرير منحنى المعادلة",
|
||||
"cmd.sketch_export_dxf": "حفظ بصيغة DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "إنهاء مع التقييد التلقائي",
|
||||
"cmd.sketch_fit_curves_to_section": "ملاءمة منحنيات لمقطع الشبكة",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "متصفح التصيير",
|
||||
"cmd.view.render_dock": "نقل لوحة التصيير",
|
||||
"cmd.view.render_focus": "عرض تركيز التصيير",
|
||||
"cmd.view.status_items": "عناصر حالة منطقة العرض",
|
||||
"cmd.view_ambient_occlusion": "الإظلال المحيطي",
|
||||
"cmd.view_angle_readout": "زوايا العرض",
|
||||
"cmd.view_apply": "استعادة عرض مسمّى",
|
||||
@@ -1374,6 +1405,18 @@
|
||||
"help.occurrence.move": "يحرّك جزءًا في التجميع فقط ضمن درجات الحرية التي تسمح بها مفاصله. حدد وجهًا للجزء، ثم اسحب سهمًا أو قوسًا متاحًا.",
|
||||
"help.parameters.change": "يفتح جدول القيم المسماة والتعبيرات التي تتحكم في أبعاد التصميم. استخدمه لتغيير مقاس في مكان واحد فتتبعه كل الميزات التي تستخدمه.",
|
||||
"help.pointcloud.insert": "أدرج مسحًا بصيغة PLY أو XYZ أو PTS كسحابة نقاط بجانب النموذج. استخدمه كمرجع عند النمذجة انطلاقًا من بيانات القياس.",
|
||||
"help.sketch.construction_line": "أنشئ خطًا إنشائيًا لا نهائيًا يمر بنقطتين. استخدمه لتخطيط الرسم دون تقسيم مقاطعه.",
|
||||
"help.sketch.construction_line.angle": "أنشئ خطًا إنشائيًا لا نهائيًا بزاوية من محور X للرسم. اختر النقطة ثم اكتب الزاوية، أو اختر اتجاهه.",
|
||||
"help.sketch.construction_line.bisector": "اختر خطين مستقيمين متقاطعين في الرسم، ثم اختر أحد منصفي الزاوية. يتبع الناتج الخطين اللذين أُنشئ منهما.",
|
||||
"help.sketch.construction_line.horizontal": "أنشئ خطًا إنشائيًا أفقيًا لا نهائيًا يمر بنقطة. يحافظ القيد الأفقي على الاتجاه بعد التعديلات.",
|
||||
"help.sketch.construction_line.parallel": "اختر خطًا مستقيمًا في الرسم ثم ضع خطًا إنشائيًا لا نهائيًا موازيًا له. انقر بزر الفأرة الأيمن لتغيير المرجع.",
|
||||
"help.sketch.construction_line.perpendicular": "اختر خطًا مستقيمًا في الرسم ثم ضع خطًا إنشائيًا لا نهائيًا عموديًا عليه. انقر بزر الفأرة الأيمن لتغيير المرجع.",
|
||||
"help.sketch.construction_line.tangent_at": "أنشئ مماسًا عند نقطة على دائرة أو قوس دائري، أو عند نهاية منحنى شريحي مفتوح أو قطع مخروطي مفتوح. اختر المنحنى ثم نقطة التماس.",
|
||||
"help.sketch.construction_line.tangent_external": "اختر دائرة أو قوسًا دائريًا، ثم نقطة خارجية وحل المماس. تعرض المعاينة نقاط التماس الواقعة على القوس المرسوم فقط.",
|
||||
"help.sketch.construction_line.tangent_two": "اختر دائرتين أو قوسين دائريين ثم اختر مماسًا مشتركًا من المعاينة. يجب أن تقع نقطتا التماس على المنحنيين المرسومين.",
|
||||
"help.sketch.construction_line.vertical": "أنشئ خطًا إنشائيًا رأسيًا لا نهائيًا يمر بنقطة. يحافظ القيد الرأسي على الاتجاه بعد التعديلات.",
|
||||
"help.sketch.equation_curve": "يرسم منحنى من صيغ على مدى: x(t) و y(t)، أو y = f(x). يمكن أن تستخدم الصيغ المعلمات فيتبعها المنحنى: استخدمه لموجة جيبية أو لولب أو منحنى انفلات لسن ترس.",
|
||||
"help.sketch.inspect": "يفتح تقريرًا عن الرسم المفتوح: عدد درجات الحرية المتبقية وهل هو مقيد بالكامل. استخدمه لمعرفة ما لا يزال يتحرك قبل إنهاء الرسم.",
|
||||
"help.solid.align": "يحرّك الأجسام المحددة بحيث تلتقي نقطة أو وجه أو مستوى منها بنقطة أو وجه أو مستوى في مكان آخر. استخدمه لوضع قطعة ملاصقة لأخرى دون قياس المسافة.",
|
||||
"help.solid.chamfer": "يقطع الحواف المحددة بشطفة مستوية بالمسافة التي تحددها. استخدمه لكسر الحواف الحادة أو لتسهيل إدخال مسمار أو برغي.",
|
||||
"help.solid.combine": "يضم الأجسام، أو يقتطعها من جسم هدف، أو يُبقي الحجم المشترك بينها فقط، ويمكنه الاحتفاظ بأجسام الأداة. استخدمه لدمج القطع، أو لقطع شكل بشكل آخر، أو لمعرفة موضع تداخل جسمين.",
|
||||
@@ -1467,7 +1510,7 @@
|
||||
"home.recovery_hint": "أُغلق SolidCraft قبل حفظ هذه التصاميم.",
|
||||
"home.report_issue": "الإبلاغ عن مشكلة",
|
||||
"home.samples": "أمثلة",
|
||||
"home.settings": "الإعدادات",
|
||||
"home.settings": "التفضيلات",
|
||||
"home.short_date": "{day} {month}",
|
||||
"home.shortcuts": "اختصارات لوحة المفاتيح",
|
||||
"home.start_hint": "أنشئ تصميمًا، أو افتح ملفًا حديثًا، أو استكشف مثالًا.",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "مواد مختلفة",
|
||||
"measure.at": "عند",
|
||||
"measure.item": "العنصر {number}",
|
||||
"measure.quick_copied": "تم نسخ القياس",
|
||||
"measure.quick_copy": "انقر لنسخ القياس",
|
||||
"measure.quick_edges": "{count} حواف",
|
||||
"measure.quick_faces": "{count} أوجه",
|
||||
"messages.ago_h": "قبل {n} ساعة",
|
||||
"messages.ago_min": "قبل {n} دقيقة",
|
||||
"messages.ago_s": "قبل {n} ث",
|
||||
@@ -1642,7 +1689,7 @@
|
||||
"navbar.custom.hidden_design": "مخفي في التصميم",
|
||||
"navbar.custom.hidden_render": "مخفي في التصيير",
|
||||
"navbar.custom.hide": "إخفاء شريط التنقل",
|
||||
"navbar.custom.hide_idle": "إخفاء حتى التمرير",
|
||||
"navbar.custom.hide_idle": "إخفاء حتى يمر المؤشر فوقه",
|
||||
"navbar.custom.icon_only": "الأيقونة فقط",
|
||||
"navbar.custom.icon_value": "الأيقونة والقيمة",
|
||||
"navbar.custom.icons": "الأيقونات",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "ليس تحريكًا",
|
||||
"not a number": "ليس عددًا",
|
||||
"open a sketch first": "افتح رسمًا أولًا",
|
||||
"parameters.apply_live": "طبّق كل تغيير عند مغادرة حقله",
|
||||
"parameters.apply_live_tip": "عند الإيقاف: تنتظر التغييرات حتى «تطبيق» أو «موافق»، ثم يُعاد بناء التصميم مرة واحدة لها جميعًا. «إلغاء» أو Escape يتجاهلها.",
|
||||
"parameters.held": "{count} تغييرات بانتظار «تطبيق»",
|
||||
"parameters.held_hint": "عدّل التعابير والوحدات. تنتظر التغييرات «تطبيق» أو «موافق».",
|
||||
"parameters.held_one": "تغيير واحد بانتظار «تطبيق»",
|
||||
"parts.automatic_name": "تلقائي",
|
||||
"parts.dimension.across_flats": "مقاس المفتاح",
|
||||
"parts.dimension.bore": "قطر الثقب",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "السماكة",
|
||||
"parts.dimension.width": "العرض",
|
||||
"parts.family.bearing": "محمل كريات أخدودي عميق (الغلاف)",
|
||||
"parts.family.button_head_cap_screw": "برغي برأس زرّي بتجويف سداسي",
|
||||
"parts.family.dowel_pin": "مسمار توجيه أسطواني",
|
||||
"parts.family.hex_bolt": "برغي سداسي الرأس",
|
||||
"parts.family.hex_nut": "صامولة سداسية",
|
||||
"parts.family.set_screw": "برغي تثبيت بتجويف سداسي، طرف مسطح",
|
||||
"parts.family.socket_head_cap_screw": "برغي برأس أسطواني بتجويف سداسي",
|
||||
"parts.family.washer": "حلقة مسطحة",
|
||||
"parts.holes": "الثقوب (اختياري)",
|
||||
"parts.placement_hint": "اختر ثقبًا أو أكثر لتثبيت قطعة في كل منها، أو اضغط موافق لوضعها عند نقطة الأصل",
|
||||
"pattern.alignment_2": "المحاذاة 2",
|
||||
"pattern.alignment_hint": "العدد يشمل الأصل. «توسيط» يوازن النسخ؛ و«قلب» يختار الجانب الإضافي عندما يكون العدد زوجيًا.",
|
||||
"pattern.direction_1": "الاتجاه 1",
|
||||
@@ -1801,8 +1856,10 @@
|
||||
"prefs.bottom_centre": "أسفل الوسط",
|
||||
"prefs.bottom_right": "أسفل اليمين",
|
||||
"prefs.browser": "المستعرض",
|
||||
"prefs.browser_reveal_on_hover": "إظهار عند التمرير",
|
||||
"prefs.browser_show_note": "«ظاهر» يُبقي المستعرض على الشاشة. «إظهار عند التمرير» يُخفيه حتى يمر المؤشر فوق مكانه أو فوق الشريط الرفيع عند حافته اليسرى، ويبقى مفتوحًا ما دام المؤشر داخله أو كانت قائمة منه مفتوحة.",
|
||||
"prefs.browser_eye_left": "أيقونة الإظهار بجانب سهم الطي",
|
||||
"prefs.browser_eye_left_note": "تعرض صفوف المستعرض أيقونة الإظهار بجانب سهم الطي كما كانت من قبل، بدلاً من عمود في الطرف الأيمن للصفوف.",
|
||||
"prefs.browser_reveal_on_hover": "إظهار عند مرور المؤشر",
|
||||
"prefs.browser_show_note": "«ظاهر» يُبقي المستعرض على الشاشة. «إظهار عند مرور المؤشر» يُخفيه حتى يمر المؤشر فوق مكانه أو فوق الشريط الرفيع عند حافته اليسرى، ويبقى مفتوحًا ما دام المؤشر داخله أو كانت قائمة منه مفتوحة.",
|
||||
"prefs.browser_shown": "ظاهر",
|
||||
"prefs.built_in": "مدمج",
|
||||
"prefs.button_left": "سحب بالزر الأيسر",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "يُطبَّق بعد إعادة تشغيل SolidCraft. يتجاوز WGPU_ADAPTER_NAME هذا الاختيار.",
|
||||
"prefs.graphics_note": "وازن بين السرعة والنعومة. كل خيار يعرض أثره على عيّنة.",
|
||||
"prefs.graphics_presets_note": "الإعدادات المسبقة تضبط الخيارات أدناه معًا.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "إخفاء رموز القيود عند التصغير",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "تختفي رموز القيود عندما تُصغَّر المسودة بما يكفي حتى لا تزحم العرض. معطّل: تبقى بحجم شاشة ثابت عند أي تكبير.",
|
||||
"prefs.history": "السجل",
|
||||
"prefs.history_origin_bodies": "إظهار الأصل والأجسام في الأعلى",
|
||||
"prefs.history_origin_bodies_note": "يبدأ السجل على اليسار أو تحت المستعرض بمجلد الأجسام للمكوّن النشط وبالأصل، مع أيقونات الإظهار والقوائم كما في المستعرض. لا يتغير السجل في الأسفل.",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "المضغوط يثبّت اللوحات على حواف النافذة. شفافية المستعرض متاحة في الوضع العائم. غيّر جهة المساعد من صفحة المساعد.",
|
||||
"prefs.left": "يسار",
|
||||
"prefs.left_click": "نقر أيسر",
|
||||
"prefs.line_drag_draws_one": "الضغط والسحب يرسم خطًا واحدًا",
|
||||
"prefs.line_drag_draws_one_note": "في أداة الخط، الضغط ثم السحب ثم الإفلات يرسم خطًا واحدًا من نقطة الضغط إلى نقطة الإفلات وينتهي هناك. لا تزال النقرات ترسم سلسلة. عند الإيقاف: يضع السحب نقطة حيث يُفلت، كما تفعل النقرة.",
|
||||
"prefs.linked_designs": "التصاميم المرتبطة",
|
||||
"prefs.live_input": "الإدخال المباشر",
|
||||
"prefs.live_preview": "المعاينة المباشرة",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "ملفات STEP والاستيراد",
|
||||
"prefs.max_file_size_web": "يفتح تطبيق الويب ملفات STEP والاستيراد حتى 512 MB والتصاميم حتى 256 MB؛ لا يتسع تبويب المتصفح لملفات أكبر. يمكن رفع هذه الحدود في تطبيق سطح المكتب.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "أيقونات كبيرة",
|
||||
"prefs.menu_list": "قائمة",
|
||||
"prefs.menus": "القوائم",
|
||||
"prefs.minutes": "دقائق",
|
||||
"prefs.minutes_suffix": " دقيقة",
|
||||
"prefs.mouse": "الفأرة ولوحة اللمس",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "أسماء مستويات الأصل",
|
||||
"prefs.origin_plane_names_note": "الأسماء المعروضة في المستعرض والحوارات والقوائم. {top} هو XY و{front} هو XZ و{right} هو YZ، والمحور Z للأعلى. تحتفظ الأوامر والسكربتات والتصاميم المحفوظة بـ XY وXZ وYZ.",
|
||||
"prefs.overall_speed": "السرعة العامة",
|
||||
"prefs.parameter_list_rows": "صفوف قائمة المعاملات",
|
||||
"prefs.parameter_list_rows_tip": "يعرض السهم لأسفل في حقل قيمة فارغ المعاملات، المفضلة أولًا، حتى هذا العدد. العدد الأقل يبقي القائمة خفيفة في التصميم الكبير.",
|
||||
"prefs.persistent_ribbon_pressed": "تمييز أوامر الشريط النشطة",
|
||||
"prefs.persistent_ribbon_pressed_help": "تمييز أوامر الشريط أثناء تفعيل تأثيراتها. أوقف هذا الخيار للاحتفاظ بالمظهر المحايد السابق ومساعدة الأوامر.",
|
||||
"prefs.perspective_fov": "مجال الرؤية",
|
||||
"prefs.placement": "الموضع",
|
||||
"prefs.prefer_free_sketch_points": "تفضيل نقاط الرسم القابلة للتحريك عند تداخل النقاط",
|
||||
"prefs.preview_choices": "معاينة اختياراتك",
|
||||
"prefs.project_options_dialog": "مربع حوار خيارات Project",
|
||||
"prefs.print_face_highlight": "إبراز وجه الطباعة",
|
||||
"prefs.print_face_highlight_tip": "مدى قوة تلوين وجه الطباعة للجسم وتحديده في العرض. 0 % لا يُظهر أي إبراز.",
|
||||
"prefs.profile_active": "ملف التعريف النشط",
|
||||
"prefs.profile_applied": "تم تطبيق ملف التعريف.",
|
||||
"prefs.profile_changed": "تغيّرت الإعدادات منذ حفظ ملف التعريف. «حفظ» يحفظها فيه.",
|
||||
"prefs.profile_deleted": "تم حذف ملف التعريف.",
|
||||
"prefs.profile_export": "تصدير…",
|
||||
"prefs.profile_exported": "تم تصدير ملف التعريف.",
|
||||
"prefs.profile_imported": "تم استيراد ملف التعريف. اختره في «ملف التعريف النشط» للتبديل إليه.",
|
||||
"prefs.profile_name_hint": "اسم ملف التعريف، مثل: حاسوب محمول",
|
||||
"prefs.profile_rename": "إعادة تسمية",
|
||||
"prefs.profile_renamed": "تمت إعادة تسمية ملف التعريف.",
|
||||
"prefs.profile_save": "حفظ",
|
||||
"prefs.profile_saved": "تم حفظ الإعدادات الحالية في ملف التعريف.",
|
||||
"prefs.profile_skipped": "تم تطبيق ملف التعريف؛ احتفظ {n} من الإعدادات بقيمها الحالية (راجع السجل).",
|
||||
"prefs.profiles": "ملفات تعريف الإعدادات",
|
||||
"prefs.profiles_note": "الاختصارات وشريط الأدوات والتنقل والقائمة الدائرية وإعدادات الواجهة، محفوظة معًا تحت اسم واحد وتُبدَّل دفعة واحدة.",
|
||||
"prefs.project_options_dialog": "مربع حوار خيارات الإسقاط",
|
||||
"prefs.project_options_dialog_note": "تشغيل: اختر الهندسة أو الأجسام ورابط الإسقاط قبل الإسقاط. إيقاف: الإبقاء على سير العمل السابق بالاختيار المباشر.",
|
||||
"prefs.quality_default": "افتراضي",
|
||||
"prefs.quality_fastest": "الأسرع",
|
||||
"prefs.quality_slowest": "الأبطأ",
|
||||
"prefs.quality_smoother": "أنعم",
|
||||
"prefs.quick_measure": "قياس سريع في زاوية العرض",
|
||||
"prefs.quick_measure_note": "مقاس العناصر المحددة في الزاوية اليمنى السفلية من العرض: طول الحافة (أو Ø وR للحافة الدائرية)، ومساحة الوجه، وموضع النقطة، والمسافة والزاوية بين عنصرين، ومجموع عدة حواف أو أوجه. النقر ينسخه.",
|
||||
"prefs.render_previous_geometry_budget": "استخدام ميزانية الهندسة السابقة لمعاينة التصيير",
|
||||
"prefs.render_previous_geometry_budget_help": "استعادة حد الهندسة الثابت السابق (512 ميبيبايت على سطح المكتب 64 بت، و128 ميبيبايت على المنصات الأخرى) بدلًا من الميزانية المعتمدة على الجهاز.",
|
||||
"prefs.reports_saved": "{n} محفوظة",
|
||||
"prefs.ribbon_reveal": "إظهار مكان نتائج البحث في الشريط",
|
||||
"prefs.ribbon_reveal_note": "عند تمرير المؤشر فوق نتيجة في «البحث في الأوامر» يظهر مكان الأمر في الشريط: تبويبه أو زره أو صفه في القائمة المنسدلة للوحة. ويومض هناك الأمر الذي بدأ من البحث، ويُعلِّم الأمر الجاري من قائمة منسدلة لوحتَه.",
|
||||
"prefs.right_click": "نقر أيمن",
|
||||
"prefs.saving": "الحفظ التلقائي والاستعادة",
|
||||
"prefs.scale_note": "أو Ctrl + / Ctrl − في النافذة. الأزرار 28 px عند 100%.",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "لا توجد إعدادات مطابقة",
|
||||
"prefs.select": "تحديد",
|
||||
"prefs.select_one_item": "تحديد عنصر واحد",
|
||||
"prefs.select_other_hidden": "تحديد العناصر الهندسية المخفية باستخدام «تحديد عنصر آخر»",
|
||||
"prefs.select_other_hidden_help": "عند التفعيل: تضمين الأجسام والمخططات المخفية والحواف المحجوبة قرب المؤشر. عند التعطيل: استخدام القائمة الأصلية للعناصر الهندسية المرئية أسفل المؤشر.",
|
||||
"prefs.selecting": "التحديد",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift يضيف فقط، وCtrl / Cmd يبدّل",
|
||||
"prefs.shift_add_note": "عند التشغيل: Shift يضيف، وCtrl / Cmd يبدّل. عند الإيقاف (الافتراضي): كلاهما يبدّل.",
|
||||
"prefs.shortcuts": "الاختصارات",
|
||||
"prefs.single_surface_analysis": "استخدام تحليل سطح واحد",
|
||||
"prefs.single_surface_analysis_help": "عند إيقاف هذا الخيار، يمكن إبقاء تظليل السطح وتحليل الاستمرارية مفعّلين معًا. عند تشغيله، يبقى آخر تحليل تم بدؤه أو تغييره فقط.",
|
||||
"prefs.sketch_align_points": "المحاذاة مع نقاط الرسم الأخرى أثناء الرسم",
|
||||
"prefs.sketch_align_points_note": "أثناء الرسم، تتحاذى النقطة أفقيًا مع نقطة رسم وعموديًا مع نقطة أخرى في الوقت نفسه، مع خط إرشادي منقط، وتحتفظ النقرة بالمحاذاتين. عند الإيقاف: مع النقطة السابقة فقط، محور واحد في كل مرة.",
|
||||
"prefs.sketch_conflict_colour": "الهندسة المتعارضة بلون التعارض",
|
||||
"prefs.sketch_conflict_colour_note": "عندما تتعارض قيود الرسم، تُرسم المنحنيات والنقاط التي يمسكها قيد فاشل بلون التعارض أيضًا، لا رمزه أو بُعده فقط. عند الإيقاف: تحتفظ بألوانها المعتادة.",
|
||||
"prefs.sketch_construction_lines": "أدوات الخطوط الإنشائية الموسعة",
|
||||
"prefs.sketch_exit_view": "عند انتهاء الرسم",
|
||||
"prefs.sketch_exit_view.keep": "إبقاء العرض الحالي",
|
||||
"prefs.sketch_exit_view.previous": "العودة إلى العرض السابق",
|
||||
"prefs.sketch_exit_view.unless_rotated": "العودة ما لم يُدوَّر العرض",
|
||||
"prefs.sketch_exit_view_note": "أين ينتقل العرض بعد إنهاء الرسم أو الإلغاء أو الضغط على Esc مرتين.",
|
||||
"prefs.sketch_open_look_at": "توجيه العرض نحو الرسم عند فتحه",
|
||||
"prefs.sketch_open_look_at_note": "عند الإيقاف: إنشاء الرسم أو تحريره يُبقي العرض كما هو. يوجّه «النظر إلى» العرض نحو الرسم عند الحاجة.",
|
||||
"prefs.sketch_recent_snap": "الالتقاط التلقائي إلى المراكز ونقاط المنتصف الأخيرة",
|
||||
"prefs.sketch_recent_snap_note": "أثناء الرسم، يلتقط المؤشر الموضع الذي يتقاطع فيه دليلا آخر مركزي دائرتين أو نقطتي منتصف حافتين مستقيمتين. عند الإيقاف: تبقى تلك الأدلة للعرض فقط ولا يتحرك المؤشر.",
|
||||
"prefs.sketch_selection": "الرسم والتحديد",
|
||||
"prefs.sketch_selection_heading": "الرسم والتحديد",
|
||||
"prefs.sketch_selection_note": "كيف تلتقط الرسومات وكيف تحدد النقرات.",
|
||||
@@ -1988,27 +2089,41 @@
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "اضغط على هذا المفتاح فقط للتكبير عند المؤشر بالتمرير العمودي. يحافظ الإيقاف على سلوك التمرير الحالي.",
|
||||
"prefs.trackpad_zoom_modifier.help": "اضغط مع الاستمرار على هذا المفتاح وحده للتكبير عند المؤشر بالتمرير العمودي. عند الإيقاف يبقى سلوك التمرير كما هو.",
|
||||
"prefs.trackpad_zoom_modifier.off": "إيقاف",
|
||||
"prefs.translucent": "شفاف",
|
||||
"prefs.under_browser": "تحت المستعرض",
|
||||
"prefs.under_cursor": "تحت المؤشر",
|
||||
"prefs.units_precision": "الوحدات والدقة",
|
||||
"prefs.updates": "التحديثات",
|
||||
"prefs.value_boxes_in_view": "إظهار القيم بجانب مقابضها في العرض",
|
||||
"prefs.value_boxes_in_view_tip": "قيمة الأمر (المسافة، نصف القطر…) في مربع بجانب مقبضه، فوق النموذج. عند الإيقاف: تكتبها في نافذة الأمر، التي تتلقى لوحة المفاتيح بعد التحديد، ولا شيء يغطي النموذج.",
|
||||
"prefs.view": "سلوك العرض",
|
||||
"prefs.view_confirm_corner": "موافق وإلغاء في زاوية العرض",
|
||||
"prefs.view_confirm_corner_note": "أثناء فتح مربع حوار أو رسم، تؤدي علامة الصح وعلامة الإكس أعلى يمين العرض ما يؤديه زرّا موافق وإلغاء في مربع الحوار، أو تنهي الرسم وتلغيه. وينتقل متصفح العرض إلى أسفلهما.",
|
||||
"prefs.viewport": "منطقة العرض",
|
||||
"prefs.viewport_analysis_status": "إظهار حالة التحليل في منفذ العرض",
|
||||
"prefs.viewport_analysis_status_help": "عرض التحليلات النشطة أعلى منفذ العرض وفتح مفتاح كل تحليل من عنصره. ينهي Esc أحدث تحليل. أوقف الخيار لاستعادة المفاتيح في الزاوية وسلوك Esc السابق.",
|
||||
"prefs.viewport_background": "الخلفية",
|
||||
"prefs.viewport_background_colour": "لون",
|
||||
"prefs.viewport_background_theme": "تدرج السمة",
|
||||
"prefs.viewport_section_status": "إظهار حالة المقطع في منفذ العرض",
|
||||
"prefs.viewport_section_status_help": "عرض إعداد المقطع في منفذ العرض. يُوقف Escape وزر الشريط النشط المقطع. عطّل الخيار للاحتفاظ بأدوات المقطع السابقة.",
|
||||
"prefs.viewport_status_summary": "تلخيص عناصر حالة منفذ العرض",
|
||||
"prefs.viewport_status_summary_help": "اجمع ثلاثة عناصر أو أكثر لحالة منفذ العرض في شارة ملخّصة واحدة. عطّل الخيار لإبقاء كل عنصر في الصف الكامل.",
|
||||
"prefs.wheel": "العجلة",
|
||||
"prefs.wheel_trackpad": "العجلة ولوحة اللمس",
|
||||
"prefs.workspace": "مساحة العمل",
|
||||
"prefs.zoom_stop_at_model": "إيقاف التكبير عند النموذج",
|
||||
"prefs.zoom_stop_at_model_tip": "تُكبّر الفأرة ثلاثية الأبعاد وتطبيق الجهاز نحو السطح في منتصف العرض، ويثبّت التكبير بالسحب نقطة بدء السحب. عند الإيقاف يمكن للتكبير المرور عبر النموذج. تستخدم العجلة وإيماءة القرص إعداد التكبير نحو المؤشر بشكل مستقل",
|
||||
"prefs.zoom_toward_cursor": "التكبير نحو المؤشر",
|
||||
"properties.title": "الخصائص: {name}",
|
||||
"recovery.days_ago": "قبل {count} يوم",
|
||||
"recovery.detail": "{file} · {features} ميزة · حُفظ تلقائيًا {when}",
|
||||
"recovery.discard_all": "تجاهل الكل",
|
||||
"recovery.discard_all_detail": "لا يمكن التراجع عن هذا الإجراء.",
|
||||
"recovery.discard_all_title": "تجاهل {count} من عمليات الحفظ التلقائي؟",
|
||||
"recovery.discard_all_title_one": "تجاهل حفظ تلقائي واحد؟",
|
||||
"recovery.hours_ago": "قبل {count} ساعة",
|
||||
"recovery.just_now": "الآن",
|
||||
"recovery.min_ago": "قبل {count} دقيقة",
|
||||
@@ -2702,7 +2817,7 @@
|
||||
"render.light_intensity": "الشدة",
|
||||
"render.light_missing": "هذا الضوء لم يعد موجودًا. اختر ضوءًا في المتصفح.",
|
||||
"render.light_place_highlight": "وضع بالتمييز",
|
||||
"render.light_place_pending": "الوضع بالتمييز يتطلب اختيار الأضواء في منفذ العرض وهو غير مدعوم بعد.",
|
||||
"render.light_place_pending": "الوضع بالتمييز يتطلب اختيار الأضواء في منطقة العرض وهو غير مدعوم بعد.",
|
||||
"render.light_position": "الموضع",
|
||||
"render.light_preview_help": "العرض الحي بلا ظلال؛ الأضواء المساحية تستخدم تقريب عينة المركز. التصيير يستخدم نموذج الضوء الكامل.",
|
||||
"render.light_product_centre": "مركز المنتج",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "جاهز للتصيير",
|
||||
"render.output_run_check": "تشغيل الفحص",
|
||||
"render.output_size_limit": "{method}: حتى {dimension} بكسل لكل ضلع و{pixels} بكسل. أكبر حجم مناسب: {width} × {height}.",
|
||||
"render.output_size_method_profile": "لتصيير {width} × {height}، اختر {method} مع ملف موارد CPU «{profile}»، أو حجمًا أصغر.",
|
||||
"render.output_size_ok": "الحجم مناسب · {width} × {height} بكسل",
|
||||
"render.output_size_profile": "لتصيير {width} × {height}، اختر ملف موارد CPU «{profile}»، أو حجمًا أصغر.",
|
||||
"render.output_swap_orientation": "تبديل العرض والارتفاع",
|
||||
"render.output_tools_inspector": "عدّل الحجم والصيغة في مفتش المخرجات.",
|
||||
"render.output_view_image": "عرض الصورة",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "مخصص…",
|
||||
"render.size_full_hd": "Full HD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · يتطلب «{profile}»",
|
||||
"render.size_presets": "إعدادات الحجم المسبقة",
|
||||
"render.size_presets_pending": "تصل مع محرر المخرجات",
|
||||
"render.size_preview": "معاينة",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "انقر نقرًا مزدوجًا على مكوّن لتنشيطه، أو لتحرير مكوّن مرتبط في مكانه",
|
||||
"settings.frame_rate_details_note": "يضيف رسمًا لأزمنة الإطارات الأخيرة مع المثلثات المرسومة فوقه، ومدرّجًا تكراريًا لأزمنة الإطارات، وما رسمته وحدة GPU. انقر معدل الإطارات في العرض لإظهارها أو إخفائها.",
|
||||
"settings.frame_rate_note": "يعرض الإطارات في الثانية في الزاوية اليمنى السفلية من العرض. أثناء تفعيله يُعاد رسم العرض باستمرار.",
|
||||
"settings.insert_lists_open_designs": "يعرض إدراج تصميم أولًا التصاميم المفتوحة في علامات التبويب الأخرى",
|
||||
"settings.measure_axis_distances": "إظهار المسافات على X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "إظهار مركّبات الأبعاد على محاور العالم بجانب المسافة الكلية أثناء فتح أداة القياس.",
|
||||
"settings.msaa_applies_on_restart": "يُطبّق تنعيم الحواف في المرة القادمة التي يبدأ فيها SolidCraft",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "محيط",
|
||||
"sheet.flange_type_edge": "حافة",
|
||||
"sheet.no_body": "لا يوجد جسم صفائح معدنية: ابدأ واحدًا من حافة مثنية > أساسية، أو حوّل لوحًا إلى صفائح معدنية بأمر تحويل إلى صفائح معدنية (اختر وجهه المسطح الكبير)",
|
||||
"sheet.personal_rules.confirm_delete": "تأكيد الحذف",
|
||||
"sheet.personal_rules.delete": "حذف",
|
||||
"sheet.personal_rules.delete_prompt": "هل تحذف هذه القاعدة الشخصية؟ القواعد الموجودة في التصاميم لا تتغير.",
|
||||
"sheet.personal_rules.full": "المكتبة الشخصية فيها 64 قاعدة بالفعل.",
|
||||
"sheet.personal_rules.invalid_name": "أدخل اسمًا قصيرًا بلا فواصل أسطر ولا محارف تحكم.",
|
||||
"sheet.personal_rules.invalid_values": "أكمل قيم القاعدة: يجب أن تُحسب كل قيمة في هذا التصميم، بسماكة موجبة ومعامل K من 0 إلى 1.",
|
||||
"sheet.personal_rules.missing": "القاعدة الشخصية المحددة لم تعد متاحة.",
|
||||
"sheet.personal_rules.name": "اسم القاعدة",
|
||||
"sheet.personal_rules.name_exists": "توجد قاعدة شخصية بهذا الاسم. استخدم اسمًا آخر.",
|
||||
"sheet.personal_rules.name_hint": "اسم فريد",
|
||||
"sheet.personal_rules.overwrite": "حفظ التغييرات في القاعدة الشخصية المحددة",
|
||||
"sheet.personal_rules.rename": "إعادة تسمية",
|
||||
"sheet.personal_rules.rule": "القاعدة الشخصية",
|
||||
"sheet.personal_rules.save": "حفظ كجديدة",
|
||||
"sheet.personal_rules.scope": "محفوظة في ملفك الشخصي لكل التصاميم.",
|
||||
"sheet.personal_rules.select": "اختر قاعدة",
|
||||
"sheet.personal_rules.title": "القواعد الشخصية",
|
||||
"sheet.personal_rules.unsupported": "تحتوي هذه القاعدة على قيم لا يستطيع هذا الإصدار استخدامها.",
|
||||
"shortcut.json_error": "يجب أن تكون المعاملات بصيغة JSON: {error}",
|
||||
"shortcut.no_command": "لا يوجد أمر `{id}`، ويجب أن يكون النص قبل JSON معرّف أمر",
|
||||
"shortcut.pin": "تثبيت في أعلى مربع S",
|
||||
"shortcut.unpin": "إلغاء التثبيت",
|
||||
"sketch is missing": "الرسم مفقود",
|
||||
"sketch.degrees_of_freedom": "{count} درجات حرية",
|
||||
"sketch.dimension_added_driven": "الرسم يحدد هذا البُعد بالفعل، لذا أُضيف بُعدًا مُشتقًا (مرجعيًا)",
|
||||
"sketch.dimension_applied": "تم تطبيق البُعد",
|
||||
"sketch.dimension_applied_defined": "تم تطبيق البُعد؛ تم تعريف المعامل `{name}`",
|
||||
"sketch.dimension_applied_renamed": "تم تطبيق البُعد؛ أصبح اسم المعامل `{name}`",
|
||||
"sketch.dof_left": "تبقّت {count} درجات حرية",
|
||||
"sketch.dof_left_one": "تبقّت {count} درجة حرية",
|
||||
"sketch.draw_curves": "الرسم كـ {linetype}",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "يمين",
|
||||
"sketch_text.bold": "غامق",
|
||||
"sketch_text.builtin_font": "{family} (مدمج)",
|
||||
"sketch_text.formula": "ابدأ بـ = لتكوين النص من المعاملات: ='W' + number(Width)",
|
||||
"sketch_text.italic": "مائل",
|
||||
"sketch_text.loading_fonts": "جارٍ البحث عن الخطوط المثبتة…",
|
||||
"sketch_text.on_path": "النص يتبع مساره: المنحنى يحدد موضعه",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "الإبقاء على ميزاتها ومجلداتها الفرعية في السجل",
|
||||
"timeline.delete_folders_with_features_tip": "حذف المجلدات مع كل الميزات التي فيها والمجلدات المتداخلة فيها",
|
||||
"timeline.delete_many": "حذف {count} ميزات محددة",
|
||||
"timeline.edited_rolled_back": "تم تغيير {name}، لكنه يقع بعد مؤشر السجل ولذلك لا يُبنى: انقل المؤشر إلى ما بعده لرؤية النتيجة",
|
||||
"timeline.feature_error": "خطأ: {message}",
|
||||
"timeline.feature_hint": "انقر نقرًا مزدوجًا للتحرير · اسحب لإعادة الترتيب · انقر بالزر الأيمن للمزيد",
|
||||
"timeline.feature_rolled_back": "تم التراجع: بعد مؤشر السجل، لذلك لا يُبنى",
|
||||
"timeline.feature_warning": "تحذير: {message}",
|
||||
"timeline.group": "مجلد ميزات جديد",
|
||||
"timeline.move_many": "نقل عناصر الخط الزمني",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "معايرة الفأرة ثلاثية الأبعاد تصلح المحاور المتبادلة أو المعكوسة وتضبط سرعتها وإحساسها.",
|
||||
"ui.3d_mouse_offer_never": "عدم الإظهار مرة أخرى",
|
||||
"ui.3d_mouse_offer_swap": "التبديل إلى Hidraw",
|
||||
"ui.3d_mouse_orbit": "تدوير العرض",
|
||||
"ui.3d_mouse_orbit_classic": "كلاسيكي",
|
||||
"ui.3d_mouse_orbit_tip": "متتبَّع: تُدير الفأرة ثلاثية الأبعاد العرض حول جزء النموذج الموجود في منتصف العرض عند بدء الدوران، وتُعلّمه بكرة باهتة. كلاسيكي: حول مركز العرض",
|
||||
"ui.3d_mouse_orbit_traced": "متتبَّع",
|
||||
"ui.3d_mouse_reading": "القراءة",
|
||||
"ui.3d_mouse_reset_axes": "إعادة تعيين المحاور",
|
||||
"ui.3d_mouse_reset_view": "إعادة تعيين العرض",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "الفأرة ثلاثية الأبعاد",
|
||||
"ui.3d_mouse_show_in_view": "إظهار الفأرة ثلاثية الأبعاد في العرض ثلاثي الأبعاد",
|
||||
"ui.3d_mouse_show_in_view_tip": "صورة للفأرة ثلاثية الأبعاد في الزاوية السفلية اليسرى، تتحرك كلما حرّكتها.",
|
||||
"ui.3d_mouse_sketch_orbit": "تدوير الرسومات بالفأرة ثلاثية الأبعاد",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "تدير الفأرة ثلاثية الأبعاد العرض أيضًا أثناء فتح رسم ورؤيته من الأمام مباشرة، كما تفعل الفأرة. عند الإيقاف: تُزيح الرسم وتكبّره فقط حتى تُميل العرض.",
|
||||
"ui.3d_mouse_skip": "جهازي لا يستطيع ذلك",
|
||||
"ui.3d_mouse_skip_tip": "يتخطى هذه الحركة في الاتجاهين، وتستبعدها المعايرة.",
|
||||
"ui.3d_mouse_speed": "سرعة الفأرة ثلاثية الأبعاد",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "لُفّ الغطاء عكس عقارب الساعة، وأمسكه، ثم اتركه.",
|
||||
"ui.3d_mouse_switch_cap": "المعايرة كجهاز العودة إلى المركز",
|
||||
"ui.3d_mouse_switch_trackball": "المعايرة ككرة تتبّع",
|
||||
"ui.3d_mouse_use_direct": "المشغل المباشر",
|
||||
"ui.3d_mouse_use_direct_tip": "قراءة الفأرة ثلاثية الأبعاد مباشرة (hidraw) بدلًا من المرور عبر spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "محور العرض",
|
||||
"ui.3d_mouse_view_off": "متوقف",
|
||||
"ui.3d_mouse_view_off_tip": "ملف تعريف مشغّل الفأرة ثلاثية الأبعاد يوقف هذا المحور، فلا تحرك حركتُه العرض. اختيار حركة محور آخر هنا يبادل بينهما، فتتوقف تلك الحركة عن تحريك العرض.",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "إزالة من قائمة الانتظار",
|
||||
"ui.agent_chat_remove_file": "إزالته من هذه الرسالة",
|
||||
"ui.agent_chat_remove_imported": "إزالته من هذه الرسالة؛ تبقى القطعة في التصميم (التراجع يزيلها)",
|
||||
"ui.agent_chat_reply_cut_off": "بلغ الرد حد طوله قبل أن يكتمل، لذا قد يكون ناقصًا. اطلب من الوكيل أن يتابع، أو أن يجيب بإيجاز أكبر.",
|
||||
"ui.agent_chat_reply_declined": "رفض النموذج الإجابة عن هذه الرسالة.",
|
||||
"ui.agent_chat_retry": "إعادة المحاولة",
|
||||
"ui.agent_chat_right": "يمين",
|
||||
"ui.agent_chat_save": "حفظ",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "دائرة",
|
||||
"ui.circular_pattern": "نمط دائري",
|
||||
"ui.clear": "مسح",
|
||||
"ui.clear_print_face": "مسح وجه الطباعة",
|
||||
"ui.clear_recent": "مسح الأخيرة",
|
||||
"ui.clear_the_selection": "مسح التحديد",
|
||||
"ui.click_selects_whole_bodies": "النقر يحدد الأجسام كاملة",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "ثابت",
|
||||
"ui.constraints_conflict": "تعارض في القيود",
|
||||
"ui.construction": "مساعد",
|
||||
"ui.construction.angle_hint": "خط إنشائي: انقر نقطة ثم أدخل زاوية أو اختر اتجاهًا",
|
||||
"ui.construction.bisector_hint": "منصف زاوية: اختر خطين مستقيمين متقاطعين ثم الحل المطلوب",
|
||||
"ui.construction.common_hint": "مماس مشترك: اختر دائرتين/قوسين ثم الحل المطلوب",
|
||||
"ui.construction.contact_hint": "مماس: اختر دائرة/قوسًا أو منحنى شريحيًا/قطعًا مخروطيًا مفتوحًا ثم نقطة التماس (للمنحنيات الحرة: النهايات فقط)",
|
||||
"ui.construction.external_hint": "مماس: اختر دائرة أو قوسًا ثم نقطة خارجية ثم الحل المطلوب",
|
||||
"ui.construction.free_hint": "خط إنشائي: انقر نقطتين؛ انقر بزر الفأرة الأيمن للبدء من جديد",
|
||||
"ui.construction.point_hint": "خط إنشائي: انقر نقطة المرور",
|
||||
"ui.construction.reference_hint": "خط إنشائي: اختر خطًا مستقيمًا ثم نقطة؛ انقر بزر الفأرة الأيمن لتغيير المرجع",
|
||||
"ui.construction.ribbon_label": "خطوط مساعدة",
|
||||
"ui.context_menu": "القائمة السياقية",
|
||||
"ui.continuity_g0": "G0 تجعّد",
|
||||
"ui.continuity_g1": "G1 مماس",
|
||||
@@ -4008,6 +4172,14 @@
|
||||
"ui.end_scale": "مقياس النهاية",
|
||||
"ui.entities": "العناصر",
|
||||
"ui.equal": "متساوٍ",
|
||||
"ui.equation_end": "النهاية",
|
||||
"ui.equation_explicit": "صريح",
|
||||
"ui.equation_form": "الشكل",
|
||||
"ui.equation_note": "المتغير رقم بلا وحدة: تأخذه sin(t) بالراديان. والنتيجة التي بلا وحدة تكون بوحدة التصميم.",
|
||||
"ui.equation_parametric": "بارامتري",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "نصف القطر المكافئ",
|
||||
"ui.expand": "توسيع",
|
||||
"ui.exportDxf": "تصدير DXF…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "التصميم",
|
||||
"ui.heading_draft": "ميل السحب",
|
||||
"ui.heading_edit": "تعديل",
|
||||
"ui.heading_equation_curve": "منحنى معادلة",
|
||||
"ui.heading_extrude": "بثق",
|
||||
"ui.heading_fillet": "تقويس",
|
||||
"ui.heading_finish_editing": "إنهاء التحرير",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "استيراد…",
|
||||
"ui.infinite": "لا نهائي",
|
||||
"ui.insert": "إدراج",
|
||||
"ui.insert_design.browse": "استعراض…",
|
||||
"ui.insert_design.open_designs": "التصاميم المفتوحة",
|
||||
"ui.insert_design.saved_file": "في {name} تغييرات غير محفوظة، لذا أُدرج ملفه المحفوظ. احفظه، ثم استخدم تحديث الروابط لإدخال التغييرات.",
|
||||
"ui.insert_design.unsaved": "تغييرات غير محفوظة",
|
||||
"ui.inspect": "فحص",
|
||||
"ui.intersect": "تقاطع",
|
||||
"ui.isolate": "عزل",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "تعذّرت قراءة {count} مجلد(ات).",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "نقطة",
|
||||
"ui.point_cloud_add_filter": "إضافة مرشح…",
|
||||
"ui.point_cloud_auto_range": "نطاق تلقائي",
|
||||
"ui.point_cloud_color_by": "التلوين حسب",
|
||||
"ui.point_cloud_file_colors": "ألوان الملف",
|
||||
"ui.point_cloud_filter_by": "التصفية حسب",
|
||||
"ui.point_cloud_height_high": "أعلى ارتفاع",
|
||||
"ui.point_cloud_height_low": "أدنى ارتفاع",
|
||||
"ui.point_cloud_legend_filter": "تُعرض وتُخفى في وسيلة الإيضاح أعلاه",
|
||||
"ui.point_cloud_no_file_colors": "لا يحتوي الملف على ألوان",
|
||||
"ui.point_cloud_pause": "إيقاف مؤقت",
|
||||
"ui.point_cloud_play": "تشغيل",
|
||||
"ui.point_cloud_single_color": "لون واحد",
|
||||
"ui.point_cloud_size": "حجم النقطة",
|
||||
"ui.point_cloud_units": "وحدات الملف",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "مضلع",
|
||||
"ui.preferences": "التفضيلات",
|
||||
"ui.press_a_key": "اضغط مفتاحًا…",
|
||||
"ui.print_face_cleared": "{body}: تم مسح وجه الطباعة",
|
||||
"ui.print_face_input": "وجه الطباعة",
|
||||
"ui.print_face_one_body": "يُختار وجه الطباعة لجسم واحد: أرسل ذلك الجسم وحده لتغييره",
|
||||
"ui.print_face_pick": "اختر وجهًا مستويًا واحدًا لجسم صلب لجعله وجه الطباعة",
|
||||
"ui.print_face_set": "{body}: تم تعيين وجه الطباعة؛ الإرسال إلى برنامج التقطيع يضع الجسم عليه",
|
||||
"ui.profile": "المقطع",
|
||||
"ui.profile_plane": "مستوى المقطع",
|
||||
"ui.profiles": "المقاطع",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "دوران",
|
||||
"ui.ribbon_exit": "خروج",
|
||||
"ui.ribbon_labels": "إظهار النص تحت أيقونات الشريط",
|
||||
"ui.ribbon_menus_skip_pinned": "استبعاد الأوامر المثبتة من القوائم المنسدلة",
|
||||
"ui.ribbon_pin_footer": "الأوامر المثبتة تظهر في الشريط. مرّر المؤشر على صف لتثبيته أو إلغاء تثبيته.",
|
||||
"ui.ribbon_workspace": "مساحة العمل",
|
||||
"ui.right": "يمين",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "تحديد",
|
||||
"ui.selectOther": "تحديد آخر…",
|
||||
"ui.selectTangentChain": "تحديد سلسلة مماسية",
|
||||
"ui.select_all": "تحديد الكل",
|
||||
"ui.select_components_by_face": "تحديد المكوّنات (تحديد وجه يحدّد المكوّن الذي ينتمي إليه)",
|
||||
"ui.selection": "التحديد",
|
||||
"ui.selection_modifiers": "مُعدِّلات التحديد",
|
||||
"ui.selection_shift_add_only": "Shift مع النقر يضيف دون إزالة",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "مرشح التحديد",
|
||||
"ui.sketch_modifiers": "مُعدِّلات الرسم",
|
||||
"ui.sketch_project_geometry": "الهندسة",
|
||||
"ui.sketch_report.all_constrained": "كل شيء مقيد بالكامل.",
|
||||
"ui.sketch_report.dof": "درجات الحرية",
|
||||
"ui.sketch_report.loose": "غير مقيد بالكامل",
|
||||
"ui.sketch_report.status": "الحالة",
|
||||
"ui.sketch_report.title": "تقرير الرسم",
|
||||
"ui.sketch_scale": "تحجيم الرسم",
|
||||
"ui.sketches": "الرسومات",
|
||||
"ui.slice": "تقطيع",
|
||||
@@ -4532,10 +4727,19 @@
|
||||
"ui.view_centre": "مركز العرض",
|
||||
"ui.viewport_status_clear": "إيقاف {name}",
|
||||
"ui.viewport_status_clear_hint": "إيقاف {name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} حواف",
|
||||
"ui.viewport_status_from": "من {direction}",
|
||||
"ui.viewport_status_key": "إظهار مفتاح الألوان لـ {name}",
|
||||
"ui.viewport_status_minimum_radius": "أقل نصف قطر",
|
||||
"ui.viewport_status_pairs": "{count} أزواج",
|
||||
"ui.viewport_status_section_hatch": "{setting} · تهشير",
|
||||
"ui.viewport_status_section_plane": "المستوى الحالي",
|
||||
"ui.viewport_status_section_tilted": "مائل · {offset}",
|
||||
"ui.viewport_status_stripes": "{count} شريطًا",
|
||||
"ui.viewport_status_summary_clear": "إيقاف كل شيء",
|
||||
"ui.viewport_status_summary_heading": "في هذا العرض",
|
||||
"ui.viewport_status_summary_label": "{name} و{count} عناصر أخرى",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "اتباع السمة",
|
||||
"ui.visual_shaded_hidden_edges": "مظلل مع الحواف المخفية",
|
||||
"ui.visual_shaded_with_edges": "مظلل مع الحواف",
|
||||
@@ -4572,7 +4776,9 @@
|
||||
"update.button": "تحديث",
|
||||
"update.button_version": "التحديث إلى {version}",
|
||||
"update.check_automatically": "التحقق من التحديثات تلقائيًا",
|
||||
"update.check_for_updates": "التحقق من وجود تحديثات",
|
||||
"update.check_now": "تحقق الآن",
|
||||
"update.check_unavailable": "التحقق من التحديثات غير متاح لهذا التثبيت.",
|
||||
"update.checking": "جارٍ التحقق…",
|
||||
"update.copy": "نسخ",
|
||||
"update.dmg_opened": "صورة القرص مفتوحة وموثّقة: اسحب SolidCraft إلى مجلد التطبيقات مستبدلًا النسخة القديمة، ثم أعد تشغيل SolidCraft.",
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
"Edges": "Ivice",
|
||||
"Edit": "Uredi",
|
||||
"Edit Profile Sketch": "Uredi skicu profila",
|
||||
"Edit shortcuts": "Uredi prečice",
|
||||
"Enable rule": "Omogući pravilo",
|
||||
"Enabled": "Omogućeno",
|
||||
"End Radius": "Krajnji poluprečnik",
|
||||
@@ -468,6 +469,7 @@
|
||||
"Radius": "Poluprečnik",
|
||||
"Radius Fit": "Uklapanje poluprečnika",
|
||||
"Ratio": "Omjer",
|
||||
"Read-only list: shortcuts can't be changed here.": "Popis samo za čitanje: prečice se ovdje ne mogu mijenjati.",
|
||||
"Reattach selected face": "Ponovo pričvrsti izabrano lice",
|
||||
"Recover": "Oporavi",
|
||||
"Recover unsaved design?": "Oporaviti nesačuvani dizajn?",
|
||||
@@ -652,6 +654,7 @@
|
||||
"Third point": "Treća tačka",
|
||||
"This child is shared. Deleting it removes it from every copy of its parent.": "Ovaj podređeni element je dijeljen. Brisanjem se uklanja iz svake kopije njegovog roditelja.",
|
||||
"This child is shared. Position changes apply to every copy of its parent.": "Ovaj podređeni element je dijeljen. Promjene položaja primjenjuju se na svaku kopiju njegovog roditelja.",
|
||||
"This component is inside a subassembly placed more than once: aligning it moves it in every placement.": "Ova komponenta je unutar podsklopa koji je postavljen više puta: njeno poravnavanje pomjera je u svakom postavljanju.",
|
||||
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Ovo lice ne može dati trajno pričvršćenje. Izaberite drugo lice ili izričito koristite fiksnu ravan.",
|
||||
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Ova slika još nije priložena na GitHubu. Kopirajte je ili sačuvajte, a zatim je priložite na GitHubu.",
|
||||
"Thread depth": "Dubina navoja",
|
||||
@@ -772,6 +775,8 @@
|
||||
"at the face": "na licu",
|
||||
"bom.group_children": "Poddijelovi u redu svog dijela",
|
||||
"browser.body_name": "Tijelo{number}",
|
||||
"browser.calibrate_click_a": "Kliknite sliku da zadate tačku A ili upišite njene koordinate.",
|
||||
"browser.calibrate_click_b": "Kliknite sliku da zadate tačku B ili upišite njene koordinate.",
|
||||
"browser.calibrate_title": "Kalibriši: {name}",
|
||||
"browser.capture_many": "Pomjerene komponente bez zabilježenog položaja: {count}.",
|
||||
"browser.capture_note": "Zabilježi zadržava novi položaj; Vrati ga vraća nazad.",
|
||||
@@ -793,6 +798,11 @@
|
||||
"cam.roller": "Valjak",
|
||||
"cam.roller_pick": "Valjak (neobavezno)",
|
||||
"cam.tip_pick": "Vrh (neobavezno)",
|
||||
"camera.shot_pitch": "Nagib",
|
||||
"camera.shot_roll": "Valjanje",
|
||||
"camera.shot_yaw": "Skretanje",
|
||||
"canvas.decal_place_hint": "Kliknite lice da postavite naljepnicu",
|
||||
"canvas.place_hint": "Kliknite ravan ili lice da postavite platno",
|
||||
"choose a profile": "izaberite profil",
|
||||
"choose the cam's and the follower's joints": "izaberite spojeve brijega i pratioca",
|
||||
"choose the joints to couple": "izaberite spojeve koje treba spregnuti",
|
||||
@@ -800,12 +810,16 @@
|
||||
"click sketch curves": "kliknite na krive skice",
|
||||
"cmd.appearance_assign": "Izgled",
|
||||
"cmd.appearance_chain": "Lanac izgleda",
|
||||
"cmd.appearance_copy": "Kopiraj izgled",
|
||||
"cmd.appearance_favorite": "Omiljeni izgled",
|
||||
"cmd.appearance_library": "Biblioteka izgleda",
|
||||
"cmd.appearance_list": "Popis izgleda",
|
||||
"cmd.appearance_paint": "Oboji izgledom",
|
||||
"cmd.appearance_paste": "Zalijepi izgled",
|
||||
"cmd.appearance_pick_up": "Preuzmi izgled",
|
||||
"cmd.appearance_replace": "Zamijeni izgled",
|
||||
"cmd.assembly_bom": "Sastavnica",
|
||||
"cmd.body.print_face": "Površina za štampu",
|
||||
"cmd.body_rename": "Preimenuj tijelo",
|
||||
"cmd.browser_collapse_all": "Skupi sve",
|
||||
"cmd.browser_expand_all": "Proširi sve",
|
||||
@@ -813,6 +827,7 @@
|
||||
"cmd.browser_move": "Premjesti stavke stabla modela",
|
||||
"cmd.browser_order": "Poredaj stavke stabla modela",
|
||||
"cmd.browser_rename_group": "Preimenuj grupu",
|
||||
"cmd.browser_reparent": "Premjesti u komponentu",
|
||||
"cmd.browser_ungroup": "Razgrupiši",
|
||||
"cmd.browser_visibility": "Prikaži/sakrij",
|
||||
"cmd.canvas_calibrate": "Kalibriši platno",
|
||||
@@ -839,7 +854,9 @@
|
||||
"cmd.component_metadata": "Svojstva dijela",
|
||||
"cmd.component_metadata_set": "Promijeni svojstva dijela",
|
||||
"cmd.component_move_bodies": "Premjesti tijela u komponentu",
|
||||
"cmd.component_move_features": "Premjesti operacije u komponentu",
|
||||
"cmd.component_move_sketches": "Premjesti skice u komponentu",
|
||||
"cmd.component_paste_from_design": "Zalijepi iz drugog dizajna",
|
||||
"cmd.component_paste_new": "Zalijepi kao novo",
|
||||
"cmd.component_properties": "Fizička svojstva komponente",
|
||||
"cmd.component_relink": "Ponovo poveži izvor",
|
||||
@@ -976,6 +993,7 @@
|
||||
"cmd.motion_trace": "Trag kretanja",
|
||||
"cmd.motion_trace_edit": "Uredi trag kretanja",
|
||||
"cmd.motion_trace_keep": "Zadrži trag kretanja",
|
||||
"cmd.occurrence_align": "Poravnaj primjerak",
|
||||
"cmd.occurrence_copy": "Zalijepi (primjerak)",
|
||||
"cmd.occurrence_drag": "Povuci primjerak",
|
||||
"cmd.occurrence_ground": "Učvrsti",
|
||||
@@ -1033,11 +1051,17 @@
|
||||
"cmd.render_library_surface_unbind": "Ukloni vezu površine",
|
||||
"cmd.render_library_targets": "Pronađi ciljeve biblioteke renderovanja",
|
||||
"cmd.render_lights_add": "Dodaj svjetlo",
|
||||
"cmd.render_lights_duplicate": "Dupliciraj svjetlo renderovanja",
|
||||
"cmd.render_lights_list": "Popis svjetala renderovanja",
|
||||
"cmd.render_lights_mute": "Isključi svjetlo",
|
||||
"cmd.render_lights_remove": "Ukloni svjetlo renderovanja",
|
||||
"cmd.render_lights_set": "Postavi svjetlo renderovanja",
|
||||
"cmd.render_lights_solo": "Samo ovo svjetlo",
|
||||
"cmd.render_optics_bind": "Sačuvaj optičku vezu",
|
||||
"cmd.render_optics_unbind": "Ukloni optičku vezu",
|
||||
"cmd.render_output_size": "Postavi veličinu izlaza renderovanja",
|
||||
"cmd.render_preflight": "Provjeri zahtjev za renderovanje",
|
||||
"cmd.render_preflight_copy": "Kopiraj izvještaj provjere renderovanja",
|
||||
"cmd.render_preset_apply": "Primijeni izvorni studio",
|
||||
"cmd.render_preset_resolve": "Pregledaj izvorni studio",
|
||||
"cmd.render_quality_prepare": "Pregledaj fiksni budžet uzorkovanja",
|
||||
@@ -1060,6 +1084,13 @@
|
||||
"cmd.render_start": "Renderuj sliku",
|
||||
"cmd.render_status": "Napredak renderovanja",
|
||||
"cmd.select_clear": "Poništi izbor",
|
||||
"cmd.settings_profile_apply": "Primijeni profil postavki",
|
||||
"cmd.settings_profile_delete": "Izbriši profil postavki",
|
||||
"cmd.settings_profile_export": "Izvezi profil postavki",
|
||||
"cmd.settings_profile_import": "Uvezi profil postavki",
|
||||
"cmd.settings_profile_list": "Profili postavki",
|
||||
"cmd.settings_profile_rename": "Preimenuj profil postavki",
|
||||
"cmd.settings_profile_save": "Sačuvaj profil postavki",
|
||||
"cmd.sheet_convert": "Pretvori u lim",
|
||||
"cmd.sheet_export_bend_table": "Izvezi tabelu savijanja",
|
||||
"cmd.sheet_export_dxf": "Izvezi razvijeni oblik kao DXF",
|
||||
@@ -1073,6 +1104,16 @@
|
||||
"cmd.sheet_refold": "Ponovo presavij",
|
||||
"cmd.sheet_rules": "Popis pravila za lim",
|
||||
"cmd.sheet_unfold": "Razvij",
|
||||
"cmd.sketch.construction_line": "Pomoćna prava",
|
||||
"cmd.sketch.construction_line.angle": "Pomoćna prava pod uglom",
|
||||
"cmd.sketch.construction_line.bisector": "Simetrala ugla",
|
||||
"cmd.sketch.construction_line.horizontal": "Horizontalna pomoćna prava",
|
||||
"cmd.sketch.construction_line.parallel": "Paralelna pomoćna prava",
|
||||
"cmd.sketch.construction_line.perpendicular": "Okomita pomoćna prava",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tangenta u tački krive",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tangenta kroz vanjsku tačku",
|
||||
"cmd.sketch.construction_line.tangent_two": "Zajednička tangenta",
|
||||
"cmd.sketch.construction_line.vertical": "Vertikalna pomoćna prava",
|
||||
"cmd.sketch_arc3d": "3D luk",
|
||||
"cmd.sketch_arc_center_point": "Luk iz centra",
|
||||
"cmd.sketch_arc_tangent": "Tangentni luk",
|
||||
@@ -1105,6 +1146,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Veličina crteža",
|
||||
"cmd.sketch_edit": "Uredi skicu",
|
||||
"cmd.sketch_edit_text": "Uredi tekst",
|
||||
"cmd.sketch_equation_curve": "Kriva iz jednačine",
|
||||
"cmd.sketch_equation_curve_edit": "Uredi krivu iz jednačine",
|
||||
"cmd.sketch_export_dxf": "Sačuvaj kao DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "Završi s automatskim ograničenjima",
|
||||
"cmd.sketch_fit_curves_to_section": "Uklopi krive u presjek mreže",
|
||||
@@ -1201,6 +1244,7 @@
|
||||
"cmd.view.render_browser": "Stablo renderovanja",
|
||||
"cmd.view.render_dock": "Premjesti panel renderovanja",
|
||||
"cmd.view.render_focus": "Prikaz fokusa renderovanja",
|
||||
"cmd.view.status_items": "Stavke statusa prozora prikaza",
|
||||
"cmd.view_ambient_occlusion": "Ambijentalna okluzija",
|
||||
"cmd.view_angle_readout": "Uglovi prikaza",
|
||||
"cmd.view_apply": "Vrati imenovani prikaz",
|
||||
@@ -1222,6 +1266,7 @@
|
||||
"cmd.view_normal_to": "Okomito na izbor",
|
||||
"cmd.view_previous_tab": "Prethodna kartica",
|
||||
"cmd.view_rename": "Preimenuj imenovani prikaz",
|
||||
"cmd.view_render_frame": "Pomoćne linije kadra renderovanja",
|
||||
"cmd.view_right": "Pogled zdesna",
|
||||
"cmd.view_save": "Novi imenovani prikaz",
|
||||
"cmd.view_shots_strip": "Traka kadrova",
|
||||
@@ -1232,10 +1277,14 @@
|
||||
"color.copy": "Kliknite da kopirate vrijednosti boje",
|
||||
"color.edit": "Kliknite da uredite boju",
|
||||
"color.gamma": "Prikaz vrijednosti boje u gama prostoru 0-255",
|
||||
"color.hex": "Hex",
|
||||
"color.hex_help": "Unesite #rrggbb ili #rrggbbaa; šest cifara zadržava neprozirnost",
|
||||
"color.hex_hint": "#rrggbb",
|
||||
"color.hue": "Nijansa",
|
||||
"color.linear": "Prikaz vrijednosti boje u linearnom prostoru 0-1",
|
||||
"color.saturation_value": "Zasićenost i vrijednost",
|
||||
"color.selected": "Izabrana boja",
|
||||
"config.column_filter_empty": "Nema odgovarajućih kolona",
|
||||
"contact.components_count": "Komponente: {count}",
|
||||
"contact.enabled_label": "omogućeno",
|
||||
"coupling.gear_1": "Zupčanik 1",
|
||||
@@ -1350,8 +1399,20 @@
|
||||
"help.material.assign": "Određuje od čega su izabrana tijela napravljena, npr. čelik, aluminij ili ABS. Koristite ga da masa i težina odgovaraju stvarnom dijelu.",
|
||||
"help.mit": "MIT licenca",
|
||||
"help.notice": "NOTICE",
|
||||
"help.occurrence.move": "Pomjera dio sklopa samo duž stepeni slobode koje dozvoljavaju njegovi spojevi. Izaberite lice dijela, a zatim prevucite dostupnu strelicu ili luk.",
|
||||
"help.parameters.change": "Otvara tabelu imenovanih vrijednosti i izraza koji upravljaju kotama dizajna. Koristite je da promijenite mjeru na jednom mjestu, a sve operacije koje je koriste je slijede.",
|
||||
"help.pointcloud.insert": "Umetnite PLY, XYZ ili PTS skeniranje kao oblak tačaka uz model. Koristite ga kao referencu pri izradi modela iz izmjerenih podataka.",
|
||||
"help.sketch.construction_line": "Napravite beskonačnu pomoćnu pravu kroz dvije tačke. Koristite je da rasporedite skicu bez razdvajanja profila.",
|
||||
"help.sketch.construction_line.angle": "Napravite beskonačnu pomoćnu pravu pod uglom od ose X skice. Izaberite tačku i upišite ugao ili izaberite smjer.",
|
||||
"help.sketch.construction_line.bisector": "Izaberite dvije prave linije skice koje se sijeku, pa jednu od dvije simetrale ugla. Rezultat prati izvorne linije.",
|
||||
"help.sketch.construction_line.horizontal": "Napravite beskonačnu horizontalnu pomoćnu pravu kroz tačku. Njeno ograničenje horizontalnosti ostaje na snazi pri kasnijim izmjenama.",
|
||||
"help.sketch.construction_line.parallel": "Izaberite pravu liniju skice, pa postavite paralelnu beskonačnu pomoćnu pravu. Desnim klikom izaberite drugu referencu.",
|
||||
"help.sketch.construction_line.perpendicular": "Izaberite pravu liniju skice, pa postavite okomitu beskonačnu pomoćnu pravu. Desnim klikom izaberite drugu referencu.",
|
||||
"help.sketch.construction_line.tangent_at": "Napravite tangentu u tački na krugu ili kružnom luku, ili u krajnjoj tački otvorenog splajna ili konike. Izaberite krivu, pa tačku dodira.",
|
||||
"help.sketch.construction_line.tangent_external": "Izaberite krug ili kružni luk, pa vanjsku tačku i rješenje tangente. Pregledi prikazuju samo dodirne tačke na nacrtanom luku.",
|
||||
"help.sketch.construction_line.tangent_two": "Izaberite dva kruga ili kružna luka, pa u pregledu izaberite zajedničku tangentu. Dodirne tačke moraju ležati na nacrtanim krivama.",
|
||||
"help.sketch.construction_line.vertical": "Napravite beskonačnu vertikalnu pomoćnu pravu kroz tačku. Njeno ograničenje vertikalnosti ostaje na snazi pri kasnijim izmjenama.",
|
||||
"help.sketch.equation_curve": "Crta krivu iz formula: x(t) i y(t) ili y = f(x), u zadanom rasponu. Formule mogu koristiti parametre i kriva ih prati: koristite je za sinusoidu, spiralu ili evolventu zupca zupčanika.",
|
||||
"help.solid.align": "Pomjera izabrana tijela tako da se tačka, lice ili ravan na njima poklopi s tačkom, licem ili ravni negdje drugdje. Koristite ga da postavite dio uz drugi bez mjerenja odmaka.",
|
||||
"help.solid.chamfer": "Odsijeca izabrane ivice ravnim skošenjem zadate udaljenosti. Koristite ga da ublažite oštre ivice ili olakšate uvođenje zatika ili vijka.",
|
||||
"help.solid.combine": "Spaja tijela, oduzima ih od ciljnog tijela ili zadržava samo zajedničku zapreminu, a može zadržati i alatna tijela. Koristite ga da spojite dijelove, da jednim oblikom odsiječete drugi ili da pronađete gdje se dva tijela preklapaju.",
|
||||
@@ -1480,6 +1541,21 @@
|
||||
"joint.one_component": "Ovi dijelovi su tijela jedne komponente: {bodies}. Spoj pomjera jednu komponentu u odnosu na drugu, pa svaki dio treba svoju komponentu.",
|
||||
"joint.rigid_group_one_component": "Sva tijela ({count}) su u jednoj komponenti (ili u samom dizajnu): prvo koristite {command}.",
|
||||
"joint.rigid_group_select_components": "Izaberite dvije ili više komponenti.",
|
||||
"joint_move.blocked_hint": "Provjerite vrstu spoja (npr. Kruti), učvršćenje, granice spoja i vrijednosti koje pokreću parametri.",
|
||||
"joint_move.blocked_title": "Ovaj dio se ne može pomjeriti",
|
||||
"joint_move.coarse": "Korak rotacije blizu ose (°)",
|
||||
"joint_move.distance": "Udaljenost od početka",
|
||||
"joint_move.done": "Gotovo",
|
||||
"joint_move.fine": "Korak rotacije dalje od ose (°)",
|
||||
"joint_move.fixed": "Ovaj dio nema pomičnu osu spoja.",
|
||||
"joint_move.help": "Pomjeri — prevucite strelicu ili prsten. Esc otkazuje trenutno povlačenje.",
|
||||
"joint_move.legacy_hint": "Isključite da biste koristili prethodni panel Pomjeri.",
|
||||
"joint_move.precision": "Povucite izvan isprekidane vodilje za finu rotaciju.",
|
||||
"joint_move.rotation": "Rotacija od početka",
|
||||
"joint_move.select": "Izaberite lice ili jedan dio sklopa, a zatim izaberite Pomjeri.",
|
||||
"joint_move.settings": "Pomjeranje u sklopu",
|
||||
"joint_move.step": "Korak",
|
||||
"joint_move.use_handles": "Koristi ručice kretanja spojeva za Pomjeri u sklopu",
|
||||
"keymap.command_id": "ID komande",
|
||||
"keymap.empty": "Nema odgovarajućih komandi",
|
||||
"keymap.use_anyway": "Ipak koristi {key} ovdje",
|
||||
@@ -1574,6 +1650,8 @@
|
||||
"nav.maya.help": "Alt+lijevo povlačenje orbitira, Alt+srednje pomjera, Alt+desno zumira; srednje povlačenje također pomjera",
|
||||
"nav.openscad.help": "Povlačenje lijevim dugmetom po praznom prostoru orbitira, Shift+povlačenje lijevim bira okvirom, povlačenje geometrije skice je uređuje; povlačenje desnim ili srednjim dugmetom pomjera, Shift+desno ili Shift+srednje zumira",
|
||||
"nav.perspective.sketch": "Uređivanje skice koristi ortografski prikaz. Završite skicu da prebacite na perspektivu.",
|
||||
"nav.right_drag_orbits.help": "Isključeno: povlačenje desnim dugmetom ne dira kameru, a desno dugme samo otvara kontekstni meni. Izbor mapiranja miša SolidWorks to isključuje.",
|
||||
"nav.right_drag_orbits.label": "Povlačenje desnim dugmetom orbitira",
|
||||
"nav.solidworks.help": "Povlačenje srednjim dugmetom orbitira, Ctrl+srednje pomjera, Shift+srednje zumira, povlačenje desnim orbitira",
|
||||
"nav.tinkercad.help": "Povlačenje desnim dugmetom orbitira, povlačenje srednjim ili Shift+desnim pomjera",
|
||||
"nav.touchpad.help": "Držite Shift i pomjerajte pokazivač za pomjeranje prikaza; držite Alt/Option i pomjerajte ga za orbitiranje. Dugme miša nije potrebno. Vertikalno skrolovanje zumira.",
|
||||
@@ -1595,6 +1673,9 @@
|
||||
"navbar.custom.customise": "Prilagodi navigacijsku traku…",
|
||||
"navbar.custom.design": "Dizajn",
|
||||
"navbar.custom.duplicate": "Ovo mjesto je već na traci.",
|
||||
"navbar.custom.edge": "Rub",
|
||||
"navbar.custom.edge_bottom": "Dolje",
|
||||
"navbar.custom.edge_top": "Gore",
|
||||
"navbar.custom.fade": "Izblijedi",
|
||||
"navbar.custom.full": "Uklonite jedno mjesto da biste dodali drugo.",
|
||||
"navbar.custom.hidden_design": "Skriveno u Dizajnu",
|
||||
@@ -1701,6 +1782,7 @@
|
||||
"parts.dimension.thickness": "Debljina",
|
||||
"parts.dimension.width": "Širina",
|
||||
"parts.family.bearing": "Kuglični ležaj s dubokim žlijebom (omotač)",
|
||||
"parts.family.button_head_cap_screw": "Vijak s poluokruglom glavom i imbusom",
|
||||
"parts.family.dowel_pin": "Cilindrični zatik",
|
||||
"parts.family.hex_bolt": "Vijak sa šestougaonom glavom",
|
||||
"parts.family.hex_nut": "Šestougaona matica",
|
||||
@@ -1759,6 +1841,11 @@
|
||||
"prefs.bottom_centre": "Dolje u sredini",
|
||||
"prefs.bottom_right": "Dolje desno",
|
||||
"prefs.browser": "Stablo modela",
|
||||
"prefs.browser_eye_left": "Oko pored strelice za skupljanje",
|
||||
"prefs.browser_eye_left_note": "Redovi stabla modela prikazuju oko za prikazivanje/skrivanje pored strelice za skupljanje, kao ranije, umjesto u koloni na desnom kraju redova.",
|
||||
"prefs.browser_reveal_on_hover": "Prikaži pri prelasku mišem",
|
||||
"prefs.browser_show_note": "Prikazano drži stablo modela na ekranu. Prikaži pri prelasku mišem drži ga skrivenim dok pokazivač ne pređe preko njegovog mjesta ili tankog jezička na njegovom lijevom rubu, a ostaje otvoreno dok je pokazivač u njemu ili dok je otvoren neki meni iz njega.",
|
||||
"prefs.browser_shown": "Prikazano",
|
||||
"prefs.built_in": "Ugrađeno",
|
||||
"prefs.button_left": "Povlačenje lijevim dugmetom",
|
||||
"prefs.button_middle": "Povlačenje srednjim dugmetom",
|
||||
@@ -1806,6 +1893,8 @@
|
||||
"prefs.graphics_card_restart": "Stupa na snagu nakon ponovnog pokretanja SolidCrafta. WGPU_ADAPTER_NAME ima prednost nad ovim izborom.",
|
||||
"prefs.graphics_note": "Žrtvujte brzinu za glatkoću. Svaki izbor pokazuje svoj učinak na primjeru.",
|
||||
"prefs.graphics_presets_note": "Unaprijed postavljene vrijednosti podešavaju sve izbore ispod odjednom.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Sakrij simbole ograničenja kada je prikaz umanjen",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Simboli ograničenja nestaju iz prikaza kada je skica toliko umanjena da bi je zatrpali. Isključeno: ostaju fiksne veličine na ekranu pri svakom zumiranju.",
|
||||
"prefs.history": "Vremenska traka",
|
||||
"prefs.history_origin_bodies": "Prikaži ishodište i tijela na vrhu",
|
||||
"prefs.history_origin_bodies_note": "Vremenska traka lijevo ili ispod stabla modela počinje folderom Tijela aktivne komponente i Ishodištem, s njihovim okom i menijima kao u stablu modela. Vremenska traka na dnu ostaje nepromijenjena.",
|
||||
@@ -1829,6 +1918,8 @@
|
||||
"prefs.layout_note": "Kompaktno pričvršćuje panele uz ivice prozora. Prozirnost stabla modela dostupna je u opciji Plutajuće. Stranu Asistenta promijenite na stranici Asistent.",
|
||||
"prefs.left": "Lijevo",
|
||||
"prefs.left_click": "Lijevi klik",
|
||||
"prefs.line_drag_draws_one": "Pritisak i povlačenje crta jednu liniju",
|
||||
"prefs.line_drag_draws_one_note": "U alatu Linija pritisak, povlačenje i puštanje crta jednu liniju od mjesta pritiska do mjesta puštanja i tu se završava. Klikovi i dalje crtaju lanac. Isključeno: povlačenje postavlja tačku tamo gdje se pusti, kao i klik.",
|
||||
"prefs.linked_designs": "Povezani dizajni",
|
||||
"prefs.live_input": "Ulaz uživo",
|
||||
"prefs.live_preview": "Pregled uživo",
|
||||
@@ -1842,6 +1933,9 @@
|
||||
"prefs.max_file_size_step": "STEP i uvezene datoteke",
|
||||
"prefs.max_file_size_web": "Web aplikacija otvara STEP i uvezene datoteke do 512 MB i dizajne do 256 MB: kartica preglednika ne može držati veće datoteke. Desktop aplikacija može povećati ove granice.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Velike ikone",
|
||||
"prefs.menu_list": "Popis",
|
||||
"prefs.menus": "Meniji",
|
||||
"prefs.minutes": "minuta",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "Miš i trackpad",
|
||||
@@ -1861,14 +1955,40 @@
|
||||
"prefs.origin_plane_names": "Nazivi ravni ishodišta",
|
||||
"prefs.origin_plane_names_note": "Nazivi prikazani u stablu modela, dijalozima i listama. {top} je XY, {front} je XZ, a {right} je YZ, sa Z prema gore. Komande, skripte i sačuvani dizajni zadržavaju XY, XZ i YZ.",
|
||||
"prefs.overall_speed": "Ukupna brzina",
|
||||
"prefs.persistent_ribbon_pressed": "Istakni aktivne komande na traci",
|
||||
"prefs.persistent_ribbon_pressed_help": "Ističe komande na traci dok su njihovi efekti uključeni. Isključite da biste zadržali prethodni neutralni izgled i pomoć za komande.",
|
||||
"prefs.perspective_fov": "Vidno polje",
|
||||
"prefs.placement": "Postavljanje",
|
||||
"prefs.prefer_free_sketch_points": "Daj prednost pokretnim tačkama skice kada se tačke preklapaju",
|
||||
"prefs.preview_choices": "Pregled vaših izbora",
|
||||
"prefs.print_face_highlight": "Isticanje površine za štampu",
|
||||
"prefs.print_face_highlight_tip": "Koliko se jako površina za štampu tijela boji i obrubljuje u prikazu. 0 % ne prikazuje isticanje.",
|
||||
"prefs.profile_active": "Aktivni profil",
|
||||
"prefs.profile_applied": "Profil je primijenjen.",
|
||||
"prefs.profile_changed": "Postavke su promijenjene otkako je profil sačuvan. Sačuvaj ih upisuje u profil.",
|
||||
"prefs.profile_deleted": "Profil je izbrisan.",
|
||||
"prefs.profile_export": "Izvezi…",
|
||||
"prefs.profile_exported": "Profil je izvezen.",
|
||||
"prefs.profile_imported": "Profil je uvezen. Izaberite ga pod Aktivni profil da se prebacite na njega.",
|
||||
"prefs.profile_name_hint": "Naziv profila, npr. Laptop",
|
||||
"prefs.profile_rename": "Preimenuj",
|
||||
"prefs.profile_renamed": "Profil je preimenovan.",
|
||||
"prefs.profile_save": "Sačuvaj",
|
||||
"prefs.profile_saved": "Trenutne postavke su sačuvane u profil.",
|
||||
"prefs.profile_skipped": "Profil je primijenjen; postavke koje su zadržale trenutnu vrijednost: {n} (pogledajte zapisnik).",
|
||||
"prefs.profiles": "Profili postavki",
|
||||
"prefs.profiles_note": "Prečice, traka s alatima, navigacija, radijalni meni i postavke interfejsa čuvaju se zajedno pod jednim nazivom i mijenjaju odjednom.",
|
||||
"prefs.project_options_dialog": "Dijalog opcija za projektovanje",
|
||||
"prefs.project_options_dialog_note": "Uključeno: prije projektovanja izaberite Geometrija ili Tijela i Veza projekcije. Isključeno: zadržava se prethodni tok rada s direktnim izborom.",
|
||||
"prefs.quality_default": "podrazumijevano",
|
||||
"prefs.quality_fastest": "najbrže",
|
||||
"prefs.quality_slowest": "najsporije",
|
||||
"prefs.quality_smoother": "glađe",
|
||||
"prefs.render_previous_geometry_budget": "Koristi prethodni budžet geometrije za pregled renderovanja",
|
||||
"prefs.render_previous_geometry_budget_help": "Vraća prethodno fiksno ograničenje geometrije (512 MiB na 64-bitnim desktop računarima, 128 MiB drugdje) umjesto budžeta prema uređaju.",
|
||||
"prefs.reports_saved": "Sačuvano: {n}",
|
||||
"prefs.ribbon_reveal": "Prikaži rezultate pretrage na traci",
|
||||
"prefs.ribbon_reveal_note": "Zadržavanje pokazivača iznad rezultata u Pretraži komande pokazuje gdje se komanda nalazi na traci: njenu karticu, njeno dugme ili njen red u padajućem meniju panela. Komanda pokrenuta iz pretrage tamo trepće, a pokrenuta komanda iz padajućeg menija označava svoj panel.",
|
||||
"prefs.right_click": "Desni klik",
|
||||
"prefs.saving": "Automatsko čuvanje i oporavak",
|
||||
"prefs.scale_note": "Također Ctrl + / Ctrl − u prozoru. Dugmad su 28 px pri 100%.",
|
||||
@@ -1877,18 +1997,29 @@
|
||||
"prefs.search_empty": "Nema odgovarajućih postavki",
|
||||
"prefs.select": "Izbor",
|
||||
"prefs.select_one_item": "Izaberi jednu stavku",
|
||||
"prefs.select_other_hidden": "Izaberi skrivenu geometriju pomoću Izaberi drugo",
|
||||
"prefs.select_other_hidden_help": "Uključeno: obuhvata skrivena tijela, skice i zaklonjene ivice u blizini pokazivača. Isključeno: koristi se izvorni popis vidljive geometrije ispod pokazivača.",
|
||||
"prefs.selecting": "Biranje",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift samo dodaje; Ctrl / Cmd uključuje i isključuje",
|
||||
"prefs.shift_add_note": "Uključeno: Shift dodaje, Ctrl / Cmd uključuje i isključuje. Isključeno (podrazumijevano): oba uključuju i isključuju.",
|
||||
"prefs.shortcuts": "Prečice",
|
||||
"prefs.single_surface_analysis": "Koristi samo jednu analizu površi",
|
||||
"prefs.single_surface_analysis_help": "Kada je isključeno, sjenčenje površi i Kontinuitet mogu ostati uključeni zajedno. Uključivanje zadržava posljednju pokrenutu ili promijenjenu analizu.",
|
||||
"prefs.sketch_align_points": "Poravnaj s drugim tačkama skice tokom crtanja",
|
||||
"prefs.sketch_align_points_note": "Tokom crtanja tačka se istovremeno poravnava vodoravno s jednom tačkom skice i okomito s drugom, uz tačkastu pomoćnu liniju, a klik zadržava oba poravnanja. Isključeno: samo s prethodnom tačkom, po jedna osa.",
|
||||
"prefs.sketch_conflict_colour": "Geometrija u sukobu u boji sukoba",
|
||||
"prefs.sketch_conflict_colour_note": "Dok su ograničenja skice u sukobu, krive i tačke koje drži ograničenje koje ne uspijeva crtaju se također u boji sukoba, ne samo njegov simbol ili kota. Isključeno: zadržavaju uobičajene boje.",
|
||||
"prefs.sketch_construction_lines": "Prošireni alati za pomoćne prave",
|
||||
"prefs.sketch_exit_view": "Kada se skica završi",
|
||||
"prefs.sketch_exit_view.keep": "Zadrži trenutni prikaz",
|
||||
"prefs.sketch_exit_view.previous": "Vrati se na prethodni prikaz",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Vrati se osim ako je rotirano",
|
||||
"prefs.sketch_exit_view_note": "Kuda prikaz ide nakon Završi skicu, Otkaži ili dvostrukog Esc.",
|
||||
"prefs.sketch_open_look_at": "Okreni kameru prema skici kad se otvori",
|
||||
"prefs.sketch_open_look_at_note": "Isključeno: kad napravite ili uredite skicu, prikaz ostaje onakav kakav jest. Pogledaj okreće prikaz prema skici kad to želite.",
|
||||
"prefs.sketch_recent_snap": "Automatski privlači na nedavne centre i središnje tačke",
|
||||
"prefs.sketch_recent_snap_note": "Tokom crtanja pokazivač se privlači tamo gdje se sijeku pomoćne linije dvaju posljednjih centara krugova ili središnjih tačaka pravih ivica. Isključeno: te pomoćne linije služe samo za prikaz i pokazivač se ne pomjera.",
|
||||
"prefs.sketch_selection": "Skica i izbor",
|
||||
"prefs.sketch_selection_heading": "Skica i izbor",
|
||||
"prefs.sketch_selection_note": "Kako se skice privlače i kako klikovi biraju.",
|
||||
@@ -1933,7 +2064,14 @@
|
||||
"prefs.toast_place": "Obavještenja",
|
||||
"prefs.toggle_item": "Dodaj stavku ili je ponovo ukloni",
|
||||
"prefs.toolbar": "Traka s alatima",
|
||||
"prefs.toolbar_tabs": "Kartice trake s alatima",
|
||||
"prefs.top": "Gore",
|
||||
"prefs.trackpad_zoom_modifier": "Zumiranje skrolovanjem s dva prsta uz držanje tipke",
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "Držite samo ovu tipku da zumirate prema pokazivaču vertikalnim skrolovanjem. Isključeno zadržava postojeće ponašanje skrolovanja.",
|
||||
"prefs.trackpad_zoom_modifier.off": "Isključeno",
|
||||
"prefs.translucent": "Prozirno",
|
||||
"prefs.under_browser": "Ispod stabla modela",
|
||||
"prefs.under_cursor": "Ispod pokazivača",
|
||||
@@ -1943,13 +2081,24 @@
|
||||
"prefs.view_confirm_corner": "U redu i Otkaži u uglu prikaza",
|
||||
"prefs.view_confirm_corner_note": "Dok je otvoren dijalog ili skica, kvačica i krstić gore desno u prikazu rade isto što i dugmad U redu i Otkaži u dijalogu, odnosno završavaju i otkazuju skicu. Navigator prikaza pomjera se ispod njih.",
|
||||
"prefs.viewport": "Prozor prikaza",
|
||||
"prefs.viewport_analysis_status": "Prikaži status analize u prozoru prikaza",
|
||||
"prefs.viewport_analysis_status_help": "Prikazuje aktivne analize iznad prozora prikaza, otvara njihove legende iz svake stavke, a tipka Esc isključuje najnoviju analizu. Isključite da biste vratili legende u uglovima i prethodno ponašanje tipke Esc.",
|
||||
"prefs.viewport_background": "Pozadina",
|
||||
"prefs.viewport_background_colour": "Boja",
|
||||
"prefs.viewport_background_theme": "Gradijent teme",
|
||||
"prefs.wheel": "Točkić",
|
||||
"prefs.wheel_trackpad": "Točkić i trackpad",
|
||||
"prefs.workspace": "Radni prostor",
|
||||
"prefs.zoom_stop_at_model": "Zaustavi zumiranje na modelu",
|
||||
"prefs.zoom_stop_at_model_tip": "3D miš i aplikacija uređaja zumiraju prema površini u sredini prikaza; zumiranje povlačenjem drži tačku na kojoj je povlačenje počelo. Isključeno: zumiranje može proći kroz model. Točkić i štipanje zasebno koriste Zumiranje prema pokazivaču",
|
||||
"prefs.zoom_toward_cursor": "Zumiranje prema pokazivaču",
|
||||
"properties.title": "Svojstva: {name}",
|
||||
"recovery.days_ago": "prije {count} dana",
|
||||
"recovery.detail": "{file} · operacija: {features} · automatski sačuvano {when}",
|
||||
"recovery.discard_all": "Odbaci sve",
|
||||
"recovery.discard_all_detail": "Ovo se ne može poništiti.",
|
||||
"recovery.discard_all_title": "Odbaciti automatska čuvanja ({count})?",
|
||||
"recovery.discard_all_title_one": "Odbaciti 1 automatsko čuvanje?",
|
||||
"recovery.hours_ago": "prije {count} h",
|
||||
"recovery.just_now": "upravo sada",
|
||||
"recovery.min_ago": "prije {count} min",
|
||||
@@ -2034,6 +2183,7 @@
|
||||
"render.appearance_editor.weight": "Težina",
|
||||
"render.appearance_physics_separate": "Vizuelni izgled ne dodjeljuje gustinu, toplotne podatke niti druga inženjerska svojstva.",
|
||||
"render.appearances": "Izgledi",
|
||||
"render.assign_help": "Kliknite za primjenu na izbor; prevucite za pregled i ispustite ili kliknite kada ništa nije izabrano da bojite.",
|
||||
"render.availability_native": "Izvorni sastav; pregledajte prije primjene",
|
||||
"render.availability_projection": "Podržana projekcija; pogledajte opseg i izostavke",
|
||||
"render.availability_reference": "Referentni podaci; nije automatska dodjela",
|
||||
@@ -2072,6 +2222,7 @@
|
||||
"render.bloom_threshold": "Prag linearnih svijetlih dijelova",
|
||||
"render.browse_capabilities": "Pregledaj kompletan katalog mogućnosti",
|
||||
"render.browse_environments": "Pregledaj izvorna HDR okruženja",
|
||||
"render.browse_looks": "Pregledaj…",
|
||||
"render.browse_native_scenes": "Pregledaj izvorne studije",
|
||||
"render.browse_physical": "Pregledaj fizičke reference",
|
||||
"render.browse_quality": "Pregledaj specifikacije kvaliteta",
|
||||
@@ -2095,6 +2246,82 @@
|
||||
"render.check_opaque": "Prozirnost: samo neprozirne površi; alfa pozadine je podržana.",
|
||||
"render.check_sorted_alpha": "Prozirnost: aproksimacija sortirane alfe.",
|
||||
"render.check_transmission": "Prozirnost: fizička transmisija.",
|
||||
"render.children.absolute_floor": "Apsolutni donji prag",
|
||||
"render.children.adaptive": "Adaptivno",
|
||||
"render.children.add_look_reason": "Dodajte izgled da biste uredili njegovo uključivanje i jačinu.",
|
||||
"render.children.all_shots": "Svi kadrovi",
|
||||
"render.children.bloom": "Sjaj",
|
||||
"render.children.check": "Provjera",
|
||||
"render.children.check_now": "Provjeri sada",
|
||||
"render.children.chromatic": "Hromatski pomak",
|
||||
"render.children.compact": "Kompaktno",
|
||||
"render.children.contrast": "Kontrast",
|
||||
"render.children.copy_image": "Kopiraj",
|
||||
"render.children.copy_job": "Kopiraj JSON posla",
|
||||
"render.children.copy_request": "Kopiraj JSON zahtjeva",
|
||||
"render.children.coverage_error": "Greška pokrivenosti",
|
||||
"render.children.cpu": "CPU praćenje zraka",
|
||||
"render.children.denoise": "Smanji šum na završenoj slici",
|
||||
"render.children.depth": "Dubina putanje",
|
||||
"render.children.distortion": "Izobličenje",
|
||||
"render.children.edge_samples": "Uzorci ivica",
|
||||
"render.children.effects_banner": "Ovi efekti zahtijevaju GPU praćenje putanja. Otvaranje ovoga nikad ne mijenja metodu.",
|
||||
"render.children.enable_adaptive": "Omogućite nezavisne probne uzorke da biste uredili adaptivna ograničenja.",
|
||||
"render.children.enable_bloom": "Omogućite sjaj da biste uredili njegovu jačinu, prag i poluprečnik.",
|
||||
"render.children.finishing": "Završna obrada",
|
||||
"render.children.flare": "Odsjaj",
|
||||
"render.children.fresnel": "Fresnelovi slojevi",
|
||||
"render.children.ghosts": "Duhovi prstenova",
|
||||
"render.children.glass": "Transport kroz staklo",
|
||||
"render.children.go_to": "Idi na {editor}",
|
||||
"render.children.grain": "Zrno",
|
||||
"render.children.halo": "Oreol",
|
||||
"render.children.hdr": "HDR",
|
||||
"render.children.keep_master": "Zadrži sirovi linearni master",
|
||||
"render.children.last_result": "Posljednje: {number} · {width} × {height} · {phase}",
|
||||
"render.children.lens_effects": "Efekti objektiva",
|
||||
"render.children.look_summary": "{tone} · izgledi: {count}",
|
||||
"render.children.looks": "Kreativni izgledi",
|
||||
"render.children.memory": "Memorija",
|
||||
"render.children.method": "Metoda",
|
||||
"render.children.minimum": "Minimum",
|
||||
"render.children.needs_cpu": "Potrebno je CPU praćenje zraka. Otvaranje ovoga nikad ne mijenja metodu.",
|
||||
"render.children.nested": "Potvrđeni ugniježđeni dielektrici",
|
||||
"render.children.not_checked": "Nije provjereno",
|
||||
"render.children.path": "Praćenje putanja",
|
||||
"render.children.pilots": "Probni uzorci",
|
||||
"render.children.preview": "Podaci pregleda",
|
||||
"render.children.progressive_reason": "Izaberite Progresivno da biste uredili broj uzoraka i sjeme.",
|
||||
"render.children.radius": "Poluprečnik",
|
||||
"render.children.reflect_depth": "Dubina refleksije",
|
||||
"render.children.reflect_samples": "Uzorci refleksije",
|
||||
"render.children.regrade": "Ponovna gradacija",
|
||||
"render.children.relative_error": "Relativna greška",
|
||||
"render.children.render": "Renderovanje",
|
||||
"render.children.render_shot": "Renderuj kadar",
|
||||
"render.children.renderer": "Renderer",
|
||||
"render.children.renderers": "Rendereri",
|
||||
"render.children.request": "Ovaj zahtjev",
|
||||
"render.children.reset_finishing": "Resetuj završnu obradu",
|
||||
"render.children.review_quality": "Pregledaj specifikaciju kvaliteta…",
|
||||
"render.children.rgb_gain": "RGB pojačanje",
|
||||
"render.children.samples": "Uzorci",
|
||||
"render.children.sampling": "Uzorkovanje",
|
||||
"render.children.saturation": "Zasićenost",
|
||||
"render.children.scene_summary": "Tijela: {bodies} · trouglovi: {triangles}",
|
||||
"render.children.seed": "Sjeme",
|
||||
"render.children.sharpening": "Izoštravanje",
|
||||
"render.children.single_image": "Jedna slika",
|
||||
"render.children.soft_focus": "Meki fokus",
|
||||
"render.children.streak": "Pruga",
|
||||
"render.children.strength": "Jačina",
|
||||
"render.children.studio": "Studio",
|
||||
"render.children.threshold": "Prag",
|
||||
"render.children.tone": "Ton",
|
||||
"render.children.under_hood": "Ispod haube",
|
||||
"render.children.vignette": "Vinjeta",
|
||||
"render.children.workstation": "Radna stanica",
|
||||
"render.choose_look": "Prvo izaberite izgled u Izgledima",
|
||||
"render.chromatic_offset": "Hromatski pomak ivica",
|
||||
"render.clear_stage": "Ukloni sačuvanu scenu",
|
||||
"render.copy_request": "Kopiraj JSON",
|
||||
@@ -2346,8 +2573,33 @@
|
||||
"render.flare_strength": "Jačina odsjaja svijetlih dijelova",
|
||||
"render.flare_threshold": "Linearni prag odsjaja scene",
|
||||
"render.fold_browser": "Skupi stablo modela",
|
||||
"render.frame_aspect": "Omjer",
|
||||
"render.frame_centre_mark": "Oznaka centra",
|
||||
"render.frame_copy_limit": "Nema slobodnog naziva za duplikat kadra",
|
||||
"render.frame_copy_name": "{name} kopija {number}",
|
||||
"render.frame_custom": "Prilagođeno",
|
||||
"render.frame_distance_unit": " × veličina",
|
||||
"render.frame_duplicate": "Dupliciraj",
|
||||
"render.frame_exposure": "Ekspozicija",
|
||||
"render.frame_fov": "Vidno polje",
|
||||
"render.frame_guides": "Pomoćne linije",
|
||||
"render.frame_invalid_aspect": "Neispravan predložak omjera",
|
||||
"render.frame_lens": "FOV {fov}° · ≈ {mm} mm",
|
||||
"render.frame_name": "Naziv",
|
||||
"render.frame_output_size": "Veličina izlaza",
|
||||
"render.frame_photo": "3:2 · Fotografija",
|
||||
"render.frame_portrait": "4:5 · Portret",
|
||||
"render.frame_presets": "Predlošci kadra",
|
||||
"render.frame_presets_pending": "Stiže s uređivačem kadrova",
|
||||
"render.frame_projection": "Projekcija",
|
||||
"render.frame_render_shot": "Renderuj ovaj kadar",
|
||||
"render.frame_rule_thirds": "Pravilo trećina",
|
||||
"render.frame_safe_area": "Sigurna zona",
|
||||
"render.frame_shot_title": "Kadar · {name}",
|
||||
"render.frame_square": "1:1 · Kvadrat",
|
||||
"render.frame_tall": "9:16 · Vertikalno",
|
||||
"render.frame_thirds": "Trećine",
|
||||
"render.frame_wide": "16:9 · Široki ekran",
|
||||
"render.gpu_depth": "Maksimalna dubina putanje",
|
||||
"render.gpu_options_help": "Uzorci, dubina, sjeme i ekspozicija čuvaju se s ovom postavkom. Čuva se samo aktivna metoda slike.",
|
||||
"render.gpu_path_failed": "GPU praćenje putanja nije dostupno",
|
||||
@@ -2375,6 +2627,7 @@
|
||||
"render.heading_results": "REZULTATI",
|
||||
"render.heading_shots": "KADROVI",
|
||||
"render.hide_shots_label": "Sakrij traku kadrova",
|
||||
"render.hover_look": "{object} · {look} · kliknite za izbor",
|
||||
"render.image_advanced": "Napredne GPU kontrole",
|
||||
"render.image_cancelled": "Renderovanje je otkazano",
|
||||
"render.image_cancelling": "Otkazivanje",
|
||||
@@ -2521,17 +2774,95 @@
|
||||
"render.library_uniform_ack": "Koristi jednoličnu aproksimaciju bez prostornih ili naprednih efekata",
|
||||
"render.library_usable": "Izvršne projekcije",
|
||||
"render.library_users": "Korisnici",
|
||||
"render.light_aim": "Usmjeri na",
|
||||
"render.light_anchor_pending": "Promjena koordinatnog sistema svjetla još nije podržana.",
|
||||
"render.light_azimuth": "Azimut",
|
||||
"render.light_backend_limit": "Izaberite CPU praćenje zraka ili izričit GPU studio da biste uređivali svjetla. Svjetla starog GPU studija ostaju samo za čitanje.",
|
||||
"render.light_behaviour": "PONAŠANJE",
|
||||
"render.light_default_fill": "Popunjavajuće",
|
||||
"render.light_default_key": "Glavno",
|
||||
"render.light_default_number": "Svjetlo {number}",
|
||||
"render.light_default_rim": "Rubno",
|
||||
"render.light_delete": "Izbriši",
|
||||
"render.light_distance": "Udaljenost",
|
||||
"render.light_duplicate": "Dupliciraj",
|
||||
"render.light_elevation": "Elevacija",
|
||||
"render.light_gpu_punctual": "Tačkasta svjetla i reflektori dostupni su uz CPU praćenje zraka.",
|
||||
"render.light_hard_shadow": "Ovo svjetlo ima oštre sjene; mekoća emitera nije dostupna.",
|
||||
"render.light_intensity": "Intenzitet",
|
||||
"render.light_missing": "Ovo svjetlo više ne postoji. Izaberite svjetlo u stablu modela.",
|
||||
"render.light_place_highlight": "Postavi prema odsjaju",
|
||||
"render.light_place_pending": "Postavljanje prema odsjaju zahtijeva izbor svjetla u prozoru prikaza i još nije podržano.",
|
||||
"render.light_position": "POLOŽAJ",
|
||||
"render.light_preview_help": "Prikaz uživo je bez sjena; površinska svjetla koriste aproksimaciju uzorkom iz centra. Renderovanje koristi potpuni model svjetla.",
|
||||
"render.light_product_centre": "Centar proizvoda",
|
||||
"render.light_size": "Veličina",
|
||||
"render.light_softness": "Mekoća",
|
||||
"render.light_temperature": "Temperatura boje",
|
||||
"render.light_temperature_help": "Približna nijansa crnog tijela; čuva se kao linearni RGB.",
|
||||
"render.light_type": "Vrsta",
|
||||
"render.light_type_area": "Površinsko",
|
||||
"render.light_type_point": "Tačkasto",
|
||||
"render.light_type_spot": "Reflektor",
|
||||
"render.light_type_sun": "Sunce",
|
||||
"render.light_view_only": "Samo ovo svjetlo i isključivanje svjetla utiču na ovaj prikaz i njegova renderovanja; nikad se ne čuvaju u dizajnu.",
|
||||
"render.light_world_origin": "Ishodište svijeta",
|
||||
"render.lighting_aim_point": "Tačka usmjeravanja",
|
||||
"render.lighting_apply": "Primijeni postavku",
|
||||
"render.lighting_area_samples": "Uzorci površinskog svjetla",
|
||||
"render.lighting_budget": "Budžet",
|
||||
"render.lighting_budget_help": "Brojevi su samo za čitanje. Dodajte, duplicirajte ili izbrišite svjetla da ih promijenite; metoda određuje ograničenja.",
|
||||
"render.lighting_colour": "Boja",
|
||||
"render.lighting_consent": "Zamijeni usmjerena svjetla ovom postavkom",
|
||||
"render.lighting_custom": "Prilagođena svjetla",
|
||||
"render.lighting_custom_help": "Izbor opcije Prilagođeno pretvara postavku u svjetla koja se mogu uređivati, svako u svom redu u stablu.",
|
||||
"render.lighting_direction": "Smjer X Y Z",
|
||||
"render.lighting_direction_help": "Ili upišite smjer prema svjetlu (X Y Z).",
|
||||
"render.lighting_distance_unit": " × veličina",
|
||||
"render.lighting_edge_u": "Vektor stranice U",
|
||||
"render.lighting_edge_v": "Vektor stranice V",
|
||||
"render.lighting_falloff": "Slabljenje",
|
||||
"render.lighting_falloff_help": "Intenzitet se navodi na referentnoj udaljenosti.",
|
||||
"render.lighting_height": "Visina V",
|
||||
"render.lighting_minimum": "Minimum",
|
||||
"render.lighting_mute": "Isključi ovo svjetlo",
|
||||
"render.lighting_point": "Tačka",
|
||||
"render.lighting_preset": "Postavka studija",
|
||||
"render.lighting_preset_cpu": "Usmjerene postavke studija zahtijevaju CPU praćenje zraka. GPU osvjetljenje koristi izričita sunčeva i površinska svjetla.",
|
||||
"render.lighting_preset_row": "Postavka",
|
||||
"render.lighting_radiance": "Radijansa",
|
||||
"render.lighting_reference": "Referenca",
|
||||
"render.lighting_review_help": "Zamjenjuje popis usmjerenih svjetala. Zadržava tačkasta i površinska svjetla, okruženje, sjene, kameru i sve ostale postavke kadra.",
|
||||
"render.lighting_review_title": "Pregledaj postavku osvjetljenja",
|
||||
"render.lighting_samples_cpu": "Uzorci površinskog svjetla primjenjuju se na CPU praćenje zraka.",
|
||||
"render.lighting_samples_need_area": "Dodajte CPU površinsko svjetlo da biste postavili uzorke površinskog svjetla.",
|
||||
"render.lighting_samples_reason": "Uzorci površinskog svjetla moraju biti 1, 4, 16 ili 64.",
|
||||
"render.lighting_shadow_cpu": "Prekidač sjena zahtijeva CPU praćenje zraka. GPU praćenje putanja uvijek baca sjene.",
|
||||
"render.lighting_shadows": "Baci sjene",
|
||||
"render.lighting_shadows_section": "Sjene i uzorkovanje",
|
||||
"render.lighting_shape": "Oblik",
|
||||
"render.lighting_solo": "Samo ovo svjetlo",
|
||||
"render.lighting_source": "Izvor",
|
||||
"render.lighting_source_section": "Izvor svjetla",
|
||||
"render.lighting_spot_preserved": "Ovo tačkasto svjetlo zadržava sačuvani konus reflektora dok mu se ne promijeni vrsta.",
|
||||
"render.lighting_sun_distance": "Smjer sunca ne zavisi od udaljenosti i tačke usmjeravanja.",
|
||||
"render.lighting_unsupported": "nepodržano",
|
||||
"render.lighting_used": "{used} od {limit}",
|
||||
"render.lighting_width": "Širina U",
|
||||
"render.lighting_world_position": "Svjetski X Y Z",
|
||||
"render.lights_fixed_to": "Svjetla vezana za",
|
||||
"render.linear_help": "Zadržava 32-bitni float RGBA master prije uklanjanja šuma, ekspozicije, mapiranja tonova, filtera i pozadine. Linearni sRGB/D65; pomnožen pokrivenošću. Dodatna memorija se izričito odobrava. Bez kompresije i dodatnih prolaza.",
|
||||
"render.linear_retain": "Zadrži sirovi linearni EXR",
|
||||
"render.linear_unavailable": "Izabrani završeni kadar nema zadržani EXR. Omogućite zadržavanje prije renderovanja; stariji PNG ne može vratiti sirovu radijansu.",
|
||||
"render.look_add": "Dodaj izgled boje",
|
||||
"render.look_applied": "Primijenjeno: {name}",
|
||||
"render.look_bleach": "Po uzoru na bleach bypass",
|
||||
"render.look_cool": "Hladno",
|
||||
"render.look_cyanotype": "Po uzoru na cijanotipiju",
|
||||
"render.look_faded": "Izblijedjeli otisak",
|
||||
"render.look_material": "Materijal",
|
||||
"render.look_mono": "Jednobojno",
|
||||
"render.look_pasted": "Izgled je zalijepljen",
|
||||
"render.look_sepia": "Sepija",
|
||||
"render.look_strength": "Jačina izgleda",
|
||||
"render.look_teal_orange": "Tirkizno / narandžasto",
|
||||
@@ -2607,9 +2938,11 @@
|
||||
"render.output_advanced": "Napredno",
|
||||
"render.output_backend_ready": "Spremno",
|
||||
"render.output_check": "Provjeri",
|
||||
"render.output_check_failed": "Provjera · greška",
|
||||
"render.output_check_help": "Pokrenite provjeru da pregledate ovaj zahtjev bez pokretanja renderovanja.",
|
||||
"render.output_check_summary": "Provjera · Napomene: {count}",
|
||||
"render.output_copy": "Kopiraj",
|
||||
"render.output_copy_report": "Kopiraj izvještaj",
|
||||
"render.output_destination": "Odredište",
|
||||
"render.output_destination_help": "Odredišnu datoteku birate pri izvozu završene slike.",
|
||||
"render.output_dimensions": "Veličina",
|
||||
@@ -2619,6 +2952,7 @@
|
||||
"render.output_fit": "Uklopi",
|
||||
"render.output_format": "Format",
|
||||
"render.output_format_status": "PNG je tačna završena slika za prikaz. Neobavezni GPU EXR zadržava sirovu linearnu radijansu scene u formatu FLOAT32 prije filtera prikaza. Izvoz nikad ne zamjenjuje keš pregleda ni drugi posao.",
|
||||
"render.output_grading": "Gradacija",
|
||||
"render.output_image": "Slika",
|
||||
"render.output_largest": "Najviše {width} × {height}",
|
||||
"render.output_lock_ratio": "Zaključaj omjer stranica",
|
||||
@@ -2628,6 +2962,8 @@
|
||||
"render.output_quality_waiting": "čeka se specifikacija kvaliteta",
|
||||
"render.output_ratio_refused": "Povezana dimenzija premašuje ograničenje veličine ove metode. Prethodna veličina se zadržava; otključajte omjer ili izaberite manju vrijednost.",
|
||||
"render.output_ready": "Spremno za renderovanje",
|
||||
"render.output_run_check": "Pokreni provjeru",
|
||||
"render.output_size_limit": "{method}: do {dimension} px po strani i {pixels} piksela. Najveća veličina koja staje: {width} × {height}.",
|
||||
"render.output_size_ok": "Veličina u redu · {width} × {height} px",
|
||||
"render.output_swap_orientation": "Zamijeni širinu i visinu",
|
||||
"render.output_tools_inspector": "Veličinu i format uredite u inspektoru Izlaz.",
|
||||
@@ -2644,6 +2980,7 @@
|
||||
"render.page_output": "Izlaz",
|
||||
"render.page_scene": "Scena",
|
||||
"render.paint_label": "Oboji",
|
||||
"render.painting_with": "Bojenje izgledom: {name}",
|
||||
"render.passive_stage": "Podloga i pasivna scena",
|
||||
"render.passive_stage_help": "Konačni pasivni paneli pripadaju samo renderovanim slikama. Ne dodaju CAD tijela ni masu. Postavljanje je fiksno nakon primjene; presijecanje granica proizvoda se odbija. CPU ne daje difuzno odbijeno osvjetljenje.",
|
||||
"render.perspective": "Perspektivna kamera",
|
||||
@@ -2665,6 +3002,7 @@
|
||||
"render.pick_help": "Izaberite Tijelo, Lice ili Komponenta. Kliknite prazan prostor da očistite izbor; Shift ili Ctrl dodaje ili uključuje/isključuje. Isticanja se pojavljuju samo u živom prikazu proizvoda.",
|
||||
"render.pick_label": "Izaberi",
|
||||
"render.pick_up_label": "Preuzmi",
|
||||
"render.pick_up_prompt": "Kliknite objekt da preuzmete njegov izgled",
|
||||
"render.pick_waiting": "Izbor proizvoda još nije podržan.",
|
||||
"render.post_contrast": "Kontrast",
|
||||
"render.post_gain_b": "Pojačanje plave",
|
||||
@@ -2704,13 +3042,17 @@
|
||||
"render.radial_distortion": "Radijalno izobličenje",
|
||||
"render.radial_fit": "Uklopi proizvod",
|
||||
"render.radial_save": "Sačuvaj kadar",
|
||||
"render.recent_looks": "Nedavni izgledi",
|
||||
"render.regrade_action": "Ponovna gradacija sirovog mastera (bez uklanjanja šuma)",
|
||||
"render.regrade_help": "Pravi zaseban PNG iz izabranog završenog sirovog mastera, koristeći ove kontrole prikaza. Ne prati zrake, ne mijenja zabilježenu veličinu, kameru ni svjetla i ne prepisuje EXR. Uklanjanje šuma se ne primjenjuje ponovo: sirovi masteri ne čuvaju njegove vodilje. Izvedena slika se i dalje može izvesti istim kontrolama posla.",
|
||||
"render.regrade_label": "Ponovna gradacija",
|
||||
"render.reload_settings": "Ponovo učitaj sačuvane postavke",
|
||||
"render.remove_override": "Ukloni nadjačavanje",
|
||||
"render.replace_all": "Zamijeni sve",
|
||||
"render.replace_ground": "Potvrdi zamjenu postojeće scene",
|
||||
"render.replace_label": "Zamijeni",
|
||||
"render.replace_saved_surface": "Zamijeni postojeću sačuvanu vezu za ovaj cilj",
|
||||
"render.replace_with": "Zamijeni sa",
|
||||
"render.restore_camera": "Vrati sačuvanu kameru",
|
||||
"render.result_actual": "100%",
|
||||
"render.result_actual_help": "Jedan piksel slike po pikselu ekrana.",
|
||||
@@ -2762,14 +3104,28 @@
|
||||
"render.saved_surface_remove": "Ukloni sačuvanu vezu",
|
||||
"render.saved_surfaces": "Sačuvane veze površina",
|
||||
"render.saved_surfaces_help": "Fiksirane ugrađene mape prate izabrani primjerak u lokalnim milimetrima. Zamijenjen ili nedostajući cilj je greška, nikad automatska ponovna dodjela.",
|
||||
"render.scene_all_shots": "Svi kadrovi ({count})",
|
||||
"render.scene_apply": "Primijeni pregledani studio",
|
||||
"render.scene_batch_reason": "Za Svi kadrovi potreban je red čekanja za renderovanje sačuvanih kadrova, koji još nije dostupan.",
|
||||
"render.scene_check_now": "Provjeri sada",
|
||||
"render.scene_check_passed": "Provjera uspješna · napomene: {notes}",
|
||||
"render.scene_check_stale": "Provjera je zastarjela · provjerite ponovo",
|
||||
"render.scene_check_unchecked": "Još nije provjereno · 0 napomena",
|
||||
"render.scene_consent": "Potvrdi zamjenu osvjetljenja, okruženja, ekspozicije i scene",
|
||||
"render.scene_light_summary": "{environment} · svjetla: {lights}",
|
||||
"render.scene_look_summary": "Izgledi: {looks} · nadjačavanja: {overrides}",
|
||||
"render.scene_open_check": "Otvori provjeru",
|
||||
"render.scene_preserved_fields": "Kamera, uzorkovanje, dimenzije, optičke veze, CAD geometrija i inženjerski materijali se čuvaju.",
|
||||
"render.scene_preserves_design": "Sastavite osvjetljenje i pasivnu scenu za vidljivi predmet. Geometrija, inženjerski materijali i kamera ostaju odvojeni.",
|
||||
"render.scene_ready": "Spremno za renderovanje",
|
||||
"render.scene_reminder": "Scena čuva dizajn. Geometrija, inženjerska svojstva i CAD nikad se ne mijenjaju iz Renderovanja.",
|
||||
"render.scene_reminders": "Podsjetnici",
|
||||
"render.scene_renderer_ready": "{renderer}: spremno",
|
||||
"render.scene_replaces": "Zamjenjuje",
|
||||
"render.scene_review": "Razriješi i pregledaj",
|
||||
"render.scene_review_help": "Pregledajte kompletnu izvornu kompoziciju prije primjene. Nevezane napredne SCENE specifikacije se ne zamjenjuju.",
|
||||
"render.scene_scope_details": "Opseg kompozicije",
|
||||
"render.scene_stages": "Faze",
|
||||
"render.search_appearances": "Pretraži {count} izgleda",
|
||||
"render.setup_legacy_environment": "Ova starija postavka koristi naslijeđenu rotaciju ili intenzitet okruženja. Te vrijednosti se zadržavaju; izričito ih pretvorite prije čuvanja punog posla slike.",
|
||||
"render.setup_name": "Naziv postavke",
|
||||
@@ -2782,7 +3138,22 @@
|
||||
"render.shell_tab_camera": "KAMERA RENDERA",
|
||||
"render.shell_tab_lighting": "OSVJETLJENJE",
|
||||
"render.shell_tab_scene": "SCENA RENDERA",
|
||||
"render.shot_aperture": "Otvor blende",
|
||||
"render.shot_distance": "Udaljenost",
|
||||
"render.shot_dof": "Dubinska oštrina",
|
||||
"render.shot_duplicate": "Dupliciraj sačuvani kadar",
|
||||
"render.shot_edit_output": "Uredi u Izlazu",
|
||||
"render.shot_exposure_reason": "Ekspozicija zahtijeva CPU praćenje zraka ili GPU praćenje putanja.",
|
||||
"render.shot_exposure_section": "Ekspozicija",
|
||||
"render.shot_focus_distance": "Udaljenost fokusa",
|
||||
"render.shot_fov_reason": "Vidno polje zahtijeva perspektivnu projekciju.",
|
||||
"render.shot_frame_subject": "Uokviri predmet",
|
||||
"render.shot_invalid_camera": "Vrijednosti kamere moraju biti konačne i unutar raspona.",
|
||||
"render.shot_lens": "Objektiv",
|
||||
"render.shot_lens_enable_reason": "Omogućite dubinsku oštrinu da biste uredili otvor blende i udaljenost fokusa.",
|
||||
"render.shot_lens_gpu_reason": "Dubinska oštrina zahtijeva GPU praćenje putanja.",
|
||||
"render.shot_lens_perspective_reason": "Dubinska oštrina zahtijeva perspektivnu projekciju.",
|
||||
"render.shot_look_selection": "Usmjeri na izbor",
|
||||
"render.shot_manager": "Sačuvani kadrovi",
|
||||
"render.shot_new_name": "Naziv novog kadra",
|
||||
"render.shot_remove": "Ukloni sačuvani kadar",
|
||||
@@ -2790,6 +3161,9 @@
|
||||
"render.shot_remove_title": "Ukloniti sačuvani kadar?",
|
||||
"render.shot_rename": "Preimenuj sačuvani kadar",
|
||||
"render.shot_saved_only": "Prvo sačuvajte trenutni nacrt. Dupliciranje i preimenovanje čuvaju tačne sačuvane opcije i reference na resurse.",
|
||||
"render.shot_selection_reason": "Izaberite tijelo ili lice prema kojem treba usmjeriti kameru.",
|
||||
"render.shot_size": "Veličina",
|
||||
"render.shot_target": "Cilj",
|
||||
"render.shots_camera_changed": "Kamera je promijenjena od čuvanja ovog kadra",
|
||||
"render.shots_name_help": "Unesite jedinstven naziv za trenutni kadar.",
|
||||
"render.shots_no_result": "Još nema renderovanja",
|
||||
@@ -3052,6 +3426,7 @@
|
||||
"select an axis": "izaberite osu",
|
||||
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "prvo izaberite osu, pravu ili kružnu ivicu, ili lice cilindra, konusa ili torusa",
|
||||
"select bodies first": "prvo izaberite tijela",
|
||||
"select components first": "prvo izaberite komponente",
|
||||
"select corner points, or the two lines of one corner": "izaberite tačke uglova ili dvije linije jednog ugla",
|
||||
"select one corner point, or the two lines of one corner": "izaberite jednu tačku ugla ili dvije linije jednog ugla",
|
||||
"select sheet edges first": "prvo izaberite ivice lima",
|
||||
@@ -3070,6 +3445,7 @@
|
||||
"settings.double_click_components": "Dvaput kliknite komponentu da je aktivirate ili da uredite povezanu komponentu na mjestu",
|
||||
"settings.frame_rate_details_note": "Dodaje graf vremena posljednjih kadrova s brojem iscrtanih trouglova, histogram vremena kadrova i šta je GPU nacrtao. Kliknite broj kadrova u sekundi u prikazu da ih prikažete ili sakrijete.",
|
||||
"settings.frame_rate_note": "Prikazuje broj kadrova u sekundi u donjem desnom uglu prikaza.",
|
||||
"settings.insert_lists_open_designs": "Umetni dizajn prvo navodi dizajne otvorene na drugim karticama",
|
||||
"settings.measure_axis_distances": "Prikaži udaljenosti X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "Prikazuj komponente udaljenosti po svjetskim osama uz ukupnu udaljenost dok je Mjerenje otvoreno.",
|
||||
"settings.msaa_applies_on_restart": "Uglađivanje ivica primjenjuje se pri sljedećem pokretanju SolidCrafta",
|
||||
@@ -3094,6 +3470,10 @@
|
||||
"shortcut.unpin": "Otkači",
|
||||
"sketch is missing": "skica nedostaje",
|
||||
"sketch.degrees_of_freedom": "Stepeni slobode: {count}",
|
||||
"sketch.dimension_added_driven": "Skica već određuje tu kotu, pa je dodana kao zavisna (referentna) kota",
|
||||
"sketch.dimension_applied": "Kota je primijenjena",
|
||||
"sketch.dimension_applied_defined": "Kota je primijenjena; parametar `{name}` je definisan",
|
||||
"sketch.dimension_applied_renamed": "Kota je primijenjena; parametar je nazvan `{name}`",
|
||||
"sketch.dof_left": "Preostali stepeni slobode: {count}",
|
||||
"sketch.dof_left_one": "Preostali stepeni slobode: {count}",
|
||||
"sketch.draw_curves": "Crtaj kao {linetype}",
|
||||
@@ -3128,6 +3508,8 @@
|
||||
"sketch_text.use_font_file": "Koristi datoteku fonta {path}",
|
||||
"solid": "puno",
|
||||
"status.editing": "Uređivanje: {name}",
|
||||
"status.navigation": "Mapiranje miša: {mapping}",
|
||||
"status.navigation_tip": "Kako miš pomjera prikaz. Kliknite da izaberete drugo mapiranje",
|
||||
"status.under_constrained": "Nedovoljno ograničeno (stepeni slobode: {count})",
|
||||
"status.under_constrained_one": "Nedovoljno ograničeno ({count} stepen slobode)",
|
||||
"status.units_tip": "Jedinice dizajna. Kliknite da ih promijenite",
|
||||
@@ -3161,8 +3543,10 @@
|
||||
"timeline.delete_folders_tip": "Zadrži njihove operacije i ugniježđene foldere u vremenskoj traci",
|
||||
"timeline.delete_folders_with_features_tip": "Izbriši foldere sa svim operacijama u njima i njihove ugniježđene foldere",
|
||||
"timeline.delete_many": "Izbriši izabrane operacije: {count}",
|
||||
"timeline.edited_rolled_back": "Operacija {name} je promijenjena, ali je iza oznake vraćanja, pa se ne gradi: pomjerite oznaku iza nje da vidite rezultat",
|
||||
"timeline.feature_error": "Greška: {message}",
|
||||
"timeline.feature_hint": "Dvaput kliknite za uređivanje · povucite za promjenu redoslijeda · desni klik za više",
|
||||
"timeline.feature_rolled_back": "Vraćeno: iza oznake vraćanja, pa se ne gradi",
|
||||
"timeline.feature_warning": "Upozorenje: {message}",
|
||||
"timeline.group": "Novi folder operacija",
|
||||
"timeline.move_many": "Premjesti stavke vremenske trake",
|
||||
@@ -3244,6 +3628,10 @@
|
||||
"ui.3d_mouse_offer": "Kalibracija 3D miša ispravlja zamijenjene ili obrnute ose i podešava njegovu brzinu i osjećaj.",
|
||||
"ui.3d_mouse_offer_never": "Ne prikazuj više",
|
||||
"ui.3d_mouse_offer_swap": "Prebaci na Hidraw (direktni drajver)",
|
||||
"ui.3d_mouse_orbit": "Orbitiranje",
|
||||
"ui.3d_mouse_orbit_classic": "Klasično",
|
||||
"ui.3d_mouse_orbit_tip": "Prema modelu: 3D miš okreće prikaz oko dijela modela koji je u sredini prikaza kada okretanje počne, označenog blijedom kuglom. Klasično: oko centra prikaza",
|
||||
"ui.3d_mouse_orbit_traced": "Prema modelu",
|
||||
"ui.3d_mouse_reading": "Očitanje",
|
||||
"ui.3d_mouse_reset_axes": "Resetuj dodjelu osa",
|
||||
"ui.3d_mouse_reset_view": "Resetuj prikaz",
|
||||
@@ -3280,6 +3668,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Zakrenite kapicu suprotno od kazaljke na satu, držite je, a zatim pustite.",
|
||||
"ui.3d_mouse_switch_cap": "Kalibriši kao Povratak u centar",
|
||||
"ui.3d_mouse_switch_trackball": "Kalibriši kao trackball",
|
||||
"ui.3d_mouse_use_direct": "Koristi direktni drajver",
|
||||
"ui.3d_mouse_use_direct_tip": "Čitaj 3D miš direktno (hidraw) umjesto preko spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "Osa prikaza",
|
||||
"ui.3d_mouse_view_off": "Isključeno",
|
||||
"ui.3d_mouse_view_off_tip": "Profil drajvera 3D miša isključuje ovu osu, pa njeno kretanje ne pomjera prikaz. Izbor kretanja druge ose ovdje ih zamjenjuje, a to kretanje prestaje pomjerati prikaz.",
|
||||
@@ -3596,6 +3986,7 @@
|
||||
"ui.circle": "Krug",
|
||||
"ui.circular_pattern": "Kružni niz",
|
||||
"ui.clear": "Očisti",
|
||||
"ui.clear_print_face": "Ukloni površinu za štampu",
|
||||
"ui.clear_recent": "Očisti nedavno",
|
||||
"ui.clear_the_selection": "Poništi izbor",
|
||||
"ui.click_selects_whole_bodies": "Klik bira cijela tijela",
|
||||
@@ -3630,6 +4021,15 @@
|
||||
"ui.constant": "Konstantno",
|
||||
"ui.constraints_conflict": "Ograničenja su u sukobu",
|
||||
"ui.construction": "Pomoćna",
|
||||
"ui.construction.angle_hint": "Pomoćna prava: kliknite tačku, pa upišite ugao ili izaberite smjer",
|
||||
"ui.construction.bisector_hint": "Simetrala: izaberite dvije prave linije koje se sijeku, pa željeno rješenje",
|
||||
"ui.construction.common_hint": "Zajednička tangenta: izaberite dva kruga ili luka, pa željeno rješenje",
|
||||
"ui.construction.contact_hint": "Tangenta: izaberite krug/luk ili otvoreni splajn/koniku, pa tačku dodira (krive slobodnog oblika: krajnje tačke)",
|
||||
"ui.construction.external_hint": "Tangenta: izaberite krug ili luk, vanjsku tačku, pa željeno rješenje",
|
||||
"ui.construction.free_hint": "Pomoćna prava: kliknite dvije tačke; desnim klikom počnite ispočetka",
|
||||
"ui.construction.point_hint": "Pomoćna prava: kliknite tačku kroz koju prolazi",
|
||||
"ui.construction.reference_hint": "Pomoćna prava: izaberite pravu liniju, pa tačku; desnim klikom promijenite referencu",
|
||||
"ui.construction.ribbon_label": "Pomoćne",
|
||||
"ui.context_menu": "Kontekstni meni",
|
||||
"ui.continuity_g0": "G0 pregib",
|
||||
"ui.continuity_g1": "G1 tangentno",
|
||||
@@ -3670,6 +4070,7 @@
|
||||
"ui.design_properties.part_number": "Broj dijela",
|
||||
"ui.design_properties.project": "Projekat",
|
||||
"ui.design_properties.revision": "Revizija",
|
||||
"ui.design_saved": "Sačuvano: {path}",
|
||||
"ui.diameter": "Prečnik",
|
||||
"ui.dimension": "Kota",
|
||||
"ui.direct_interaction": "Direktna interakcija",
|
||||
@@ -3720,6 +4121,14 @@
|
||||
"ui.end_scale": "Krajnje skaliranje",
|
||||
"ui.entities": "Elementi",
|
||||
"ui.equal": "Jednakost",
|
||||
"ui.equation_end": "Kraj",
|
||||
"ui.equation_explicit": "Eksplicitno",
|
||||
"ui.equation_form": "Oblik",
|
||||
"ui.equation_note": "Varijabla je običan broj: sin(t) je uzima u radijanima. Rezultat bez jedinice je u jedinici dizajna.",
|
||||
"ui.equation_parametric": "Parametarski",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Ekvivalentni poluprečnik",
|
||||
"ui.expand": "Proširi",
|
||||
"ui.exportDxf": "Izvezi DXF…",
|
||||
@@ -3785,6 +4194,7 @@
|
||||
"ui.heading_design": "DIZAJN",
|
||||
"ui.heading_draft": "NAGIB",
|
||||
"ui.heading_edit": "UREDI",
|
||||
"ui.heading_equation_curve": "KRIVA IZ JEDNAČINE",
|
||||
"ui.heading_extrude": "EKSTRUDIRAJ",
|
||||
"ui.heading_fillet": "ZAOBLJENJE",
|
||||
"ui.heading_finish_editing": "ZAVRŠI UREĐIVANJE",
|
||||
@@ -3876,6 +4286,10 @@
|
||||
"ui.import_ellipsis": "Uvezi…",
|
||||
"ui.infinite": "Beskonačno",
|
||||
"ui.insert": "Umetni",
|
||||
"ui.insert_design.browse": "Pregledaj…",
|
||||
"ui.insert_design.open_designs": "Otvoreni dizajni",
|
||||
"ui.insert_design.saved_file": "{name} ima nesačuvane promjene, pa je umetnuta njegova sačuvana datoteka. Sačuvajte ga, a zatim pokrenite Ažuriraj veze da unesete promjene.",
|
||||
"ui.insert_design.unsaved": "Nesačuvane promjene",
|
||||
"ui.inspect": "Pregledaj",
|
||||
"ui.intersect": "Presjek",
|
||||
"ui.isolate": "Izoluj",
|
||||
@@ -4019,12 +4433,29 @@
|
||||
"ui.polygon": "Poligon",
|
||||
"ui.preferences": "Postavke",
|
||||
"ui.press_a_key": "pritisnite tipku…",
|
||||
"ui.print_face_cleared": "{body}: površina za štampu uklonjena",
|
||||
"ui.print_face_input": "Površina za štampu",
|
||||
"ui.print_face_one_body": "Površina za štampu pripada jednom tijelu: pošaljite to tijelo samo da biste je promijenili",
|
||||
"ui.print_face_pick": "Odaberite ravnu površinu punog tijela da postane površina za štampu",
|
||||
"ui.print_face_set": "{body}: površina za štampu postavljena; Pošalji u slajser polaže tijelo na nju",
|
||||
"ui.profile": "Profil",
|
||||
"ui.profile_plane": "Ravan profila",
|
||||
"ui.profiles": "Profili",
|
||||
"ui.project": "Projektuj",
|
||||
"ui.project_face_edges_sketch": "Projektuj ivice lica u nove skice",
|
||||
"ui.properties": "Svojstva",
|
||||
"ui.properties.copy_matrix": "Kopiraj matricu",
|
||||
"ui.properties.first_moments": "Statički momenti",
|
||||
"ui.properties.inertia": "Moment inercije",
|
||||
"ui.properties.inertia_note": "Oko centra mase, u svjetskim osama (g·{unit}²)",
|
||||
"ui.properties.inertia_unavailable": "Nije dostupno: mreža jednog tijela nije zatvorena.",
|
||||
"ui.properties.inertia_x": "Ixx, Ixy, Ixz",
|
||||
"ui.properties.inertia_y": "Iyx, Iyy, Iyz",
|
||||
"ui.properties.inertia_z": "Izx, Izy, Izz",
|
||||
"ui.properties.measuring": "Mjerenje…",
|
||||
"ui.properties.measuring_failed": "Mjerenje je zaustavljeno prije završetka.",
|
||||
"ui.properties.principal_axis": "Glavna osa {number}",
|
||||
"ui.properties.principal_moments": "Glavni momenti",
|
||||
"ui.pull_direction": "Smjer vađenja iz kalupa",
|
||||
"ui.quality": "Kvalitet",
|
||||
"ui.quantity": "Broj",
|
||||
@@ -4070,6 +4501,7 @@
|
||||
"ui.revolve": "Rotiraj",
|
||||
"ui.ribbon_exit": "Izađi",
|
||||
"ui.ribbon_labels": "Prikaži tekst ispod ikona na traci",
|
||||
"ui.ribbon_menus_skip_pinned": "Izostavi prikačene komande iz padajućih menija",
|
||||
"ui.ribbon_pin_footer": "Prikačene komande prikazuju se na traci. Zadržite pokazivač iznad reda da ga prikačite ili otkačite.",
|
||||
"ui.ribbon_workspace": "Radni prostor",
|
||||
"ui.right": "Desno",
|
||||
@@ -4087,6 +4519,7 @@
|
||||
"ui.select": "Izaberi",
|
||||
"ui.selectOther": "Izaberi drugo…",
|
||||
"ui.selectTangentChain": "Izaberi tangentni lanac",
|
||||
"ui.select_all": "Izaberi sve",
|
||||
"ui.selection": "Izbor",
|
||||
"ui.selection_modifiers": "Modifikatori izbora",
|
||||
"ui.selection_shift_add_only": "Shift+klik dodaje bez uklanjanja",
|
||||
@@ -4123,7 +4556,11 @@
|
||||
"ui.sketch": "Skica",
|
||||
"ui.sketch_dimension": "Kota skice",
|
||||
"ui.sketch_grid": "Mreža skice",
|
||||
"ui.sketch_intersect_geometry": "Geometrija",
|
||||
"ui.sketch_intersect_projection_link": "Veza projekcije",
|
||||
"ui.sketch_intersect_selection_filter": "Filter izbora",
|
||||
"ui.sketch_modifiers": "Modifikatori skice",
|
||||
"ui.sketch_project_geometry": "Geometrija",
|
||||
"ui.sketch_scale": "Skaliranje skice",
|
||||
"ui.sketches": "Skice",
|
||||
"ui.slice": "Presijeci",
|
||||
@@ -4170,6 +4607,11 @@
|
||||
"ui.symmetric": "Simetrično",
|
||||
"ui.symmetry": "Simetrija",
|
||||
"ui.system": "Sistem",
|
||||
"ui.tab_assemble": "Sklopi",
|
||||
"ui.tab_manage": "Upravljanje",
|
||||
"ui.tab_sheet_metal": "Lim",
|
||||
"ui.tab_view": "Prikaz",
|
||||
"ui.tab_weldments": "Zavarene konstrukcije",
|
||||
"ui.tangent": "Tangentno",
|
||||
"ui.taper_angle": "Ugao suženja",
|
||||
"ui.tapped": "S navojem",
|
||||
@@ -4185,6 +4627,7 @@
|
||||
"ui.tip_angle": "Ugao vrha",
|
||||
"ui.to_object": "Do objekta",
|
||||
"ui.tool_direction": "Smjer alata",
|
||||
"ui.toolbar_tabs_hidden": "Sve kartice trake s alatima su skrivene. Kliknite + ili kliknite desnim dugmetom ovdje da prikažete jednu.",
|
||||
"ui.top": "Odozgo",
|
||||
"ui.top_diameter": "Gornji prečnik",
|
||||
"ui.top_radius": "Gornji poluprečnik",
|
||||
@@ -4222,6 +4665,8 @@
|
||||
"ui.view_centre": "Centar prikaza",
|
||||
"ui.viewport_status_clear": "Isključi: {name}",
|
||||
"ui.viewport_status_clear_hint": "Isključi: {name} · Esc",
|
||||
"ui.viewport_status_edges": "Ivice: {count}",
|
||||
"ui.viewport_status_from": "iz smjera {direction}",
|
||||
"ui.viewport_status_key": "Prikaži legendu: {name}",
|
||||
"ui.viewport_status_minimum_radius": "Minimalni poluprečnik",
|
||||
"ui.viewport_status_pairs": "Parovi: {count}",
|
||||
@@ -4231,6 +4676,7 @@
|
||||
"ui.visual_shaded_with_edges": "Osjenčeno s ivicama",
|
||||
"ui.visual_style": "Vizuelni stil",
|
||||
"ui.visual_wireframe": "Žičani model",
|
||||
"ui.wheel_zoom_speed": "Brzina zumiranja točkićem miša",
|
||||
"ui.width": "Širina",
|
||||
"ui.window_system": "Sistem prozora",
|
||||
"ui.window_system_auto": "Automatski",
|
||||
@@ -4261,7 +4707,9 @@
|
||||
"update.button": "Ažuriraj",
|
||||
"update.button_version": "Ažuriraj na {version}",
|
||||
"update.check_automatically": "Automatski provjeravaj ažuriranja",
|
||||
"update.check_for_updates": "Provjeri ažuriranja",
|
||||
"update.check_now": "Provjeri sada",
|
||||
"update.check_unavailable": "Provjera ažuriranja nije dostupna za ovu instalaciju.",
|
||||
"update.checking": "Provjera…",
|
||||
"update.copy": "Kopiraj",
|
||||
"update.dmg_opened": "Slika diska je otvorena i provjerena: prevucite SolidCraft u Applications, zamijenite staru kopiju, a zatim ponovo pokrenite SolidCraft.",
|
||||
@@ -4284,6 +4732,9 @@
|
||||
"update.prefs_managed": "Ovo je SolidCraft {version}, kojim upravlja {manager}. Provjera pita GitHub za najnovije izdanje i ne šalje ništa drugo; ažurirajte SolidCraft u {manager}.",
|
||||
"update.prefs_note": "Ovo je SolidCraft {version} ({kind}). Provjera pita GitHub za najnovije izdanje i ne šalje ništa drugo.",
|
||||
"update.prefs_web": "Ponovo učitajte stranicu da dobijete najnoviju web aplikaciju. Ako mreža nije dostupna ili se ažuriranje ne može preuzeti na vrijeme, otvara se sačuvana verzija; preuzimanje u toku nastavlja se za sljedeće ponovno učitavanje.",
|
||||
"update.refresh_checking": "Provjera najnovijeg izdanja…",
|
||||
"update.refresh_fallback": "Provjera novijeg izdanja nije uspjela; ažurira se na verziju {version}, pronađenu ranije.",
|
||||
"update.refresh_selected": "Ažuriranje na {version}.",
|
||||
"update.release_page": "Otvori stranicu izdanja",
|
||||
"update.restart": "Ponovo pokreni sada",
|
||||
"update.restart_later": "Kasnije",
|
||||
|
||||
@@ -1,22 +1,42 @@
|
||||
{
|
||||
"A Single hole snaps to the middle of its face and to the centres of its round edges": "A Single hole snaps to the middle of its face and to the centres of its round edges",
|
||||
"Base Center": "Base Centre",
|
||||
"Center X": "Centre X",
|
||||
"Center Y": "Centre Y",
|
||||
"Center of mass": "Centre of mass",
|
||||
"Centre to centre": "Centre to centre",
|
||||
"Circle center": "Circle centre",
|
||||
"Colour": "Colour",
|
||||
"Copy all licences": "Copy all licences",
|
||||
"Customize Toolbar": "Customise Toolbar",
|
||||
"Customize…": "Customise…",
|
||||
"Face center": "Face centre",
|
||||
"Favorites": "Favourites",
|
||||
"Favourite": "Favourite",
|
||||
"Mass Center": "Mass Centre",
|
||||
"Modeled": "Modelled",
|
||||
"Select the centre the pattern turns around first": "Select the centre the pattern turns around first",
|
||||
"Snap to face and edge centres": "Snap to face and edge centres",
|
||||
"Specialise": "Specialise",
|
||||
"cmd.appearance_favorite": "Favourite Look",
|
||||
"cmd.component_cycle_color": "Cycle Component Colour",
|
||||
"cmd.construct_point_center": "Point At Centre Of Circle/Sphere/Torus",
|
||||
"cmd.inspect_center_of_mass": "Centre of Mass",
|
||||
"cmd.inspect_colored_components": "Enable Component Colours",
|
||||
"cmd.inspect_colored_components_disable": "Disable Component Colours",
|
||||
"cmd.parameters_favorite": "Favourite Parameter",
|
||||
"cmd.render_aging_describe": "Layered Surface Aging",
|
||||
"cmd.render_effects_describe": "Lens and Creative Effects",
|
||||
"cmd.sketch.construction_line": "Construction Line",
|
||||
"cmd.sketch.construction_line.angle": "Construction Line at Angle",
|
||||
"cmd.sketch.construction_line.bisector": "Angle Bisector",
|
||||
"cmd.sketch.construction_line.horizontal": "Horizontal Construction Line",
|
||||
"cmd.sketch.construction_line.parallel": "Parallel Construction Line",
|
||||
"cmd.sketch.construction_line.perpendicular": "Perpendicular Construction Line",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tangent at Curve Point",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tangent through External Point",
|
||||
"cmd.sketch.construction_line.tangent_two": "Common Tangent",
|
||||
"cmd.sketch.construction_line.vertical": "Vertical Construction Line",
|
||||
"cmd.sketch_arc_center_point": "Centre Point Arc",
|
||||
"cmd.sketch_circle_center": "Centre Diameter Circle",
|
||||
"cmd.sketch_rectangle_center": "Centre Rectangle",
|
||||
@@ -28,7 +48,26 @@
|
||||
"color.gamma": "Showing colour values in 0-255 gamma space",
|
||||
"color.linear": "Showing colour values in 0-1 linear space",
|
||||
"color.selected": "Selected colour",
|
||||
"dxf.cancelled": "DXF export cancelled",
|
||||
"dxf.cancelling": "Cancelling DXF export",
|
||||
"help.apache": "Apache licence 2.0",
|
||||
"help.appearance.assign": "Gives the selected bodies, faces or components a colour or a material look, without changing their weight. Use it to tell parts apart or to preview a finish.",
|
||||
"help.face.delete": "Removes the selected faces and lets the neighbouring faces close the gap, or leaves the gap open as a surface. Use it to take off a rounded edge, a hole or a boss that is in the way.",
|
||||
"help.font_details": "The interface uses egui's built-in fonts (Ubuntu Light and Hack, under the Ubuntu Font Licence and the MIT/Bitstream Vera licence; Noto Emoji and the emoji icon font, under the OFL and MIT). Sketch text uses Liberation Sans (SIL OFL 1.1). The Crafting Apps' optional font pack, craft-fonts (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic; SIL OFL 1.1), is not bundled in SolidCraft builds.",
|
||||
"help.licences": "Licences",
|
||||
"help.material.assign": "Sets what the selected bodies are made of, such as steel, aluminium or ABS. Use it so that the mass and weight match the real part.",
|
||||
"help.mit": "MIT licence",
|
||||
"help.solid.draft": "Tilts the selected faces by the angle you set, measured from a neutral plane. Use it on moulded or cast parts so that they slide out of the mould.",
|
||||
"help.solid.revolve": "Spins a sketch profile around an axis to make a round solid. Use it for shafts, knobs, bowls and any part that is round about a centre line.",
|
||||
"help.solid.split_body": "Cuts a body into separate bodies with a plane, the face of another body or a sketch line. Use it to make parts that are printed, machined or coloured on their own.",
|
||||
"help.solid.split_face": "Divides the selected faces along a plane, the face of another body or sketch curves, without cutting the body. Use it to give part of a face its own draft, colour or offset.",
|
||||
"help.third_party": "Third-party licences",
|
||||
"home.new_mm_hint": "Millimetres · opens in Design",
|
||||
"navbar.custom.customise": "Customise navigation bar…",
|
||||
"navbar.custom.position_centre": "Centre",
|
||||
"navbar.description.separator": "A thin line that groups neighbouring slots.",
|
||||
"pattern.alignment_hint": "Counts include the original. Centre balances copies; Flip chooses the extra side for even totals.",
|
||||
"prefs.bottom_centre": "Bottom centre",
|
||||
"prefs.logo_theme": "Theme's colours",
|
||||
"prefs.max_file_size": "Largest file to open",
|
||||
"prefs.max_file_size_design": "Design files",
|
||||
@@ -39,6 +78,9 @@
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.sketch_conflict_colour": "Conflicting geometry in the conflict colour",
|
||||
"prefs.sketch_conflict_colour_note": "While a sketch's constraints conflict, the curves and points a failing constraint holds are drawn in the conflict colour too, not only its glyph or dimension. Off: they keep their usual colours.",
|
||||
"prefs.sketch_construction_lines": "Extended construction line tools",
|
||||
"prefs.sketch_recent_snap": "Auto snap to recent centres and midpoints",
|
||||
"prefs.sketch_recent_snap_note": "While drawing, snap the cursor where the guides of the two most recent circle centres or straight-edge midpoints cross. Off: those guides stay visual and the cursor does not move.",
|
||||
"prefs.sketch_state_icons": "Sketch icons in the colour of their state",
|
||||
"prefs.sketch_state_icons_note": "In History and the browser, a sketch's icon takes the colour of its state (under constrained, fully constrained or conflicting) and its tooltip names the state. Off: every sketch has the same icon.",
|
||||
"prefs.sketch_tracking_guides": "Centre and midpoint alignment guides",
|
||||
@@ -50,6 +92,7 @@
|
||||
"prefs.theme_follow_note": "Reloaded whenever another tool rewrites it. Choosing a theme stops following it.",
|
||||
"prefs.theme_follow_off": "Off",
|
||||
"prefs.theme_follow_stop": "Stop following",
|
||||
"prefs.trackpad_zoom_modifier.help": "Hold only this key to zoom at the pointer with vertical scroll. Off keeps the existing scroll behaviour.",
|
||||
"prefs.view": "View behaviour",
|
||||
"prefs.viewport_background_colour": "Colour",
|
||||
"render.aging_add": "Add aging layer",
|
||||
@@ -79,6 +122,7 @@
|
||||
"render.aging_target_help": "A named target must still match its captured index and name. Global masks are world-anchored; they do not follow moving parts. This is neither cavity detection nor true edge wear. Filter the list to reach additional bodies.",
|
||||
"render.aging_target_search": "Filter body names",
|
||||
"render.aging_upward": "Upward-facing deposition",
|
||||
"render.appearance_editor.base_colour": "Base colour",
|
||||
"render.backdrop_first": "Start / centre colour",
|
||||
"render.backdrop_second": "End / edge colour",
|
||||
"render.backdrop_x": "Centre X",
|
||||
@@ -95,21 +139,31 @@
|
||||
"render.base_color": "Base colour · sRGB",
|
||||
"render.bloom_help": "Creative output-only glow from positive linear highlights, spread with three normalised box passes. Radius is in output pixels. Added in linear display light before sRGB; not a lens, volumetric effect or convergence improvement. The raw EXR is unchanged.",
|
||||
"render.chromatic_offset": "Chromatic edge offset",
|
||||
"render.cpu_area_editor_help": "Full side vectors in millimeters; U cross V points towards the emitting side. This differs from GPU half-edge vectors.",
|
||||
"render.cpu_light_help": "Up to eight directional lights. An empty custom list turns them off; selecting a preset restores its lights. Colours are linear RGB and intensity is relative, not watts.",
|
||||
"render.cpu_linear_color": "Linear colour (R, G, B)",
|
||||
"render.effects_gpu_only": "These effects require GPU path tracing. Changing the page never switches the renderer automatically.",
|
||||
"render.effects_help": "Combine ordered colour looks and image-space lens effects. Rendering and raw-master regrading use the same saved settings. Raw EXR stays unchanged. These are original artistic controls, not calibrated lens or branded-film emulations.",
|
||||
"render.effects_reset_lens": "Reset lens effects",
|
||||
"render.effects_seed": "Pattern seed",
|
||||
"render.env_colour": "Colour",
|
||||
"render.environment.radial_only": "Centre and radius apply to Radial mode.",
|
||||
"render.error_finish_gesture": "finish the modelling gesture before previewing",
|
||||
"render.error_finish_operation": "finish the current modelling operation before entering Render",
|
||||
"render.film_grain": "Photographic grain",
|
||||
"render.flare_ghosts": "Ghost rings per source",
|
||||
"render.flare_halo": "Flare halo",
|
||||
"render.flare_streak": "Anamorphic-style streak",
|
||||
"render.flare_strength": "Highlight flare strength",
|
||||
"render.flare_threshold": "Scene-linear flare threshold",
|
||||
"render.frame_centre_mark": "Centre mark",
|
||||
"render.hdr_primaries_declared": "The source declares its colour primaries.",
|
||||
"render.hdr_primaries_srgb": "Colour primaries: sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "The source does not declare primaries; review the renderer colour requirements.",
|
||||
"render.image_cancelled": "Render cancelled",
|
||||
"render.image_cancelling": "Cancelling",
|
||||
"render.image_scene_stale": "Finish the modelling gesture or refresh the scene before checking or starting an image.",
|
||||
"render.inspector_colour": "Colour",
|
||||
"render.layer_down": "Move down",
|
||||
"render.layer_enabled": "Layer enabled",
|
||||
"render.layer_remove": "Remove layer",
|
||||
@@ -124,6 +178,11 @@
|
||||
"render.library_rig_help": "Fit once at an explicit centre and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_source_preview_help": "Authored base-colour source map. This is not a rendered or measured material preview.",
|
||||
"render.library_unfavorite": "Remove favourite",
|
||||
"render.light_behaviour": "BEHAVIOUR",
|
||||
"render.light_preview_help": "Live view is unshadowed; Area lights use a centre-sample approximation. Render uses the complete light model.",
|
||||
"render.light_product_centre": "Product centre",
|
||||
"render.light_temperature": "Colour temperature",
|
||||
"render.lighting_colour": "Colour",
|
||||
"render.look_add": "Add colour look",
|
||||
"render.look_bleach": "Bleach-bypass-inspired",
|
||||
"render.look_cool": "Cool",
|
||||
@@ -147,30 +206,45 @@
|
||||
"render.radial_distortion": "Radial distortion",
|
||||
"render.ribbon_aging": "Aging",
|
||||
"render.ribbon_effects": "Effects",
|
||||
"render.ribbon_studios_help": "Browse implemented studio compositions and review their replacements before applying. Concept-only scenes remain labelled.",
|
||||
"render.sharpening": "Detail sharpening",
|
||||
"render.soft_focus": "Soft focus",
|
||||
"render.stage_panels.centre": "Centre",
|
||||
"render.stage_panels.source_note": "Authored base-colour source map. Not a measured material.",
|
||||
"render.studio_area_help": "Up to four one-sided rectangles. Orthogonal half-edges U and V define size; U × V faces the lit side. Coordinates are world-space millimetres.",
|
||||
"render.studio_center": "Centre X, Y, Z (mm)",
|
||||
"render.studio_hdr_help": "Radiance .hdr, 2:1 panorama, up to 2048 × 1024. EXR is unavailable. The colour assumption applies only when primaries are unspecified.",
|
||||
"sketch_text.align_center": "Centre",
|
||||
"ui.3d_mouse_kind_cap": "Return to Centre",
|
||||
"ui.3d_mouse_looks_like_cap": "The reading stays put while you hold it, the way a Return to Centre device does.",
|
||||
"ui.3d_mouse_orbit_tip": "Traced: the 3D mouse turns the view around the part of the model in the middle of the view when the turn begins, marked by a faint ball. Classic: around the view's centre",
|
||||
"ui.3d_mouse_step_pull": "Pull the cap towards you, hold it, then let go.",
|
||||
"ui.3d_mouse_switch_cap": "Calibrate as Return to Centre",
|
||||
"ui.agent_chat_minimize": "Minimise to a strip",
|
||||
"ui.ai_mode_edits_note": "Modelling commands run without asking; saving, opening, exporting and other file or destructive actions still ask.",
|
||||
"ui.center": "Centre",
|
||||
"ui.center_arc_follows_cursor": "Centre point arc follows the cursor's direction",
|
||||
"ui.center_arc_follows_cursor_tip": "A centre point arc runs clockwise or counter-clockwise the way the cursor goes round its centre. Off: always counter-clockwise from the start.",
|
||||
"ui.centerline": "Centreline",
|
||||
"ui.colour_vision": "Colour vision",
|
||||
"ui.colour_vision_note": "Changes the colours that carry a meaning: sketch states, axes, bends, analyses and icons. If you use Windows colour filters, keep this Off.",
|
||||
"ui.colour_vision_off_tip": "The theme's own colours",
|
||||
"ui.construction.ribbon_label": "X-Lines",
|
||||
"ui.customizeToolbar": "Customise Toolbar…",
|
||||
"ui.default_modelling_orientation": "Default modelling orientation",
|
||||
"ui.design_properties.license": "Licence",
|
||||
"ui.design_properties.organization": "Organisation",
|
||||
"ui.export_keymap_tip": "Keys, S box favourites and the toolbar, as a file",
|
||||
"ui.layout_compact": "Compact",
|
||||
"ui.layout_floating": "Floating",
|
||||
"ui.material_review.claims": "Sources and licences are unverified claims. Missing values remain unknown.",
|
||||
"ui.point_cloud_color_by": "Colour By",
|
||||
"ui.point_cloud_file_colors": "File Colours",
|
||||
"ui.point_cloud_no_file_colors": "The file has no colours",
|
||||
"ui.point_cloud_single_color": "Single Colour",
|
||||
"ui.properties.inertia_note": "About the centre of mass, in world axes (g·{unit}²)",
|
||||
"ui.ribbon_labels": "Show text under ribbon icons",
|
||||
"ui.view_centre": "View centre",
|
||||
"ui.workspace_layout": "Workspace layout",
|
||||
"ui.zoom_to_cursor_tip": "The wheel zooms towards the point under the cursor (off: towards the view's centre)",
|
||||
"update.prefs_flatpak": "Flatpak updates this copy ({version}): run {command} or use your software centre. SolidCraft doesn't check."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"2. Attach your screenshot: copy and paste it, or save and upload the PNG.": "2. Attach your screenshot: copy and paste it, or save and upload the PNG.",
|
||||
"2D": "2D",
|
||||
"3. Click Submit new issue on GitHub to send your report.": "3. Click Submit new issue on GitHub to send your report.",
|
||||
"A Single hole snaps to the middle of its face and to the centres of its round edges": "A Single hole snaps to the middle of its face and to the centres of its round edges",
|
||||
"A Single hole snaps to the middle of its face and to the centres of its round edges": "A Single hole snaps to the middle of its face and to the centers of its round edges",
|
||||
"A new configuration, a copy of the active one": "A new configuration, a copy of the active one",
|
||||
"A placed Single hole has a handle to drag it, and picking its face again moves the hole there instead of taking it out": "A placed Single hole has a handle to drag it, and picking its face again moves the hole there instead of taking it out",
|
||||
"A short title for the problem (optional)": "A short title for the problem (optional)",
|
||||
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "BLEND SURFACE",
|
||||
"BOUNDARY SURFACE": "BOUNDARY SURFACE",
|
||||
"BROWSER": "BROWSER",
|
||||
"Back to the original order": "Back to the original order",
|
||||
"Ball": "Ball",
|
||||
"Bar": "Bar",
|
||||
"Base Center": "Base Center",
|
||||
@@ -100,7 +101,7 @@
|
||||
"Center X": "Center X",
|
||||
"Center Y": "Center Y",
|
||||
"Center of mass": "Center of mass",
|
||||
"Centre to centre": "Centre to centre",
|
||||
"Centre to centre": "Center to center",
|
||||
"Centroid": "Centroid",
|
||||
"Chamfer Type": "Chamfer Type",
|
||||
"Channel": "Channel",
|
||||
@@ -117,7 +118,7 @@
|
||||
"Close draft": "Close draft",
|
||||
"Collapse": "Collapse",
|
||||
"Collisions": "Collisions",
|
||||
"Colour": "Colour",
|
||||
"Colour": "Color",
|
||||
"Command": "Command",
|
||||
"Comment": "Comment",
|
||||
"Component 1": "Component 1",
|
||||
@@ -137,7 +138,7 @@
|
||||
"Copies the definition only. Assign it from Physical Material when ready.": "Copies the definition only. Assign it from Physical Material when ready.",
|
||||
"Copy Error Message": "Copy Error Message",
|
||||
"Copy Warning Message": "Copy Warning Message",
|
||||
"Copy all licences": "Copy all licences",
|
||||
"Copy all licences": "Copy all licenses",
|
||||
"Copy diagnostic information": "Copy diagnostic information",
|
||||
"Copy report": "Copy report",
|
||||
"Copy screenshot": "Copy screenshot",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "Edges",
|
||||
"Edit": "Edit",
|
||||
"Edit Profile Sketch": "Edit Profile Sketch",
|
||||
"Edit shortcuts": "Edit shortcuts",
|
||||
"Enable rule": "Enable rule",
|
||||
"Enabled": "Enabled",
|
||||
"End Radius": "End Radius",
|
||||
@@ -243,7 +245,7 @@
|
||||
"Factor must be a positive number": "Factor must be a positive number",
|
||||
"Fastener": "Fastener",
|
||||
"Favorites": "Favorites",
|
||||
"Favourite": "Favourite",
|
||||
"Favourite": "Favorite",
|
||||
"Feature": "Feature",
|
||||
"Files from many CAD programs have Y up, so they open lying on their back here (Z up).": "Files from many CAD programs have Y up, so they open lying on their back here (Z up).",
|
||||
"Filter": "Filter",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "Radius",
|
||||
"Radius Fit": "Radius Fit",
|
||||
"Ratio": "Ratio",
|
||||
"Read-only list: shortcuts can't be changed here.": "Read-only list: shortcuts can't be changed here.",
|
||||
"Reattach selected face": "Reattach selected face",
|
||||
"Recover": "Recover",
|
||||
"Recover unsaved design?": "Recover unsaved design?",
|
||||
@@ -561,7 +564,7 @@
|
||||
"Select bodies or faces instead": "Select bodies or faces instead",
|
||||
"Select edges": "Select edges",
|
||||
"Select points of the sketch being edited": "Select points of the sketch being edited",
|
||||
"Select the centre the pattern turns around first": "Select the centre the pattern turns around first",
|
||||
"Select the centre the pattern turns around first": "Select the center the pattern turns around first",
|
||||
"Select the curves to offset first": "Select the curves to offset first",
|
||||
"Select the mirror line": "Select the mirror line",
|
||||
"Select the sketch curves or points to mirror first": "Select the sketch curves or points to mirror first",
|
||||
@@ -590,12 +593,14 @@
|
||||
"Sketch points": "Sketch points",
|
||||
"Slider": "Slider",
|
||||
"Slot width": "Slot width",
|
||||
"Snap to face and edge centres": "Snap to face and edge centres",
|
||||
"Snap to face and edge centres": "Snap to face and edge centers",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft closed before these designs were saved. Their last autosave can be opened.",
|
||||
"Sort A to Z": "Sort A to Z",
|
||||
"Sort Z to A": "Sort Z to A",
|
||||
"Spacing 2 must be a non-zero number": "Spacing 2 must be a non-zero number",
|
||||
"Spacing must be a non-zero number": "Spacing must be a non-zero number",
|
||||
"Specialise": "Specialise",
|
||||
"Specialise": "Specialize",
|
||||
"Speed": "Speed",
|
||||
"Splitting tool": "Splitting tool",
|
||||
"Square": "Square",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "at the face",
|
||||
"bom.group_children": "Sub-parts in their part's row",
|
||||
"browser.body_name": "Body{number}",
|
||||
"browser.calibrate_click_a": "Click the image for Point A, or type its coordinates.",
|
||||
"browser.calibrate_click_b": "Click the image for Point B, or type its coordinates.",
|
||||
"browser.calibrate_title": "Calibrate: {name}",
|
||||
"browser.capture_many": "{count} components were moved but their positions aren't captured.",
|
||||
"browser.capture_note": "Capture keeps the new position; Revert puts it back.",
|
||||
@@ -807,7 +814,7 @@
|
||||
"cmd.appearance_assign": "Appearance",
|
||||
"cmd.appearance_chain": "Appearance Chain",
|
||||
"cmd.appearance_copy": "Copy Look",
|
||||
"cmd.appearance_favorite": "Favourite Look",
|
||||
"cmd.appearance_favorite": "Favorite Look",
|
||||
"cmd.appearance_library": "Appearance Library",
|
||||
"cmd.appearance_list": "List Appearances",
|
||||
"cmd.appearance_paint": "Paint Appearance",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "Pick Up Appearance",
|
||||
"cmd.appearance_replace": "Replace Appearance",
|
||||
"cmd.assembly_bom": "Bill of Materials",
|
||||
"cmd.body.print_face": "Print Face",
|
||||
"cmd.body_rename": "Rename Body",
|
||||
"cmd.browser_collapse_all": "Collapse All",
|
||||
"cmd.browser_expand_all": "Expand All",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "Move Browser Items",
|
||||
"cmd.browser_order": "Order Browser Items",
|
||||
"cmd.browser_rename_group": "Rename Group",
|
||||
"cmd.browser_reparent": "Move to Component",
|
||||
"cmd.browser_ungroup": "Ungroup",
|
||||
"cmd.browser_visibility": "Show/Hide",
|
||||
"cmd.canvas_calibrate": "Calibrate Canvas",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "Part Properties",
|
||||
"cmd.component_metadata_set": "Change Part Properties",
|
||||
"cmd.component_move_bodies": "Move Bodies to Component",
|
||||
"cmd.component_move_features": "Move Features to Component",
|
||||
"cmd.component_move_sketches": "Move Sketches to Component",
|
||||
"cmd.component_paste_from_design": "Paste from Another Design",
|
||||
"cmd.component_paste_new": "Paste New",
|
||||
"cmd.component_properties": "Component Physical Properties",
|
||||
"cmd.component_relink": "Relink Source",
|
||||
@@ -998,7 +1009,7 @@
|
||||
"cmd.parameters_complete": "Complete Expression",
|
||||
"cmd.parameters_delete": "Delete Parameter",
|
||||
"cmd.parameters_export": "Export Parameters",
|
||||
"cmd.parameters_favorite": "Favourite Parameter",
|
||||
"cmd.parameters_favorite": "Favorite Parameter",
|
||||
"cmd.parameters_graph": "Parameter Graph",
|
||||
"cmd.parameters_import": "Import Parameters",
|
||||
"cmd.parameters_list": "List Parameters",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "Render Image",
|
||||
"cmd.render_status": "Render Progress",
|
||||
"cmd.select_clear": "Clear Selection",
|
||||
"cmd.settings_profile_apply": "Apply Settings Profile",
|
||||
"cmd.settings_profile_delete": "Delete Settings Profile",
|
||||
"cmd.settings_profile_export": "Export Settings Profile",
|
||||
"cmd.settings_profile_import": "Import Settings Profile",
|
||||
"cmd.settings_profile_list": "Settings Profiles",
|
||||
"cmd.settings_profile_rename": "Rename Settings Profile",
|
||||
"cmd.settings_profile_save": "Save Settings Profile",
|
||||
"cmd.sheet_convert": "Convert to Sheet Metal",
|
||||
"cmd.sheet_export_bend_table": "Export Bend Table",
|
||||
"cmd.sheet_export_dxf": "Export Flat Pattern as DXF",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "Refold",
|
||||
"cmd.sheet_rules": "List Sheet Metal Rules",
|
||||
"cmd.sheet_unfold": "Unfold",
|
||||
"cmd.sketch.construction_line": "Construction Line",
|
||||
"cmd.sketch.construction_line.angle": "Construction Line at Angle",
|
||||
"cmd.sketch.construction_line.bisector": "Angle Bisector",
|
||||
"cmd.sketch.construction_line.horizontal": "Horizontal Construction Line",
|
||||
"cmd.sketch.construction_line.parallel": "Parallel Construction Line",
|
||||
"cmd.sketch.construction_line.perpendicular": "Perpendicular Construction Line",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tangent at Curve Point",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tangent through External Point",
|
||||
"cmd.sketch.construction_line.tangent_two": "Common Tangent",
|
||||
"cmd.sketch.construction_line.vertical": "Vertical Construction Line",
|
||||
"cmd.sketch_arc3d": "3D Arc",
|
||||
"cmd.sketch_arc_center_point": "Center Point Arc",
|
||||
"cmd.sketch_arc_tangent": "Tangent Arc",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Drawing Size",
|
||||
"cmd.sketch_edit": "Edit Sketch",
|
||||
"cmd.sketch_edit_text": "Edit Text",
|
||||
"cmd.sketch_equation_curve": "Equation Curve",
|
||||
"cmd.sketch_equation_curve_edit": "Edit Equation Curve",
|
||||
"cmd.sketch_export_dxf": "Save As DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "Finish with AutoConstrain",
|
||||
"cmd.sketch_fit_curves_to_section": "Fit Curves to Mesh Section",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "Render Browser",
|
||||
"cmd.view.render_dock": "Move Render Dock",
|
||||
"cmd.view.render_focus": "Render Focus View",
|
||||
"cmd.view.status_items": "Viewport Status Items",
|
||||
"cmd.view_ambient_occlusion": "Ambient Occlusion",
|
||||
"cmd.view_angle_readout": "View Angles",
|
||||
"cmd.view_apply": "Restore Named View",
|
||||
@@ -1325,8 +1356,8 @@
|
||||
"drive.stopped_by_loop": "Stopped at {value}: the loop through {joint} can't close any further",
|
||||
"drive.unconnected": "Moves nothing: {part} is not connected to anything grounded",
|
||||
"dxf.cancel_wait": "Waiting for the export to stop…",
|
||||
"dxf.cancelled": "DXF export cancelled",
|
||||
"dxf.cancelling": "Cancelling DXF export",
|
||||
"dxf.cancelled": "DXF export canceled",
|
||||
"dxf.cancelling": "Canceling DXF export",
|
||||
"dxf.exporting": "Exporting DXF",
|
||||
"dxf.invalid_tolerance": "Curve tolerance must be between 0.0001 and 1 mm.",
|
||||
"dxf.progress.index": "Preparing surfaces (2/5)",
|
||||
@@ -1357,27 +1388,39 @@
|
||||
"fits the face, e.g. M8": "fits the face, e.g. M8",
|
||||
"from the profile": "from the profile",
|
||||
"from the rule": "from the rule",
|
||||
"help.apache": "Apache licence 2.0",
|
||||
"help.appearance.assign": "Gives the selected bodies, faces or components a colour or a material look, without changing their weight. Use it to tell parts apart or to preview a finish.",
|
||||
"help.apache": "Apache license 2.0",
|
||||
"help.appearance.assign": "Gives the selected bodies, faces or components a color or a material look, without changing their weight. Use it to tell parts apart or to preview a finish.",
|
||||
"help.attributions": "Attributions (ATTRIBUTION.md)",
|
||||
"help.build": "Version {version} · commit {commit} · built {date}",
|
||||
"help.component.finish_edit": "Saves the part you are editing in place, returns to its assembly and updates the assembly from it. Use it when your changes to the linked part are done.",
|
||||
"help.connect_note": "Restart each assistant to load the SolidCraft server. Each file was backed up as .bak before it changed.",
|
||||
"help.connect_title": "Connect AI assistants",
|
||||
"help.face.delete": "Removes the selected faces and lets the neighbouring faces close the gap, or leaves the gap open as a surface. Use it to take off a rounded edge, a hole or a boss that is in the way.",
|
||||
"help.font_details": "The interface uses egui's built-in fonts (Ubuntu Light and Hack, under the Ubuntu Font Licence and the MIT/Bitstream Vera licence; Noto Emoji and the emoji icon font, under the OFL and MIT). Sketch text uses Liberation Sans (SIL OFL 1.1). The Crafting Apps' optional font pack, craft-fonts (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic; SIL OFL 1.1), is not bundled in SolidCraft builds.",
|
||||
"help.face.delete": "Removes the selected faces and lets the neighboring faces close the gap, or leaves the gap open as a surface. Use it to take off a rounded edge, a hole or a boss that is in the way.",
|
||||
"help.font_details": "The interface uses egui's built-in fonts (Ubuntu Light and Hack, under the Ubuntu Font Licence and the MIT/Bitstream Vera license; Noto Emoji and the emoji icon font, under the OFL and MIT). Sketch text uses Liberation Sans (SIL OFL 1.1). The Crafting Apps' optional font pack, craft-fonts (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic; SIL OFL 1.1), is not bundled in SolidCraft builds.",
|
||||
"help.fonts": "Fonts",
|
||||
"help.licences": "Licences",
|
||||
"help.material.assign": "Sets what the selected bodies are made of, such as steel, aluminium or ABS. Use it so that the mass and weight match the real part.",
|
||||
"help.mit": "MIT licence",
|
||||
"help.licences": "Licenses",
|
||||
"help.material.assign": "Sets what the selected bodies are made of, such as steel, aluminum or ABS. Use it so that the mass and weight match the real part.",
|
||||
"help.mit": "MIT license",
|
||||
"help.notice": "NOTICE",
|
||||
"help.occurrence.move": "Moves an assembly part only along freedoms allowed by its joints. Select a part face, then drag an available arrow or arc.",
|
||||
"help.parameters.change": "Opens the table of named values and expressions that drive the dimensions of the design. Use it to change a size in one place and let every feature that uses it follow.",
|
||||
"help.pointcloud.insert": "Insert a PLY, XYZ or PTS scan as a point cloud alongside the model. Use it as a reference when building a model from measured data.",
|
||||
"help.sketch.construction_line": "Create an infinite construction line through two points. Use it to lay out a sketch without splitting profiles.",
|
||||
"help.sketch.construction_line.angle": "Create an infinite construction line at an angle from sketch X. Pick the point and type the angle, or pick its direction.",
|
||||
"help.sketch.construction_line.bisector": "Pick two intersecting straight sketch lines, then choose either angle bisector. The result follows its source lines.",
|
||||
"help.sketch.construction_line.horizontal": "Create an infinite horizontal construction line through a point. Its horizontal constraint follows later edits.",
|
||||
"help.sketch.construction_line.parallel": "Pick a straight sketch line, then place a parallel infinite construction line. Right-click to choose another reference.",
|
||||
"help.sketch.construction_line.perpendicular": "Pick a straight sketch line, then place a perpendicular infinite construction line. Right-click to choose another reference.",
|
||||
"help.sketch.construction_line.tangent_at": "Create a tangent at a point on a circle or circular arc, or an endpoint of an open spline or conic. Pick the curve, then its contact point.",
|
||||
"help.sketch.construction_line.tangent_external": "Pick a circle or circular arc, then an external point and a tangent solution. The previews show only contacts on the drawn arc.",
|
||||
"help.sketch.construction_line.tangent_two": "Pick two circles or circular arcs, then choose a common tangent in the preview. Contacts must lie on the drawn curves.",
|
||||
"help.sketch.construction_line.vertical": "Create an infinite vertical construction line through a point. Its vertical constraint follows later edits.",
|
||||
"help.sketch.equation_curve": "Draws a curve from formulas: x(t) and y(t), or y = f(x), over a range. The formulas can use parameters and the curve follows them: use it for a sine wave, a spiral or a gear tooth's involute.",
|
||||
"help.sketch.inspect": "Opens a report on the open sketch: how many degrees of freedom are left and whether it is fully constrained. Use it to find out what still moves before you finish the sketch.",
|
||||
"help.solid.align": "Moves the selected bodies so that a point, face or plane on them meets a point, face or plane elsewhere. Use it to place a part against another one without measuring the offset.",
|
||||
"help.solid.chamfer": "Cuts the selected edges with a flat bevel of the distance you set. Use it to break sharp edges or to ease the entry of a pin or screw.",
|
||||
"help.solid.combine": "Joins bodies, cuts them out of a target body, or keeps only the volume they share, and can keep the tool bodies. Use it to merge parts, to cut one shape with another or to find where two bodies overlap.",
|
||||
"help.solid.draft": "Tilts the selected faces by the angle you set, measured from a neutral plane. Use it on moulded or cast parts so that they slide out of the mould.",
|
||||
"help.solid.draft": "Tilts the selected faces by the angle you set, measured from a neutral plane. Use it on molded or cast parts so that they slide out of the mold.",
|
||||
"help.solid.extrude": "Pushes a sketch profile into 3D along a distance, adding or removing material. Use it to turn a flat outline into a block, a boss or a pocket.",
|
||||
"help.solid.fillet": "Rounds the selected edges with a smooth circular blend of the radius you set. Use it to soften sharp edges for strength, comfort or looks.",
|
||||
"help.solid.hole": "Drills a round hole of the diameter you set at a chosen point on a face. Use it for screw clearances, pins and other simple round openings.",
|
||||
@@ -1390,13 +1433,13 @@
|
||||
"help.solid.press_pull": "Adds or removes material as you drag a face, or rounds edges as you drag them. Use it for quick changes straight on the model.",
|
||||
"help.solid.remove": "Takes the selected bodies out of the design from this point in the timeline on; earlier steps keep them. Use it to drop a helper body, such as a cutting tool you no longer need.",
|
||||
"help.solid.replace_face": "Moves the selected flat faces onto a plane or onto a parallel face, and the body grows or shrinks to meet it. Use it to bring a face flush with another part or a construction plane.",
|
||||
"help.solid.revolve": "Spins a sketch profile around an axis to make a round solid. Use it for shafts, knobs, bowls and any part that is round about a centre line.",
|
||||
"help.solid.revolve": "Spins a sketch profile around an axis to make a round solid. Use it for shafts, knobs, bowls and any part that is round about a center line.",
|
||||
"help.solid.scale": "Makes the selected bodies larger or smaller by a factor, the same in every direction or one per axis. Use it to resize an imported shape or to allow for shrinkage.",
|
||||
"help.solid.shell": "Hollows out a solid, leaving walls of the thickness you set, and can open the faces you pick. Use it for boxes, covers and other thin-walled parts.",
|
||||
"help.solid.split_body": "Cuts a body into separate bodies with a plane, the face of another body or a sketch line. Use it to make parts that are printed, machined or coloured on their own.",
|
||||
"help.solid.split_face": "Divides the selected faces along a plane, the face of another body or sketch curves, without cutting the body. Use it to give part of a face its own draft, colour or offset.",
|
||||
"help.solid.split_body": "Cuts a body into separate bodies with a plane, the face of another body or a sketch line. Use it to make parts that are printed, machined or colored on their own.",
|
||||
"help.solid.split_face": "Divides the selected faces along a plane, the face of another body or sketch curves, without cutting the body. Use it to give part of a face its own draft, color or offset.",
|
||||
"help.solid.sweep": "Drags a sketch profile along a path to make a solid. Use it for pipes, rails, handles and any part of constant section that follows a curve.",
|
||||
"help.third_party": "Third-party licences",
|
||||
"help.third_party": "Third-party licenses",
|
||||
"help.timeline.compute_all": "Rebuilds every feature in the timeline from the start. Use it to refresh the model and to see which features fail.",
|
||||
"help.timeline.delete": "Deletes the selected features from the timeline; deleting a sketch also deletes the features built from it. Use it to remove a step that is no longer wanted.",
|
||||
"help.timeline.play": "Replay the remaining features one at a time, with a half-second pause after each rebuild. Run this command again or press Escape to stop; Go to end jumps immediately.",
|
||||
@@ -1450,7 +1493,7 @@
|
||||
"home.new_inches": "New design, inches",
|
||||
"home.new_inches_hint": "Inches · opens in Design",
|
||||
"home.new_mm": "New design",
|
||||
"home.new_mm_hint": "Millimetres · opens in Design",
|
||||
"home.new_mm_hint": "Millimeters · opens in Design",
|
||||
"home.open": "Open…",
|
||||
"home.open_hint": "A .sc design ({shortcut})",
|
||||
"home.open_now": "Open now",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "Different materials",
|
||||
"measure.at": "At",
|
||||
"measure.item": "Item {number}",
|
||||
"measure.quick_copied": "Measurement copied",
|
||||
"measure.quick_copy": "Click to copy the measurement",
|
||||
"measure.quick_edges": "{count} edges",
|
||||
"measure.quick_faces": "{count} faces",
|
||||
"messages.ago_h": "{n} h ago",
|
||||
"messages.ago_min": "{n} min ago",
|
||||
"messages.ago_s": "{n} s ago",
|
||||
@@ -1631,7 +1678,7 @@
|
||||
"navbar.custom.buttons": "Buttons",
|
||||
"navbar.custom.compact": "Compact",
|
||||
"navbar.custom.count": "{count} of 16 slots",
|
||||
"navbar.custom.customise": "Customise navigation bar…",
|
||||
"navbar.custom.customise": "Customize navigation bar…",
|
||||
"navbar.custom.design": "Design",
|
||||
"navbar.custom.duplicate": "This slot is already on the bar.",
|
||||
"navbar.custom.edge": "Edge",
|
||||
@@ -1651,7 +1698,7 @@
|
||||
"navbar.custom.labels": "Icons and labels",
|
||||
"navbar.custom.left": "Move left",
|
||||
"navbar.custom.position": "Position",
|
||||
"navbar.custom.position_centre": "Centre",
|
||||
"navbar.custom.position_centre": "Center",
|
||||
"navbar.custom.position_left": "Left",
|
||||
"navbar.custom.position_right": "Right",
|
||||
"navbar.custom.preview_as": "Preview as",
|
||||
@@ -1680,7 +1727,7 @@
|
||||
"navbar.description.orbit": "Turns the view around the model.",
|
||||
"navbar.description.pan": "Slides the view sideways, up or down.",
|
||||
"navbar.description.projection": "Switches between orthographic and perspective views.",
|
||||
"navbar.description.separator": "A thin line that groups neighbouring slots.",
|
||||
"navbar.description.separator": "A thin line that groups neighboring slots.",
|
||||
"navbar.description.spin": "Keeps the view turning until you click or press a key.",
|
||||
"navbar.description.visual_style": "Switches how the model is drawn: shaded, wireframe or with hidden edges.",
|
||||
"navbar.description.zoom": "Moves the view closer to or further from the model.",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "not a move",
|
||||
"not a number": "not a number",
|
||||
"open a sketch first": "open a sketch first",
|
||||
"parameters.apply_live": "Apply each change as you leave its field",
|
||||
"parameters.apply_live_tip": "Off: changes wait until Apply or OK, then the design rebuilds once for all of them. Cancel or Escape drops them.",
|
||||
"parameters.held": "{count} changes waiting for Apply",
|
||||
"parameters.held_hint": "Edit expressions and units. Changes wait for Apply or OK.",
|
||||
"parameters.held_one": "1 change waiting for Apply",
|
||||
"parts.automatic_name": "automatic",
|
||||
"parts.dimension.across_flats": "Across flats",
|
||||
"parts.dimension.bore": "Bore",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "Thickness",
|
||||
"parts.dimension.width": "Width",
|
||||
"parts.family.bearing": "Deep groove ball bearing (envelope)",
|
||||
"parts.family.button_head_cap_screw": "Button head cap screw",
|
||||
"parts.family.dowel_pin": "Parallel pin (dowel)",
|
||||
"parts.family.hex_bolt": "Hex head bolt / screw",
|
||||
"parts.family.hex_nut": "Hex nut",
|
||||
"parts.family.set_screw": "Hex socket set screw, flat point",
|
||||
"parts.family.socket_head_cap_screw": "Socket head cap screw",
|
||||
"parts.family.washer": "Plain washer",
|
||||
"parts.holes": "Holes (optional)",
|
||||
"parts.placement_hint": "pick one or more holes to seat a part in each, or OK places it at the origin",
|
||||
"pattern.alignment_2": "Alignment 2",
|
||||
"pattern.alignment_hint": "Counts include the original. Center balances copies; Flip chooses the extra side for even totals.",
|
||||
"pattern.direction_1": "Direction 1",
|
||||
@@ -1798,9 +1853,11 @@
|
||||
"prefs.bodies_folders_never": "Never",
|
||||
"prefs.bodies_folders_several": "Several bodies only",
|
||||
"prefs.bottom": "Bottom",
|
||||
"prefs.bottom_centre": "Bottom centre",
|
||||
"prefs.bottom_centre": "Bottom center",
|
||||
"prefs.bottom_right": "Bottom right",
|
||||
"prefs.browser": "Browser",
|
||||
"prefs.browser_eye_left": "Eye next to the fold arrow",
|
||||
"prefs.browser_eye_left_note": "Browser rows show their show/hide eye next to the fold arrow, as before, instead of in a column at the right end of the rows.",
|
||||
"prefs.browser_reveal_on_hover": "Reveal on hover",
|
||||
"prefs.browser_show_note": "Shown keeps the browser on screen. Reveal on hover keeps it out of sight until the pointer comes over its place or the thin tab at its left edge, and it stays open while the pointer is inside it or a menu from it is open.",
|
||||
"prefs.browser_shown": "Shown",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "Takes effect after restarting SolidCraft. WGPU_ADAPTER_NAME overrides this choice.",
|
||||
"prefs.graphics_note": "Trade speed for smoothness. Each choice shows its effect on a sample.",
|
||||
"prefs.graphics_presets_note": "Presets set the choices below together.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Hide constraint glyphs when zoomed out",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Constraint glyphs leave the view when the sketch is zoomed out far enough that they would clutter it. Off: they stay at a fixed screen size at every zoom.",
|
||||
"prefs.history": "History",
|
||||
"prefs.history_origin_bodies": "Show origin and bodies at the top",
|
||||
"prefs.history_origin_bodies_note": "The History on the left or under the browser starts with the active component's Bodies folder and the Origin, with their eyes and menus as in the browser. The History at the bottom is unchanged.",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "Compact docks panels to the window edges. Browser translucency is available in Floating. Change the Assistant side on the Assistant page.",
|
||||
"prefs.left": "Left",
|
||||
"prefs.left_click": "Left click",
|
||||
"prefs.line_drag_draws_one": "Press and drag draws one line",
|
||||
"prefs.line_drag_draws_one_note": "In the Line tool, pressing, dragging and letting go draws one line from the press to the release, and it ends there. Clicks still draw a chain. Off: a drag places a point where it is let go, as a click does.",
|
||||
"prefs.linked_designs": "Linked designs",
|
||||
"prefs.live_input": "Live input",
|
||||
"prefs.live_preview": "Live preview",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "STEP and import files",
|
||||
"prefs.max_file_size_web": "The web app opens STEP and import files up to 512 MB and designs up to 256 MB: a browser tab can't hold larger files. The desktop app can raise these limits.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Large icons",
|
||||
"prefs.menu_list": "List",
|
||||
"prefs.menus": "Menus",
|
||||
"prefs.minutes": "minutes",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "Mouse and trackpad",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "Origin plane names",
|
||||
"prefs.origin_plane_names_note": "Names shown in the browser, dialogs and lists. {top} is XY, {front} is XZ and {right} is YZ, with Z up. Commands, scripts and saved designs keep XY, XZ and YZ.",
|
||||
"prefs.overall_speed": "Overall speed",
|
||||
"prefs.parameter_list_rows": "Parameter list rows",
|
||||
"prefs.parameter_list_rows_tip": "Down arrow in an empty value field lists the parameters, favourites first, up to this many. Fewer keeps the list light in a large design.",
|
||||
"prefs.persistent_ribbon_pressed": "Highlight active ribbon commands",
|
||||
"prefs.persistent_ribbon_pressed_help": "Highlight ribbon commands while their effects are on. Turn off to keep the previous neutral appearance and command help.",
|
||||
"prefs.perspective_fov": "Field of view",
|
||||
"prefs.placement": "Placement",
|
||||
"prefs.prefer_free_sketch_points": "Prefer movable sketch points when points overlap",
|
||||
"prefs.preview_choices": "Preview of your choices",
|
||||
"prefs.print_face_highlight": "Print face highlight",
|
||||
"prefs.print_face_highlight_tip": "How strongly the print face of a body is tinted and outlined in the view. 0 % shows no highlight.",
|
||||
"prefs.profile_active": "Active profile",
|
||||
"prefs.profile_applied": "Profile applied.",
|
||||
"prefs.profile_changed": "Settings changed since the profile was saved. Save keeps them in it.",
|
||||
"prefs.profile_deleted": "Profile deleted.",
|
||||
"prefs.profile_export": "Export…",
|
||||
"prefs.profile_exported": "Profile exported.",
|
||||
"prefs.profile_imported": "Profile imported. Choose it under Active profile to switch to it.",
|
||||
"prefs.profile_name_hint": "Profile name, e.g. Laptop",
|
||||
"prefs.profile_rename": "Rename",
|
||||
"prefs.profile_renamed": "Profile renamed.",
|
||||
"prefs.profile_save": "Save",
|
||||
"prefs.profile_saved": "Current settings saved to the profile.",
|
||||
"prefs.profile_skipped": "Profile applied; {n} setting(s) kept their current value (see the log).",
|
||||
"prefs.profiles": "Settings profiles",
|
||||
"prefs.profiles_note": "Shortcuts, the toolbar, navigation, the radial menu and interface settings, kept together under a name and switched at once.",
|
||||
"prefs.project_options_dialog": "Project options dialog",
|
||||
"prefs.project_options_dialog_note": "On: choose Geometry or Bodies and Projection Link before projecting. Off: keep the previous direct-pick workflow.",
|
||||
"prefs.quality_default": "default",
|
||||
"prefs.quality_fastest": "fastest",
|
||||
"prefs.quality_slowest": "slowest",
|
||||
"prefs.quality_smoother": "smoother",
|
||||
"prefs.quick_measure": "Quick measurement in the view's corner",
|
||||
"prefs.quick_measure_note": "The selection's size in the view's bottom right corner: an edge's length, or Ø and R for a round one, a face's area, a point's position, two items' distance and angle, several edges' or faces' total. A click copies it.",
|
||||
"prefs.render_previous_geometry_budget": "Use previous Render preview geometry budget",
|
||||
"prefs.render_previous_geometry_budget_help": "Restore the previous fixed geometry limit (512 MiB on 64-bit desktop, 128 MiB elsewhere) instead of the device-based budget.",
|
||||
"prefs.reports_saved": "{n} saved",
|
||||
"prefs.ribbon_reveal": "Show search results in the ribbon",
|
||||
"prefs.ribbon_reveal_note": "Hovering a result in Search commands shows where the command sits in the ribbon: its tab, its button or its row in a panel's drop-down. A command started from the search blinks there, and a running command from a drop-down marks its panel.",
|
||||
"prefs.right_click": "Right click",
|
||||
"prefs.saving": "Autosave and recovery",
|
||||
"prefs.scale_note": "Also Ctrl + / Ctrl − in the window. Buttons are 28 px at 100%.",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "No matching preferences",
|
||||
"prefs.select": "Select",
|
||||
"prefs.select_one_item": "Select one item",
|
||||
"prefs.select_other_hidden": "Select hidden geometry with Select Other",
|
||||
"prefs.select_other_hidden_help": "On: include hidden bodies, sketches and occluded edges near the pointer. Off: use the original list of visible geometry under the pointer.",
|
||||
"prefs.selecting": "Selecting",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift adds only; Ctrl / Cmd toggles",
|
||||
"prefs.shift_add_note": "On: Shift adds, Ctrl / Cmd toggles. Off (default): both toggle.",
|
||||
"prefs.shortcuts": "Shortcuts",
|
||||
"prefs.single_surface_analysis": "Use a single surface analysis",
|
||||
"prefs.single_surface_analysis_help": "When off, surface shading and Continuity can stay on together. Turning this on keeps the last analysis started or changed.",
|
||||
"prefs.sketch_align_points": "Line up with other sketch points while drawing",
|
||||
"prefs.sketch_align_points_note": "While drawing, a point lines up horizontally with one sketch point and vertically with another at the same time, with a dotted guide, and the click keeps both alignments. Off: only with the previous point, one axis at a time.",
|
||||
"prefs.sketch_conflict_colour": "Conflicting geometry in the conflict color",
|
||||
"prefs.sketch_conflict_colour_note": "While a sketch's constraints conflict, the curves and points a failing constraint holds are drawn in the conflict color too, not only its glyph or dimension. Off: they keep their usual colors.",
|
||||
"prefs.sketch_construction_lines": "Extended construction line tools",
|
||||
"prefs.sketch_exit_view": "When a sketch ends",
|
||||
"prefs.sketch_exit_view.keep": "Keep the current view",
|
||||
"prefs.sketch_exit_view.previous": "Return to the previous view",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Return unless rotated",
|
||||
"prefs.sketch_exit_view_note": "Where the view goes after Finish Sketch, Cancel or a double Esc.",
|
||||
"prefs.sketch_open_look_at": "Turn to face a sketch when it opens",
|
||||
"prefs.sketch_open_look_at_note": "Off: creating or editing a sketch leaves the view as it is. Look At faces the sketch when you want it.",
|
||||
"prefs.sketch_recent_snap": "Auto snap to recent centers and midpoints",
|
||||
"prefs.sketch_recent_snap_note": "While drawing, snap the cursor where the guides of the two most recent circle centers or straight-edge midpoints cross. Off: those guides stay visual and the cursor does not move.",
|
||||
"prefs.sketch_selection": "Sketch & selection",
|
||||
"prefs.sketch_selection_heading": "Sketch and selection",
|
||||
"prefs.sketch_selection_note": "How sketches snap and how clicks select.",
|
||||
@@ -1988,27 +2089,41 @@
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "Hold only this key to zoom at the pointer with vertical scroll. Off keeps the existing scroll behaviour.",
|
||||
"prefs.trackpad_zoom_modifier.help": "Hold only this key to zoom at the pointer with vertical scroll. Off keeps the existing scroll behavior.",
|
||||
"prefs.trackpad_zoom_modifier.off": "Off",
|
||||
"prefs.translucent": "Translucent",
|
||||
"prefs.under_browser": "Under browser",
|
||||
"prefs.under_cursor": "Under cursor",
|
||||
"prefs.units_precision": "Units and precision",
|
||||
"prefs.updates": "Updates",
|
||||
"prefs.value_boxes_in_view": "Show values beside their handles in the view",
|
||||
"prefs.value_boxes_in_view_tip": "A command's value (Distance, Radius…) in a box next to its handle, over the model. Off: you type it in the command window, which takes the keyboard after a pick, and nothing covers the model.",
|
||||
"prefs.view": "View behavior",
|
||||
"prefs.view_confirm_corner": "OK and Cancel in the view's corner",
|
||||
"prefs.view_confirm_corner_note": "While a dialog or a sketch is open, a check and a cross at the top right of the view do what the dialog's OK and Cancel do, or finish and cancel the sketch. The view navigator moves down below them.",
|
||||
"prefs.viewport": "Viewport",
|
||||
"prefs.viewport_analysis_status": "Show viewport analysis status",
|
||||
"prefs.viewport_analysis_status_help": "Show active analyses above the viewport, open their legends from each item, and use Esc to turn off the newest analysis. Turn off to restore corner legends and the previous Esc behaviour.",
|
||||
"prefs.viewport_background": "Background",
|
||||
"prefs.viewport_background_colour": "Color",
|
||||
"prefs.viewport_background_theme": "Theme's gradient",
|
||||
"prefs.viewport_section_status": "Show viewport section status",
|
||||
"prefs.viewport_section_status_help": "Show the section setting in the viewport. Escape and the active ribbon button turn it off. Disable to keep the previous section controls.",
|
||||
"prefs.viewport_status_summary": "Fold viewport status items",
|
||||
"prefs.viewport_status_summary_help": "Fold three or more viewport status items into one summary badge. Disable to keep every item in the full row.",
|
||||
"prefs.wheel": "Wheel",
|
||||
"prefs.wheel_trackpad": "Wheel and trackpad",
|
||||
"prefs.workspace": "Workspace",
|
||||
"prefs.zoom_stop_at_model": "Stop zoom at the model",
|
||||
"prefs.zoom_stop_at_model_tip": "The 3D mouse and device app zoom toward the surface in the middle of the view; drag-zoom holds the point where the drag began. Off: zoom can pass through the model. Wheel and pinch use Zoom to the cursor separately",
|
||||
"prefs.zoom_toward_cursor": "Zoom, toward the cursor",
|
||||
"properties.title": "Properties: {name}",
|
||||
"recovery.days_ago": "{count} days ago",
|
||||
"recovery.detail": "{file} · {features} features · autosaved {when}",
|
||||
"recovery.discard_all": "Discard all",
|
||||
"recovery.discard_all_detail": "This cannot be undone.",
|
||||
"recovery.discard_all_title": "Discard {count} autosaves?",
|
||||
"recovery.discard_all_title_one": "Discard 1 autosave?",
|
||||
"recovery.hours_ago": "{count} h ago",
|
||||
"recovery.just_now": "just now",
|
||||
"recovery.min_ago": "{count} min ago",
|
||||
@@ -2031,13 +2146,13 @@
|
||||
"render.aging_class_any": "All opaque material classes",
|
||||
"render.aging_class_dielectric": "Nonmetallic surfaces only",
|
||||
"render.aging_class_metal": "Metallic surfaces only",
|
||||
"render.aging_color": "Layer colour · sRGB",
|
||||
"render.aging_color": "Layer color · sRGB",
|
||||
"render.aging_coverage": "Coverage",
|
||||
"render.aging_dust": "Deposited dust",
|
||||
"render.aging_empty": "No aging layers: the original surfaces remain unchanged.",
|
||||
"render.aging_fading": "Faded coating",
|
||||
"render.aging_grime": "Grime & staining",
|
||||
"render.aging_help": "Combine up to eight optical layers, in order. Rust and patina are authored appearances, not age/corrosion simulations. Scale is in world millimetres. No geometry, mass or engineering property is changed; glass and passive stages are excluded.",
|
||||
"render.aging_help": "Combine up to eight optical layers, in order. Rust and patina are authored appearances, not age/corrosion simulations. Scale is in world millimeters. No geometry, mass or engineering property is changed; glass and passive stages are excluded.",
|
||||
"render.aging_metallic": "Layer metallic fraction",
|
||||
"render.aging_origin": "Field origin · world mm",
|
||||
"render.aging_patina": "Copper-green patina",
|
||||
@@ -2053,7 +2168,7 @@
|
||||
"render.all_controls_help": "Dense inspection of all current controls. Section pages provide focused editing without changing the underlying request.",
|
||||
"render.all_shots_label": "All Shots",
|
||||
"render.appearance_editor.absorption": "Absorption",
|
||||
"render.appearance_editor.base_colour": "Base colour",
|
||||
"render.appearance_editor.base_colour": "Base color",
|
||||
"render.appearance_editor.body_reason": "Optical bindings target one whole body. Pick Body to edit these controls.",
|
||||
"render.appearance_editor.boundary": "Boundary",
|
||||
"render.appearance_editor.box": "Box",
|
||||
@@ -2117,7 +2232,7 @@
|
||||
"render.background_not_light": "Background color is presentation, not an additional lighting source.",
|
||||
"render.background_regrade": "Apply to retained raw master",
|
||||
"render.background_stage_occlusion": "This shot includes physical stage geometry. A large floor or wall can fill the frame and hide a camera-only background. Clear or resize the stage deliberately, or change its physical reflectance. Regrading cannot remove captured geometry.",
|
||||
"render.background_workflow": "Choose the background you intend: a camera-only colour/gradient, a physical stage that receives light, or HDR illumination. They are independent. Live Preview is a modelling view; render a new image or regrade a retained master to see camera finishing.",
|
||||
"render.background_workflow": "Choose the background you intend: a camera-only color/gradient, a physical stage that receives light, or HDR illumination. They are independent. Live Preview is a modeling view; render a new image or regrade a retained master to see camera finishing.",
|
||||
"render.base_appearance": "Editable body appearance",
|
||||
"render.base_apply": "Apply body appearance",
|
||||
"render.base_apply_help": "One undoable visual assignment to the reviewed exact body. Existing face-specific looks and engineering materials remain separate.",
|
||||
@@ -2238,7 +2353,7 @@
|
||||
"render.cpu_aa_help": "Spatial samples: more samples improve edges and increase render time.",
|
||||
"render.cpu_area_add": "Add rectangular CPU light",
|
||||
"render.cpu_area_editor": "CPU rectangular lights",
|
||||
"render.cpu_area_editor_help": "Full side vectors in millimeters; U cross V points towards the emitting side. This differs from GPU half-edge vectors.",
|
||||
"render.cpu_area_editor_help": "Full side vectors in millimeters; U cross V points toward the emitting side. This differs from GPU half-edge vectors.",
|
||||
"render.cpu_area_full_u": "Full U side · mm",
|
||||
"render.cpu_area_full_v": "Full V side · mm",
|
||||
"render.cpu_area_samples": "Area-light samples",
|
||||
@@ -2327,7 +2442,7 @@
|
||||
"render.draft_confirm_help": "The current render draft has unapplied edits. Save them before switching, discard them explicitly, or keep editing.",
|
||||
"render.draft_confirm_title": "Preserve edited render settings",
|
||||
"render.effects_gpu_only": "These effects require GPU path tracing. Changing the page never switches the renderer automatically.",
|
||||
"render.effects_help": "Combine ordered colour looks and image-space lens effects. Rendering and raw-master regrading use the same saved settings. Raw EXR stays unchanged. These are original artistic controls, not calibrated lens or branded-film emulations.",
|
||||
"render.effects_help": "Combine ordered color looks and image-space lens effects. Rendering and raw-master regrading use the same saved settings. Raw EXR stays unchanged. These are original artistic controls, not calibrated lens or branded-film emulations.",
|
||||
"render.effects_reset_lens": "Reset lens effects",
|
||||
"render.effects_seed": "Pattern seed",
|
||||
"render.emitted_axis": "Emitted axis",
|
||||
@@ -2338,7 +2453,7 @@
|
||||
"render.env_change": "Change",
|
||||
"render.env_choose_source": "Choose an environment in Studios and Environments before editing the lighting.",
|
||||
"render.env_clear": "Clear",
|
||||
"render.env_colour": "Colour",
|
||||
"render.env_colour": "Color",
|
||||
"render.env_environments": "Environments",
|
||||
"render.env_ground": "Ground",
|
||||
"render.env_ground_pending": "Physical ground receives shadows as a finite diffuse surface. Shadow-only catching and ground reflections are not supported yet.",
|
||||
@@ -2393,7 +2508,7 @@
|
||||
"render.environment.primaries": "Treat unspecified primaries as linear sRGB",
|
||||
"render.environment.primaries_gpu": "Interpreting unspecified primaries needs GPU path tracing.",
|
||||
"render.environment.radial": "Radial",
|
||||
"render.environment.radial_only": "Centre and radius apply to Radial mode.",
|
||||
"render.environment.radial_only": "Center and radius apply to Radial mode.",
|
||||
"render.environment.reflectance": "Reflectance",
|
||||
"render.environment.remove": "Remove stage",
|
||||
"render.environment.remove_confirm": "Remove the saved stage?",
|
||||
@@ -2425,8 +2540,8 @@
|
||||
"render.error_duplicate_face": "duplicate product face appearance",
|
||||
"render.error_export_document": "The render export document changed while choosing its destination",
|
||||
"render.error_face_cap": "product preview exceeds the face-appearance admission cap",
|
||||
"render.error_finish_gesture": "finish the modelling gesture before previewing",
|
||||
"render.error_finish_operation": "finish the current modelling operation before entering Render",
|
||||
"render.error_finish_gesture": "finish the modeling gesture before previewing",
|
||||
"render.error_finish_operation": "finish the current modeling operation before entering Render",
|
||||
"render.error_fixed_preview": "fixed studio preview requires exposure 0, environment rotation 0 and intensity 1",
|
||||
"render.error_geometry_size": "product geometry size overflow",
|
||||
"render.error_glass_recipe": "unknown glass recipe",
|
||||
@@ -2484,7 +2599,7 @@
|
||||
"render.flare_threshold": "Scene-linear flare threshold",
|
||||
"render.fold_browser": "Fold Browser",
|
||||
"render.frame_aspect": "Aspect",
|
||||
"render.frame_centre_mark": "Centre mark",
|
||||
"render.frame_centre_mark": "Center mark",
|
||||
"render.frame_copy_limit": "No available duplicate shot name",
|
||||
"render.frame_copy_name": "{name} copy {number}",
|
||||
"render.frame_custom": "Custom",
|
||||
@@ -2539,8 +2654,8 @@
|
||||
"render.hide_shots_label": "Hide Shots strip",
|
||||
"render.hover_look": "{object} · {look} · click to select",
|
||||
"render.image_advanced": "Advanced GPU controls",
|
||||
"render.image_cancelled": "Render cancelled",
|
||||
"render.image_cancelling": "Cancelling",
|
||||
"render.image_cancelled": "Render canceled",
|
||||
"render.image_cancelling": "Canceling",
|
||||
"render.image_completed": "Image ready to export",
|
||||
"render.image_encoding": "Encoding PNG",
|
||||
"render.image_export": "Export completed image",
|
||||
@@ -2557,7 +2672,7 @@
|
||||
"render.image_reduce": "Try a smaller image or simpler scene.",
|
||||
"render.image_running": "Rendering image",
|
||||
"render.image_samples": "Samples per pixel",
|
||||
"render.image_scene_stale": "Finish the modelling gesture or refresh the scene before checking or starting an image.",
|
||||
"render.image_scene_stale": "Finish the modeling gesture or refresh the scene before checking or starting an image.",
|
||||
"render.image_stale": "This image uses the scene captured before subsequent changes.",
|
||||
"render.image_start": "Start Render",
|
||||
"render.image_supported": "Render request is supported; the queue and memory pool are checked again at start.",
|
||||
@@ -2576,7 +2691,7 @@
|
||||
"render.inspector_applies_to": "Applies to",
|
||||
"render.inspector_both_users": "Both users",
|
||||
"render.inspector_chain": "Where this look comes from",
|
||||
"render.inspector_colour": "Colour",
|
||||
"render.inspector_colour": "Color",
|
||||
"render.inspector_edit": "Edit",
|
||||
"render.inspector_finish": "Finish",
|
||||
"render.inspector_from_material": "From Material",
|
||||
@@ -2688,7 +2803,7 @@
|
||||
"render.light_anchor_pending": "Changing the light coordinate frame is not supported yet.",
|
||||
"render.light_azimuth": "Azimuth",
|
||||
"render.light_backend_limit": "Choose CPU ray tracing or an explicit GPU studio to edit lights. Legacy GPU studio lights remain read-only.",
|
||||
"render.light_behaviour": "BEHAVIOUR",
|
||||
"render.light_behaviour": "BEHAVIOR",
|
||||
"render.light_default_fill": "Fill",
|
||||
"render.light_default_key": "Key",
|
||||
"render.light_default_number": "Light {number}",
|
||||
@@ -2704,11 +2819,11 @@
|
||||
"render.light_place_highlight": "Place by highlight",
|
||||
"render.light_place_pending": "Highlight placement needs viewport light picking and is not supported yet.",
|
||||
"render.light_position": "POSITION",
|
||||
"render.light_preview_help": "Live view is unshadowed; Area lights use a centre-sample approximation. Render uses the complete light model.",
|
||||
"render.light_product_centre": "Product centre",
|
||||
"render.light_preview_help": "Live view is unshadowed; Area lights use a center-sample approximation. Render uses the complete light model.",
|
||||
"render.light_product_centre": "Product center",
|
||||
"render.light_size": "Size",
|
||||
"render.light_softness": "Softness",
|
||||
"render.light_temperature": "Colour temperature",
|
||||
"render.light_temperature": "Color temperature",
|
||||
"render.light_temperature_help": "Approximate blackbody tint; saved as linear RGB.",
|
||||
"render.light_type": "Type",
|
||||
"render.light_type_area": "Area",
|
||||
@@ -2722,7 +2837,7 @@
|
||||
"render.lighting_area_samples": "Area samples",
|
||||
"render.lighting_budget": "Budget",
|
||||
"render.lighting_budget_help": "Counts are read-only. Add, duplicate or delete lights to change them; the method sets the limits.",
|
||||
"render.lighting_colour": "Colour",
|
||||
"render.lighting_colour": "Color",
|
||||
"render.lighting_consent": "Replace the directional lights with this preset",
|
||||
"render.lighting_custom": "Custom lights",
|
||||
"render.lighting_custom_help": "Choosing Custom turns the preset into editable lights, one row each in the tree.",
|
||||
@@ -2764,7 +2879,7 @@
|
||||
"render.linear_help": "Keeps a 32-bit float RGBA master before denoising, exposure, tone mapping, filters and backdrop. Linear sRGB/D65; coverage-premultiplied. Additional memory is admitted explicitly. No compression or extra passes.",
|
||||
"render.linear_retain": "Retain raw linear EXR",
|
||||
"render.linear_unavailable": "The selected completed frame has no retained EXR. Enable retention before rendering; an older PNG cannot recover raw radiance.",
|
||||
"render.look_add": "Add colour look",
|
||||
"render.look_add": "Add color look",
|
||||
"render.look_applied": "Applied {name}",
|
||||
"render.look_bleach": "Bleach-bypass-inspired",
|
||||
"render.look_cool": "Cool",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "Ready to render",
|
||||
"render.output_run_check": "Run check",
|
||||
"render.output_size_limit": "{method}: up to {dimension} px per side and {pixels} pixels. Largest fitting size: {width} × {height}.",
|
||||
"render.output_size_method_profile": "To render {width} × {height}, choose {method} with the {profile} CPU resource profile, or a smaller size.",
|
||||
"render.output_size_ok": "Size OK · {width} × {height} px",
|
||||
"render.output_size_profile": "To render {width} × {height}, choose the {profile} CPU resource profile, or a smaller size.",
|
||||
"render.output_swap_orientation": "Swap width and height",
|
||||
"render.output_tools_inspector": "Edit size and format in the Output inspector.",
|
||||
"render.output_view_image": "View image",
|
||||
@@ -3004,7 +3121,7 @@
|
||||
"render.ribbon_saved_camera": "Saved Camera",
|
||||
"render.ribbon_shots": "Shots",
|
||||
"render.ribbon_studios": "Studios",
|
||||
"render.ribbon_studios_help": "Browse implemented studio compositions and review their replacements before applying. Concept-only scenes remain labelled.",
|
||||
"render.ribbon_studios_help": "Browse implemented studio compositions and review their replacements before applying. Concept-only scenes remain labeled.",
|
||||
"render.ribbon_surface_maps": "Surface Maps",
|
||||
"render.sampling_title": "Adaptive and transmission sampling",
|
||||
"render.save_continue": "Save and continue",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "Custom…",
|
||||
"render.size_full_hd": "Full HD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · needs {profile}",
|
||||
"render.size_presets": "Size presets",
|
||||
"render.size_presets_pending": "Arrives with the Output editor",
|
||||
"render.size_preview": "Preview",
|
||||
@@ -3115,7 +3233,7 @@
|
||||
"render.stage_panels.badge_specification": "spec only",
|
||||
"render.stage_panels.candidate_summary": "Candidates: {count} sourced values. Grade and finish need review.",
|
||||
"render.stage_panels.captured_bounds": "Use captured scene bounds",
|
||||
"render.stage_panels.centre": "Centre",
|
||||
"render.stage_panels.centre": "Center",
|
||||
"render.stage_panels.depth": "depth",
|
||||
"render.stage_panels.environments": "Environments",
|
||||
"render.stage_panels.extent": "Extent",
|
||||
@@ -3170,7 +3288,7 @@
|
||||
"render.stage_panels.scope": "Scope",
|
||||
"render.stage_panels.search_studios": "Search studios",
|
||||
"render.stage_panels.search_surfaces": "Search surfaces and references",
|
||||
"render.stage_panels.source_note": "Authored base-colour source map. Not a measured material.",
|
||||
"render.stage_panels.source_note": "Authored base-color source map. Not a measured material.",
|
||||
"render.stage_panels.specifications": "Specifications · read-only",
|
||||
"render.stage_panels.studio_ack": "Confirm replacing lighting, environment, exposure and stage",
|
||||
"render.stage_panels.studio_note": "Click to review. Applying replaces lighting, environment and stage only after you confirm. Lights stay editable.",
|
||||
@@ -3200,7 +3318,7 @@
|
||||
"render.studio_ambient_rgb": "Constant environment radiance (linear RGB)",
|
||||
"render.studio_aperture": "Aperture radius",
|
||||
"render.studio_area": "Area light",
|
||||
"render.studio_area_help": "Up to four one-sided rectangles. Orthogonal half-edges U and V define size; U × V faces the lit side. Coordinates are world-space millimetres.",
|
||||
"render.studio_area_help": "Up to four one-sided rectangles. Orthogonal half-edges U and V define size; U × V faces the lit side. Coordinates are world-space millimeters.",
|
||||
"render.studio_center": "Center X, Y, Z (mm)",
|
||||
"render.studio_denoise": "Reduce noise in the finished image",
|
||||
"render.studio_denoise_help": "Final edge-aware filter; fine detail can soften. Glass and sharp specular surfaces bypass the filter.",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "Double-click a component to activate it, or to edit a linked one in place",
|
||||
"settings.frame_rate_details_note": "Adds a graph of the last frames' times with the triangles drawn over it, a histogram of frame times and what the GPU drew. Click the frame rate in the view to show or hide them.",
|
||||
"settings.frame_rate_note": "Shows frames per second in the view's bottom-right corner.",
|
||||
"settings.insert_lists_open_designs": "Insert Design lists the designs open in other tabs first",
|
||||
"settings.measure_axis_distances": "Show X/Y/Z distances",
|
||||
"settings.measure_axis_distances_help": "Show world-axis component dimensions alongside the total distance while Measure is open.",
|
||||
"settings.msaa_applies_on_restart": "Anti-aliasing applies the next time SolidCraft starts",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "Contour",
|
||||
"sheet.flange_type_edge": "Edge",
|
||||
"sheet.no_body": "there is no sheet metal body: start one with Flange > Base, or turn a plate into sheet metal with Convert to Sheet Metal (pick its large flat face)",
|
||||
"sheet.personal_rules.confirm_delete": "Confirm delete",
|
||||
"sheet.personal_rules.delete": "Delete",
|
||||
"sheet.personal_rules.delete_prompt": "Delete this personal rule? Rules already in designs are unchanged.",
|
||||
"sheet.personal_rules.full": "The personal library already contains 64 rules.",
|
||||
"sheet.personal_rules.invalid_name": "Enter a short name without line breaks or control characters.",
|
||||
"sheet.personal_rules.invalid_values": "Complete the rule's values: each must work out in this design, with a positive thickness and a K factor from 0 to 1.",
|
||||
"sheet.personal_rules.missing": "The selected personal rule is no longer available.",
|
||||
"sheet.personal_rules.name": "Rule name",
|
||||
"sheet.personal_rules.name_exists": "A personal rule with this name already exists. Use a different name.",
|
||||
"sheet.personal_rules.name_hint": "A unique name",
|
||||
"sheet.personal_rules.overwrite": "Save changes to selected personal rule",
|
||||
"sheet.personal_rules.rename": "Rename",
|
||||
"sheet.personal_rules.rule": "Personal rule",
|
||||
"sheet.personal_rules.save": "Save new",
|
||||
"sheet.personal_rules.scope": "Saved in your profile for all designs.",
|
||||
"sheet.personal_rules.select": "Select a rule",
|
||||
"sheet.personal_rules.title": "Personal rules",
|
||||
"sheet.personal_rules.unsupported": "This rule has values that this version can't use.",
|
||||
"shortcut.json_error": "parameters must be JSON: {error}",
|
||||
"shortcut.no_command": "no command `{id}`; the text before the JSON must be a command id",
|
||||
"shortcut.pin": "Pin to the top of the S box",
|
||||
"shortcut.unpin": "Unpin",
|
||||
"sketch is missing": "sketch is missing",
|
||||
"sketch.degrees_of_freedom": "{count} degrees of freedom",
|
||||
"sketch.dimension_added_driven": "The sketch already determines that dimension, so it was added as a driven (reference) dimension",
|
||||
"sketch.dimension_applied": "Dimension applied",
|
||||
"sketch.dimension_applied_defined": "Dimension applied; parameter `{name}` defined",
|
||||
"sketch.dimension_applied_renamed": "Dimension applied; parameter named `{name}`",
|
||||
"sketch.dof_left": "{count} degrees of freedom left",
|
||||
"sketch.dof_left_one": "{count} degree of freedom left",
|
||||
"sketch.draw_curves": "Draw as {linetype}",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "Right",
|
||||
"sketch_text.bold": "Bold",
|
||||
"sketch_text.builtin_font": "{family} (built-in)",
|
||||
"sketch_text.formula": "Start with = to build the words from parameters: ='W' + number(Width)",
|
||||
"sketch_text.italic": "Italic",
|
||||
"sketch_text.loading_fonts": "Looking for installed fonts…",
|
||||
"sketch_text.on_path": "The text follows its path: the curve places it",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "Keep their features and nested folders in the history",
|
||||
"timeline.delete_folders_with_features_tip": "Delete the folders with every feature in them and their nested folders",
|
||||
"timeline.delete_many": "Delete {count} Selected Features",
|
||||
"timeline.edited_rolled_back": "{name} changed, but it is after the history marker, so it is not built: move the marker past it to see the result",
|
||||
"timeline.feature_error": "Error: {message}",
|
||||
"timeline.feature_hint": "Double-click to edit · drag to reorder · right-click for more",
|
||||
"timeline.feature_rolled_back": "Rolled back: after the history marker, so not built",
|
||||
"timeline.feature_warning": "Warning: {message}",
|
||||
"timeline.group": "New Feature Folder",
|
||||
"timeline.move_many": "Move Timeline Items",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "Calibrating your 3D mouse fixes swapped or reversed axes and sets its speed and feel.",
|
||||
"ui.3d_mouse_offer_never": "Never show again",
|
||||
"ui.3d_mouse_offer_swap": "Swap to Hidraw (Direct Driver)",
|
||||
"ui.3d_mouse_orbit": "Orbit",
|
||||
"ui.3d_mouse_orbit_classic": "Classic",
|
||||
"ui.3d_mouse_orbit_tip": "Traced: the 3D mouse turns the view around the part of the model in the middle of the view when the turn begins, marked by a faint ball. Classic: around the view's center",
|
||||
"ui.3d_mouse_orbit_traced": "Traced",
|
||||
"ui.3d_mouse_reading": "Reading",
|
||||
"ui.3d_mouse_reset_axes": "Reset axis assignment",
|
||||
"ui.3d_mouse_reset_view": "Reset view",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "3D mouse",
|
||||
"ui.3d_mouse_show_in_view": "Show the 3D mouse in the 3D view",
|
||||
"ui.3d_mouse_show_in_view_tip": "A picture of your 3D mouse in the lower left corner, moving as you move it.",
|
||||
"ui.3d_mouse_sketch_orbit": "Turn sketches with the 3D mouse",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "The 3D mouse also turns the view while a sketch is open and seen square on, as the mouse can. Off: it pans and zooms the sketch until you tilt the view.",
|
||||
"ui.3d_mouse_skip": "My device can't do this",
|
||||
"ui.3d_mouse_skip_tip": "Skips this motion both ways, and the calibration leaves it out.",
|
||||
"ui.3d_mouse_speed": "3D mouse speed",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Twist the cap anticlockwise, hold it, then let go.",
|
||||
"ui.3d_mouse_switch_cap": "Calibrate as Return to Center",
|
||||
"ui.3d_mouse_switch_trackball": "Calibrate as a trackball",
|
||||
"ui.3d_mouse_use_direct": "Use Direct Driver",
|
||||
"ui.3d_mouse_use_direct_tip": "Read the 3D mouse directly (hidraw) instead of through spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "View axis",
|
||||
"ui.3d_mouse_view_off": "Off",
|
||||
"ui.3d_mouse_view_off_tip": "The 3D mouse driver's profile turns this axis off, so its motion doesn't move the view. Picking another axis's motion here swaps the two, and that motion stops moving the view.",
|
||||
@@ -3657,7 +3809,7 @@
|
||||
"ui.agent_chat_left": "Left",
|
||||
"ui.agent_chat_limit": "The agent reached the limit of {limit} changes for one message. Send another message to let it go on.",
|
||||
"ui.agent_chat_login_found": "login found",
|
||||
"ui.agent_chat_minimize": "Minimise to a strip",
|
||||
"ui.agent_chat_minimize": "Minimize to a strip",
|
||||
"ui.agent_chat_mode_all": "All",
|
||||
"ui.agent_chat_mode_ask": "Ask",
|
||||
"ui.agent_chat_mode_edits": "Edits",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "Remove from the queue",
|
||||
"ui.agent_chat_remove_file": "Take it off this message",
|
||||
"ui.agent_chat_remove_imported": "Take it off this message; the part stays in the design (Undo removes it)",
|
||||
"ui.agent_chat_reply_cut_off": "The reply reached its length limit before it finished, so it may be incomplete. Ask the agent to go on, or for a shorter answer.",
|
||||
"ui.agent_chat_reply_declined": "The model declined to answer this message.",
|
||||
"ui.agent_chat_retry": "Retry",
|
||||
"ui.agent_chat_right": "Right",
|
||||
"ui.agent_chat_save": "Save",
|
||||
@@ -3774,7 +3928,7 @@
|
||||
"ui.ai_mode_ask": "Ask every time",
|
||||
"ui.ai_mode_ask_note": "Every change to the design, and every file action, waits for your Allow.",
|
||||
"ui.ai_mode_edits": "Auto-allow model edits",
|
||||
"ui.ai_mode_edits_note": "Modelling commands run without asking; saving, opening, exporting and other file or destructive actions still ask.",
|
||||
"ui.ai_mode_edits_note": "Modeling commands run without asking; saving, opening, exporting and other file or destructive actions still ask.",
|
||||
"ui.ai_mode_global": "As set above",
|
||||
"ui.ai_model": "Model",
|
||||
"ui.ai_model_hint": "qwen3:14b",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "Circle",
|
||||
"ui.circular_pattern": "Circular Pattern",
|
||||
"ui.clear": "Clear",
|
||||
"ui.clear_print_face": "Clear Print Face",
|
||||
"ui.clear_recent": "Clear Recent",
|
||||
"ui.clear_the_selection": "Clear the selection",
|
||||
"ui.click_selects_whole_bodies": "Click selects whole bodies",
|
||||
@@ -3892,15 +4047,15 @@
|
||||
"ui.coincident": "Coincident",
|
||||
"ui.collapse": "Collapse",
|
||||
"ui.collinear": "Collinear",
|
||||
"ui.colour_vision": "Colour vision",
|
||||
"ui.colour_vision": "Color vision",
|
||||
"ui.colour_vision_deutan": "Deutan",
|
||||
"ui.colour_vision_deutan_tip": "For a weak or missing green sense",
|
||||
"ui.colour_vision_failed": "Failed",
|
||||
"ui.colour_vision_fixed": "Fixed",
|
||||
"ui.colour_vision_mode": "Mode",
|
||||
"ui.colour_vision_note": "Changes the colours that carry a meaning: sketch states, axes, bends, analyses and icons. If you use Windows colour filters, keep this Off.",
|
||||
"ui.colour_vision_note": "Changes the colors that carry a meaning: sketch states, axes, bends, analyses and icons. If you use Windows color filters, keep this Off.",
|
||||
"ui.colour_vision_off": "Off",
|
||||
"ui.colour_vision_off_tip": "The theme's own colours",
|
||||
"ui.colour_vision_off_tip": "The theme's own colors",
|
||||
"ui.colour_vision_projected": "Projected",
|
||||
"ui.colour_vision_protan": "Protan",
|
||||
"ui.colour_vision_protan_tip": "For a weak or missing red sense",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "Constant",
|
||||
"ui.constraints_conflict": "Constraints conflict",
|
||||
"ui.construction": "Construction",
|
||||
"ui.construction.angle_hint": "Construction line: click a point, then type an angle or pick a direction",
|
||||
"ui.construction.bisector_hint": "Bisector: pick two intersecting straight lines, then the desired solution",
|
||||
"ui.construction.common_hint": "Common tangent: pick two circles/arcs, then the desired solution",
|
||||
"ui.construction.contact_hint": "Tangent: pick a circle/arc or open spline/conic, then the contact point (free-form curves: endpoints)",
|
||||
"ui.construction.external_hint": "Tangent: pick a circle or arc, an external point, then the desired solution",
|
||||
"ui.construction.free_hint": "Construction line: click two points; right-click to restart",
|
||||
"ui.construction.point_hint": "Construction line: click the point to pass through",
|
||||
"ui.construction.reference_hint": "Construction line: pick a straight line, then a point; right-click to change the reference",
|
||||
"ui.construction.ribbon_label": "X-Lines",
|
||||
"ui.context_menu": "Context menu",
|
||||
"ui.continuity_g0": "G0 crease",
|
||||
"ui.continuity_g1": "G1 tangent",
|
||||
@@ -3942,7 +4106,7 @@
|
||||
"ui.cut": "Cut",
|
||||
"ui.cylinder": "Cylinder",
|
||||
"ui.dark": "Dark",
|
||||
"ui.default_modelling_orientation": "Default modelling orientation",
|
||||
"ui.default_modelling_orientation": "Default modeling orientation",
|
||||
"ui.delete": "Delete",
|
||||
"ui.depth": "Depth",
|
||||
"ui.design": "Design",
|
||||
@@ -4008,11 +4172,19 @@
|
||||
"ui.end_scale": "End Scale",
|
||||
"ui.entities": "Entities",
|
||||
"ui.equal": "Equal",
|
||||
"ui.equation_end": "End",
|
||||
"ui.equation_explicit": "Explicit",
|
||||
"ui.equation_form": "Form",
|
||||
"ui.equation_note": "The variable is a plain number: sin(t) takes it in radians. A result without a unit is in the design's unit.",
|
||||
"ui.equation_parametric": "Parametric",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Equivalent Radius",
|
||||
"ui.expand": "Expand",
|
||||
"ui.exportDxf": "Export DXF…",
|
||||
"ui.export_ellipsis_keymap": "Export…",
|
||||
"ui.export_keymap_tip": "Keys, S box favourites and the toolbar, as a file",
|
||||
"ui.export_keymap_tip": "Keys, S box favorites and the toolbar, as a file",
|
||||
"ui.extend": "Extend",
|
||||
"ui.extent_type": "Extent Type",
|
||||
"ui.extract_component": "Extract to File…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "DESIGN",
|
||||
"ui.heading_draft": "DRAFT",
|
||||
"ui.heading_edit": "EDIT",
|
||||
"ui.heading_equation_curve": "EQUATION CURVE",
|
||||
"ui.heading_extrude": "EXTRUDE",
|
||||
"ui.heading_fillet": "FILLET",
|
||||
"ui.heading_finish_editing": "FINISH EDITING",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "Import…",
|
||||
"ui.infinite": "Infinite",
|
||||
"ui.insert": "Insert",
|
||||
"ui.insert_design.browse": "Browse…",
|
||||
"ui.insert_design.open_designs": "Open designs",
|
||||
"ui.insert_design.saved_file": "{name} has unsaved changes, so its saved file was inserted. Save it, then Update Links to bring the changes in.",
|
||||
"ui.insert_design.unsaved": "Unsaved changes",
|
||||
"ui.inspect": "Inspect",
|
||||
"ui.intersect": "Intersect",
|
||||
"ui.isolate": "Isolate",
|
||||
@@ -4192,7 +4369,7 @@
|
||||
"ui.manipulator_free_alt_tip": "On: Alt/Option or Ctrl/Cmd on extrude / gizmo arrows disables value snapping. Off: Ctrl/Cmd only.",
|
||||
"ui.manufacture": "Manufacture",
|
||||
"ui.material_review.axes": "Material-local axes; no body orientation is assigned.",
|
||||
"ui.material_review.claims": "Sources and licences are unverified claims. Missing values remain unknown.",
|
||||
"ui.material_review.claims": "Sources and licenses are unverified claims. Missing values remain unknown.",
|
||||
"ui.material_review.compressive_strength": "Compressive strength",
|
||||
"ui.material_review.conditions": "Stated conditions",
|
||||
"ui.material_review.density": "Density",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "{count} folder(s) could not be read.",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "Point",
|
||||
"ui.point_cloud_add_filter": "Add filter…",
|
||||
"ui.point_cloud_auto_range": "Automatic Range",
|
||||
"ui.point_cloud_color_by": "Color By",
|
||||
"ui.point_cloud_file_colors": "File Colors",
|
||||
"ui.point_cloud_filter_by": "Filter by",
|
||||
"ui.point_cloud_height_high": "Highest",
|
||||
"ui.point_cloud_height_low": "Lowest",
|
||||
"ui.point_cloud_legend_filter": "Shown and hidden in the legend above",
|
||||
"ui.point_cloud_no_file_colors": "The file has no colors",
|
||||
"ui.point_cloud_pause": "Pause",
|
||||
"ui.point_cloud_play": "Play",
|
||||
"ui.point_cloud_single_color": "Single Color",
|
||||
"ui.point_cloud_size": "Point Size",
|
||||
"ui.point_cloud_units": "File Units",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "Polygon",
|
||||
"ui.preferences": "Preferences",
|
||||
"ui.press_a_key": "press a key…",
|
||||
"ui.print_face_cleared": "{body}: print face cleared",
|
||||
"ui.print_face_input": "Print face",
|
||||
"ui.print_face_one_body": "A print face is picked for one body: send that body on its own to change it",
|
||||
"ui.print_face_pick": "Select one flat face of a solid body to make it the print face",
|
||||
"ui.print_face_set": "{body}: print face set; Send to Slicer lays the body on it",
|
||||
"ui.profile": "Profile",
|
||||
"ui.profile_plane": "Profile Plane",
|
||||
"ui.profiles": "Profiles",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "Revolve",
|
||||
"ui.ribbon_exit": "Exit",
|
||||
"ui.ribbon_labels": "Show text under ribbon icons",
|
||||
"ui.ribbon_menus_skip_pinned": "Leave pinned commands out of the drop-down menus",
|
||||
"ui.ribbon_pin_footer": "Pinned commands show on the ribbon. Hover a row to pin or unpin it.",
|
||||
"ui.ribbon_workspace": "Workspace",
|
||||
"ui.right": "Right",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "Select",
|
||||
"ui.selectOther": "Select Other…",
|
||||
"ui.selectTangentChain": "Select Tangent Chain",
|
||||
"ui.select_all": "Select All",
|
||||
"ui.select_components_by_face": "Select components (a face picks its component)",
|
||||
"ui.selection": "Selection",
|
||||
"ui.selection_modifiers": "Selection modifiers",
|
||||
"ui.selection_shift_add_only": "Shift+click adds without removing",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "Selection Filter",
|
||||
"ui.sketch_modifiers": "Sketch modifiers",
|
||||
"ui.sketch_project_geometry": "Geometry",
|
||||
"ui.sketch_report.all_constrained": "Everything is fully constrained.",
|
||||
"ui.sketch_report.dof": "Degrees of freedom",
|
||||
"ui.sketch_report.loose": "Not fully constrained",
|
||||
"ui.sketch_report.status": "Status",
|
||||
"ui.sketch_report.title": "Sketch Report",
|
||||
"ui.sketch_scale": "Sketch Scale",
|
||||
"ui.sketches": "Sketches",
|
||||
"ui.slice": "Slice",
|
||||
@@ -4529,13 +4724,22 @@
|
||||
"ui.view_angles_readout": "Pitch {pitch} · Yaw {yaw} · Roll {roll}",
|
||||
"ui.view_angles_roll": "Roll",
|
||||
"ui.view_angles_yaw": "Yaw",
|
||||
"ui.view_centre": "View centre",
|
||||
"ui.view_centre": "View center",
|
||||
"ui.viewport_status_clear": "Turn off {name}",
|
||||
"ui.viewport_status_clear_hint": "Turn off {name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} edges",
|
||||
"ui.viewport_status_from": "from {direction}",
|
||||
"ui.viewport_status_key": "Show key for {name}",
|
||||
"ui.viewport_status_minimum_radius": "Minimum radius",
|
||||
"ui.viewport_status_pairs": "{count} pairs",
|
||||
"ui.viewport_status_section_hatch": "{setting} · hatch",
|
||||
"ui.viewport_status_section_plane": "Current plane",
|
||||
"ui.viewport_status_section_tilted": "tilted · {offset}",
|
||||
"ui.viewport_status_stripes": "{count} stripes",
|
||||
"ui.viewport_status_summary_clear": "Turn everything off",
|
||||
"ui.viewport_status_summary_heading": "In this view",
|
||||
"ui.viewport_status_summary_label": "{name} and {count} more items",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "Follow theme",
|
||||
"ui.visual_shaded_hidden_edges": "Shaded with hidden edges",
|
||||
"ui.visual_shaded_with_edges": "Shaded with edges",
|
||||
@@ -4566,13 +4770,15 @@
|
||||
"ui.y_up": "Y up",
|
||||
"ui.z_up": "Z up",
|
||||
"ui.zoom": "Zoom",
|
||||
"ui.zoom_to_cursor_tip": "The wheel zooms toward the point under the cursor (off: toward the view's centre)",
|
||||
"ui.zoom_to_cursor_tip": "The wheel zooms toward the point under the cursor (off: toward the view's center)",
|
||||
"ui.zoom_to_the_cursor": "Zoom to the cursor",
|
||||
"update.available": "SolidCraft {version} is available",
|
||||
"update.button": "Update",
|
||||
"update.button_version": "Update to {version}",
|
||||
"update.check_automatically": "Check for updates automatically",
|
||||
"update.check_for_updates": "Check for updates",
|
||||
"update.check_now": "Check now",
|
||||
"update.check_unavailable": "Update checks are not available for this installation.",
|
||||
"update.checking": "Checking…",
|
||||
"update.copy": "Copy",
|
||||
"update.dmg_opened": "The disk image is open and verified: drag SolidCraft to Applications, replacing the old copy, then restart SolidCraft.",
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "משטח מעבר",
|
||||
"BOUNDARY SURFACE": "משטח גבול",
|
||||
"BROWSER": "עץ התכן",
|
||||
"Back to the original order": "חזרה לסדר המקורי",
|
||||
"Ball": "כדורי",
|
||||
"Bar": "מוט",
|
||||
"Base Center": "מרכז הבסיס",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "מקצועות",
|
||||
"Edit": "עריכה",
|
||||
"Edit Profile Sketch": "עריכת סקיצת הפרופיל",
|
||||
"Edit shortcuts": "עריכת קיצורי דרך",
|
||||
"Enable rule": "הפעלת הכלל",
|
||||
"Enabled": "מופעל",
|
||||
"End Radius": "רדיוס סיום",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "רדיוס",
|
||||
"Radius Fit": "התאמת רדיוס",
|
||||
"Ratio": "יחס",
|
||||
"Read-only list: shortcuts can't be changed here.": "רשימה לקריאה בלבד: לא ניתן לשנות כאן קיצורי דרך.",
|
||||
"Reattach selected face": "הצמדה מחדש לפאה שנבחרה",
|
||||
"Recover": "שחזור",
|
||||
"Recover unsaved design?": "לשחזר תכן שלא נשמר?",
|
||||
@@ -593,6 +596,8 @@
|
||||
"Snap to face and edge centres": "הצמדה למרכזי פאות ומקצועות",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "אין אפשרות לשלוח דיווחים ישירות מתוך SolidCraft. יש לשלוח אותם ב-GitHub; אין צורך באסימון גישה באפליקציה.",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft נסגרה לפני שתכנים אלה נשמרו. אפשר לפתוח את השמירה האוטומטית האחרונה שלהם.",
|
||||
"Sort A to Z": "מיון בסדר עולה",
|
||||
"Sort Z to A": "מיון בסדר יורד",
|
||||
"Spacing 2 must be a non-zero number": "מרווח 2 חייב להיות מספר שונה מאפס",
|
||||
"Spacing must be a non-zero number": "המרווח חייב להיות מספר שונה מאפס",
|
||||
"Specialise": "התמחות",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "על הפאה",
|
||||
"bom.group_children": "תת-חלקים בשורת החלק שלהם",
|
||||
"browser.body_name": "גוף{number}",
|
||||
"browser.calibrate_click_a": "לחצו על התמונה כדי לבחור את נקודה A, או הקלידו את הקואורדינטות שלה.",
|
||||
"browser.calibrate_click_b": "לחצו על התמונה כדי לבחור את נקודה B, או הקלידו את הקואורדינטות שלה.",
|
||||
"browser.calibrate_title": "כיול: {name}",
|
||||
"browser.capture_many": "{count} רכיבים הוזזו, אך המיקומים שלהם לא נלכדו.",
|
||||
"browser.capture_note": "לכידה שומרת את המיקום החדש; החזרה מחזירה את המיקום הקודם.",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "בחירת מראה",
|
||||
"cmd.appearance_replace": "החלפת מראה",
|
||||
"cmd.assembly_bom": "רשימת חלקים",
|
||||
"cmd.body.print_face": "פאת הדפסה",
|
||||
"cmd.body_rename": "שינוי שם גוף",
|
||||
"cmd.browser_collapse_all": "כיווץ הכול",
|
||||
"cmd.browser_expand_all": "הרחבת הכול",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "הזזת פריטים בעץ",
|
||||
"cmd.browser_order": "סידור פריטים בעץ",
|
||||
"cmd.browser_rename_group": "שינוי שם קבוצה",
|
||||
"cmd.browser_reparent": "העברה לרכיב",
|
||||
"cmd.browser_ungroup": "פירוק קבוצה",
|
||||
"cmd.browser_visibility": "הצגה/הסתרה",
|
||||
"cmd.canvas_calibrate": "כיול קנבס",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "מאפייני חלק",
|
||||
"cmd.component_metadata_set": "שינוי מאפייני חלק",
|
||||
"cmd.component_move_bodies": "העברת גופים לרכיב",
|
||||
"cmd.component_move_features": "העברת פיצ'רים לרכיב",
|
||||
"cmd.component_move_sketches": "העברת סקיצות לרכיב",
|
||||
"cmd.component_paste_from_design": "הדבק מעיצוב אחר",
|
||||
"cmd.component_paste_new": "הדבקה כחדש",
|
||||
"cmd.component_properties": "תכונות פיזיקליות של רכיב",
|
||||
"cmd.component_relink": "קישור מחדש למקור",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "יצירת תמונת הדמיה",
|
||||
"cmd.render_status": "התקדמות ההדמיה",
|
||||
"cmd.select_clear": "ניקוי הבחירה",
|
||||
"cmd.settings_profile_apply": "החלת פרופיל הגדרות",
|
||||
"cmd.settings_profile_delete": "מחיקת פרופיל הגדרות",
|
||||
"cmd.settings_profile_export": "ייצוא פרופיל הגדרות",
|
||||
"cmd.settings_profile_import": "ייבוא פרופיל הגדרות",
|
||||
"cmd.settings_profile_list": "פרופילי הגדרות",
|
||||
"cmd.settings_profile_rename": "שינוי שם פרופיל הגדרות",
|
||||
"cmd.settings_profile_save": "שמירת פרופיל הגדרות",
|
||||
"cmd.sheet_convert": "המרה לפח",
|
||||
"cmd.sheet_export_bend_table": "ייצוא טבלת כיפופים",
|
||||
"cmd.sheet_export_dxf": "ייצוא פריסה כ־DXF",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "קיפול מחדש",
|
||||
"cmd.sheet_rules": "רשימת כללי פח",
|
||||
"cmd.sheet_unfold": "פתיחת קיפול",
|
||||
"cmd.sketch.construction_line": "ישר עזר",
|
||||
"cmd.sketch.construction_line.angle": "ישר עזר בזווית",
|
||||
"cmd.sketch.construction_line.bisector": "חוצה זווית",
|
||||
"cmd.sketch.construction_line.horizontal": "ישר עזר אופקי",
|
||||
"cmd.sketch.construction_line.parallel": "ישר עזר מקביל",
|
||||
"cmd.sketch.construction_line.perpendicular": "ישר עזר ניצב",
|
||||
"cmd.sketch.construction_line.tangent_at": "משיק בנקודה על העקומה",
|
||||
"cmd.sketch.construction_line.tangent_external": "משיק דרך נקודה חיצונית",
|
||||
"cmd.sketch.construction_line.tangent_two": "משיק משותף",
|
||||
"cmd.sketch.construction_line.vertical": "ישר עזר אנכי",
|
||||
"cmd.sketch_arc3d": "קשת תלת־ממדית",
|
||||
"cmd.sketch_arc_center_point": "קשת מרכז ונקודה",
|
||||
"cmd.sketch_arc_tangent": "קשת משיקה",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "גודל הציור",
|
||||
"cmd.sketch_edit": "עריכת סקיצה",
|
||||
"cmd.sketch_edit_text": "עריכת טקסט",
|
||||
"cmd.sketch_equation_curve": "עקומת משוואה",
|
||||
"cmd.sketch_equation_curve_edit": "עריכת עקומת משוואה",
|
||||
"cmd.sketch_export_dxf": "שמירה כ־DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "סיום עם אילוץ אוטומטי",
|
||||
"cmd.sketch_fit_curves_to_section": "התאמת עקומות לחתך רשת משולשים",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "דפדפן רינדור",
|
||||
"cmd.view.render_dock": "הזז את עגינת הרינדור",
|
||||
"cmd.view.render_focus": "תצוגת מיקוד רינדור",
|
||||
"cmd.view.status_items": "פריטי מצב תצוגה",
|
||||
"cmd.view_ambient_occlusion": "הצללה סביבתית",
|
||||
"cmd.view_angle_readout": "זוויות תצוגה",
|
||||
"cmd.view_apply": "שחזור תצוגה שמורה",
|
||||
@@ -1374,6 +1405,18 @@
|
||||
"help.occurrence.move": "מזיז חלק בהרכבה רק בכיוונים שהמפרקים שלו מאפשרים. בחרו פאה של החלק, ואז גררו חץ או קשת זמינים.",
|
||||
"help.parameters.change": "פתיחת הטבלה של ערכים בעלי שם וביטויים שקובעים את מידות התכנון. כך משנים מידה במקום אחד וכל הפיצ'רים שמשתמשים בה מתעדכנים.",
|
||||
"help.pointcloud.insert": "הוספת סריקה בפורמט PLY, XYZ או PTS כענן נקודות לצד המודל. משמש כעזר למידול על סמך נתוני מדידה.",
|
||||
"help.sketch.construction_line": "יצירת ישר עזר אינסופי דרך שתי נקודות, לתכנון הסקיצה בלי לפצל את הפרופילים.",
|
||||
"help.sketch.construction_line.angle": "יצירת ישר עזר אינסופי בזווית מציר X של הסקיצה. יש לבחור נקודה ולהקליד זווית או לבחור כיוון.",
|
||||
"help.sketch.construction_line.bisector": "יש לבחור שני ישרים נחתכים בסקיצה ואז אחד משני חוצי הזווית. התוצאה עוקבת אחר עריכת ישרי המקור.",
|
||||
"help.sketch.construction_line.horizontal": "יצירת ישר עזר אופקי אינסופי דרך נקודה. האילוץ האופקי נשמר בעריכות מאוחרות יותר.",
|
||||
"help.sketch.construction_line.parallel": "יש לבחור ישר בסקיצה ואז למקם ישר עזר אינסופי מקביל. לחיצה ימנית מאפשרת לבחור ייחוס אחר.",
|
||||
"help.sketch.construction_line.perpendicular": "יש לבחור ישר בסקיצה ואז למקם ישר עזר אינסופי ניצב. לחיצה ימנית מאפשרת לבחור ייחוס אחר.",
|
||||
"help.sketch.construction_line.tangent_at": "יצירת משיק בנקודה על מעגל או קשת מעגלית, או בנקודת קצה של ספליין פתוח או חתך חרוט פתוח. יש לבחור את העקומה ואז את נקודת ההשקה.",
|
||||
"help.sketch.construction_line.tangent_external": "יש לבחור מעגל או קשת מעגלית, נקודה חיצונית ואז פתרון למשיק. התצוגה המקדימה מציגה רק נקודות השקה על הקשת המצוירת.",
|
||||
"help.sketch.construction_line.tangent_two": "יש לבחור שני מעגלים או קשתות מעגליות ואז משיק משותף בתצוגה המקדימה. נקודות ההשקה חייבות להיות על העקומות המצוירות.",
|
||||
"help.sketch.construction_line.vertical": "יצירת ישר עזר אנכי אינסופי דרך נקודה. האילוץ האנכי נשמר בעריכות מאוחרות יותר.",
|
||||
"help.sketch.equation_curve": "משרטט עקומה מנוסחאות על פני טווח: x(t) ו־y(t), או y = f(x). הנוסחאות יכולות להשתמש בפרמטרים והעקומה עוקבת אחריהם: לגל סינוס, לספירלה או לאבולבנטה של שן גלגל שיניים.",
|
||||
"help.sketch.inspect": "פותח דוח על הסקיצה הפתוחה: כמה דרגות חופש נותרו והאם היא מאולצת במלואה. השתמשו בו כדי לגלות מה עדיין זז לפני שמסיימים את הסקיצה.",
|
||||
"help.solid.align": "הזזת הגופים שנבחרו כך שנקודה, פאה או מישור שלהם יפגשו נקודה, פאה או מישור במקום אחר. מתאים להצמדת חלק לחלק אחר בלי למדוד את המרחק.",
|
||||
"help.solid.chamfer": "חיתוך המקצועות שנבחרו בשיפוע ישר במרחק שנקבע. כך שוברים מקצועות חדים או מקלים על הכנסה של פין או בורג.",
|
||||
"help.solid.combine": "איחוד גופים, חיסורם מגוף יעד או השארת הנפח המשותף להם בלבד, עם אפשרות לשמור את גופי הכלי. מתאים למיזוג חלקים, לחיתוך צורה אחת בעזרת אחרת או למציאת החפיפה בין שני גופים.",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "חומרים שונים",
|
||||
"measure.at": "מיקום",
|
||||
"measure.item": "פריט {number}",
|
||||
"measure.quick_copied": "המדידה הועתקה",
|
||||
"measure.quick_copy": "לחיצה מעתיקה את המדידה",
|
||||
"measure.quick_edges": "{count} מקצועות",
|
||||
"measure.quick_faces": "{count} פאות",
|
||||
"messages.ago_h": "לפני {n} שע'",
|
||||
"messages.ago_min": "לפני {n} דק'",
|
||||
"messages.ago_s": "לפני {n} שנ'",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "זו אינה הזזה",
|
||||
"not a number": "לא מספר",
|
||||
"open a sketch first": "יש לפתוח סקיצה תחילה",
|
||||
"parameters.apply_live": "להחיל כל שינוי ביציאה מהשדה שלו",
|
||||
"parameters.apply_live_tip": "כבוי: השינויים ממתינים עד ל„החל” או „אישור”, ואז התכן נבנה מחדש פעם אחת עבור כולם. „ביטול” או Escape משליכים אותם.",
|
||||
"parameters.held": "{count} שינויים ממתינים ל„החל”",
|
||||
"parameters.held_hint": "עריכת ביטויים ויחידות. השינויים ממתינים ל„החל” או ל„אישור”.",
|
||||
"parameters.held_one": "שינוי אחד ממתין ל„החל”",
|
||||
"parts.automatic_name": "אוטומטי",
|
||||
"parts.dimension.across_flats": "מידת מפתח",
|
||||
"parts.dimension.bore": "קוטר קדח",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "עובי",
|
||||
"parts.dimension.width": "רוחב",
|
||||
"parts.family.bearing": "מסב כדורי חריץ עמוק (מעטפת)",
|
||||
"parts.family.button_head_cap_screw": "בורג ראש כפתור עם שקע משושה",
|
||||
"parts.family.dowel_pin": "פין גלילי",
|
||||
"parts.family.hex_bolt": "בורג ראש משושה",
|
||||
"parts.family.hex_nut": "אום משושה",
|
||||
"parts.family.set_screw": "בורג אלן ללא ראש, קצה שטוח",
|
||||
"parts.family.socket_head_cap_screw": "בורג ראש גלילי עם משושה פנימי",
|
||||
"parts.family.washer": "דסקית שטוחה",
|
||||
"parts.holes": "חורים (אופציונלי)",
|
||||
"parts.placement_hint": "בחרו חור אחד או יותר כדי להושיב חלק בכל אחד, או לחצו אישור כדי למקם אותו בראשית",
|
||||
"pattern.alignment_2": "יישור 2",
|
||||
"pattern.alignment_hint": "הספירה כוללת את המקור. מרכוז מאזן את העותקים; היפוך בוחר את הצד שמקבל את העותק הנוסף כשהסך זוגי.",
|
||||
"pattern.direction_1": "כיוון 1",
|
||||
@@ -1801,6 +1856,8 @@
|
||||
"prefs.bottom_centre": "למטה במרכז",
|
||||
"prefs.bottom_right": "למטה מימין",
|
||||
"prefs.browser": "עץ התכן",
|
||||
"prefs.browser_eye_left": "סמל העין ליד חץ הקיפול",
|
||||
"prefs.browser_eye_left_note": "שורות עץ התכן מציגות את סמל העין ליד חץ הקיפול, כמו קודם, במקום בעמודה בקצה הימני של השורות.",
|
||||
"prefs.browser_reveal_on_hover": "הצגה בריחוף",
|
||||
"prefs.browser_show_note": "״מוצג״ משאיר את הדפדפן על המסך. ״הצגה בריחוף״ מסתיר אותו עד שהמצביע מגיע למקומו או ללשונית הדקה בקצהו השמאלי, והוא נשאר פתוח כל עוד המצביע בתוכו או שתפריט ממנו פתוח.",
|
||||
"prefs.browser_shown": "מוצג",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "ייכנס לתוקף אחרי הפעלה מחדש של SolidCraft. WGPU_ADAPTER_NAME גובר על בחירה זו.",
|
||||
"prefs.graphics_note": "איזון בין מהירות לחלקות. כל בחירה מציגה את השפעתה על דוגמה.",
|
||||
"prefs.graphics_presets_note": "הגדרות קבועות מראש קובעות יחד את הבחירות שלמטה.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "הסתרת סמלי אילוצים בהקטנה",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "סמלי האילוצים נעלמים כשהשרטוט מוקטן מספיק כדי שלא יעמיסו על התצוגה. כבוי: הם נשארים בגודל מסך קבוע בכל זום.",
|
||||
"prefs.history": "ציר הזמן",
|
||||
"prefs.history_origin_bodies": "הצגת הראשית והגופים למעלה",
|
||||
"prefs.history_origin_bodies_note": "ההיסטוריה משמאל או מתחת לדפדפן מתחילה בתיקיית הגופים של הרכיב הפעיל ובראשית, עם סמלי העין והתפריטים כמו בדפדפן. ההיסטוריה למטה לא משתנה.",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "הפריסה הדחוסה מצמידה חלוניות לשולי החלון. שקיפות עץ התכן זמינה בפריסה הצפה. את צד העוזר אפשר לשנות בעמוד העוזר.",
|
||||
"prefs.left": "שמאל",
|
||||
"prefs.left_click": "לחיצה שמאלית",
|
||||
"prefs.line_drag_draws_one": "לחיצה וגרירה משרטטות קו אחד",
|
||||
"prefs.line_drag_draws_one_note": "בכלי הקו, לחיצה, גרירה ושחרור משרטטים קו אחד מנקודת הלחיצה עד נקודת השחרור, והוא מסתיים שם. לחיצות עדיין משרטטות שרשרת. כבוי: גרירה מציבה נקודה היכן שמשחררים, כמו לחיצה.",
|
||||
"prefs.linked_designs": "תכנים מקושרים",
|
||||
"prefs.live_input": "קלט חי",
|
||||
"prefs.live_preview": "תצוגה מקדימה חיה",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "קובצי STEP וייבוא",
|
||||
"prefs.max_file_size_web": "יישום הדפדפן פותח קובצי STEP וייבוא עד 512 MB וקובצי תכן עד 256 MB: לשונית דפדפן אינה יכולה להכיל קבצים גדולים יותר. ביישום למחשב ניתן להעלות מגבלות אלה.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "סמלים גדולים",
|
||||
"prefs.menu_list": "רשימה",
|
||||
"prefs.menus": "תפריטים",
|
||||
"prefs.minutes": "דקות",
|
||||
"prefs.minutes_suffix": " דק'",
|
||||
"prefs.mouse": "עכבר ומשטח מגע",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "שמות מישורי הראשית",
|
||||
"prefs.origin_plane_names_note": "השמות המוצגים בדפדפן, בתיבות הדו־שיח וברשימות. {top} הוא XY, {front} הוא XZ ו־{right} הוא YZ, כש־Z למעלה. פקודות, סקריפטים ותכנונים שמורים שומרים על XY, XZ ו־YZ.",
|
||||
"prefs.overall_speed": "מהירות כללית",
|
||||
"prefs.parameter_list_rows": "שורות ברשימת הפרמטרים",
|
||||
"prefs.parameter_list_rows_tip": "חץ למטה בשדה ערך ריק מציג את הפרמטרים, המועדפים תחילה, עד מספר זה. מספר קטן יותר שומר על רשימה קלה בתכנון גדול.",
|
||||
"prefs.persistent_ribbon_pressed": "הדגשת פקודות פעילות ברצועת הכלים",
|
||||
"prefs.persistent_ribbon_pressed_help": "הדגשת פקודות ברצועת הכלים כל עוד ההשפעות שלהן פעילות. כבו אפשרות זו כדי לשמור על המראה הניטרלי הקודם ועל עזרת הפקודות.",
|
||||
"prefs.perspective_fov": "שדה ראייה",
|
||||
"prefs.placement": "מיקום",
|
||||
"prefs.prefer_free_sketch_points": "העדפת נקודות סקיצה ניתנות להזזה כשנקודות חופפות",
|
||||
"prefs.preview_choices": "תצוגה מקדימה של הבחירות שלך",
|
||||
"prefs.print_face_highlight": "הדגשת פאת ההדפסה",
|
||||
"prefs.print_face_highlight_tip": "עד כמה חזק צובעים ומקיפים את פאת ההדפסה של גוף בתצוגה. 0 % אינו מציג הדגשה.",
|
||||
"prefs.profile_active": "פרופיל פעיל",
|
||||
"prefs.profile_applied": "הפרופיל הוחל.",
|
||||
"prefs.profile_changed": "ההגדרות השתנו מאז שהפרופיל נשמר. „שמירה“ מכניסה אותן לפרופיל.",
|
||||
"prefs.profile_deleted": "הפרופיל נמחק.",
|
||||
"prefs.profile_export": "ייצוא…",
|
||||
"prefs.profile_exported": "הפרופיל יוצא.",
|
||||
"prefs.profile_imported": "הפרופיל יובא. בחרו בו תחת „פרופיל פעיל“ כדי לעבור אליו.",
|
||||
"prefs.profile_name_hint": "שם הפרופיל, למשל מחשב נייד",
|
||||
"prefs.profile_rename": "שינוי שם",
|
||||
"prefs.profile_renamed": "שם הפרופיל שונה.",
|
||||
"prefs.profile_save": "שמירה",
|
||||
"prefs.profile_saved": "ההגדרות הנוכחיות נשמרו בפרופיל.",
|
||||
"prefs.profile_skipped": "הפרופיל הוחל; {n} הגדרות שמרו על ערכן הנוכחי (ראו ביומן).",
|
||||
"prefs.profiles": "פרופילי הגדרות",
|
||||
"prefs.profiles_note": "קיצורי מקלדת, סרגל הכלים, ניווט, התפריט המעגלי והגדרות הממשק, נשמרים יחד תחת שם אחד ומוחלפים בבת אחת.",
|
||||
"prefs.project_options_dialog": "תיבת האפשרויות של Project",
|
||||
"prefs.project_options_dialog_note": "פעיל: לבחור גאומטריה או גופים וקישור הטלה לפני ההטלה. כבוי: להשאיר את זרימת העבודה הקודמת של בחירה ישירה.",
|
||||
"prefs.quality_default": "ברירת מחדל",
|
||||
"prefs.quality_fastest": "המהיר ביותר",
|
||||
"prefs.quality_slowest": "האיטי ביותר",
|
||||
"prefs.quality_smoother": "חלק יותר",
|
||||
"prefs.quick_measure": "מדידה מהירה בפינת התצוגה",
|
||||
"prefs.quick_measure_note": "מציג את מידות הבחירה בפינה הימנית התחתונה של התצוגה, מעל ההיסטוריה: אורך מקצוע (או Ø ו-R למקצוע עגול), שטח פאה, מיקום נקודה, המרחק והזווית בין שני פריטים, והסכום של כמה מקצועות או פאות. לחיצה מעתיקה אותו.",
|
||||
"prefs.render_previous_geometry_budget": "שימוש בתקציב הגאומטריה הקודם לתצוגה מקדימה של רינדור",
|
||||
"prefs.render_previous_geometry_budget_help": "שחזור מגבלת הגאומטריה הקבועה הקודמת (512 MiB במחשב שולחני של 64 סיביות, 128 MiB בפלטפורמות אחרות) במקום התקציב המבוסס על ההתקן.",
|
||||
"prefs.reports_saved": "{n} שמורים",
|
||||
"prefs.ribbon_reveal": "הצגת תוצאות חיפוש בסרט",
|
||||
"prefs.ribbon_reveal_note": "מעבר עם הסמן מעל תוצאה בחיפוש פקודות מראה היכן הפקודה נמצאת בסרט: הלשונית, הכפתור או השורה שלה בתפריט הנפתח של לוח. פקודה שהופעלה מהחיפוש מהבהבת שם, ופקודה פעילה מתפריט נפתח מסמנת את הלוח שלה.",
|
||||
"prefs.right_click": "לחיצה ימנית",
|
||||
"prefs.saving": "שמירה אוטומטית ושחזור",
|
||||
"prefs.scale_note": "גם Ctrl + / Ctrl − בחלון. הכפתורים בגודל 28 px ב־100%.",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "אין הגדרות תואמות",
|
||||
"prefs.select": "בחירה",
|
||||
"prefs.select_one_item": "בחירת פריט אחד",
|
||||
"prefs.select_other_hidden": "בחירת גאומטריה מוסתרת באמצעות בחירה אחרת",
|
||||
"prefs.select_other_hidden_help": "מופעל: כולל גופים, סקיצות וקצוות מוסתרים בקרבת הסמן. כבוי: שימוש ברשימה המקורית של גאומטריה גלויה מתחת לסמן.",
|
||||
"prefs.selecting": "בחירה",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift מוסיף בלבד; Ctrl / Cmd מחליף מצב",
|
||||
"prefs.shift_add_note": "כשפועל: Shift מוסיף, Ctrl / Cmd מחליף מצב. כשכבוי (ברירת מחדל): שניהם מחליפים מצב.",
|
||||
"prefs.shortcuts": "קיצורים",
|
||||
"prefs.single_surface_analysis": "שימוש בניתוח משטח יחיד",
|
||||
"prefs.single_surface_analysis_help": "כשהאפשרות כבויה, הצללת המשטח וניתוח הרציפות יכולים להישאר פעילים יחד. הפעלתה משאירה רק את הניתוח האחרון שהופעל או שונה.",
|
||||
"prefs.sketch_align_points": "יישור לנקודות סקיצה אחרות בזמן השרטוט",
|
||||
"prefs.sketch_align_points_note": "בזמן השרטוט, נקודה מתיישרת אופקית עם נקודת סקיצה אחת ואנכית עם אחרת בו-זמנית, עם קו עזר מנוקד, והלחיצה שומרת את שני היישורים. כבוי: רק עם הנקודה הקודמת, ציר אחד בכל פעם.",
|
||||
"prefs.sketch_conflict_colour": "גאומטריה סותרת בצבע הסתירה",
|
||||
"prefs.sketch_conflict_colour_note": "כשאילוצי סקיצה סותרים, העקומות והנקודות שאילוץ כושל מחזיק מצוירות גם הן בצבע הסתירה, לא רק הסמל או המידה שלו. כבוי: הן שומרות על צבעיהן הרגילים.",
|
||||
"prefs.sketch_construction_lines": "כלי ישרי עזר מורחבים",
|
||||
"prefs.sketch_exit_view": "בסיום סקיצה",
|
||||
"prefs.sketch_exit_view.keep": "שמירה על התצוגה הנוכחית",
|
||||
"prefs.sketch_exit_view.previous": "חזרה לתצוגה הקודמת",
|
||||
"prefs.sketch_exit_view.unless_rotated": "חזרה אלא אם התצוגה סובבה",
|
||||
"prefs.sketch_exit_view_note": "לאן התצוגה עוברת אחרי סיום סקיצה, ביטול או Esc כפול.",
|
||||
"prefs.sketch_open_look_at": "הפניית התצוגה אל הסקיצה בפתיחתה",
|
||||
"prefs.sketch_open_look_at_note": "כבוי: יצירה או עריכה של סקיצה משאירות את התצוגה כפי שהיא. «מבט אל» מפנה את התצוגה אל הסקיצה כשרוצים.",
|
||||
"prefs.sketch_recent_snap": "הצמדה אוטומטית למרכזים ולנקודות אמצע אחרונים",
|
||||
"prefs.sketch_recent_snap_note": "בזמן שרטוט, הסמן נצמד למקום שבו נחתכים קווי העזר של שני מרכזי המעגלים או נקודות האמצע של קצוות ישרים האחרונים. כבוי: קווי העזר נשארים לתצוגה בלבד והסמן אינו זז.",
|
||||
"prefs.sketch_selection": "סקיצה ובחירה",
|
||||
"prefs.sketch_selection_heading": "סקיצה ובחירה",
|
||||
"prefs.sketch_selection_note": "איך סקיצות נצמדות ואיך לחיצות בוחרות.",
|
||||
@@ -1995,20 +2096,34 @@
|
||||
"prefs.under_cursor": "מתחת לסמן",
|
||||
"prefs.units_precision": "יחידות ודיוק",
|
||||
"prefs.updates": "עדכונים",
|
||||
"prefs.value_boxes_in_view": "הצגת ערכים ליד הידיות שלהם בתצוגה",
|
||||
"prefs.value_boxes_in_view_tip": "ערך הפקודה (מרחק, רדיוס…) בתיבה ליד הידית שלו, מעל המודל. כבוי: מקלידים אותו בחלון הפקודה, שמקבל את המקלדת אחרי בחירה, ושום דבר לא מסתיר את המודל.",
|
||||
"prefs.view": "התנהגות המבט",
|
||||
"prefs.view_confirm_corner": "אישור וביטול בפינת התצוגה",
|
||||
"prefs.view_confirm_corner_note": "כשתיבת דו־שיח או סקיצה פתוחות, סימן וי וסימן איקס בפינה הימנית העליונה של התצוגה עושים את מה שעושים אישור וביטול של תיבת הדו־שיח, או מסיימים ומבטלים את הסקיצה. ניווט התצוגה זז אל מתחתיהם.",
|
||||
"prefs.viewport": "אזור התצוגה",
|
||||
"prefs.viewport_analysis_status": "הצגת מצב ניתוח בחלון התצוגה",
|
||||
"prefs.viewport_analysis_status_help": "הצגת ניתוחים פעילים מעל חלון התצוגה ופתיחת המקרא מכל פריט. Esc מכבה את הניתוח האחרון. כיבוי האפשרות משחזר את המקרא בפינה ואת פעולת Esc הקודמת.",
|
||||
"prefs.viewport_background": "רקע",
|
||||
"prefs.viewport_background_colour": "צבע",
|
||||
"prefs.viewport_background_theme": "מעבר הצבעים של ערכת הנושא",
|
||||
"prefs.viewport_section_status": "הצגת מצב חתך בחלון התצוגה",
|
||||
"prefs.viewport_section_status_help": "הצגת הגדרת החתך בחלון התצוגה. Escape ולחצן הסרט הפעיל מכבים את החתך. כיבוי האפשרות שומר על בקרי החתך הקודמים.",
|
||||
"prefs.viewport_status_summary": "סיכום פריטי מצב בחלון התצוגה",
|
||||
"prefs.viewport_status_summary_help": "קיבוץ שלושה פריטי מצב או יותר לתג סיכום אחד. כיבוי האפשרות משאיר כל פריט בשורה המלאה.",
|
||||
"prefs.wheel": "גלגלת",
|
||||
"prefs.wheel_trackpad": "גלגלת ומשטח מגע",
|
||||
"prefs.workspace": "סביבת עבודה",
|
||||
"prefs.zoom_stop_at_model": "עצירת הזום במודל",
|
||||
"prefs.zoom_stop_at_model_tip": "העכבר התלת־ממדי ויישום ההתקן מקרבים את המבט אל המשטח שבמרכז התצוגה; זום בגרירה שומר על נקודת תחילת הגרירה. כשהאפשרות כבויה, אפשר לעבור דרך המודל. הגלגלת ומחוות הצביטה משתמשות בנפרד בהגדרת הזום אל הסמן",
|
||||
"prefs.zoom_toward_cursor": "זום, לכיוון הסמן",
|
||||
"properties.title": "מאפיינים: {name}",
|
||||
"recovery.days_ago": "לפני {count} ימים",
|
||||
"recovery.detail": "{file} · {features} פיצ'רים · נשמר אוטומטית {when}",
|
||||
"recovery.discard_all": "השלכת הכול",
|
||||
"recovery.discard_all_detail": "לא ניתן לבטל פעולה זו.",
|
||||
"recovery.discard_all_title": "להשליך {count} שמירות אוטומטיות?",
|
||||
"recovery.discard_all_title_one": "להשליך שמירה אוטומטית אחת?",
|
||||
"recovery.hours_ago": "לפני {count} שע'",
|
||||
"recovery.just_now": "זה עתה",
|
||||
"recovery.min_ago": "לפני {count} דק'",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "מוכן לרינדור",
|
||||
"render.output_run_check": "הפעל בדיקה",
|
||||
"render.output_size_limit": "{method}: עד {dimension} פיקסלים לצלע ו-{pixels} פיקסלים. הגודל הגדול ביותר שמתאים: {width} × {height}.",
|
||||
"render.output_size_method_profile": "כדי לרנדר {width} × {height}, יש לבחור ב-{method} עם פרופיל משאבי CPU {profile} או בגודל קטן יותר.",
|
||||
"render.output_size_ok": "הגודל תקין · {width} × {height} פיקסלים",
|
||||
"render.output_size_profile": "כדי לרנדר {width} × {height}, יש לבחור בפרופיל משאבי CPU {profile} או בגודל קטן יותר.",
|
||||
"render.output_swap_orientation": "החלפת רוחב וגובה",
|
||||
"render.output_tools_inspector": "ערוך גודל ופורמט במפקח הפלט.",
|
||||
"render.output_view_image": "הצג תמונה",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "מותאם…",
|
||||
"render.size_full_hd": "Full HD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · נדרש {profile}",
|
||||
"render.size_presets": "הגדרות גודל מוכנות",
|
||||
"render.size_presets_pending": "יגיע עם עורך הפלט",
|
||||
"render.size_preview": "תצוגה מקדימה",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "לחיצה כפולה על רכיב מפעילה אותו, או עורכת רכיב מקושר במקומו",
|
||||
"settings.frame_rate_details_note": "מוסיף גרף של זמני התמונות האחרונות עם המשולשים שצוירו מעליו, היסטוגרמה של זמני התמונות ואת מה שה־GPU צייר. לחיצה על קצב התמונות בתצוגה מציגה או מסתירה אותם.",
|
||||
"settings.frame_rate_note": "הצגת מספר הפריימים לשנייה בפינה הימנית התחתונה של התצוגה. כל עוד האפשרות פעילה, התצוגה מצוירת מחדש ברציפות.",
|
||||
"settings.insert_lists_open_designs": "הוספת תכן מציגה קודם את התכנים הפתוחים בלשוניות אחרות",
|
||||
"settings.measure_axis_distances": "הצגת מרחקי X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "הצגת המרחקים לאורך צירי העולם לצד המרחק הכולל כשכלי המדידה פתוח.",
|
||||
"settings.msaa_applies_on_restart": "החלקת הקצוות תחול בהפעלה הבאה של SolidCraft",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "מתאר",
|
||||
"sheet.flange_type_edge": "מקצוע",
|
||||
"sheet.no_body": "אין גוף פח: יש להתחיל אחד עם אוגן > בסיס, או להמיר לוח לפח עם המרה לפח (יש לבחור את הפאה השטוחה הגדולה שלו)",
|
||||
"sheet.personal_rules.confirm_delete": "אישור מחיקה",
|
||||
"sheet.personal_rules.delete": "מחיקה",
|
||||
"sheet.personal_rules.delete_prompt": "למחוק את הכלל האישי הזה? כללים שכבר נמצאים בתכנים לא ישתנו.",
|
||||
"sheet.personal_rules.full": "הספרייה האישית כבר מכילה 64 כללים.",
|
||||
"sheet.personal_rules.invalid_name": "יש להזין שם קצר ללא מעברי שורה או תווי בקרה.",
|
||||
"sheet.personal_rules.invalid_values": "יש להשלים את ערכי הכלל: כל ערך צריך להיות ניתן לחישוב בתכן זה, עם עובי חיובי ומקדם K בין 0 ל־1.",
|
||||
"sheet.personal_rules.missing": "הכלל האישי שנבחר כבר אינו זמין.",
|
||||
"sheet.personal_rules.name": "שם הכלל",
|
||||
"sheet.personal_rules.name_exists": "כבר קיים כלל אישי בשם הזה. יש להשתמש בשם אחר.",
|
||||
"sheet.personal_rules.name_hint": "שם ייחודי",
|
||||
"sheet.personal_rules.overwrite": "שמירת השינויים בכלל האישי שנבחר",
|
||||
"sheet.personal_rules.rename": "שינוי שם",
|
||||
"sheet.personal_rules.rule": "כלל אישי",
|
||||
"sheet.personal_rules.save": "שמירה כחדש",
|
||||
"sheet.personal_rules.scope": "נשמרים בפרופיל שלך לכל התכנים.",
|
||||
"sheet.personal_rules.select": "בחירת כלל",
|
||||
"sheet.personal_rules.title": "כללים אישיים",
|
||||
"sheet.personal_rules.unsupported": "לכלל הזה יש ערכים שהגרסה הזו אינה יכולה להשתמש בהם.",
|
||||
"shortcut.json_error": "הפרמטרים חייבים להיות JSON: {error}",
|
||||
"shortcut.no_command": "אין פקודה `{id}`; הטקסט שלפני ה־JSON חייב להיות מזהה פקודה",
|
||||
"shortcut.pin": "הצמדה לראש תיבת S",
|
||||
"shortcut.unpin": "ביטול הצמדה",
|
||||
"sketch is missing": "הסקיצה חסרה",
|
||||
"sketch.degrees_of_freedom": "{count} דרגות חופש",
|
||||
"sketch.dimension_added_driven": "הסקיצה כבר קובעת את המידה הזו, ולכן היא נוספה כמידה מונעת (מידת ייחוס)",
|
||||
"sketch.dimension_applied": "המידה הוחלה",
|
||||
"sketch.dimension_applied_defined": "המידה הוחלה; הפרמטר `{name}` הוגדר",
|
||||
"sketch.dimension_applied_renamed": "המידה הוחלה; שם הפרמטר הוא כעת `{name}`",
|
||||
"sketch.dof_left": "נותרו {count} דרגות חופש",
|
||||
"sketch.dof_left_one": "נותרה {count} דרגת חופש",
|
||||
"sketch.draw_curves": "שרטוט כ־{linetype}",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "ימין",
|
||||
"sketch_text.bold": "מודגש",
|
||||
"sketch_text.builtin_font": "{family} (מובנה)",
|
||||
"sketch_text.formula": "התחילו ב־= כדי לבנות את הטקסט מפרמטרים: ='W' + number(Width)",
|
||||
"sketch_text.italic": "נטוי",
|
||||
"sketch_text.loading_fonts": "מחפש גופנים מותקנים…",
|
||||
"sketch_text.on_path": "הטקסט עוקב אחר המסלול שלו: העקומה קובעת את מיקומו",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "שמירת הפיצ'רים והתיקיות המקוננות שלהן בציר הזמן",
|
||||
"timeline.delete_folders_with_features_tip": "מחיקת התיקיות עם כל הפיצ'רים שבהן והתיקיות המקוננות בהן",
|
||||
"timeline.delete_many": "מחיקת {count} הפיצ'רים שנבחרו",
|
||||
"timeline.edited_rolled_back": "{name} שונה, אך הוא אחרי סמן ההיסטוריה ולכן לא נבנה: הזיזו את הסמן אל מעבר אליו כדי לראות את התוצאה",
|
||||
"timeline.feature_error": "שגיאה: {message}",
|
||||
"timeline.feature_hint": "לחיצה כפולה לעריכה · גרירה לשינוי הסדר · לחיצה ימנית לעוד",
|
||||
"timeline.feature_rolled_back": "בוטל: אחרי סמן ההיסטוריה, ולכן לא נבנה",
|
||||
"timeline.feature_warning": "אזהרה: {message}",
|
||||
"timeline.group": "תיקיית פיצ'רים חדשה",
|
||||
"timeline.move_many": "הזזת פריטים בציר הזמן",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "כיול העכבר התלת־ממדי מתקן צירים מוחלפים או הפוכים וקובע את המהירות והתחושה שלו.",
|
||||
"ui.3d_mouse_offer_never": "לא להציג שוב",
|
||||
"ui.3d_mouse_offer_swap": "מעבר ל־Hidraw (מנהל ישיר)",
|
||||
"ui.3d_mouse_orbit": "סיבוב",
|
||||
"ui.3d_mouse_orbit_classic": "קלאסי",
|
||||
"ui.3d_mouse_orbit_tip": "במעקב: העכבר התלת־ממדי מסובב את המבט סביב החלק של המודל שבמרכז המבט כשהסיבוב מתחיל, ומסמן אותו בכדור חיוור. קלאסי: סביב מרכז המבט",
|
||||
"ui.3d_mouse_orbit_traced": "במעקב",
|
||||
"ui.3d_mouse_reading": "קריאה",
|
||||
"ui.3d_mouse_reset_axes": "איפוס הקצאת הצירים",
|
||||
"ui.3d_mouse_reset_view": "איפוס המבט",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "עכבר תלת־ממדי",
|
||||
"ui.3d_mouse_show_in_view": "הצגת העכבר התלת־ממדי בתצוגה התלת־ממדית",
|
||||
"ui.3d_mouse_show_in_view_tip": "תמונה של העכבר התלת־ממדי בפינה השמאלית התחתונה, שזזה כשמזיזים אותו.",
|
||||
"ui.3d_mouse_sketch_orbit": "סיבוב סקיצות בעכבר התלת־ממדי",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "העכבר התלת־ממדי מסובב את התצוגה גם כשסקיצה פתוחה ונראית חזיתית, כמו שהעכבר יכול. כבוי: הוא מזיז ומגדיל את הסקיצה עד שתטה את התצוגה.",
|
||||
"ui.3d_mouse_skip": "ההתקן שלי לא יכול לעשות את זה",
|
||||
"ui.3d_mouse_skip_tip": "מדלג על התנועה הזאת בשני הכיוונים, והכיול משמיט אותה.",
|
||||
"ui.3d_mouse_speed": "מהירות עכבר תלת־ממדי",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "יש לסובב את הכיפה נגד כיוון השעון, להחזיק ואז לשחרר.",
|
||||
"ui.3d_mouse_switch_cap": "כיול כהתקן חזרה למרכז",
|
||||
"ui.3d_mouse_switch_trackball": "כיול ככדור עקיבה",
|
||||
"ui.3d_mouse_use_direct": "שימוש במנהל ישיר",
|
||||
"ui.3d_mouse_use_direct_tip": "קריאת העכבר התלת־ממדי ישירות (hidraw) במקום דרך spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "ציר מבט",
|
||||
"ui.3d_mouse_view_off": "כבוי",
|
||||
"ui.3d_mouse_view_off_tip": "הפרופיל של מנהל ההתקן לעכבר התלת־ממדי מכבה את הציר הזה, ולכן התנועה שלו לא מזיזה את המבט. בחירה כאן בתנועה של ציר אחר מחליפה בין השניים, והתנועה ההיא מפסיקה להזיז את המבט.",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "הסרה מהתור",
|
||||
"ui.agent_chat_remove_file": "הסרה מההודעה הזו",
|
||||
"ui.agent_chat_remove_imported": "הסרה מההודעה הזו; החלק נשאר בתכן (ביטול מסיר אותו)",
|
||||
"ui.agent_chat_reply_cut_off": "התשובה הגיעה למגבלת האורך שלה לפני שהסתיימה, ולכן ייתכן שהיא חלקית. יש לבקש מהסוכן להמשיך, או לענות בקצרה יותר.",
|
||||
"ui.agent_chat_reply_declined": "המודל סירב לענות על ההודעה הזו.",
|
||||
"ui.agent_chat_retry": "ניסיון חוזר",
|
||||
"ui.agent_chat_right": "ימין",
|
||||
"ui.agent_chat_save": "שמירה",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "מעגל",
|
||||
"ui.circular_pattern": "מערך מעגלי",
|
||||
"ui.clear": "ניקוי",
|
||||
"ui.clear_print_face": "נקה פאת הדפסה",
|
||||
"ui.clear_recent": "ניקוי האחרונים",
|
||||
"ui.clear_the_selection": "ניקוי הבחירה",
|
||||
"ui.click_selects_whole_bodies": "לחיצה בוחרת גופים שלמים",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "קבוע",
|
||||
"ui.constraints_conflict": "התנגשות בין אילוצים",
|
||||
"ui.construction": "עזר",
|
||||
"ui.construction.angle_hint": "ישר עזר: בחירת נקודה ואז הקלדת זווית או בחירת כיוון",
|
||||
"ui.construction.bisector_hint": "חוצה זווית: בחירת שני ישרים נחתכים ואז הפתרון הרצוי",
|
||||
"ui.construction.common_hint": "משיק משותף: בחירת שני מעגלים/קשתות ואז הפתרון הרצוי",
|
||||
"ui.construction.contact_hint": "משיק: בחירת מעגל/קשת או ספליין/חתך חרוט פתוח ואז נקודת השקה (לעקומות חופשיות: קצוות בלבד)",
|
||||
"ui.construction.external_hint": "משיק: בחירת מעגל או קשת, נקודה חיצונית ואז הפתרון הרצוי",
|
||||
"ui.construction.free_hint": "ישר עזר: לחיצה על שתי נקודות; לחיצה ימנית להתחלה מחדש",
|
||||
"ui.construction.point_hint": "ישר עזר: לחיצה על נקודת המעבר",
|
||||
"ui.construction.reference_hint": "ישר עזר: בחירת ישר ואז נקודה; לחיצה ימנית להחלפת הייחוס",
|
||||
"ui.construction.ribbon_label": "קווי עזר",
|
||||
"ui.context_menu": "תפריט הקשר",
|
||||
"ui.continuity_g0": "G0 שבר",
|
||||
"ui.continuity_g1": "G1 משיק",
|
||||
@@ -4008,6 +4172,14 @@
|
||||
"ui.end_scale": "קנה מידה בסיום",
|
||||
"ui.entities": "ישויות",
|
||||
"ui.equal": "שווה",
|
||||
"ui.equation_end": "סוף",
|
||||
"ui.equation_explicit": "מפורשת",
|
||||
"ui.equation_form": "צורה",
|
||||
"ui.equation_note": "המשתנה הוא מספר ללא יחידה: sin(t) מקבלת אותו ברדיאנים. תוצאה ללא יחידה היא ביחידה של התכנון.",
|
||||
"ui.equation_parametric": "פרמטרית",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "רדיוס שקול",
|
||||
"ui.expand": "הרחבה",
|
||||
"ui.exportDxf": "ייצוא DXF…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "תכן",
|
||||
"ui.heading_draft": "שיפוע יציקה",
|
||||
"ui.heading_edit": "עריכה",
|
||||
"ui.heading_equation_curve": "עקומת משוואה",
|
||||
"ui.heading_extrude": "שליפה",
|
||||
"ui.heading_fillet": "עיגול פינה",
|
||||
"ui.heading_finish_editing": "סיום עריכה",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "ייבוא…",
|
||||
"ui.infinite": "אינסופי",
|
||||
"ui.insert": "הוספה",
|
||||
"ui.insert_design.browse": "עיון…",
|
||||
"ui.insert_design.open_designs": "תכנים פתוחים",
|
||||
"ui.insert_design.saved_file": "ב-{name} יש שינויים שלא נשמרו, ולכן נוסף הקובץ השמור שלו. שמרו אותו ואז בחרו עדכון קישורים כדי להכניס את השינויים.",
|
||||
"ui.insert_design.unsaved": "שינויים שלא נשמרו",
|
||||
"ui.inspect": "בדיקה",
|
||||
"ui.intersect": "חיתוך משותף",
|
||||
"ui.isolate": "בידוד",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "לא ניתן היה לקרוא {count} תיקיות.",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "נקודה",
|
||||
"ui.point_cloud_add_filter": "הוספת מסנן…",
|
||||
"ui.point_cloud_auto_range": "טווח אוטומטי",
|
||||
"ui.point_cloud_color_by": "צביעה לפי",
|
||||
"ui.point_cloud_file_colors": "צבעי הקובץ",
|
||||
"ui.point_cloud_filter_by": "סינון לפי",
|
||||
"ui.point_cloud_height_high": "הגובה המרבי",
|
||||
"ui.point_cloud_height_low": "הגובה המזערי",
|
||||
"ui.point_cloud_legend_filter": "מוצגים ומוסתרים במקרא שלמעלה",
|
||||
"ui.point_cloud_no_file_colors": "אין בקובץ צבעים",
|
||||
"ui.point_cloud_pause": "השהיה",
|
||||
"ui.point_cloud_play": "הפעלה",
|
||||
"ui.point_cloud_single_color": "צבע אחיד",
|
||||
"ui.point_cloud_size": "גודל נקודה",
|
||||
"ui.point_cloud_units": "יחידות הקובץ",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "מצולע",
|
||||
"ui.preferences": "העדפות",
|
||||
"ui.press_a_key": "יש ללחוץ על מקש…",
|
||||
"ui.print_face_cleared": "{body}: פאת ההדפסה נוקתה",
|
||||
"ui.print_face_input": "פאת הדפסה",
|
||||
"ui.print_face_one_body": "פאת הדפסה נבחרת לגוף אחד: שלח את הגוף הזה לבדו כדי לשנות אותה",
|
||||
"ui.print_face_pick": "בחר פאה שטוחה אחת של גוף מוצק כדי להפוך אותה לפאת ההדפסה",
|
||||
"ui.print_face_set": "{body}: פאת ההדפסה הוגדרה; שליחה לסלייסר מניחה את הגוף עליה",
|
||||
"ui.profile": "פרופיל",
|
||||
"ui.profile_plane": "מישור הפרופיל",
|
||||
"ui.profiles": "פרופילים",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "סיבוב",
|
||||
"ui.ribbon_exit": "יציאה",
|
||||
"ui.ribbon_labels": "הצגת טקסט מתחת לסמלי רצועת הכלים",
|
||||
"ui.ribbon_menus_skip_pinned": "השמטת פקודות מוצמדות מהתפריטים הנפתחים",
|
||||
"ui.ribbon_pin_footer": "פקודות מוצמדות מוצגות ברצועת הכלים. יש לרחף מעל שורה כדי להצמיד אותה או לבטל את הצמדתה.",
|
||||
"ui.ribbon_workspace": "סביבת עבודה",
|
||||
"ui.right": "ימין",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "בחירה",
|
||||
"ui.selectOther": "בחירת אחר…",
|
||||
"ui.selectTangentChain": "בחירת שרשרת משיקה",
|
||||
"ui.select_all": "בחירת הכול",
|
||||
"ui.select_components_by_face": "בחירת רכיבים (בחירת פאה בוחרת את הרכיב שלה)",
|
||||
"ui.selection": "בחירה",
|
||||
"ui.selection_modifiers": "מקשי שינוי לבחירה",
|
||||
"ui.selection_shift_add_only": "Shift+לחיצה מוסיף בלי להסיר",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "מסנן בחירה",
|
||||
"ui.sketch_modifiers": "מקשי שינוי בסקיצה",
|
||||
"ui.sketch_project_geometry": "גאומטריה",
|
||||
"ui.sketch_report.all_constrained": "הכול מאולץ במלואו.",
|
||||
"ui.sketch_report.dof": "דרגות חופש",
|
||||
"ui.sketch_report.loose": "לא מאולץ במלואו",
|
||||
"ui.sketch_report.status": "מצב",
|
||||
"ui.sketch_report.title": "דוח סקיצה",
|
||||
"ui.sketch_scale": "קנה מידה של סקיצה",
|
||||
"ui.sketches": "סקיצות",
|
||||
"ui.slice": "חתך",
|
||||
@@ -4532,10 +4727,19 @@
|
||||
"ui.view_centre": "מרכז המבט",
|
||||
"ui.viewport_status_clear": "כיבוי {name}",
|
||||
"ui.viewport_status_clear_hint": "כיבוי {name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} קצוות",
|
||||
"ui.viewport_status_from": "מכיוון {direction}",
|
||||
"ui.viewport_status_key": "הצגת מקרא עבור {name}",
|
||||
"ui.viewport_status_minimum_radius": "רדיוס מינימלי",
|
||||
"ui.viewport_status_pairs": "{count} זוגות",
|
||||
"ui.viewport_status_section_hatch": "{setting} · קווקוו",
|
||||
"ui.viewport_status_section_plane": "המישור הנוכחי",
|
||||
"ui.viewport_status_section_tilted": "נטוי · {offset}",
|
||||
"ui.viewport_status_stripes": "{count} פסים",
|
||||
"ui.viewport_status_summary_clear": "כיבוי הכול",
|
||||
"ui.viewport_status_summary_heading": "בתצוגה זו",
|
||||
"ui.viewport_status_summary_label": "{name} ועוד {count} פריטים",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "לפי ערכת הנושא",
|
||||
"ui.visual_shaded_hidden_edges": "מוצלל עם מקצועות נסתרים",
|
||||
"ui.visual_shaded_with_edges": "מוצלל עם מקצועות",
|
||||
@@ -4572,7 +4776,9 @@
|
||||
"update.button": "עדכון",
|
||||
"update.button_version": "עדכון ל־{version}",
|
||||
"update.check_automatically": "בדיקת עדכונים אוטומטית",
|
||||
"update.check_for_updates": "בדיקת עדכונים",
|
||||
"update.check_now": "בדיקה עכשיו",
|
||||
"update.check_unavailable": "בדיקת עדכונים אינה זמינה עבור התקנה זו.",
|
||||
"update.checking": "בבדיקה…",
|
||||
"update.copy": "העתקה",
|
||||
"update.dmg_opened": "תמונת הדיסק פתוחה ואומתה: יש לגרור את SolidCraft לתיקיית היישומים במקום העותק הישן, ואז להפעיל מחדש את SolidCraft.",
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
"Edges": "Bridovi",
|
||||
"Edit": "Uredi",
|
||||
"Edit Profile Sketch": "Uredi skicu profila",
|
||||
"Edit shortcuts": "Uredi prečace",
|
||||
"Enable rule": "Omogući pravilo",
|
||||
"Enabled": "Omogućeno",
|
||||
"End Radius": "Krajnji polumjer",
|
||||
@@ -468,6 +469,7 @@
|
||||
"Radius": "Polumjer",
|
||||
"Radius Fit": "Uklapanje polumjera",
|
||||
"Ratio": "Omjer",
|
||||
"Read-only list: shortcuts can't be changed here.": "Popis samo za čitanje: prečaci se ovdje ne mogu mijenjati.",
|
||||
"Reattach selected face": "Ponovno pričvrsti odabrano lice",
|
||||
"Recover": "Oporavi",
|
||||
"Recover unsaved design?": "Oporaviti nespremljeni dizajn?",
|
||||
@@ -652,6 +654,7 @@
|
||||
"Third point": "Treća točka",
|
||||
"This child is shared. Deleting it removes it from every copy of its parent.": "Ovaj podređeni element je dijeljen. Brisanjem se uklanja iz svake kopije njegova roditelja.",
|
||||
"This child is shared. Position changes apply to every copy of its parent.": "Ovaj podređeni element je dijeljen. Promjene položaja primjenjuju se na svaku kopiju njegova roditelja.",
|
||||
"This component is inside a subassembly placed more than once: aligning it moves it in every placement.": "Ova se komponenta nalazi unutar podsklopa postavljenog više puta: njezino poravnavanje pomiče je u svakom postavljanju.",
|
||||
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Ovo lice ne može dati trajno pričvršćenje. Odaberite drugo lice ili izričito upotrijebite fiksnu ravninu.",
|
||||
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Ova slika još nije priložena na GitHubu. Kopirajte je ili spremite, a zatim je priložite na GitHubu.",
|
||||
"Thread depth": "Dubina navoja",
|
||||
@@ -772,6 +775,8 @@
|
||||
"at the face": "na licu",
|
||||
"bom.group_children": "Podređeni dijelovi u retku svojeg dijela",
|
||||
"browser.body_name": "Tijelo{number}",
|
||||
"browser.calibrate_click_a": "Kliknite sliku kako biste zadali točku A ili upišite njezine koordinate.",
|
||||
"browser.calibrate_click_b": "Kliknite sliku kako biste zadali točku B ili upišite njezine koordinate.",
|
||||
"browser.calibrate_title": "Kalibriraj: {name}",
|
||||
"browser.capture_many": "Pomaknute komponente bez zabilježenog položaja: {count}.",
|
||||
"browser.capture_note": "Zabilježi zadržava novi položaj; Vrati ga vraća nazad.",
|
||||
@@ -793,6 +798,11 @@
|
||||
"cam.roller": "Valjak",
|
||||
"cam.roller_pick": "Valjak (neobavezno)",
|
||||
"cam.tip_pick": "Vrh (neobavezno)",
|
||||
"camera.shot_pitch": "Nagib",
|
||||
"camera.shot_roll": "Valjanje",
|
||||
"camera.shot_yaw": "Skretanje",
|
||||
"canvas.decal_place_hint": "Kliknite lice kako biste postavili naljepnicu",
|
||||
"canvas.place_hint": "Kliknite ravninu ili lice kako biste postavili platno",
|
||||
"choose a profile": "odaberite profil",
|
||||
"choose the cam's and the follower's joints": "odaberite spojeve brijega i sljedbenika",
|
||||
"choose the joints to couple": "odaberite spojeve koje treba povezati",
|
||||
@@ -800,12 +810,16 @@
|
||||
"click sketch curves": "kliknite krivulje skice",
|
||||
"cmd.appearance_assign": "Izgled",
|
||||
"cmd.appearance_chain": "Lanac izgleda",
|
||||
"cmd.appearance_copy": "Kopiraj izgled",
|
||||
"cmd.appearance_favorite": "Omiljeni izgled",
|
||||
"cmd.appearance_library": "Biblioteka izgleda",
|
||||
"cmd.appearance_list": "Popis izgleda",
|
||||
"cmd.appearance_paint": "Oboji izgledom",
|
||||
"cmd.appearance_paste": "Zalijepi izgled",
|
||||
"cmd.appearance_pick_up": "Preuzmi izgled",
|
||||
"cmd.appearance_replace": "Zamijeni izgled",
|
||||
"cmd.assembly_bom": "Sastavnica",
|
||||
"cmd.body.print_face": "Ploha ispisa",
|
||||
"cmd.body_rename": "Preimenuj tijelo",
|
||||
"cmd.browser_collapse_all": "Sažmi sve",
|
||||
"cmd.browser_expand_all": "Proširi sve",
|
||||
@@ -813,6 +827,7 @@
|
||||
"cmd.browser_move": "Premjesti stavke stabla modela",
|
||||
"cmd.browser_order": "Poredaj stavke stabla modela",
|
||||
"cmd.browser_rename_group": "Preimenuj grupu",
|
||||
"cmd.browser_reparent": "Premjesti u komponentu",
|
||||
"cmd.browser_ungroup": "Razgrupiraj",
|
||||
"cmd.browser_visibility": "Prikaži/sakrij",
|
||||
"cmd.canvas_calibrate": "Kalibriraj platno",
|
||||
@@ -839,7 +854,9 @@
|
||||
"cmd.component_metadata": "Svojstva dijela",
|
||||
"cmd.component_metadata_set": "Promijeni svojstva dijela",
|
||||
"cmd.component_move_bodies": "Premjesti tijela u komponentu",
|
||||
"cmd.component_move_features": "Premjesti značajke u komponentu",
|
||||
"cmd.component_move_sketches": "Premjesti skice u komponentu",
|
||||
"cmd.component_paste_from_design": "Zalijepi iz drugog dizajna",
|
||||
"cmd.component_paste_new": "Zalijepi kao novo",
|
||||
"cmd.component_properties": "Fizička svojstva komponente",
|
||||
"cmd.component_relink": "Ponovno poveži izvor",
|
||||
@@ -976,6 +993,7 @@
|
||||
"cmd.motion_trace": "Trag kretanja",
|
||||
"cmd.motion_trace_edit": "Uredi trag kretanja",
|
||||
"cmd.motion_trace_keep": "Zadrži trag kretanja",
|
||||
"cmd.occurrence_align": "Poravnaj primjerak",
|
||||
"cmd.occurrence_copy": "Zalijepi (primjerak)",
|
||||
"cmd.occurrence_drag": "Povuci primjerak",
|
||||
"cmd.occurrence_ground": "Učvrsti",
|
||||
@@ -1033,11 +1051,17 @@
|
||||
"cmd.render_library_surface_unbind": "Ukloni vezu površine",
|
||||
"cmd.render_library_targets": "Pronađi ciljeve biblioteke renderiranja",
|
||||
"cmd.render_lights_add": "Dodaj svjetlo",
|
||||
"cmd.render_lights_duplicate": "Dupliciraj svjetlo renderiranja",
|
||||
"cmd.render_lights_list": "Popis svjetala renderiranja",
|
||||
"cmd.render_lights_mute": "Isključi svjetlo",
|
||||
"cmd.render_lights_remove": "Ukloni svjetlo renderiranja",
|
||||
"cmd.render_lights_set": "Postavi svjetlo renderiranja",
|
||||
"cmd.render_lights_solo": "Samo ovo svjetlo",
|
||||
"cmd.render_optics_bind": "Spremi optičku vezu",
|
||||
"cmd.render_optics_unbind": "Ukloni optičku vezu",
|
||||
"cmd.render_output_size": "Postavi veličinu izlaza renderiranja",
|
||||
"cmd.render_preflight": "Provjeri zahtjev za renderiranje",
|
||||
"cmd.render_preflight_copy": "Kopiraj izvješće provjere renderiranja",
|
||||
"cmd.render_preset_apply": "Primijeni izvorni studio",
|
||||
"cmd.render_preset_resolve": "Pregledaj izvorni studio",
|
||||
"cmd.render_quality_prepare": "Pregledaj fiksni proračun uzorkovanja",
|
||||
@@ -1060,6 +1084,13 @@
|
||||
"cmd.render_start": "Renderiraj sliku",
|
||||
"cmd.render_status": "Napredak renderiranja",
|
||||
"cmd.select_clear": "Poništi odabir",
|
||||
"cmd.settings_profile_apply": "Primijeni profil postavki",
|
||||
"cmd.settings_profile_delete": "Izbriši profil postavki",
|
||||
"cmd.settings_profile_export": "Izvezi profil postavki",
|
||||
"cmd.settings_profile_import": "Uvezi profil postavki",
|
||||
"cmd.settings_profile_list": "Profili postavki",
|
||||
"cmd.settings_profile_rename": "Preimenuj profil postavki",
|
||||
"cmd.settings_profile_save": "Spremi profil postavki",
|
||||
"cmd.sheet_convert": "Pretvori u lim",
|
||||
"cmd.sheet_export_bend_table": "Izvezi tablicu savijanja",
|
||||
"cmd.sheet_export_dxf": "Izvezi razvijeni oblik kao DXF",
|
||||
@@ -1073,6 +1104,16 @@
|
||||
"cmd.sheet_refold": "Ponovno presavij",
|
||||
"cmd.sheet_rules": "Popis pravila za lim",
|
||||
"cmd.sheet_unfold": "Razvij",
|
||||
"cmd.sketch.construction_line": "Pomoćni pravac",
|
||||
"cmd.sketch.construction_line.angle": "Pomoćni pravac pod kutom",
|
||||
"cmd.sketch.construction_line.bisector": "Simetrala kuta",
|
||||
"cmd.sketch.construction_line.horizontal": "Vodoravni pomoćni pravac",
|
||||
"cmd.sketch.construction_line.parallel": "Paralelni pomoćni pravac",
|
||||
"cmd.sketch.construction_line.perpendicular": "Pomoćni pravac okomit na pravac",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tangenta u točki krivulje",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tangenta kroz vanjsku točku",
|
||||
"cmd.sketch.construction_line.tangent_two": "Zajednička tangenta",
|
||||
"cmd.sketch.construction_line.vertical": "Okomiti pomoćni pravac",
|
||||
"cmd.sketch_arc3d": "3D luk",
|
||||
"cmd.sketch_arc_center_point": "Luk iz središta",
|
||||
"cmd.sketch_arc_tangent": "Tangentni luk",
|
||||
@@ -1105,6 +1146,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Veličina crteža",
|
||||
"cmd.sketch_edit": "Uredi skicu",
|
||||
"cmd.sketch_edit_text": "Uredi tekst",
|
||||
"cmd.sketch_equation_curve": "Krivulja iz jednadžbe",
|
||||
"cmd.sketch_equation_curve_edit": "Uredi krivulju iz jednadžbe",
|
||||
"cmd.sketch_export_dxf": "Spremi kao DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "Završi s automatskim ograničenjima",
|
||||
"cmd.sketch_fit_curves_to_section": "Uklopi krivulje u presjek mreže",
|
||||
@@ -1201,6 +1244,7 @@
|
||||
"cmd.view.render_browser": "Stablo renderiranja",
|
||||
"cmd.view.render_dock": "Premjesti panel renderiranja",
|
||||
"cmd.view.render_focus": "Fokusni prikaz renderiranja",
|
||||
"cmd.view.status_items": "Statusne stavke prozora prikaza",
|
||||
"cmd.view_ambient_occlusion": "Ambijentalna okluzija",
|
||||
"cmd.view_angle_readout": "Kutovi prikaza",
|
||||
"cmd.view_apply": "Vrati imenovani prikaz",
|
||||
@@ -1222,6 +1266,7 @@
|
||||
"cmd.view_normal_to": "Okomito na odabir",
|
||||
"cmd.view_previous_tab": "Prethodna kartica",
|
||||
"cmd.view_rename": "Preimenuj imenovani prikaz",
|
||||
"cmd.view_render_frame": "Vodilice kadra renderiranja",
|
||||
"cmd.view_right": "Pogled zdesna",
|
||||
"cmd.view_save": "Novi imenovani prikaz",
|
||||
"cmd.view_shots_strip": "Traka kadrova",
|
||||
@@ -1232,10 +1277,14 @@
|
||||
"color.copy": "Kliknite za kopiranje vrijednosti boje",
|
||||
"color.edit": "Kliknite za uređivanje boje",
|
||||
"color.gamma": "Prikaz vrijednosti boje u gama prostoru 0-255",
|
||||
"color.hex": "Hex",
|
||||
"color.hex_help": "Unesite #rrggbb ili #rrggbbaa; šest znamenki zadržava neprozirnost",
|
||||
"color.hex_hint": "#rrggbb",
|
||||
"color.hue": "Nijansa",
|
||||
"color.linear": "Prikaz vrijednosti boje u linearnom prostoru 0-1",
|
||||
"color.saturation_value": "Zasićenost i vrijednost",
|
||||
"color.selected": "Odabrana boja",
|
||||
"config.column_filter_empty": "Nema odgovarajućih stupaca",
|
||||
"contact.components_count": "Komponente: {count}",
|
||||
"contact.enabled_label": "omogućeno",
|
||||
"coupling.gear_1": "Zupčanik 1",
|
||||
@@ -1350,8 +1399,20 @@
|
||||
"help.material.assign": "Određuje od čega su odabrana tijela izrađena, npr. čelik, aluminij ili ABS. Upotrijebite ga kako bi masa i težina odgovarale stvarnom dijelu.",
|
||||
"help.mit": "MIT licenca",
|
||||
"help.notice": "NOTICE",
|
||||
"help.occurrence.move": "Pomiče dio sklopa samo u stupnjevima slobode koje dopuštaju njegovi spojevi. Odaberite lice dijela, a zatim povucite dostupnu strelicu ili luk.",
|
||||
"help.parameters.change": "Otvara tablicu imenovanih vrijednosti i izraza koji upravljaju kotama dizajna. Upotrijebite je kako biste promijenili mjeru na jednom mjestu, a sve značajke koje je koriste je slijede.",
|
||||
"help.pointcloud.insert": "Umetnite PLY, XYZ ili PTS skeniranje kao oblak točaka uz model. Koristite ga kao referencu pri izradi modela iz izmjerenih podataka.",
|
||||
"help.sketch.construction_line": "Izradite beskonačni pomoćni pravac kroz dvije točke. Upotrijebite ga kako biste rasporedili skicu bez razdvajanja profila.",
|
||||
"help.sketch.construction_line.angle": "Izradite beskonačni pomoćni pravac pod kutom od osi X skice. Odaberite točku i upišite kut ili odaberite smjer.",
|
||||
"help.sketch.construction_line.bisector": "Odaberite dvije ravne linije skice koje se sijeku, pa jednu od dviju simetrala kuta. Rezultat prati izvorne linije.",
|
||||
"help.sketch.construction_line.horizontal": "Izradite beskonačni vodoravni pomoćni pravac kroz točku. Njegovo ograničenje vodoravnosti ostaje na snazi pri kasnijim promjenama.",
|
||||
"help.sketch.construction_line.parallel": "Odaberite ravnu liniju skice, pa postavite paralelni beskonačni pomoćni pravac. Desnim klikom odaberite drugu referencu.",
|
||||
"help.sketch.construction_line.perpendicular": "Odaberite ravnu liniju skice, pa postavite beskonačni pomoćni pravac okomit na nju. Desnim klikom odaberite drugu referencu.",
|
||||
"help.sketch.construction_line.tangent_at": "Izradite tangentu u točki na kružnici ili kružnom luku, ili u krajnjoj točki otvorenog splinea ili konike. Odaberite krivulju, pa točku dodira.",
|
||||
"help.sketch.construction_line.tangent_external": "Odaberite kružnicu ili kružni luk, pa vanjsku točku i rješenje tangente. Pregledi prikazuju samo dodirne točke na nacrtanom luku.",
|
||||
"help.sketch.construction_line.tangent_two": "Odaberite dvije kružnice ili kružna luka, pa u pregledu odaberite zajedničku tangentu. Dodirne točke moraju ležati na nacrtanim krivuljama.",
|
||||
"help.sketch.construction_line.vertical": "Izradite beskonačni okomiti pomoćni pravac kroz točku. Njegovo ograničenje okomitosti ostaje na snazi pri kasnijim promjenama.",
|
||||
"help.sketch.equation_curve": "Crta krivulju prema formulama: x(t) i y(t) ili y = f(x), u zadanom rasponu. Formule mogu koristiti parametre i krivulja ih prati: upotrijebite je za sinusoidu, spiralu ili evolventu zuba zupčanika.",
|
||||
"help.solid.align": "Pomiče odabrana tijela tako da se točka, lice ili ravnina na njima poklopi s točkom, licem ili ravninom negdje drugdje. Upotrijebite ga kako biste postavili dio uz drugi bez mjerenja odmaka.",
|
||||
"help.solid.chamfer": "Odsijeca odabrane bridove ravnim skošenjem zadane udaljenosti. Koristite ga kako biste ublažili oštre bridove ili olakšali uvođenje zatika ili vijka.",
|
||||
"help.solid.combine": "Spaja tijela, oduzima ih od ciljnog tijela ili zadržava samo zajednički volumen, a može zadržati i alatna tijela. Koristite ga kako biste spojili dijelove, jednim oblikom odrezali drugi ili pronašli gdje se dva tijela preklapaju.",
|
||||
@@ -1480,6 +1541,21 @@
|
||||
"joint.one_component": "Ovi dijelovi su tijela jedne komponente: {bodies}. Spoj pomiče jednu komponentu u odnosu na drugu, pa svaki dio treba vlastitu komponentu.",
|
||||
"joint.rigid_group_one_component": "Sva tijela ({count}) nalaze se u jednoj komponenti (ili u samom dizajnu): najprije upotrijebite {command}.",
|
||||
"joint.rigid_group_select_components": "Odaberite dvije ili više komponenti.",
|
||||
"joint_move.blocked_hint": "Provjerite vrstu spoja (npr. Kruti), učvršćenje, granice spoja i vrijednosti kojima upravljaju parametri.",
|
||||
"joint_move.blocked_title": "Ovaj dio nije moguće pomaknuti",
|
||||
"joint_move.coarse": "Korak rotacije blizu osi (°)",
|
||||
"joint_move.distance": "Udaljenost od početka",
|
||||
"joint_move.done": "Gotovo",
|
||||
"joint_move.fine": "Korak rotacije daleko od osi (°)",
|
||||
"joint_move.fixed": "Ovaj dio nema pomičnu os spoja.",
|
||||
"joint_move.help": "Pomakni — povucite strelicu ili prsten. Esc poništava trenutno povlačenje.",
|
||||
"joint_move.legacy_hint": "Isključite kako biste koristili prethodni panel Pomakni.",
|
||||
"joint_move.precision": "Povucite izvan isprekidane vodilice za finu rotaciju.",
|
||||
"joint_move.rotation": "Rotacija od početka",
|
||||
"joint_move.select": "Odaberite lice ili jedan dio sklopa, a zatim odaberite Pomakni.",
|
||||
"joint_move.settings": "Pomicanje u sklopu",
|
||||
"joint_move.step": "Korak",
|
||||
"joint_move.use_handles": "Koristi ručice kretanja spojeva za Pomakni u sklopu",
|
||||
"keymap.command_id": "ID naredbe",
|
||||
"keymap.empty": "Nema odgovarajućih naredbi",
|
||||
"keymap.use_anyway": "Ipak upotrijebi {key} ovdje",
|
||||
@@ -1574,6 +1650,8 @@
|
||||
"nav.maya.help": "Alt+povlačenje lijevom tipkom orbitira, Alt+srednja tipka pomiče, Alt+desna tipka zumira; povlačenje srednjom tipkom također pomiče",
|
||||
"nav.openscad.help": "Povlačenje lijevom tipkom po praznom prostoru orbitira, Shift+povlačenje lijevom odabire okvirom, povlačenje geometrije skice uređuje je; povlačenje desnom ili srednjom tipkom pomiče, Shift+desna ili Shift+srednja zumira",
|
||||
"nav.perspective.sketch": "Uređivanje skice koristi ortografski prikaz. Završite skicu kako biste prešli na perspektivu.",
|
||||
"nav.right_drag_orbits.help": "Isključeno: povlačenje desnom tipkom ne dira kameru, a desna tipka samo otvara kontekstni izbornik. Odabir mapiranja miša SolidWorks isključuje ovu opciju.",
|
||||
"nav.right_drag_orbits.label": "Povlačenje desnom tipkom orbitira",
|
||||
"nav.solidworks.help": "Povlačenje srednjom tipkom orbitira, Ctrl+srednja pomiče, Shift+srednja zumira, povlačenje desnom orbitira",
|
||||
"nav.tinkercad.help": "Povlačenje desnom tipkom orbitira, povlačenje srednjom ili Shift+desnom pomiče",
|
||||
"nav.touchpad.help": "Držite Shift i pomičite pokazivač za pomicanje prikaza; držite Alt/Option i pomičite ga za orbitiranje. Tipka miša nije potrebna. Okomito pomicanje zumira.",
|
||||
@@ -1595,6 +1673,9 @@
|
||||
"navbar.custom.customise": "Prilagodi navigacijsku traku…",
|
||||
"navbar.custom.design": "Dizajn",
|
||||
"navbar.custom.duplicate": "Ovo mjesto je već na traci.",
|
||||
"navbar.custom.edge": "Rub",
|
||||
"navbar.custom.edge_bottom": "Dolje",
|
||||
"navbar.custom.edge_top": "Gore",
|
||||
"navbar.custom.fade": "Izblijedi",
|
||||
"navbar.custom.full": "Uklonite jedno mjesto kako biste dodali drugo.",
|
||||
"navbar.custom.hidden_design": "Skriveno u Dizajnu",
|
||||
@@ -1701,6 +1782,7 @@
|
||||
"parts.dimension.thickness": "Debljina",
|
||||
"parts.dimension.width": "Širina",
|
||||
"parts.family.bearing": "Kuglični ležaj s dubokim utorom (ovojni oblik)",
|
||||
"parts.family.button_head_cap_screw": "Vijak s poluokruglom glavom i unutarnjim šesterokutom",
|
||||
"parts.family.dowel_pin": "Cilindrični zatik",
|
||||
"parts.family.hex_bolt": "Vijak sa šesterokutnom glavom",
|
||||
"parts.family.hex_nut": "Šesterokutna matica",
|
||||
@@ -1759,6 +1841,11 @@
|
||||
"prefs.bottom_centre": "Dolje u sredini",
|
||||
"prefs.bottom_right": "Dolje desno",
|
||||
"prefs.browser": "Stablo modela",
|
||||
"prefs.browser_eye_left": "Oko pored strelice za sažimanje",
|
||||
"prefs.browser_eye_left_note": "Redci stabla modela prikazuju oko za prikazivanje/skrivanje pored strelice za sažimanje, kao prije, umjesto u stupcu na desnom kraju redaka.",
|
||||
"prefs.browser_reveal_on_hover": "Prikaži pri prelasku mišem",
|
||||
"prefs.browser_show_note": "Prikazano drži stablo modela na zaslonu. Prikaži pri prelasku mišem skriva ga dok pokazivač ne dođe na njegovo mjesto ili na tanku karticu uz njegov lijevi rub, a ostaje otvoreno dok je pokazivač unutar njega ili dok je otvoren izbornik iz njega.",
|
||||
"prefs.browser_shown": "Prikazano",
|
||||
"prefs.built_in": "Ugrađeno",
|
||||
"prefs.button_left": "Povlačenje lijevom tipkom",
|
||||
"prefs.button_middle": "Povlačenje srednjom tipkom",
|
||||
@@ -1806,6 +1893,8 @@
|
||||
"prefs.graphics_card_restart": "Stupa na snagu nakon ponovnog pokretanja SolidCrafta. WGPU_ADAPTER_NAME ima prednost nad ovim odabirom.",
|
||||
"prefs.graphics_note": "Žrtvujte brzinu za glatkoću. Svaki odabir pokazuje svoj učinak na primjeru.",
|
||||
"prefs.graphics_presets_note": "Unaprijed zadane vrijednosti postavljaju sve odabire ispod odjednom.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Sakrij simbole ograničenja kada je prikaz umanjen",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Simboli ograničenja nestaju iz prikaza kada je skica toliko umanjena da bi je zatrpali. Isključeno: ostaju fiksne veličine na zaslonu pri svakom zumiranju.",
|
||||
"prefs.history": "Vremenska traka",
|
||||
"prefs.history_origin_bodies": "Prikaži ishodište i tijela na vrhu",
|
||||
"prefs.history_origin_bodies_note": "Vremenska traka lijevo ili ispod stabla modela počinje mapom Tijela aktivne komponente i Ishodištem, s njihovim okom i izbornicima kao u stablu modela. Vremenska traka na dnu ostaje nepromijenjena.",
|
||||
@@ -1829,6 +1918,8 @@
|
||||
"prefs.layout_note": "Kompaktno pričvršćuje panele uz rubove prozora. Prozirnost stabla modela dostupna je u opciji Plutajuće. Stranu Asistenta promijenite na stranici Asistent.",
|
||||
"prefs.left": "Lijevo",
|
||||
"prefs.left_click": "Lijevi klik",
|
||||
"prefs.line_drag_draws_one": "Pritisak i povlačenje crta jednu liniju",
|
||||
"prefs.line_drag_draws_one_note": "U alatu Linija pritisak, povlačenje i otpuštanje crta jednu liniju od mjesta pritiska do mjesta otpuštanja i ondje završava. Klikovi i dalje crtaju lanac. Isključeno: povlačenje postavlja točku ondje gdje se otpusti, kao i klik.",
|
||||
"prefs.linked_designs": "Povezani dizajni",
|
||||
"prefs.live_input": "Ulaz uživo",
|
||||
"prefs.live_preview": "Pregled uživo",
|
||||
@@ -1842,6 +1933,9 @@
|
||||
"prefs.max_file_size_step": "STEP i uvezene datoteke",
|
||||
"prefs.max_file_size_web": "Web aplikacija otvara STEP i uvezene datoteke do 512 MB te dizajne do 256 MB: kartica preglednika ne može primiti veće datoteke. Desktop aplikacija može podići ove granice.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Velike ikone",
|
||||
"prefs.menu_list": "Popis",
|
||||
"prefs.menus": "Izbornici",
|
||||
"prefs.minutes": "minuta",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "Miš i dodirna pločica",
|
||||
@@ -1861,14 +1955,40 @@
|
||||
"prefs.origin_plane_names": "Nazivi ravnina ishodišta",
|
||||
"prefs.origin_plane_names_note": "Nazivi prikazani u stablu modela, dijalozima i popisima. {top} je XY, {front} je XZ, a {right} je YZ, sa Z prema gore. Naredbe, skripte i spremljeni dizajni zadržavaju XY, XZ i YZ.",
|
||||
"prefs.overall_speed": "Ukupna brzina",
|
||||
"prefs.persistent_ribbon_pressed": "Istakni aktivne naredbe na vrpci",
|
||||
"prefs.persistent_ribbon_pressed_help": "Ističe naredbe na vrpci dok su njihovi efekti uključeni. Isključite kako biste zadržali prethodni neutralni izgled i pomoć za naredbe.",
|
||||
"prefs.perspective_fov": "Vidno polje",
|
||||
"prefs.placement": "Postavljanje",
|
||||
"prefs.prefer_free_sketch_points": "Daj prednost pomičnim točkama skice kad se točke preklapaju",
|
||||
"prefs.preview_choices": "Pregled vaših odabira",
|
||||
"prefs.print_face_highlight": "Isticanje plohe ispisa",
|
||||
"prefs.print_face_highlight_tip": "Koliko se jako ploha ispisa tijela boji i obrubljuje u prikazu. 0 % ne prikazuje isticanje.",
|
||||
"prefs.profile_active": "Aktivni profil",
|
||||
"prefs.profile_applied": "Profil je primijenjen.",
|
||||
"prefs.profile_changed": "Postavke su se promijenile otkako je profil spremljen. Spremi ih zadržava u njemu.",
|
||||
"prefs.profile_deleted": "Profil je izbrisan.",
|
||||
"prefs.profile_export": "Izvezi…",
|
||||
"prefs.profile_exported": "Profil je izvezen.",
|
||||
"prefs.profile_imported": "Profil je uvezen. Odaberite ga pod Aktivni profil kako biste se prebacili na njega.",
|
||||
"prefs.profile_name_hint": "Naziv profila, npr. Prijenosnik",
|
||||
"prefs.profile_rename": "Preimenuj",
|
||||
"prefs.profile_renamed": "Profil je preimenovan.",
|
||||
"prefs.profile_save": "Spremi",
|
||||
"prefs.profile_saved": "Trenutne postavke spremljene su u profil.",
|
||||
"prefs.profile_skipped": "Profil je primijenjen; postavke koje su zadržale trenutnu vrijednost: {n} (pogledajte zapisnik).",
|
||||
"prefs.profiles": "Profili postavki",
|
||||
"prefs.profiles_note": "Prečaci, alatna traka, navigacija, radijalni izbornik i postavke sučelja, spremljeni zajedno pod jednim nazivom i mijenjani odjednom.",
|
||||
"prefs.project_options_dialog": "Dijalog opcija projiciranja",
|
||||
"prefs.project_options_dialog_note": "Uključeno: prije projiciranja odaberite Geometrija ili Tijela i Veza projekcije. Isključeno: zadržava se prethodni način rada s izravnim odabirom.",
|
||||
"prefs.quality_default": "zadano",
|
||||
"prefs.quality_fastest": "najbrže",
|
||||
"prefs.quality_slowest": "najsporije",
|
||||
"prefs.quality_smoother": "glađe",
|
||||
"prefs.render_previous_geometry_budget": "Koristi prethodni proračun geometrije za pregled renderiranja",
|
||||
"prefs.render_previous_geometry_budget_help": "Vrati prethodnu fiksnu granicu geometrije (512 MiB na 64-bitnom desktopu, 128 MiB drugdje) umjesto proračuna prema uređaju.",
|
||||
"prefs.reports_saved": "Spremljeno: {n}",
|
||||
"prefs.ribbon_reveal": "Prikaži rezultate pretraživanja na vrpci",
|
||||
"prefs.ribbon_reveal_note": "Zadržavanje pokazivača iznad rezultata u Pretraži naredbe pokazuje gdje se naredba nalazi na vrpci: njezinu karticu, gumb ili redak u padajućem izborniku panela. Naredba pokrenuta iz pretraživanja ondje zatreperi, a pokrenuta naredba iz padajućeg izbornika označava svoj panel.",
|
||||
"prefs.right_click": "Desni klik",
|
||||
"prefs.saving": "Automatsko spremanje i oporavak",
|
||||
"prefs.scale_note": "Također Ctrl + / Ctrl − u prozoru. Gumbi su 28 px pri 100 %.",
|
||||
@@ -1877,18 +1997,29 @@
|
||||
"prefs.search_empty": "Nema odgovarajućih postavki",
|
||||
"prefs.select": "Odabir",
|
||||
"prefs.select_one_item": "Odaberi jednu stavku",
|
||||
"prefs.select_other_hidden": "Odaberi skrivenu geometriju pomoću Odaberi drugo",
|
||||
"prefs.select_other_hidden_help": "Uključeno: obuhvaća skrivena tijela, skice i zaklonjene bridove u blizini pokazivača. Isključeno: koristi se izvorni popis vidljive geometrije ispod pokazivača.",
|
||||
"prefs.selecting": "Odabiranje",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift samo dodaje; Ctrl / Cmd uključuje i isključuje",
|
||||
"prefs.shift_add_note": "Uključeno: Shift dodaje, Ctrl / Cmd uključuje i isključuje. Isključeno (zadano): oba uključuju i isključuju.",
|
||||
"prefs.shortcuts": "Prečaci",
|
||||
"prefs.single_surface_analysis": "Koristi samo jednu analizu ploha",
|
||||
"prefs.single_surface_analysis_help": "Kad je isključeno, sjenčanje ploha i Kontinuitet mogu ostati uključeni zajedno. Kad je uključeno, zadržava se posljednja pokrenuta ili promijenjena analiza.",
|
||||
"prefs.sketch_align_points": "Poravnaj s drugim točkama skice tijekom crtanja",
|
||||
"prefs.sketch_align_points_note": "Tijekom crtanja točka se istodobno poravnava vodoravno s jednom točkom skice i okomito s drugom, uz točkastu vodilicu, a klik zadržava oba poravnanja. Isključeno: samo s prethodnom točkom, po jedna os.",
|
||||
"prefs.sketch_conflict_colour": "Geometrija u sukobu u boji sukoba",
|
||||
"prefs.sketch_conflict_colour_note": "Dok su ograničenja skice u sukobu, krivulje i točke koje drži neuspjelo ograničenje crtaju se i u boji sukoba, a ne samo njegov simbol ili kota. Isključeno: zadržavaju uobičajene boje.",
|
||||
"prefs.sketch_construction_lines": "Prošireni alati za pomoćne pravce",
|
||||
"prefs.sketch_exit_view": "Kad se skica završi",
|
||||
"prefs.sketch_exit_view.keep": "Zadrži trenutni prikaz",
|
||||
"prefs.sketch_exit_view.previous": "Vrati se na prethodni prikaz",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Vrati se osim ako je rotirano",
|
||||
"prefs.sketch_exit_view_note": "Kamo prikaz ide nakon Završi skicu, Odustani ili dvostrukog Esc.",
|
||||
"prefs.sketch_open_look_at": "Okreni kameru prema skici pri otvaranju",
|
||||
"prefs.sketch_open_look_at_note": "Isključeno: kad izradite ili uredite skicu, prikaz ostaje onakav kakav jest. Pogledaj okreće prikaz prema skici kad to želite.",
|
||||
"prefs.sketch_recent_snap": "Automatski privlači na nedavna središta i središnje točke",
|
||||
"prefs.sketch_recent_snap_note": "Tijekom crtanja pokazivač se privlači ondje gdje se sijeku vodilice dvaju posljednjih središta kružnica ili središnjih točaka ravnih bridova. Isključeno: te vodilice služe samo za prikaz i pokazivač se ne pomiče.",
|
||||
"prefs.sketch_selection": "Skica i odabir",
|
||||
"prefs.sketch_selection_heading": "Skica i odabir",
|
||||
"prefs.sketch_selection_note": "Kako se skice privlače i kako klikovi odabiru.",
|
||||
@@ -1933,7 +2064,14 @@
|
||||
"prefs.toast_place": "Obavijesti",
|
||||
"prefs.toggle_item": "Dodaj stavku ili je ponovno ukloni",
|
||||
"prefs.toolbar": "Alatna traka",
|
||||
"prefs.toolbar_tabs": "Kartice alatne trake",
|
||||
"prefs.top": "Gore",
|
||||
"prefs.trackpad_zoom_modifier": "Zumiranje pomicanjem s dva prsta uz držanje tipke",
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "Držite samo ovu tipku kako biste okomitim pomicanjem zumirali prema pokazivaču. Isključeno zadržava postojeće ponašanje pomicanja.",
|
||||
"prefs.trackpad_zoom_modifier.off": "Isključeno",
|
||||
"prefs.translucent": "Prozirno",
|
||||
"prefs.under_browser": "Ispod stabla modela",
|
||||
"prefs.under_cursor": "Ispod pokazivača",
|
||||
@@ -1943,13 +2081,24 @@
|
||||
"prefs.view_confirm_corner": "U redu i Odustani u kutu prikaza",
|
||||
"prefs.view_confirm_corner_note": "Dok je otvoren dijalog ili skica, kvačica i križić gore desno u prikazu rade isto što i gumbi U redu i Odustani u dijalogu, odnosno završavaju i poništavaju skicu. Navigator prikaza pomiče se ispod njih.",
|
||||
"prefs.viewport": "Prozor prikaza",
|
||||
"prefs.viewport_analysis_status": "Prikaži status analize u prozoru prikaza",
|
||||
"prefs.viewport_analysis_status_help": "Prikazuje aktivne analize iznad prozora prikaza, otvara njihove legende iz svake stavke, a tipka Esc isključuje najnoviju analizu. Isključite kako biste vratili legende u kutovima i prethodno ponašanje tipke Esc.",
|
||||
"prefs.viewport_background": "Pozadina",
|
||||
"prefs.viewport_background_colour": "Boja",
|
||||
"prefs.viewport_background_theme": "Gradijent teme",
|
||||
"prefs.wheel": "Kotačić",
|
||||
"prefs.wheel_trackpad": "Kotačić i dodirna pločica",
|
||||
"prefs.workspace": "Radni prostor",
|
||||
"prefs.zoom_stop_at_model": "Zaustavi zumiranje na modelu",
|
||||
"prefs.zoom_stop_at_model_tip": "3D miš i aplikacija uređaja zumiraju prema površini u sredini prikaza; zumiranje povlačenjem zadržava točku na kojoj je povlačenje počelo. Isključeno: zumiranje može proći kroz model. Kotačić i štipanje zasebno koriste Zumiranje prema pokazivaču",
|
||||
"prefs.zoom_toward_cursor": "Zumiranje prema pokazivaču",
|
||||
"properties.title": "Svojstva: {name}",
|
||||
"recovery.days_ago": "prije {count} dana",
|
||||
"recovery.detail": "{file} · značajki: {features} · automatski spremljeno {when}",
|
||||
"recovery.discard_all": "Odbaci sve",
|
||||
"recovery.discard_all_detail": "Ovo se ne može poništiti.",
|
||||
"recovery.discard_all_title": "Odbaciti automatska spremanja ({count})?",
|
||||
"recovery.discard_all_title_one": "Odbaciti 1 automatsko spremanje?",
|
||||
"recovery.hours_ago": "prije {count} h",
|
||||
"recovery.just_now": "upravo",
|
||||
"recovery.min_ago": "prije {count} min",
|
||||
@@ -2034,6 +2183,7 @@
|
||||
"render.appearance_editor.weight": "Težina",
|
||||
"render.appearance_physics_separate": "Vizualni izgled ne dodjeljuje gustoću, toplinske podatke niti druga inženjerska svojstva.",
|
||||
"render.appearances": "Izgledi",
|
||||
"render.assign_help": "Kliknite za primjenu na odabir; povucite za pregled i ispustite ili, kad ništa nije odabrano, kliknite za bojenje.",
|
||||
"render.availability_native": "Izvorni sastav; pregledajte prije primjene",
|
||||
"render.availability_projection": "Podržana projekcija; pogledajte opseg i izostavke",
|
||||
"render.availability_reference": "Referentni podaci; nije automatska dodjela",
|
||||
@@ -2072,6 +2222,7 @@
|
||||
"render.bloom_threshold": "Prag linearnih svijetlih dijelova",
|
||||
"render.browse_capabilities": "Pregledaj potpuni katalog mogućnosti",
|
||||
"render.browse_environments": "Pregledaj izvorna HDR okruženja",
|
||||
"render.browse_looks": "Pregledaj…",
|
||||
"render.browse_native_scenes": "Pregledaj izvorne studije",
|
||||
"render.browse_physical": "Pregledaj fizičke reference",
|
||||
"render.browse_quality": "Pregledaj specifikacije kvalitete",
|
||||
@@ -2095,6 +2246,82 @@
|
||||
"render.check_opaque": "Prozirnost: samo neprozirne površine; alfa pozadine je podržana.",
|
||||
"render.check_sorted_alpha": "Prozirnost: sortirana aproksimacija alfe.",
|
||||
"render.check_transmission": "Prozirnost: fizičko propuštanje svjetlosti.",
|
||||
"render.children.absolute_floor": "Apsolutni donji prag",
|
||||
"render.children.adaptive": "Prilagodljivo",
|
||||
"render.children.add_look_reason": "Dodajte izgled kako biste uredili njegovo uključeno stanje i jačinu.",
|
||||
"render.children.all_shots": "Svi kadrovi",
|
||||
"render.children.bloom": "Sjaj",
|
||||
"render.children.check": "Provjera",
|
||||
"render.children.check_now": "Provjeri sada",
|
||||
"render.children.chromatic": "Kromatski pomak",
|
||||
"render.children.compact": "Kompaktno",
|
||||
"render.children.contrast": "Kontrast",
|
||||
"render.children.copy_image": "Kopiraj",
|
||||
"render.children.copy_job": "Kopiraj JSON posla",
|
||||
"render.children.copy_request": "Kopiraj JSON zahtjeva",
|
||||
"render.children.coverage_error": "Pogreška pokrivenosti",
|
||||
"render.children.cpu": "CPU praćenje zraka",
|
||||
"render.children.denoise": "Smanji šum na dovršenoj slici",
|
||||
"render.children.depth": "Dubina putanje",
|
||||
"render.children.distortion": "Izobličenje",
|
||||
"render.children.edge_samples": "Uzorci rubova",
|
||||
"render.children.effects_banner": "Ovi efekti zahtijevaju GPU praćenje putanja. Otvaranje ovoga nikad ne mijenja metodu.",
|
||||
"render.children.enable_adaptive": "Omogućite neovisne probne uzorke kako biste uredili prilagodljiva ograničenja.",
|
||||
"render.children.enable_bloom": "Omogućite sjaj kako biste uredili njegovu jačinu, prag i polumjer.",
|
||||
"render.children.finishing": "Završna obrada",
|
||||
"render.children.flare": "Odsjaj",
|
||||
"render.children.fresnel": "Fresnelovi slojevi",
|
||||
"render.children.ghosts": "Duhovi prstenova",
|
||||
"render.children.glass": "Prijenos kroz staklo",
|
||||
"render.children.go_to": "Idi na {editor}",
|
||||
"render.children.grain": "Zrno",
|
||||
"render.children.halo": "Oreol",
|
||||
"render.children.hdr": "HDR",
|
||||
"render.children.keep_master": "Zadrži sirovi linearni master",
|
||||
"render.children.last_result": "Posljednje: {number} · {width} × {height} · {phase}",
|
||||
"render.children.lens_effects": "Efekti objektiva",
|
||||
"render.children.look_summary": "{tone} · izgledi: {count}",
|
||||
"render.children.looks": "Kreativni izgledi",
|
||||
"render.children.memory": "Memorija",
|
||||
"render.children.method": "Metoda",
|
||||
"render.children.minimum": "Minimum",
|
||||
"render.children.needs_cpu": "Zahtijeva CPU praćenje zraka. Otvaranje ovoga nikad ne mijenja metodu.",
|
||||
"render.children.nested": "Potvrđeni ugniježđeni dielektrici",
|
||||
"render.children.not_checked": "Nije provjereno",
|
||||
"render.children.path": "Praćenje putanja",
|
||||
"render.children.pilots": "Probni uzorci",
|
||||
"render.children.preview": "Podaci pregleda",
|
||||
"render.children.progressive_reason": "Odaberite CPU progresivno kako biste uredili broj uzoraka i sjeme.",
|
||||
"render.children.radius": "Polumjer",
|
||||
"render.children.reflect_depth": "Dubina refleksije",
|
||||
"render.children.reflect_samples": "Uzorci refleksije",
|
||||
"render.children.regrade": "Ponovna gradacija",
|
||||
"render.children.relative_error": "Relativna pogreška",
|
||||
"render.children.render": "Renderiranje",
|
||||
"render.children.render_shot": "Renderiraj kadar",
|
||||
"render.children.renderer": "Iscrtavač",
|
||||
"render.children.renderers": "Iscrtavači",
|
||||
"render.children.request": "Ovaj zahtjev",
|
||||
"render.children.reset_finishing": "Vrati zadanu završnu obradu",
|
||||
"render.children.review_quality": "Pregledaj specifikaciju kvalitete…",
|
||||
"render.children.rgb_gain": "RGB pojačanje",
|
||||
"render.children.samples": "Uzorci",
|
||||
"render.children.sampling": "Uzorkovanje",
|
||||
"render.children.saturation": "Zasićenost",
|
||||
"render.children.scene_summary": "Tijela: {bodies} · trokuti: {triangles}",
|
||||
"render.children.seed": "Sjeme",
|
||||
"render.children.sharpening": "Izoštravanje",
|
||||
"render.children.single_image": "Jedna slika",
|
||||
"render.children.soft_focus": "Meki fokus",
|
||||
"render.children.streak": "Pruga",
|
||||
"render.children.strength": "Jačina",
|
||||
"render.children.studio": "Studio",
|
||||
"render.children.threshold": "Prag",
|
||||
"render.children.tone": "Ton",
|
||||
"render.children.under_hood": "Ispod haube",
|
||||
"render.children.vignette": "Vinjeta",
|
||||
"render.children.workstation": "Radna stanica",
|
||||
"render.choose_look": "Najprije odaberite izgled u Izgledima",
|
||||
"render.chromatic_offset": "Kromatski pomak rubova",
|
||||
"render.clear_stage": "Ukloni spremljenu scenu",
|
||||
"render.copy_request": "Kopiraj JSON",
|
||||
@@ -2346,8 +2573,33 @@
|
||||
"render.flare_strength": "Jačina odsjaja svijetlih dijelova",
|
||||
"render.flare_threshold": "Linearni prag odsjaja scene",
|
||||
"render.fold_browser": "Sažmi stablo modela",
|
||||
"render.frame_aspect": "Omjer",
|
||||
"render.frame_centre_mark": "Oznaka središta",
|
||||
"render.frame_copy_limit": "Nema dostupnog naziva za duplikat kadra",
|
||||
"render.frame_copy_name": "{name} kopija {number}",
|
||||
"render.frame_custom": "Prilagođeno",
|
||||
"render.frame_distance_unit": " × veličina",
|
||||
"render.frame_duplicate": "Dupliciraj",
|
||||
"render.frame_exposure": "Ekspozicija",
|
||||
"render.frame_fov": "Vidno polje",
|
||||
"render.frame_guides": "Vodilice",
|
||||
"render.frame_invalid_aspect": "Neispravan unaprijed zadani omjer",
|
||||
"render.frame_lens": "Vidno polje {fov}° · ≈ {mm} mm",
|
||||
"render.frame_name": "Naziv",
|
||||
"render.frame_output_size": "Veličina izlaza",
|
||||
"render.frame_photo": "3:2 · Fotografija",
|
||||
"render.frame_portrait": "4:5 · Portret",
|
||||
"render.frame_presets": "Unaprijed zadani kadrovi",
|
||||
"render.frame_presets_pending": "Stiže s uređivačem kadrova",
|
||||
"render.frame_projection": "Projekcija",
|
||||
"render.frame_render_shot": "Renderiraj ovaj kadar",
|
||||
"render.frame_rule_thirds": "Pravilo trećina",
|
||||
"render.frame_safe_area": "Sigurno područje",
|
||||
"render.frame_shot_title": "Kadar · {name}",
|
||||
"render.frame_square": "1:1 · Kvadrat",
|
||||
"render.frame_tall": "9:16 · Okomito",
|
||||
"render.frame_thirds": "Trećine",
|
||||
"render.frame_wide": "16:9 · Široki zaslon",
|
||||
"render.gpu_depth": "Maksimalna dubina putanje",
|
||||
"render.gpu_options_help": "Uzorci, dubina, sjeme i ekspozicija spremaju se s ovom postavkom. Sprema se samo aktivna metoda slike.",
|
||||
"render.gpu_path_failed": "GPU praćenje putanja nije dostupno",
|
||||
@@ -2375,6 +2627,7 @@
|
||||
"render.heading_results": "REZULTATI",
|
||||
"render.heading_shots": "KADROVI",
|
||||
"render.hide_shots_label": "Sakrij traku kadrova",
|
||||
"render.hover_look": "{object} · {look} · kliknite za odabir",
|
||||
"render.image_advanced": "Napredne GPU kontrole",
|
||||
"render.image_cancelled": "Renderiranje je prekinuto",
|
||||
"render.image_cancelling": "Prekidanje",
|
||||
@@ -2521,17 +2774,95 @@
|
||||
"render.library_uniform_ack": "Upotrijebi jednoličnu aproksimaciju bez prostornih ili naprednih efekata",
|
||||
"render.library_usable": "Izvršne projekcije",
|
||||
"render.library_users": "Korisnici",
|
||||
"render.light_aim": "Usmjeri prema",
|
||||
"render.light_anchor_pending": "Promjena koordinatnog sustava svjetla još nije podržana.",
|
||||
"render.light_azimuth": "Azimut",
|
||||
"render.light_backend_limit": "Odaberite CPU praćenje zraka ili izričiti GPU studio kako biste uređivali svjetla. Svjetla starog GPU studija ostaju samo za čitanje.",
|
||||
"render.light_behaviour": "PONAŠANJE",
|
||||
"render.light_default_fill": "Popunjavajuće",
|
||||
"render.light_default_key": "Glavno",
|
||||
"render.light_default_number": "Svjetlo {number}",
|
||||
"render.light_default_rim": "Rubno",
|
||||
"render.light_delete": "Izbriši",
|
||||
"render.light_distance": "Udaljenost",
|
||||
"render.light_duplicate": "Dupliciraj",
|
||||
"render.light_elevation": "Elevacija",
|
||||
"render.light_gpu_punctual": "Točkasta svjetla i reflektori dostupni su uz CPU praćenje zraka.",
|
||||
"render.light_hard_shadow": "Ovo svjetlo ima oštre sjene; mekoća emitera nije dostupna.",
|
||||
"render.light_intensity": "Intenzitet",
|
||||
"render.light_missing": "Ovo svjetlo više ne postoji. Odaberite svjetlo u stablu modela.",
|
||||
"render.light_place_highlight": "Postavi prema odsjaju",
|
||||
"render.light_place_pending": "Postavljanje prema odsjaju zahtijeva odabir svjetla u prozoru prikaza i još nije podržano.",
|
||||
"render.light_position": "POLOŽAJ",
|
||||
"render.light_preview_help": "Prikaz uživo je bez sjena; površinska svjetla koriste aproksimaciju s uzorkom u središtu. Renderiranje koristi potpuni model svjetla.",
|
||||
"render.light_product_centre": "Središte proizvoda",
|
||||
"render.light_size": "Veličina",
|
||||
"render.light_softness": "Mekoća",
|
||||
"render.light_temperature": "Temperatura boje",
|
||||
"render.light_temperature_help": "Približna nijansa crnog tijela; sprema se kao linearni RGB.",
|
||||
"render.light_type": "Vrsta",
|
||||
"render.light_type_area": "Površinsko",
|
||||
"render.light_type_point": "Točkasto",
|
||||
"render.light_type_spot": "Reflektor",
|
||||
"render.light_type_sun": "Sunce",
|
||||
"render.light_view_only": "Samo ovo svjetlo i isključivanje svjetla utječu na ovaj prikaz i njegova renderiranja; nikad se ne spremaju u dizajn.",
|
||||
"render.light_world_origin": "Ishodište svijeta",
|
||||
"render.lighting_aim_point": "Točka usmjeravanja",
|
||||
"render.lighting_apply": "Primijeni postavku",
|
||||
"render.lighting_area_samples": "Uzorci površinskog svjetla",
|
||||
"render.lighting_budget": "Proračun",
|
||||
"render.lighting_budget_help": "Brojevi su samo za čitanje. Dodajte, duplicirajte ili izbrišite svjetla kako biste ih promijenili; metoda određuje ograničenja.",
|
||||
"render.lighting_colour": "Boja",
|
||||
"render.lighting_consent": "Zamijeni usmjerena svjetla ovom postavkom",
|
||||
"render.lighting_custom": "Prilagođena svjetla",
|
||||
"render.lighting_custom_help": "Odabirom opcije Prilagođeno postavka se pretvara u svjetla koja se mogu uređivati, svako u svom retku u stablu.",
|
||||
"render.lighting_direction": "Smjer X Y Z",
|
||||
"render.lighting_direction_help": "Ili upišite smjer prema svjetlu (X Y Z).",
|
||||
"render.lighting_distance_unit": " × veličina",
|
||||
"render.lighting_edge_u": "Vektor stranice U",
|
||||
"render.lighting_edge_v": "Vektor stranice V",
|
||||
"render.lighting_falloff": "Slabljenje",
|
||||
"render.lighting_falloff_help": "Intenzitet je naveden za referentnu udaljenost.",
|
||||
"render.lighting_height": "Visina V",
|
||||
"render.lighting_minimum": "Minimum",
|
||||
"render.lighting_mute": "Isključi ovo svjetlo",
|
||||
"render.lighting_point": "Točka",
|
||||
"render.lighting_preset": "Postavka studija",
|
||||
"render.lighting_preset_cpu": "Usmjerene postavke studija zahtijevaju CPU praćenje zraka. GPU osvjetljenje koristi izričita svjetla vrste Sunce i Površinsko.",
|
||||
"render.lighting_preset_row": "Postavka",
|
||||
"render.lighting_radiance": "Radijancija",
|
||||
"render.lighting_reference": "Referenca",
|
||||
"render.lighting_review_help": "Zamjenjuje popis usmjerenih svjetala. Zadržava točkasta i površinska svjetla, okruženje, sjene, kameru i sve ostale postavke kadra.",
|
||||
"render.lighting_review_title": "Pregledaj postavku osvjetljenja",
|
||||
"render.lighting_samples_cpu": "Uzorci površinskog svjetla primjenjuju se na CPU praćenje zraka.",
|
||||
"render.lighting_samples_need_area": "Dodajte CPU površinsko svjetlo kako biste postavili uzorke površinskog svjetla.",
|
||||
"render.lighting_samples_reason": "Uzorci površinskog svjetla moraju biti 1, 4, 16 ili 64.",
|
||||
"render.lighting_shadow_cpu": "Prekidač sjena zahtijeva CPU praćenje zraka. GPU praćenje putanja uvijek baca sjene.",
|
||||
"render.lighting_shadows": "Baci sjene",
|
||||
"render.lighting_shadows_section": "Sjene i uzorkovanje",
|
||||
"render.lighting_shape": "Oblik",
|
||||
"render.lighting_solo": "Samo ovo svjetlo",
|
||||
"render.lighting_source": "Izvor",
|
||||
"render.lighting_source_section": "Izvor svjetla",
|
||||
"render.lighting_spot_preserved": "Ovo točkasto svjetlo zadržava spremljeni stožac reflektora dok mu se ne promijeni vrsta.",
|
||||
"render.lighting_sun_distance": "Smjer sunca ne ovisi o udaljenosti i točki usmjeravanja.",
|
||||
"render.lighting_unsupported": "nepodržano",
|
||||
"render.lighting_used": "{used} od {limit}",
|
||||
"render.lighting_width": "Širina U",
|
||||
"render.lighting_world_position": "Svjetski X Y Z",
|
||||
"render.lights_fixed_to": "Svjetla vezana za",
|
||||
"render.linear_help": "Zadržava 32-bitni float RGBA master prije uklanjanja šuma, ekspozicije, mapiranja tonova, filtara i pozadine. Linearni sRGB/D65; pomnožen pokrivenošću. Dodatna memorija izričito se odobrava. Bez sažimanja i dodatnih prolaza.",
|
||||
"render.linear_retain": "Zadrži sirovi linearni EXR",
|
||||
"render.linear_unavailable": "Odabrani dovršeni kadar nema zadržani EXR. Omogućite zadržavanje prije renderiranja; stariji PNG ne može vratiti sirovu radijanciju.",
|
||||
"render.look_add": "Dodaj izgled boje",
|
||||
"render.look_applied": "Primijenjeno: {name}",
|
||||
"render.look_bleach": "Po uzoru na bleach bypass",
|
||||
"render.look_cool": "Hladno",
|
||||
"render.look_cyanotype": "Po uzoru na cijanotipiju",
|
||||
"render.look_faded": "Izblijedjeli otisak",
|
||||
"render.look_material": "Materijal",
|
||||
"render.look_mono": "Jednobojno",
|
||||
"render.look_pasted": "Izgled je zalijepljen",
|
||||
"render.look_sepia": "Sepija",
|
||||
"render.look_strength": "Jačina izgleda",
|
||||
"render.look_teal_orange": "Tirkizno / narančasto",
|
||||
@@ -2607,9 +2938,11 @@
|
||||
"render.output_advanced": "Napredno",
|
||||
"render.output_backend_ready": "Spremno",
|
||||
"render.output_check": "Provjeri",
|
||||
"render.output_check_failed": "Provjera · pogreška",
|
||||
"render.output_check_help": "Pokrenite Provjeri da pregledate ovaj zahtjev bez pokretanja renderiranja.",
|
||||
"render.output_check_summary": "Provjera · Napomene: {count}",
|
||||
"render.output_copy": "Kopiraj",
|
||||
"render.output_copy_report": "Kopiraj izvješće",
|
||||
"render.output_destination": "Odredište",
|
||||
"render.output_destination_help": "Odaberite odredišnu datoteku pri izvozu dovršene slike.",
|
||||
"render.output_dimensions": "Veličina",
|
||||
@@ -2619,6 +2952,7 @@
|
||||
"render.output_fit": "Uklopi",
|
||||
"render.output_format": "Format",
|
||||
"render.output_format_status": "PNG je točna dovršena slika za prikaz. Neobavezni GPU EXR zadržava sirovu linearnu radijanciju scene u formatu FLOAT32 prije filtara prikaza. Izvoz nikad ne zamjenjuje predmemoriju pregleda ni drugi posao.",
|
||||
"render.output_grading": "Gradacija",
|
||||
"render.output_image": "Slika",
|
||||
"render.output_largest": "najviše {width} × {height}",
|
||||
"render.output_lock_ratio": "Zaključaj omjer stranica",
|
||||
@@ -2628,6 +2962,8 @@
|
||||
"render.output_quality_waiting": "čeka definiciju kvalitete",
|
||||
"render.output_ratio_refused": "Povezana dimenzija premašuje ograničenje veličine ove metode. Prethodna veličina zadržava se; otključajte omjer ili odaberite manju vrijednost.",
|
||||
"render.output_ready": "Spremno za renderiranje",
|
||||
"render.output_run_check": "Pokreni provjeru",
|
||||
"render.output_size_limit": "{method}: do {dimension} px po strani i {pixels} piksela. Najveća veličina koja stane: {width} × {height}.",
|
||||
"render.output_size_ok": "Veličina u redu · {width} × {height} px",
|
||||
"render.output_swap_orientation": "Zamijeni širinu i visinu",
|
||||
"render.output_tools_inspector": "Veličinu i format uredite u inspektoru Izlaz.",
|
||||
@@ -2644,6 +2980,7 @@
|
||||
"render.page_output": "Izlaz",
|
||||
"render.page_scene": "Scena",
|
||||
"render.paint_label": "Oboji",
|
||||
"render.painting_with": "Bojenje izgledom: {name}",
|
||||
"render.passive_stage": "Podloga i pasivna scena",
|
||||
"render.passive_stage_help": "Konačni pasivni paneli pripadaju samo renderiranim slikama. Ne dodaju CAD tijela ni masu. Postavljanje je fiksno nakon primjene; presijecanje granica proizvoda odbija se. CPU ne daje difuzno odbijeno osvjetljenje.",
|
||||
"render.perspective": "Perspektivna kamera",
|
||||
@@ -2665,6 +3002,7 @@
|
||||
"render.pick_help": "Odaberite Tijelo, Lice ili Komponenta. Kliknite prazan prostor kako biste očistili odabir; Shift ili Ctrl dodaje ili uključuje/isključuje. Isticanja se pojavljuju samo u živom prikazu proizvoda.",
|
||||
"render.pick_label": "Odaberi",
|
||||
"render.pick_up_label": "Preuzmi",
|
||||
"render.pick_up_prompt": "Kliknite objekt kako biste preuzeli njegov izgled",
|
||||
"render.pick_waiting": "Odabir proizvoda još nije podržan.",
|
||||
"render.post_contrast": "Kontrast",
|
||||
"render.post_gain_b": "Pojačanje plave",
|
||||
@@ -2704,13 +3042,17 @@
|
||||
"render.radial_distortion": "Radijalno izobličenje",
|
||||
"render.radial_fit": "Uklopi proizvod",
|
||||
"render.radial_save": "Spremi kadar",
|
||||
"render.recent_looks": "Nedavni izgledi",
|
||||
"render.regrade_action": "Ponovna gradacija sirovog mastera (bez uklanjanja šuma)",
|
||||
"render.regrade_help": "Izrađuje zaseban PNG iz odabranog dovršenog sirovog mastera, koristeći ove kontrole prikaza. Ne prati zrake, ne mijenja zabilježenu veličinu, kameru ni svjetla i ne prebrisuje EXR. Uklanjanje šuma ne primjenjuje se ponovno: sirovi masteri ne čuvaju njegove vodilje. Izvedena slika i dalje se može izvesti istim kontrolama posla.",
|
||||
"render.regrade_label": "Ponovna gradacija",
|
||||
"render.reload_settings": "Ponovno učitaj spremljene postavke",
|
||||
"render.remove_override": "Ukloni nadjačavanje",
|
||||
"render.replace_all": "Zamijeni sve",
|
||||
"render.replace_ground": "Potvrdi zamjenu postojeće scene",
|
||||
"render.replace_label": "Zamijeni",
|
||||
"render.replace_saved_surface": "Zamijeni postojeću spremljenu vezu za ovaj cilj",
|
||||
"render.replace_with": "Zamijeni s",
|
||||
"render.restore_camera": "Vrati spremljenu kameru",
|
||||
"render.result_actual": "100%",
|
||||
"render.result_actual_help": "Jedan piksel slike po pikselu zaslona.",
|
||||
@@ -2762,14 +3104,28 @@
|
||||
"render.saved_surface_remove": "Ukloni spremljenu vezu",
|
||||
"render.saved_surfaces": "Spremljene veze površina",
|
||||
"render.saved_surfaces_help": "Fiksirane ugrađene mape prate odabrani primjerak u lokalnim milimetrima. Zamijenjen ili nedostajući cilj pogreška je, nikad automatska ponovna dodjela.",
|
||||
"render.scene_all_shots": "Svi kadrovi ({count})",
|
||||
"render.scene_apply": "Primijeni pregledani studio",
|
||||
"render.scene_batch_reason": "Opcija Svi kadrovi zahtijeva red čekanja za renderiranje spremljenih kadrova, koji još nije dostupan.",
|
||||
"render.scene_check_now": "Provjeri sada",
|
||||
"render.scene_check_passed": "Provjera uspješna · napomene: {notes}",
|
||||
"render.scene_check_stale": "Provjera je zastarjela · provjerite ponovno",
|
||||
"render.scene_check_unchecked": "Još nije provjereno · 0 napomena",
|
||||
"render.scene_consent": "Potvrdi zamjenu osvjetljenja, okruženja, ekspozicije i scene",
|
||||
"render.scene_light_summary": "{environment} · svjetla: {lights}",
|
||||
"render.scene_look_summary": "Izgledi: {looks} · nadjačavanja: {overrides}",
|
||||
"render.scene_open_check": "Otvori provjeru",
|
||||
"render.scene_preserved_fields": "Kamera, uzorkovanje, dimenzije, optičke veze, CAD geometrija i inženjerski materijali čuvaju se.",
|
||||
"render.scene_preserves_design": "Sastavite osvjetljenje i pasivnu scenu za vidljivi predmet. Geometrija, inženjerski materijali i kamera ostaju odvojeni.",
|
||||
"render.scene_ready": "Spremno za renderiranje",
|
||||
"render.scene_reminder": "Scena čuva dizajn. Geometrija, inženjerska svojstva i CAD nikad se ne mijenjaju iz Renderiranja.",
|
||||
"render.scene_reminders": "Podsjetnici",
|
||||
"render.scene_renderer_ready": "{renderer}: spremno",
|
||||
"render.scene_replaces": "Zamjenjuje",
|
||||
"render.scene_review": "Razriješi i pregledaj",
|
||||
"render.scene_review_help": "Pregledajte potpunu izvornu kompoziciju prije primjene. Nevezane napredne SCENE specifikacije ne zamjenjuju se.",
|
||||
"render.scene_scope_details": "Opseg kompozicije",
|
||||
"render.scene_stages": "Faze",
|
||||
"render.search_appearances": "Pretraži izglede ({count})",
|
||||
"render.setup_legacy_environment": "Ova starija postavka koristi naslijeđenu rotaciju ili intenzitet okruženja. Te vrijednosti zadržavaju se; izričito ih pretvorite prije spremanja punog posla slike.",
|
||||
"render.setup_name": "Naziv postavke",
|
||||
@@ -2782,7 +3138,22 @@
|
||||
"render.shell_tab_camera": "KAMERA RENDERA",
|
||||
"render.shell_tab_lighting": "OSVJETLJENJE",
|
||||
"render.shell_tab_scene": "SCENA RENDERA",
|
||||
"render.shot_aperture": "Otvor blende",
|
||||
"render.shot_distance": "Udaljenost",
|
||||
"render.shot_dof": "Dubinska oštrina",
|
||||
"render.shot_duplicate": "Dupliciraj spremljeni kadar",
|
||||
"render.shot_edit_output": "Uredi u Izlazu",
|
||||
"render.shot_exposure_reason": "Ekspozicija zahtijeva CPU praćenje zraka ili GPU praćenje putanja.",
|
||||
"render.shot_exposure_section": "Ekspozicija",
|
||||
"render.shot_focus_distance": "Udaljenost fokusa",
|
||||
"render.shot_fov_reason": "Vidno polje zahtijeva perspektivnu projekciju.",
|
||||
"render.shot_frame_subject": "Uokviri predmet",
|
||||
"render.shot_invalid_camera": "Vrijednosti kamere moraju biti konačne i unutar raspona.",
|
||||
"render.shot_lens": "Objektiv",
|
||||
"render.shot_lens_enable_reason": "Omogućite dubinsku oštrinu kako biste uredili otvor blende i udaljenost fokusa.",
|
||||
"render.shot_lens_gpu_reason": "Dubinska oštrina zahtijeva GPU praćenje putanja.",
|
||||
"render.shot_lens_perspective_reason": "Dubinska oštrina zahtijeva perspektivnu projekciju.",
|
||||
"render.shot_look_selection": "Pogledaj odabir",
|
||||
"render.shot_manager": "Spremljeni kadrovi",
|
||||
"render.shot_new_name": "Naziv novog kadra",
|
||||
"render.shot_remove": "Ukloni spremljeni kadar",
|
||||
@@ -2790,6 +3161,9 @@
|
||||
"render.shot_remove_title": "Ukloniti spremljeni kadar?",
|
||||
"render.shot_rename": "Preimenuj spremljeni kadar",
|
||||
"render.shot_saved_only": "Najprije spremite trenutni nacrt. Dupliciranje i preimenovanje čuvaju točne spremljene opcije i reference na resurse.",
|
||||
"render.shot_selection_reason": "Odaberite tijelo ili lice prema kojem se usmjerava.",
|
||||
"render.shot_size": "Veličina",
|
||||
"render.shot_target": "Cilj",
|
||||
"render.shots_camera_changed": "Kamera je promijenjena otkako je ovaj kadar spremljen",
|
||||
"render.shots_name_help": "Upišite jedinstven naziv trenutnog kadra.",
|
||||
"render.shots_no_result": "Još nema renderiranja",
|
||||
@@ -3052,6 +3426,7 @@
|
||||
"select an axis": "odaberite os",
|
||||
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "prvo odaberite os, ravan ili kružni brid ili lice valjka, stošca ili torusa",
|
||||
"select bodies first": "prvo odaberite tijela",
|
||||
"select components first": "najprije odaberite komponente",
|
||||
"select corner points, or the two lines of one corner": "odaberite točke kutova ili dvije linije jednog kuta",
|
||||
"select one corner point, or the two lines of one corner": "odaberite jednu točku kuta ili dvije linije jednog kuta",
|
||||
"select sheet edges first": "prvo odaberite bridove lima",
|
||||
@@ -3070,6 +3445,7 @@
|
||||
"settings.double_click_components": "Dvaput kliknite komponentu kako biste je aktivirali ili uredili povezanu komponentu na mjestu",
|
||||
"settings.frame_rate_details_note": "Dodaje graf vremena posljednjih okvira s brojem iscrtanih trokuta, histogram vremena okvira i što je GPU iscrtao. Kliknite broj okvira u sekundi u prikazu kako biste ih prikazali ili sakrili.",
|
||||
"settings.frame_rate_note": "Prikazuje broj okvira u sekundi u donjem desnom kutu prikaza.",
|
||||
"settings.insert_lists_open_designs": "Umetni dizajn najprije navodi dizajne otvorene u drugim karticama",
|
||||
"settings.measure_axis_distances": "Prikaži udaljenosti X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "Prikazuj komponente udaljenosti po svjetskim osima uz ukupnu udaljenost dok je Mjerenje otvoreno.",
|
||||
"settings.msaa_applies_on_restart": "Zaglađivanje rubova primjenjuje se pri sljedećem pokretanju SolidCrafta",
|
||||
@@ -3094,6 +3470,10 @@
|
||||
"shortcut.unpin": "Otkvači",
|
||||
"sketch is missing": "skica nedostaje",
|
||||
"sketch.degrees_of_freedom": "Stupnjevi slobode: {count}",
|
||||
"sketch.dimension_added_driven": "Skica već određuje tu kotu, pa je dodana kao referentna kota",
|
||||
"sketch.dimension_applied": "Kota je primijenjena",
|
||||
"sketch.dimension_applied_defined": "Kota je primijenjena; definiran je parametar `{name}`",
|
||||
"sketch.dimension_applied_renamed": "Kota je primijenjena; parametar je nazvan `{name}`",
|
||||
"sketch.dof_left": "Preostali stupnjevi slobode: {count}",
|
||||
"sketch.dof_left_one": "Preostali stupnjevi slobode: {count}",
|
||||
"sketch.draw_curves": "Crtaj kao {linetype}",
|
||||
@@ -3128,6 +3508,8 @@
|
||||
"sketch_text.use_font_file": "Upotrijebi datoteku fonta {path}",
|
||||
"solid": "puno",
|
||||
"status.editing": "Uređivanje: {name}",
|
||||
"status.navigation": "Mapiranje miša: {mapping}",
|
||||
"status.navigation_tip": "Kako miš pomiče prikaz. Kliknite za odabir drugog mapiranja",
|
||||
"status.under_constrained": "Nedovoljno ograničeno (stupnjevi slobode: {count})",
|
||||
"status.under_constrained_one": "Nedovoljno ograničeno (stupanj slobode: {count})",
|
||||
"status.units_tip": "Jedinice dizajna. Kliknite za promjenu",
|
||||
@@ -3161,8 +3543,10 @@
|
||||
"timeline.delete_folders_tip": "Zadrži njihove značajke i ugniježđene mape u vremenskoj traci",
|
||||
"timeline.delete_folders_with_features_tip": "Izbriši mape sa svim značajkama u njima i njihove ugniježđene mape",
|
||||
"timeline.delete_many": "Izbriši odabrane značajke: {count}",
|
||||
"timeline.edited_rolled_back": "Značajka {name} je promijenjena, ali je nakon oznake vraćanja pa se ne gradi: pomaknite oznaku iza nje kako biste vidjeli rezultat",
|
||||
"timeline.feature_error": "Pogreška: {message}",
|
||||
"timeline.feature_hint": "Dvaput kliknite za uređivanje · povucite za promjenu redoslijeda · desni klik za više",
|
||||
"timeline.feature_rolled_back": "Vraćeno: nalazi se nakon oznake vraćanja, pa se ne gradi",
|
||||
"timeline.feature_warning": "Upozorenje: {message}",
|
||||
"timeline.group": "Nova mapa značajki",
|
||||
"timeline.move_many": "Premjesti stavke vremenske trake",
|
||||
@@ -3244,6 +3628,10 @@
|
||||
"ui.3d_mouse_offer": "Kalibracija 3D miša ispravlja zamijenjene ili obrnute osi i postavlja njegovu brzinu i osjećaj.",
|
||||
"ui.3d_mouse_offer_never": "Ne prikazuj više",
|
||||
"ui.3d_mouse_offer_swap": "Prebaci na Hidraw (izravno)",
|
||||
"ui.3d_mouse_orbit": "Orbitiranje",
|
||||
"ui.3d_mouse_orbit_classic": "Klasično",
|
||||
"ui.3d_mouse_orbit_tip": "Praćeno: 3D miš okreće prikaz oko dijela modela koji je u sredini prikaza kad okretanje počne, označenog blijedom kuglom. Klasično: oko središta prikaza",
|
||||
"ui.3d_mouse_orbit_traced": "Praćeno",
|
||||
"ui.3d_mouse_reading": "Očitanje",
|
||||
"ui.3d_mouse_reset_axes": "Vrati zadanu dodjelu osi",
|
||||
"ui.3d_mouse_reset_view": "Vrati prikaz",
|
||||
@@ -3280,6 +3668,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Zakrenite kapicu suprotno od kazaljke na satu, držite je, a zatim pustite.",
|
||||
"ui.3d_mouse_switch_cap": "Kalibriraj kao Povratak u središte",
|
||||
"ui.3d_mouse_switch_trackball": "Kalibriraj kao kuglični miš",
|
||||
"ui.3d_mouse_use_direct": "Koristi izravni upravljački program",
|
||||
"ui.3d_mouse_use_direct_tip": "Čitaj 3D miš izravno (hidraw) umjesto preko spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "Os prikaza",
|
||||
"ui.3d_mouse_view_off": "Isključeno",
|
||||
"ui.3d_mouse_view_off_tip": "Profil upravljačkog programa 3D miša isključuje ovu os, pa njezino kretanje ne pomiče prikaz. Odabir kretanja druge osi ovdje ih zamjenjuje, a to kretanje prestaje pomicati prikaz.",
|
||||
@@ -3596,6 +3986,7 @@
|
||||
"ui.circle": "Kružnica",
|
||||
"ui.circular_pattern": "Kružni niz",
|
||||
"ui.clear": "Očisti",
|
||||
"ui.clear_print_face": "Ukloni plohu ispisa",
|
||||
"ui.clear_recent": "Očisti nedavno",
|
||||
"ui.clear_the_selection": "Poništi odabir",
|
||||
"ui.click_selects_whole_bodies": "Klik odabire cijela tijela",
|
||||
@@ -3630,6 +4021,15 @@
|
||||
"ui.constant": "Konstantno",
|
||||
"ui.constraints_conflict": "Ograničenja su u sukobu",
|
||||
"ui.construction": "Pomoćna",
|
||||
"ui.construction.angle_hint": "Pomoćni pravac: kliknite točku, pa upišite kut ili odaberite smjer",
|
||||
"ui.construction.bisector_hint": "Simetrala: odaberite dvije ravne linije koje se sijeku, pa željeno rješenje",
|
||||
"ui.construction.common_hint": "Zajednička tangenta: odaberite dvije kružnice ili dva luka, pa željeno rješenje",
|
||||
"ui.construction.contact_hint": "Tangenta: odaberite kružnicu/luk ili otvoreni spline/koniku, pa točku dodira (krivulje slobodnog oblika: krajnje točke)",
|
||||
"ui.construction.external_hint": "Tangenta: odaberite kružnicu ili luk, vanjsku točku, pa željeno rješenje",
|
||||
"ui.construction.free_hint": "Pomoćni pravac: kliknite dvije točke; desnim klikom počnite ispočetka",
|
||||
"ui.construction.point_hint": "Pomoćni pravac: kliknite točku kroz koju prolazi",
|
||||
"ui.construction.reference_hint": "Pomoćni pravac: odaberite ravnu liniju, pa točku; desnim klikom promijenite referencu",
|
||||
"ui.construction.ribbon_label": "Pomoćne",
|
||||
"ui.context_menu": "Kontekstni izbornik",
|
||||
"ui.continuity_g0": "G0 pregib",
|
||||
"ui.continuity_g1": "G1 tangentno",
|
||||
@@ -3670,6 +4070,7 @@
|
||||
"ui.design_properties.part_number": "Broj dijela",
|
||||
"ui.design_properties.project": "Projekt",
|
||||
"ui.design_properties.revision": "Revizija",
|
||||
"ui.design_saved": "Spremljeno: {path}",
|
||||
"ui.diameter": "Promjer",
|
||||
"ui.dimension": "Kota",
|
||||
"ui.direct_interaction": "Izravna interakcija",
|
||||
@@ -3720,6 +4121,14 @@
|
||||
"ui.end_scale": "Krajnje skaliranje",
|
||||
"ui.entities": "Elementi",
|
||||
"ui.equal": "Jednakost",
|
||||
"ui.equation_end": "Kraj",
|
||||
"ui.equation_explicit": "Eksplicitni",
|
||||
"ui.equation_form": "Oblik",
|
||||
"ui.equation_note": "Varijabla je običan broj: sin(t) je uzima u radijanima. Rezultat bez jedinice izražen je u jedinici dizajna.",
|
||||
"ui.equation_parametric": "Parametarski",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Ekvivalentni polumjer",
|
||||
"ui.expand": "Proširi",
|
||||
"ui.exportDxf": "Izvezi DXF…",
|
||||
@@ -3785,6 +4194,7 @@
|
||||
"ui.heading_design": "DIZAJN",
|
||||
"ui.heading_draft": "NAGIB",
|
||||
"ui.heading_edit": "UREDI",
|
||||
"ui.heading_equation_curve": "KRIVULJA IZ JEDNADŽBE",
|
||||
"ui.heading_extrude": "EKSTRUDIRAJ",
|
||||
"ui.heading_fillet": "ZAOBLJENJE",
|
||||
"ui.heading_finish_editing": "ZAVRŠI UREĐIVANJE",
|
||||
@@ -3876,6 +4286,10 @@
|
||||
"ui.import_ellipsis": "Uvezi…",
|
||||
"ui.infinite": "Beskonačno",
|
||||
"ui.insert": "Umetni",
|
||||
"ui.insert_design.browse": "Pregledaj…",
|
||||
"ui.insert_design.open_designs": "Otvoreni dizajni",
|
||||
"ui.insert_design.saved_file": "{name} ima nespremljene promjene, pa je umetnuta njegova spremljena datoteka. Spremite ga, a zatim pokrenite Ažuriraj veze kako biste unijeli promjene.",
|
||||
"ui.insert_design.unsaved": "Nespremljene promjene",
|
||||
"ui.inspect": "Pregledaj",
|
||||
"ui.intersect": "Presjek",
|
||||
"ui.isolate": "Izoliraj",
|
||||
@@ -4019,12 +4433,29 @@
|
||||
"ui.polygon": "Mnogokut",
|
||||
"ui.preferences": "Postavke",
|
||||
"ui.press_a_key": "pritisnite tipku…",
|
||||
"ui.print_face_cleared": "{body}: ploha ispisa uklonjena",
|
||||
"ui.print_face_input": "Ploha ispisa",
|
||||
"ui.print_face_one_body": "Ploha ispisa pripada jednom tijelu: pošaljite to tijelo samo da biste je promijenili",
|
||||
"ui.print_face_pick": "Odaberite ravnu plohu punog tijela da postane ploha ispisa",
|
||||
"ui.print_face_set": "{body}: ploha ispisa postavljena; Pošalji u slicer polaže tijelo na nju",
|
||||
"ui.profile": "Profil",
|
||||
"ui.profile_plane": "Ravnina profila",
|
||||
"ui.profiles": "Profili",
|
||||
"ui.project": "Projiciraj",
|
||||
"ui.project_face_edges_sketch": "Projiciraj bridove lica u nove skice",
|
||||
"ui.properties": "Svojstva",
|
||||
"ui.properties.copy_matrix": "Kopiraj matricu",
|
||||
"ui.properties.first_moments": "Statički momenti",
|
||||
"ui.properties.inertia": "Moment tromosti",
|
||||
"ui.properties.inertia_note": "Oko središta mase, u svjetskim osima (g·{unit}²)",
|
||||
"ui.properties.inertia_unavailable": "Nije dostupno: mreža tijela nije zatvorena.",
|
||||
"ui.properties.inertia_x": "Ixx, Ixy, Ixz",
|
||||
"ui.properties.inertia_y": "Iyx, Iyy, Iyz",
|
||||
"ui.properties.inertia_z": "Izx, Izy, Izz",
|
||||
"ui.properties.measuring": "Mjerenje…",
|
||||
"ui.properties.measuring_failed": "Mjerenje je zaustavljeno prije završetka.",
|
||||
"ui.properties.principal_axis": "Glavna os {number}",
|
||||
"ui.properties.principal_moments": "Glavni momenti tromosti",
|
||||
"ui.pull_direction": "Smjer vađenja iz kalupa",
|
||||
"ui.quality": "Kvaliteta",
|
||||
"ui.quantity": "Broj",
|
||||
@@ -4070,6 +4501,7 @@
|
||||
"ui.revolve": "Rotiraj",
|
||||
"ui.ribbon_exit": "Izlaz",
|
||||
"ui.ribbon_labels": "Prikaži tekst ispod ikona na traci",
|
||||
"ui.ribbon_menus_skip_pinned": "Izostavi prikvačene naredbe iz padajućih izbornika",
|
||||
"ui.ribbon_pin_footer": "Prikvačene naredbe prikazuju se na traci. Zadržite pokazivač iznad retka kako biste ga prikvačili ili otkvačili.",
|
||||
"ui.ribbon_workspace": "Radni prostor",
|
||||
"ui.right": "Desno",
|
||||
@@ -4087,6 +4519,7 @@
|
||||
"ui.select": "Odaberi",
|
||||
"ui.selectOther": "Odaberi drugo…",
|
||||
"ui.selectTangentChain": "Odaberi tangentni lanac",
|
||||
"ui.select_all": "Odaberi sve",
|
||||
"ui.selection": "Odabir",
|
||||
"ui.selection_modifiers": "Modifikatori odabira",
|
||||
"ui.selection_shift_add_only": "Shift+klik dodaje bez uklanjanja",
|
||||
@@ -4123,7 +4556,11 @@
|
||||
"ui.sketch": "Skica",
|
||||
"ui.sketch_dimension": "Kota skice",
|
||||
"ui.sketch_grid": "Mreža skice",
|
||||
"ui.sketch_intersect_geometry": "Geometrija",
|
||||
"ui.sketch_intersect_projection_link": "Veza projekcije",
|
||||
"ui.sketch_intersect_selection_filter": "Filtar odabira",
|
||||
"ui.sketch_modifiers": "Modifikatori skice",
|
||||
"ui.sketch_project_geometry": "Geometrija",
|
||||
"ui.sketch_scale": "Skaliranje skice",
|
||||
"ui.sketches": "Skice",
|
||||
"ui.slice": "Presijeci",
|
||||
@@ -4170,6 +4607,11 @@
|
||||
"ui.symmetric": "Simetrično",
|
||||
"ui.symmetry": "Simetrija",
|
||||
"ui.system": "Sustav",
|
||||
"ui.tab_assemble": "Sklopi",
|
||||
"ui.tab_manage": "Upravljanje",
|
||||
"ui.tab_sheet_metal": "Lim",
|
||||
"ui.tab_view": "Prikaz",
|
||||
"ui.tab_weldments": "Zavarene konstrukcije",
|
||||
"ui.tangent": "Tangentno",
|
||||
"ui.taper_angle": "Kut suženja",
|
||||
"ui.tapped": "S navojem",
|
||||
@@ -4185,6 +4627,7 @@
|
||||
"ui.tip_angle": "Kut vrha",
|
||||
"ui.to_object": "Do objekta",
|
||||
"ui.tool_direction": "Smjer alata",
|
||||
"ui.toolbar_tabs_hidden": "Sve kartice alatne trake su skrivene. Kliknite + ili ovdje desnom tipkom kako biste prikazali jednu.",
|
||||
"ui.top": "Odozgo",
|
||||
"ui.top_diameter": "Gornji promjer",
|
||||
"ui.top_radius": "Gornji polumjer",
|
||||
@@ -4222,6 +4665,8 @@
|
||||
"ui.view_centre": "Središte prikaza",
|
||||
"ui.viewport_status_clear": "Isključi {name}",
|
||||
"ui.viewport_status_clear_hint": "Isključi {name} · Esc",
|
||||
"ui.viewport_status_edges": "Bridovi: {count}",
|
||||
"ui.viewport_status_from": "iz smjera {direction}",
|
||||
"ui.viewport_status_key": "Prikaži legendu za {name}",
|
||||
"ui.viewport_status_minimum_radius": "Minimalni polumjer",
|
||||
"ui.viewport_status_pairs": "Parovi: {count}",
|
||||
@@ -4231,6 +4676,7 @@
|
||||
"ui.visual_shaded_with_edges": "Osjenčano s bridovima",
|
||||
"ui.visual_style": "Vizualni stil",
|
||||
"ui.visual_wireframe": "Žičani model",
|
||||
"ui.wheel_zoom_speed": "Brzina zumiranja kotačićem miša",
|
||||
"ui.width": "Širina",
|
||||
"ui.window_system": "Sustav prozora",
|
||||
"ui.window_system_auto": "Automatski",
|
||||
@@ -4261,7 +4707,9 @@
|
||||
"update.button": "Ažuriraj",
|
||||
"update.button_version": "Ažuriraj na {version}",
|
||||
"update.check_automatically": "Automatski provjeravaj ažuriranja",
|
||||
"update.check_for_updates": "Provjeri ažuriranja",
|
||||
"update.check_now": "Provjeri sada",
|
||||
"update.check_unavailable": "Provjera ažuriranja nije dostupna za ovu instalaciju.",
|
||||
"update.checking": "Provjera…",
|
||||
"update.copy": "Kopiraj",
|
||||
"update.dmg_opened": "Slika diska je otvorena i provjerena: povucite SolidCraft u Programe, zamijenite staru kopiju, a zatim ponovno pokrenite SolidCraft.",
|
||||
@@ -4284,6 +4732,9 @@
|
||||
"update.prefs_managed": "Ovo je SolidCraft {version}, kojim upravlja {manager}. Provjera pita GitHub za najnovije izdanje i ne šalje ništa drugo; ažurirajte SolidCraft u {manager}.",
|
||||
"update.prefs_note": "Ovo je SolidCraft {version} ({kind}). Provjera pita GitHub za najnovije izdanje i ne šalje ništa drugo.",
|
||||
"update.prefs_web": "Ponovno učitajte stranicu kako biste dobili najnoviju web aplikaciju. Ako mreža nije dostupna ili se ažuriranje ne može preuzeti na vrijeme, otvara se spremljena verzija; preuzimanje u tijeku nastavlja se za sljedeće ponovno učitavanje.",
|
||||
"update.refresh_checking": "Provjera najnovijeg izdanja…",
|
||||
"update.refresh_fallback": "Nije moguće provjeriti postoji li novije izdanje; ažurira se na {version}, pronađeno ranije.",
|
||||
"update.refresh_selected": "Ažuriranje na {version}.",
|
||||
"update.release_page": "Otvori stranicu izdanja",
|
||||
"update.restart": "Ponovno pokreni sada",
|
||||
"update.restart_later": "Kasnije",
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "ブレンドサーフェス",
|
||||
"BOUNDARY SURFACE": "境界サーフェス",
|
||||
"BROWSER": "ブラウザ",
|
||||
"Back to the original order": "元の順序に戻す",
|
||||
"Ball": "ボール",
|
||||
"Bar": "平鋼",
|
||||
"Base Center": "底面の中心",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "エッジ",
|
||||
"Edit": "編集",
|
||||
"Edit Profile Sketch": "プロファイルスケッチを編集",
|
||||
"Edit shortcuts": "ショートカットを編集",
|
||||
"Enable rule": "ルールを有効化",
|
||||
"Enabled": "有効",
|
||||
"End Radius": "終了半径",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "半径",
|
||||
"Radius Fit": "半径フィット",
|
||||
"Ratio": "比率",
|
||||
"Read-only list: shortcuts can't be changed here.": "読み取り専用の一覧です。ここではショートカットを変更できません。",
|
||||
"Reattach selected face": "選択した面を再アタッチ",
|
||||
"Recover": "復元",
|
||||
"Recover unsaved design?": "未保存のデザインを復元しますか?",
|
||||
@@ -593,6 +596,8 @@
|
||||
"Snap to face and edge centres": "面とエッジの中心にスナップ",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "SolidCraftからレポートを直接送信することはできません。GitHubで送信してください。アプリにトークンは必要ありません。",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "これらのデザインが保存される前にSolidCraftが終了しました。最後の自動保存ファイルを開くことができます。",
|
||||
"Sort A to Z": "昇順で並べ替え",
|
||||
"Sort Z to A": "降順で並べ替え",
|
||||
"Spacing 2 must be a non-zero number": "間隔 2は0以外の数値にしてください",
|
||||
"Spacing must be a non-zero number": "間隔は0以外の数値にしてください",
|
||||
"Specialise": "特殊操作",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "面の位置",
|
||||
"bom.group_children": "サブパーツを親パーツの行に含める",
|
||||
"browser.body_name": "ボディ{number}",
|
||||
"browser.calibrate_click_a": "画像をクリックして点Aを指定するか、座標を入力してください。",
|
||||
"browser.calibrate_click_b": "画像をクリックして点Bを指定するか、座標を入力してください。",
|
||||
"browser.calibrate_title": "尺度を設定: {name}",
|
||||
"browser.capture_many": "{count}個のコンポーネントが移動されましたが、位置がキャプチャされていません。",
|
||||
"browser.capture_note": "「位置をキャプチャ」で新しい位置を保持し、「位置を元に戻す」で以前の位置に戻します。",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "外観を取得",
|
||||
"cmd.appearance_replace": "外観を置換",
|
||||
"cmd.assembly_bom": "部品表",
|
||||
"cmd.body.print_face": "造形面",
|
||||
"cmd.body_rename": "ボディの名前を変更",
|
||||
"cmd.browser_collapse_all": "すべて折りたたむ",
|
||||
"cmd.browser_expand_all": "すべて展開",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "ブラウザ項目を移動",
|
||||
"cmd.browser_order": "ブラウザ項目の並び順を変更",
|
||||
"cmd.browser_rename_group": "グループの名前を変更",
|
||||
"cmd.browser_reparent": "コンポーネントへ移動",
|
||||
"cmd.browser_ungroup": "グループ解除",
|
||||
"cmd.browser_visibility": "表示/非表示",
|
||||
"cmd.canvas_calibrate": "キャンバスの尺度を設定",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "部品プロパティ",
|
||||
"cmd.component_metadata_set": "部品プロパティを変更",
|
||||
"cmd.component_move_bodies": "ボディをコンポーネントに移動",
|
||||
"cmd.component_move_features": "フィーチャーをコンポーネントに移動",
|
||||
"cmd.component_move_sketches": "スケッチをコンポーネントに移動",
|
||||
"cmd.component_paste_from_design": "別のデザインから貼り付け",
|
||||
"cmd.component_paste_new": "新規として貼り付け",
|
||||
"cmd.component_properties": "コンポーネントの物理的プロパティ",
|
||||
"cmd.component_relink": "参照元を再リンク",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "画像をレンダリング",
|
||||
"cmd.render_status": "レンダリングの進行状況",
|
||||
"cmd.select_clear": "選択をクリア",
|
||||
"cmd.settings_profile_apply": "設定プロファイルを適用",
|
||||
"cmd.settings_profile_delete": "設定プロファイルを削除",
|
||||
"cmd.settings_profile_export": "設定プロファイルをエクスポート",
|
||||
"cmd.settings_profile_import": "設定プロファイルをインポート",
|
||||
"cmd.settings_profile_list": "設定プロファイル",
|
||||
"cmd.settings_profile_rename": "設定プロファイルの名前を変更",
|
||||
"cmd.settings_profile_save": "設定プロファイルを保存",
|
||||
"cmd.sheet_convert": "板金に変換",
|
||||
"cmd.sheet_export_bend_table": "曲げテーブルをエクスポート",
|
||||
"cmd.sheet_export_dxf": "展開図を DXF としてエクスポート",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "折り戻し",
|
||||
"cmd.sheet_rules": "板金ルールを一覧表示",
|
||||
"cmd.sheet_unfold": "展開",
|
||||
"cmd.sketch.construction_line": "補助直線",
|
||||
"cmd.sketch.construction_line.angle": "角度指定の補助直線",
|
||||
"cmd.sketch.construction_line.bisector": "角の二等分線",
|
||||
"cmd.sketch.construction_line.horizontal": "水平補助直線",
|
||||
"cmd.sketch.construction_line.parallel": "平行補助直線",
|
||||
"cmd.sketch.construction_line.perpendicular": "直交補助直線",
|
||||
"cmd.sketch.construction_line.tangent_at": "曲線上の点での接線",
|
||||
"cmd.sketch.construction_line.tangent_external": "外部点を通る接線",
|
||||
"cmd.sketch.construction_line.tangent_two": "共通接線",
|
||||
"cmd.sketch.construction_line.vertical": "垂直補助直線",
|
||||
"cmd.sketch_arc3d": "3D 円弧",
|
||||
"cmd.sketch_arc_center_point": "中心点円弧",
|
||||
"cmd.sketch_arc_tangent": "正接円弧",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "図面のサイズ",
|
||||
"cmd.sketch_edit": "スケッチを編集",
|
||||
"cmd.sketch_edit_text": "テキストを編集",
|
||||
"cmd.sketch_equation_curve": "方程式曲線",
|
||||
"cmd.sketch_equation_curve_edit": "方程式曲線を編集",
|
||||
"cmd.sketch_export_dxf": "DXF として保存",
|
||||
"cmd.sketch_finish_auto_constrain": "自動拘束で終了",
|
||||
"cmd.sketch_fit_curves_to_section": "メッシュ断面に曲線をフィット",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "Renderブラウザー",
|
||||
"cmd.view.render_dock": "レンダードックを移動",
|
||||
"cmd.view.render_focus": "Renderフォーカス表示",
|
||||
"cmd.view.status_items": "ビューポートの状態項目",
|
||||
"cmd.view_ambient_occlusion": "アンビエントオクルージョン",
|
||||
"cmd.view_angle_readout": "ビュー角度",
|
||||
"cmd.view_apply": "名前付きビューを復元",
|
||||
@@ -1374,6 +1405,18 @@
|
||||
"help.occurrence.move": "アセンブリ部品をジョイントが許す自由度だけで動かします。部品の面を選択してから、操作可能な矢印または円弧をドラッグしてください。",
|
||||
"help.parameters.change": "デザインの寸法を決める名前付きの値と式の表を開きます。1か所で寸法を変え、それを使うすべてのフィーチャに反映させるときに使います。",
|
||||
"help.pointcloud.insert": "PLY・XYZ・PTS形式のスキャンを点群としてモデルと一緒に挿入します。計測データを参考にモデリングするときに使います。",
|
||||
"help.sketch.construction_line": "2点を通る無限の補助直線を作成します。スケッチの輪郭を分割せずに作図できます。",
|
||||
"help.sketch.construction_line.angle": "スケッチのX軸に対して角度を指定し、無限の補助直線を作成します。点を選び、角度を入力するか方向を選びます。",
|
||||
"help.sketch.construction_line.bisector": "交差する2本のスケッチ直線を選び、2つの角の二等分線から選びます。結果は元の直線の編集に追従します。",
|
||||
"help.sketch.construction_line.horizontal": "指定点を通る無限の水平補助直線を作成します。後で編集しても水平拘束が維持されます。",
|
||||
"help.sketch.construction_line.parallel": "スケッチの直線を選び、平行な無限の補助直線を配置します。右クリックで参照を選び直します。",
|
||||
"help.sketch.construction_line.perpendicular": "スケッチの直線を選び、直交する無限の補助直線を配置します。右クリックで参照を選び直します。",
|
||||
"help.sketch.construction_line.tangent_at": "円や円弧上の点、または開いたスプラインや円錐曲線の端点に接線を作成します。曲線を選び、接点を選びます。",
|
||||
"help.sketch.construction_line.tangent_external": "円または円弧、外部点、接線の解を順に選びます。プレビューには描かれた円弧上の接点のみが表示されます。",
|
||||
"help.sketch.construction_line.tangent_two": "2つの円または円弧を選び、プレビューから共通接線を選びます。接点は描かれた曲線上にある必要があります。",
|
||||
"help.sketch.construction_line.vertical": "指定点を通る無限の垂直補助直線を作成します。後で編集しても垂直拘束が維持されます。",
|
||||
"help.sketch.equation_curve": "x(t) と y(t)、または y = f(x) の式から、範囲を指定して曲線を描きます。式にはパラメーターを使え、曲線はその変更に追従します。正弦波、らせん、歯車のインボリュートなどに使います。",
|
||||
"help.sketch.inspect": "開いているスケッチのレポートを開きます。残りの自由度と、完全に拘束されているかどうかを表示します。スケッチを終える前に、まだ動く部分を確認するときに使います。",
|
||||
"help.solid.align": "選択した立体を動かし、その点、面、平面を別の場所の点、面、平面に合わせます。距離を測らずに部品を別の部品に当てて配置するときに使います。",
|
||||
"help.solid.chamfer": "選択した辺を、指定した距離で平らに斜めに削ります。鋭い角を落とすときや、ピンやねじを入れやすくするときに使います。",
|
||||
"help.solid.combine": "複数の立体を結合したり、対象の立体から切り取ったり、共通する体積だけを残したりでき、工具の立体を残すこともできます。部品の結合、ある形での切り抜き、2つの立体が重なる範囲の確認に使います。",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "異なる材料",
|
||||
"measure.at": "位置",
|
||||
"measure.item": "項目 {number}",
|
||||
"measure.quick_copied": "測定値をコピーしました",
|
||||
"measure.quick_copy": "クリックで測定値をコピー",
|
||||
"measure.quick_edges": "エッジ {count} 本",
|
||||
"measure.quick_faces": "面 {count} 個",
|
||||
"messages.ago_h": "{n} 時間前",
|
||||
"messages.ago_min": "{n} 分前",
|
||||
"messages.ago_s": "{n} 秒前",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "移動ではありません",
|
||||
"not a number": "数値ではありません",
|
||||
"open a sketch first": "先にスケッチを開いてください",
|
||||
"parameters.apply_live": "フィールドを離れるたびに変更を適用",
|
||||
"parameters.apply_live_tip": "オフ: 変更は「適用」または「OK」まで保留され、その後すべてをまとめて一度だけ再構築します。「キャンセル」または Esc で破棄します。",
|
||||
"parameters.held": "{count} 件の変更が適用待ちです",
|
||||
"parameters.held_hint": "式と単位を編集してください。変更は「適用」または「OK」まで保留されます。",
|
||||
"parameters.held_one": "1 件の変更が適用待ちです",
|
||||
"parts.automatic_name": "自動",
|
||||
"parts.dimension.across_flats": "二面幅",
|
||||
"parts.dimension.bore": "内径",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "厚さ",
|
||||
"parts.dimension.width": "幅",
|
||||
"parts.family.bearing": "深溝玉軸受(外形)",
|
||||
"parts.family.button_head_cap_screw": "ボタンヘッド六角穴付きボルト",
|
||||
"parts.family.dowel_pin": "平行ピン",
|
||||
"parts.family.hex_bolt": "六角ボルト",
|
||||
"parts.family.hex_nut": "六角ナット",
|
||||
"parts.family.set_screw": "六角穴付き止めねじ 平先",
|
||||
"parts.family.socket_head_cap_screw": "六角穴付きボルト",
|
||||
"parts.family.washer": "平座金",
|
||||
"parts.holes": "穴 (省略可)",
|
||||
"parts.placement_hint": "1 つ以上の穴を選ぶとそれぞれに部品を取り付けます。選ばずに OK を押すと原点に配置します",
|
||||
"pattern.alignment_2": "配置 2",
|
||||
"pattern.alignment_hint": "個数には元の図形が含まれます。中央配置ではコピーを両側に配置し、反転で偶数個の場合に多く配置する側を切り替えます。",
|
||||
"pattern.direction_1": "方向 1",
|
||||
@@ -1801,6 +1856,8 @@
|
||||
"prefs.bottom_centre": "下中央",
|
||||
"prefs.bottom_right": "右下",
|
||||
"prefs.browser": "ブラウザー",
|
||||
"prefs.browser_eye_left": "表示切り替えを折りたたみ矢印の隣に表示",
|
||||
"prefs.browser_eye_left_note": "ブラウザーの各行の表示切り替えを、行の右端の列ではなく、以前のように折りたたみ矢印の隣に表示します。",
|
||||
"prefs.browser_reveal_on_hover": "ホバーで表示",
|
||||
"prefs.browser_show_note": "「表示」はブラウザーを常に画面に表示します。「ホバーで表示」はポインターがその位置か左端の細いタブに来るまで隠し、ポインターが中にある間やそのメニューが開いている間は表示したままにします。",
|
||||
"prefs.browser_shown": "表示",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "SolidCraft の再起動後に有効になります。WGPU_ADAPTER_NAME がこの選択より優先されます。",
|
||||
"prefs.graphics_note": "速度と滑らかさのバランスを調整します。各選択肢の効果をサンプルで確認できます。",
|
||||
"prefs.graphics_presets_note": "プリセットは以下の設定をまとめて変更します。",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "ズームアウト時に拘束グリフを隠す",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "スケッチを十分にズームアウトすると、拘束グリフは表示されず画面を散らかしません。オフ: ズームに関係なく固定の画面サイズのままです。",
|
||||
"prefs.history": "履歴",
|
||||
"prefs.history_origin_bodies": "原点とボディを先頭に表示",
|
||||
"prefs.history_origin_bodies_note": "左側またはブラウザー下の履歴の先頭に、アクティブなコンポーネントのボディフォルダーと原点を、ブラウザーと同じ表示切り替えとメニュー付きで表示します。下部の履歴は変わりません。",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "コンパクトではパネルをウィンドウの端に固定します。ブラウザーの半透明表示はフローティングで使用できます。アシスタントの配置はアシスタントページで変更します。",
|
||||
"prefs.left": "左",
|
||||
"prefs.left_click": "左クリック",
|
||||
"prefs.line_drag_draws_one": "押してドラッグすると線を 1 本描く",
|
||||
"prefs.line_drag_draws_one_note": "線ツールで押してドラッグし、離すと、押した位置から離した位置まで線を 1 本描いてそこで終わります。クリックでは従来どおり連続した線を描きます。オフ: ドラッグはクリックと同じく、離した位置に点を置きます。",
|
||||
"prefs.linked_designs": "リンクされたデザイン",
|
||||
"prefs.live_input": "現在の入力",
|
||||
"prefs.live_preview": "ライブプレビュー",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "STEP・インポートファイル",
|
||||
"prefs.max_file_size_web": "ウェブ版で開けるのは STEP・インポートファイルが 512 MB、デザインが 256 MB までです。ブラウザーのタブはそれ以上のファイルを保持できません。デスクトップ版では上限を上げられます。",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "大きなアイコン",
|
||||
"prefs.menu_list": "リスト",
|
||||
"prefs.menus": "メニュー",
|
||||
"prefs.minutes": "分",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "マウスとトラックパッド",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "原点平面の名前",
|
||||
"prefs.origin_plane_names_note": "ブラウザー、ダイアログ、一覧に表示される名前です。{top} は XY、{front} は XZ、{right} は YZ です (Z が上)。コマンド、スクリプト、保存されたデザインでは XY、XZ、YZ のままです。",
|
||||
"prefs.overall_speed": "全体の速度",
|
||||
"prefs.parameter_list_rows": "パラメーター一覧の行数",
|
||||
"prefs.parameter_list_rows_tip": "空の値フィールドで下矢印を押すと、お気に入りを先頭にパラメーターをこの数まで一覧表示します。少なくすると大きな設計でも一覧が軽くなります。",
|
||||
"prefs.persistent_ribbon_pressed": "有効なリボンコマンドを強調表示",
|
||||
"prefs.persistent_ribbon_pressed_help": "効果が有効な間、リボンのコマンドを強調表示します。無効にすると、従来の中立的な表示とコマンドのヘルプを保持します。",
|
||||
"prefs.perspective_fov": "画角",
|
||||
"prefs.placement": "配置",
|
||||
"prefs.prefer_free_sketch_points": "スケッチ点が重なったときは移動可能な点を優先する",
|
||||
"prefs.preview_choices": "選択した設定のプレビュー",
|
||||
"prefs.print_face_highlight": "造形面の強調",
|
||||
"prefs.print_face_highlight_tip": "ビューでボディの造形面を色付けし輪郭を描く強さ。0 % で強調しません。",
|
||||
"prefs.profile_active": "使用中のプロファイル",
|
||||
"prefs.profile_applied": "プロファイルを適用しました。",
|
||||
"prefs.profile_changed": "プロファイルの保存後に設定が変更されています。「保存」でプロファイルに反映されます。",
|
||||
"prefs.profile_deleted": "プロファイルを削除しました。",
|
||||
"prefs.profile_export": "エクスポート…",
|
||||
"prefs.profile_exported": "プロファイルをエクスポートしました。",
|
||||
"prefs.profile_imported": "プロファイルをインポートしました。切り替えるには「使用中のプロファイル」で選択してください。",
|
||||
"prefs.profile_name_hint": "プロファイル名(例: ノートPC)",
|
||||
"prefs.profile_rename": "名前を変更",
|
||||
"prefs.profile_renamed": "プロファイルの名前を変更しました。",
|
||||
"prefs.profile_save": "保存",
|
||||
"prefs.profile_saved": "現在の設定をプロファイルに保存しました。",
|
||||
"prefs.profile_skipped": "プロファイルを適用しました。{n} 件の設定は現在の値のままです(ログを参照)。",
|
||||
"prefs.profiles": "設定プロファイル",
|
||||
"prefs.profiles_note": "ショートカット、ツールバー、ナビゲーション、ラジアルメニュー、インターフェース設定を名前を付けてまとめて保存し、一度に切り替えます。",
|
||||
"prefs.project_options_dialog": "Projectのオプションダイアログ",
|
||||
"prefs.project_options_dialog_note": "オン: 投影前に「ジオメトリ」または「ボディ」と「投影リンク」を選択します。オフ: 従来の直接選択方式を使用します。",
|
||||
"prefs.quality_default": "既定",
|
||||
"prefs.quality_fastest": "最速",
|
||||
"prefs.quality_slowest": "最も低速",
|
||||
"prefs.quality_smoother": "より滑らか",
|
||||
"prefs.quick_measure": "ビューの隅にクイック測定",
|
||||
"prefs.quick_measure_note": "選択したものの寸法をビューの右下、履歴の上に表示します: エッジの長さ(円形のものは Ø と R)、面の面積、点の位置、2 つの項目の距離と角度、複数のエッジや面の合計。クリックでコピーします。",
|
||||
"prefs.render_previous_geometry_budget": "レンダープレビューで以前のジオメトリ予算を使用",
|
||||
"prefs.render_previous_geometry_budget_help": "デバイスに基づく予算の代わりに、以前の固定ジオメトリ上限(64ビットデスクトップでは512 MiB、その他では128 MiB)に戻します。",
|
||||
"prefs.reports_saved": "{n} 件保存済み",
|
||||
"prefs.ribbon_reveal": "検索結果をリボンに表示",
|
||||
"prefs.ribbon_reveal_note": "コマンド検索で結果にポインターを合わせると、そのコマンドがリボンのどこにあるか(タブ、ボタン、またはパネルのドロップダウン内の行)を表示します。検索から開始したコマンドはそこで点滅し、ドロップダウンから実行中のコマンドはそのパネルに印が付きます。",
|
||||
"prefs.right_click": "右クリック",
|
||||
"prefs.saving": "自動保存と復元",
|
||||
"prefs.scale_note": "ウィンドウ内では Ctrl + / Ctrl − でも変更できます。100% のボタンは 28 px です。",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "一致する設定がありません",
|
||||
"prefs.select": "選択",
|
||||
"prefs.select_one_item": "項目を 1 つ選択",
|
||||
"prefs.select_other_hidden": "「他を選択」で非表示のジオメトリを選択",
|
||||
"prefs.select_other_hidden_help": "オン: ポインター付近の非表示のボディやスケッチ、遮られたエッジを含めます。オフ: ポインター直下の表示中のジオメトリだけを元のリストに表示します。",
|
||||
"prefs.selecting": "選択",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift は追加のみ、Ctrl / Cmd は選択を切り替え",
|
||||
"prefs.shift_add_note": "オン:Shift は追加、Ctrl / Cmd は選択を切り替えます。オフ(既定):どちらも選択を切り替えます。",
|
||||
"prefs.shortcuts": "ショートカット",
|
||||
"prefs.single_surface_analysis": "サーフェス解析を1つだけ使用",
|
||||
"prefs.single_surface_analysis_help": "オフの場合、サーフェスのシェーディングと連続性解析を同時に有効にできます。オンにすると、最後に開始または変更した解析が残ります。",
|
||||
"prefs.sketch_align_points": "描画中にほかのスケッチ点に揃える",
|
||||
"prefs.sketch_align_points_note": "描画中、点が一つのスケッチ点と水平に、別の点と垂直に同時に揃い、点線のガイドが表示されます。クリックすると両方の整列が保持されます。オフ: 直前の点にのみ、一度に一方向だけ揃えます。",
|
||||
"prefs.sketch_conflict_colour": "競合するジオメトリを競合色で表示",
|
||||
"prefs.sketch_conflict_colour_note": "スケッチの拘束が競合している間、満たされない拘束のグリフや寸法だけでなく、その拘束が保持する曲線と点も競合色で描画します。オフ: 通常の色のままです。",
|
||||
"prefs.sketch_construction_lines": "拡張補助直線ツール",
|
||||
"prefs.sketch_exit_view": "スケッチ終了時のビュー",
|
||||
"prefs.sketch_exit_view.keep": "現在のビューを維持",
|
||||
"prefs.sketch_exit_view.previous": "前のビューに戻る",
|
||||
"prefs.sketch_exit_view.unless_rotated": "回転していなければ戻る",
|
||||
"prefs.sketch_exit_view_note": "「スケッチを終了」、キャンセル、Esc の 2 回押しの後にビューが移る先です。",
|
||||
"prefs.sketch_open_look_at": "スケッチを開いたときに正対させる",
|
||||
"prefs.sketch_open_look_at_note": "オフ: スケッチの作成や編集でビューを動かしません。必要なときは「正面視」でスケッチに正対します。",
|
||||
"prefs.sketch_recent_snap": "最近使った中心と中点へ自動スナップ",
|
||||
"prefs.sketch_recent_snap_note": "作図中、直前の2つの円の中心または直線辺の中点のガイドが交わる位置にカーソルをスナップします。オフ: ガイドは表示のみで、カーソルは移動しません。",
|
||||
"prefs.sketch_selection": "スケッチと選択",
|
||||
"prefs.sketch_selection_heading": "スケッチと選択",
|
||||
"prefs.sketch_selection_note": "スケッチのスナップとクリックによる選択。",
|
||||
@@ -1995,20 +2096,34 @@
|
||||
"prefs.under_cursor": "カーソル下",
|
||||
"prefs.units_precision": "単位と精度",
|
||||
"prefs.updates": "更新",
|
||||
"prefs.value_boxes_in_view": "ビューでハンドルの横に値を表示",
|
||||
"prefs.value_boxes_in_view_tip": "コマンドの値(距離、半径など)をモデル上のハンドルの横のボックスに表示します。オフにすると、値はコマンドウィンドウに入力します。選択後はそのウィンドウにキーボード入力が入り、モデルを覆うものはありません。",
|
||||
"prefs.view": "ビューの動作",
|
||||
"prefs.view_confirm_corner": "ビューの隅に OK とキャンセル",
|
||||
"prefs.view_confirm_corner_note": "ダイアログまたはスケッチを開いている間、ビュー右上のチェックとバツが、ダイアログの OK とキャンセルと同じ操作を行うか、スケッチを終了またはキャンセルします。ビューナビゲーターはその下に移動します。",
|
||||
"prefs.viewport": "ビューポート",
|
||||
"prefs.viewport_analysis_status": "ビューポートの解析状態を表示",
|
||||
"prefs.viewport_analysis_status_help": "有効な解析をビューポートの上部に表示し、各項目から凡例を開きます。Esc で最新の解析を解除します。無効にすると隅の凡例と従来の Esc 動作に戻ります。",
|
||||
"prefs.viewport_background": "背景",
|
||||
"prefs.viewport_background_colour": "色",
|
||||
"prefs.viewport_background_theme": "テーマのグラデーション",
|
||||
"prefs.viewport_section_status": "ビューポートの断面状態を表示",
|
||||
"prefs.viewport_section_status_help": "ビューポートに断面設定を表示します。Escape または有効なリボンボタンで断面を解除します。無効にすると従来の断面操作を維持します。",
|
||||
"prefs.viewport_status_summary": "ビューポートの状態項目をまとめる",
|
||||
"prefs.viewport_status_summary_help": "3 個以上の状態項目を 1 つのサマリーバッジにまとめます。無効にすると、すべての項目を従来の行に表示します。",
|
||||
"prefs.wheel": "ホイール",
|
||||
"prefs.wheel_trackpad": "ホイールとトラックパッド",
|
||||
"prefs.workspace": "ワークスペース",
|
||||
"prefs.zoom_stop_at_model": "モデルでズームを止める",
|
||||
"prefs.zoom_stop_at_model_tip": "3Dマウスとデバイスアプリはビュー中央の表面に向かってズームします。ドラッグズームはドラッグ開始点を固定します。オフの場合はモデルを通り抜けられます。ホイールとピンチは別の「カーソルへズーム」設定を使います",
|
||||
"prefs.zoom_toward_cursor": "カーソルに向かってズーム",
|
||||
"properties.title": "プロパティ: {name}",
|
||||
"recovery.days_ago": "{count}日前",
|
||||
"recovery.detail": "{file} · {features}フィーチャー · 自動保存: {when}",
|
||||
"recovery.discard_all": "すべて破棄",
|
||||
"recovery.discard_all_detail": "この操作は元に戻せません。",
|
||||
"recovery.discard_all_title": "{count} 件の自動保存を破棄しますか?",
|
||||
"recovery.discard_all_title_one": "1 件の自動保存を破棄しますか?",
|
||||
"recovery.hours_ago": "{count}時間前",
|
||||
"recovery.just_now": "たった今",
|
||||
"recovery.min_ago": "{count}分前",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "レンダーの準備完了",
|
||||
"render.output_run_check": "チェックを実行",
|
||||
"render.output_size_limit": "{method}:各辺 {dimension} px、合計 {pixels} ピクセルまで。対応する最大サイズ:{width} × {height}。",
|
||||
"render.output_size_method_profile": "{width} × {height} をレンダリングするには、{method} と CPUリソースプロファイル「{profile}」を選ぶか、より小さいサイズを選んでください。",
|
||||
"render.output_size_ok": "サイズOK · {width} × {height} px",
|
||||
"render.output_size_profile": "{width} × {height} をレンダリングするには、CPUリソースプロファイル「{profile}」を選ぶか、より小さいサイズを選んでください。",
|
||||
"render.output_swap_orientation": "幅と高さを交換",
|
||||
"render.output_tools_inspector": "サイズと形式は出力インスペクターで編集してください。",
|
||||
"render.output_view_image": "画像を表示",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "カスタム…",
|
||||
"render.size_full_hd": "フルHD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size}・「{profile}」が必要",
|
||||
"render.size_presets": "サイズプリセット",
|
||||
"render.size_presets_pending": "出力エディターとともに追加予定",
|
||||
"render.size_preview": "プレビュー",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "コンポーネントをダブルクリックしてアクティブにする、またはリンクされたものをその場で編集する",
|
||||
"settings.frame_rate_details_note": "直近のフレーム時間のグラフ(描画した三角形数を重ねて表示)、フレーム時間のヒストグラム、GPU が描画した内容を追加します。ビューのフレームレートをクリックすると表示/非表示を切り替えます。",
|
||||
"settings.frame_rate_note": "ビューの右下に 1 秒あたりのフレーム数を表示します。",
|
||||
"settings.insert_lists_open_designs": "デザインを挿入で、ほかのタブで開いているデザインを先に表示する",
|
||||
"settings.measure_axis_distances": "計測のX・Y・Z距離を表示",
|
||||
"settings.measure_axis_distances_help": "計測ダイアログを開いている間、2点間距離に加えてワールドX・Y・Z軸方向の寸法線と距離を表示します。",
|
||||
"settings.msaa_applies_on_restart": "アンチエイリアスは次回 SolidCraft を起動したときに適用されます",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "輪郭",
|
||||
"sheet.flange_type_edge": "エッジ",
|
||||
"sheet.no_body": "板金ボディがありません。フランジ > Base で作成するか、板金に変換でプレートを板金に変換してください(広い平面を選択)。",
|
||||
"sheet.personal_rules.confirm_delete": "削除を確認",
|
||||
"sheet.personal_rules.delete": "削除",
|
||||
"sheet.personal_rules.delete_prompt": "この個人用ルールを削除しますか?デザインに既にあるルールは変更されません。",
|
||||
"sheet.personal_rules.full": "個人用ライブラリには既に64個のルールがあります。",
|
||||
"sheet.personal_rules.invalid_name": "改行や制御文字を含まない短い名前を入力してください。",
|
||||
"sheet.personal_rules.invalid_values": "ルールの値をすべて入力してください。各値はこのデザインで計算でき、板厚は正の値、K係数は0〜1である必要があります。",
|
||||
"sheet.personal_rules.missing": "選択した個人用ルールは利用できなくなりました。",
|
||||
"sheet.personal_rules.name": "ルール名",
|
||||
"sheet.personal_rules.name_exists": "同じ名前の個人用ルールが既にあります。別の名前を指定してください。",
|
||||
"sheet.personal_rules.name_hint": "一意の名前",
|
||||
"sheet.personal_rules.overwrite": "選択した個人用ルールの変更を保存",
|
||||
"sheet.personal_rules.rename": "名前を変更",
|
||||
"sheet.personal_rules.rule": "個人用ルール",
|
||||
"sheet.personal_rules.save": "新規保存",
|
||||
"sheet.personal_rules.scope": "すべてのデザインで使えるようにプロファイルに保存します。",
|
||||
"sheet.personal_rules.select": "ルールを選択",
|
||||
"sheet.personal_rules.title": "個人用ルール",
|
||||
"sheet.personal_rules.unsupported": "このルールには、このバージョンで使用できない値が含まれています。",
|
||||
"shortcut.json_error": "パラメータはJSON形式で指定してください: {error}",
|
||||
"shortcut.no_command": "コマンド`{id}`がありません。JSONの前のテキストはコマンドIDである必要があります",
|
||||
"shortcut.pin": "Sボックスの先頭にピン留め",
|
||||
"shortcut.unpin": "ピン留めを解除",
|
||||
"sketch is missing": "スケッチが見つかりません",
|
||||
"sketch.degrees_of_freedom": "自由度 {count}",
|
||||
"sketch.dimension_added_driven": "スケッチがすでにその寸法を決めているため、従動寸法(参照寸法)として追加しました",
|
||||
"sketch.dimension_applied": "寸法を適用しました",
|
||||
"sketch.dimension_applied_defined": "寸法を適用しました。パラメータ `{name}` を定義しました",
|
||||
"sketch.dimension_applied_renamed": "寸法を適用しました。パラメータ名を `{name}` にしました",
|
||||
"sketch.dof_left": "残り自由度 {count}",
|
||||
"sketch.dof_left_one": "残り自由度 {count}",
|
||||
"sketch.draw_curves": "{linetype}として描く",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "右",
|
||||
"sketch_text.bold": "太字",
|
||||
"sketch_text.builtin_font": "{family}(内蔵)",
|
||||
"sketch_text.formula": "= で始めるとパラメーターから文字列を組み立てられます: ='W' + number(Width)",
|
||||
"sketch_text.italic": "斜体",
|
||||
"sketch_text.loading_fonts": "インストール済みフォントを検索中…",
|
||||
"sketch_text.on_path": "文字はパスに沿います: 位置は曲線で決まります",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "フィーチャーと入れ子のフォルダーを履歴に残します",
|
||||
"timeline.delete_folders_with_features_tip": "フォルダーを、中のすべてのフィーチャーと入れ子のフォルダーごと削除します",
|
||||
"timeline.delete_many": "選択した {count} 個のフィーチャーを削除",
|
||||
"timeline.edited_rolled_back": "{name} を変更しましたが、履歴マーカーより後ろにあるため構築されません。結果を見るにはマーカーをその先へ移動してください",
|
||||
"timeline.feature_error": "エラー: {message}",
|
||||
"timeline.feature_hint": "ダブルクリックで編集 · ドラッグで並べ替え · 右クリックでその他の操作",
|
||||
"timeline.feature_rolled_back": "ロールバック中: 履歴マーカーより後ろのため構築されません",
|
||||
"timeline.feature_warning": "警告: {message}",
|
||||
"timeline.group": "フィーチャーフォルダを新規作成",
|
||||
"timeline.move_many": "タイムライン項目を移動",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "3Dマウスをキャリブレーションすると、入れ替わった軸や反転した軸が直り、速度と操作感も整います。",
|
||||
"ui.3d_mouse_offer_never": "今後表示しない",
|
||||
"ui.3d_mouse_offer_swap": "Hidraw(直接ドライバー)に切り替える",
|
||||
"ui.3d_mouse_orbit": "回転",
|
||||
"ui.3d_mouse_orbit_classic": "クラシック",
|
||||
"ui.3d_mouse_orbit_tip": "トレース:3Dマウスで回転を始めたときにビューの中央にあるモデルの部分を中心にビューを回転し、その点を淡い球で示します。クラシック:ビューの中心を基準に回転します。",
|
||||
"ui.3d_mouse_orbit_traced": "トレース",
|
||||
"ui.3d_mouse_reading": "読み取り値",
|
||||
"ui.3d_mouse_reset_axes": "軸の割り当てをリセット",
|
||||
"ui.3d_mouse_reset_view": "表示をリセット",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "3Dマウス",
|
||||
"ui.3d_mouse_show_in_view": "3Dビューに3Dマウスを表示",
|
||||
"ui.3d_mouse_show_in_view_tip": "左下に3Dマウスの絵を表示し、操作に合わせて動かします。",
|
||||
"ui.3d_mouse_sketch_orbit": "3D マウスでスケッチを回転",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "スケッチを開いて正面から見ているときも、マウスと同じように 3D マウスでビューを回転します。オフ: ビューを傾けるまで、スケッチのパンとズームのみ行います。",
|
||||
"ui.3d_mouse_skip": "このデバイスではできません",
|
||||
"ui.3d_mouse_skip_tip": "この動きを両方向とも飛ばし、キャリブレーションから外します。",
|
||||
"ui.3d_mouse_speed": "3D マウス速度",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "キャップを反時計回りにひねって保持し、離してください。",
|
||||
"ui.3d_mouse_switch_cap": "センターに戻るタイプとしてキャリブレーション",
|
||||
"ui.3d_mouse_switch_trackball": "トラックボールとしてキャリブレーション",
|
||||
"ui.3d_mouse_use_direct": "直接ドライバーを使用",
|
||||
"ui.3d_mouse_use_direct_tip": "spacenavd を経由せず、3Dマウスを直接 (hidraw) 読み取ります。",
|
||||
"ui.3d_mouse_view_axis": "ビューの軸",
|
||||
"ui.3d_mouse_view_off": "オフ",
|
||||
"ui.3d_mouse_view_off_tip": "3D マウスのドライバーのプロファイルがこの軸をオフにしているため、この軸の動きではビューは動きません。ここで他の軸の動きを選ぶと 2 つが入れ替わり、その動きではビューが動かなくなります。",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "待機から削除",
|
||||
"ui.agent_chat_remove_file": "このメッセージから外す",
|
||||
"ui.agent_chat_remove_imported": "このメッセージから外します。パーツはデザインに残ります (元に戻すで削除できます)",
|
||||
"ui.agent_chat_reply_cut_off": "応答が終わる前に長さの上限に達したため、不完全な可能性があります。続けるか、もっと短く答えるようエージェントに頼んでください。",
|
||||
"ui.agent_chat_reply_declined": "モデルはこのメッセージへの回答を断りました。",
|
||||
"ui.agent_chat_retry": "再試行",
|
||||
"ui.agent_chat_right": "右",
|
||||
"ui.agent_chat_save": "保存",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "円",
|
||||
"ui.circular_pattern": "円形パターン",
|
||||
"ui.clear": "クリア",
|
||||
"ui.clear_print_face": "造形面を解除",
|
||||
"ui.clear_recent": "最近使った項目をクリア",
|
||||
"ui.clear_the_selection": "選択をクリア",
|
||||
"ui.click_selects_whole_bodies": "クリックでボディ全体を選択",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "一定",
|
||||
"ui.constraints_conflict": "拘束が競合しています",
|
||||
"ui.construction": "コンストラクション",
|
||||
"ui.construction.angle_hint": "補助直線: 点をクリックし、角度を入力するか方向を選択",
|
||||
"ui.construction.bisector_hint": "二等分線: 交差する2直線を選び、必要な解を選択",
|
||||
"ui.construction.common_hint": "共通接線: 2つの円/円弧を選び、必要な解を選択",
|
||||
"ui.construction.contact_hint": "接線: 円/円弧または開いたスプライン/円錐曲線を選び、接点を選択 (自由曲線は端点のみ)",
|
||||
"ui.construction.external_hint": "接線: 円または円弧、外部点、必要な解の順に選択",
|
||||
"ui.construction.free_hint": "補助直線: 2点をクリック。右クリックで最初から",
|
||||
"ui.construction.point_hint": "補助直線: 通過点をクリック",
|
||||
"ui.construction.reference_hint": "補助直線: 直線、点の順に選択。右クリックで参照を変更",
|
||||
"ui.construction.ribbon_label": "補助線",
|
||||
"ui.context_menu": "コンテキスト メニュー",
|
||||
"ui.continuity_g0": "G0 折れ",
|
||||
"ui.continuity_g1": "G1 接線",
|
||||
@@ -4008,6 +4172,14 @@
|
||||
"ui.end_scale": "終端スケール",
|
||||
"ui.entities": "エンティティ",
|
||||
"ui.equal": "等しい",
|
||||
"ui.equation_end": "終了",
|
||||
"ui.equation_explicit": "陽関数",
|
||||
"ui.equation_form": "形式",
|
||||
"ui.equation_note": "変数は単位のない数値です。sin(t) はラジアンとして扱います。単位のない結果はデザインの単位になります。",
|
||||
"ui.equation_parametric": "パラメトリック",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "等価半径",
|
||||
"ui.expand": "展開",
|
||||
"ui.exportDxf": "DXF をエクスポート…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "デザイン",
|
||||
"ui.heading_draft": "勾配",
|
||||
"ui.heading_edit": "編集",
|
||||
"ui.heading_equation_curve": "方程式曲線",
|
||||
"ui.heading_extrude": "押し出し",
|
||||
"ui.heading_fillet": "フィレット",
|
||||
"ui.heading_finish_editing": "編集を終了",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "インポート…",
|
||||
"ui.infinite": "無限",
|
||||
"ui.insert": "挿入",
|
||||
"ui.insert_design.browse": "参照…",
|
||||
"ui.insert_design.open_designs": "開いているデザイン",
|
||||
"ui.insert_design.saved_file": "{name} に保存されていない変更があるため、保存済みのファイルを挿入しました。保存してから、リンクを更新で変更を取り込んでください。",
|
||||
"ui.insert_design.unsaved": "未保存の変更",
|
||||
"ui.inspect": "検査",
|
||||
"ui.intersect": "交差",
|
||||
"ui.isolate": "分離表示",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "{count} 個のフォルダを読めませんでした。",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "点",
|
||||
"ui.point_cloud_add_filter": "フィルターを追加…",
|
||||
"ui.point_cloud_auto_range": "範囲を自動設定",
|
||||
"ui.point_cloud_color_by": "色の付け方",
|
||||
"ui.point_cloud_file_colors": "ファイルの色",
|
||||
"ui.point_cloud_filter_by": "フィルター",
|
||||
"ui.point_cloud_height_high": "最高の高さ",
|
||||
"ui.point_cloud_height_low": "最低の高さ",
|
||||
"ui.point_cloud_legend_filter": "上の凡例で表示・非表示を切り替え",
|
||||
"ui.point_cloud_no_file_colors": "ファイルに色情報がありません",
|
||||
"ui.point_cloud_pause": "一時停止",
|
||||
"ui.point_cloud_play": "再生",
|
||||
"ui.point_cloud_single_color": "単色",
|
||||
"ui.point_cloud_size": "点のサイズ",
|
||||
"ui.point_cloud_units": "ファイルの単位",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "ポリゴン",
|
||||
"ui.preferences": "環境設定",
|
||||
"ui.press_a_key": "キーを押してください…",
|
||||
"ui.print_face_cleared": "{body}: 造形面を解除しました",
|
||||
"ui.print_face_input": "造形面",
|
||||
"ui.print_face_one_body": "造形面はボディごとに選びます。変更するにはそのボディだけを送信してください",
|
||||
"ui.print_face_pick": "ソリッドボディの平面を1つ選択すると造形面になります",
|
||||
"ui.print_face_set": "{body}: 造形面を設定しました。スライサーへ送るとこの面を下にして置きます",
|
||||
"ui.profile": "プロファイル",
|
||||
"ui.profile_plane": "プロファイル平面",
|
||||
"ui.profiles": "プロファイル",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "回転",
|
||||
"ui.ribbon_exit": "終了",
|
||||
"ui.ribbon_labels": "リボンのアイコンの下にテキストを表示",
|
||||
"ui.ribbon_menus_skip_pinned": "ピン留めしたコマンドをドロップダウンメニューに表示しない",
|
||||
"ui.ribbon_pin_footer": "ピン留めしたコマンドはリボンに表示されます。行にポインターを合わせて、ピン留めや解除ができます。",
|
||||
"ui.ribbon_workspace": "ワークスペース",
|
||||
"ui.right": "右側面",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "選択",
|
||||
"ui.selectOther": "その他を選択…",
|
||||
"ui.selectTangentChain": "接線チェーンを選択",
|
||||
"ui.select_all": "すべて選択",
|
||||
"ui.select_components_by_face": "コンポーネントを選択(面をクリックするとそのコンポーネントが選択されます)",
|
||||
"ui.selection": "選択",
|
||||
"ui.selection_modifiers": "選択修飾キー",
|
||||
"ui.selection_shift_add_only": "Shift+クリックで追加のみ(解除なし)",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "選択フィルター",
|
||||
"ui.sketch_modifiers": "スケッチ修飾キー",
|
||||
"ui.sketch_project_geometry": "ジオメトリ",
|
||||
"ui.sketch_report.all_constrained": "すべて完全に拘束されています。",
|
||||
"ui.sketch_report.dof": "自由度",
|
||||
"ui.sketch_report.loose": "完全には拘束されていません",
|
||||
"ui.sketch_report.status": "状態",
|
||||
"ui.sketch_report.title": "スケッチ レポート",
|
||||
"ui.sketch_scale": "スケッチ尺度",
|
||||
"ui.sketches": "スケッチ",
|
||||
"ui.slice": "スライス",
|
||||
@@ -4532,10 +4727,19 @@
|
||||
"ui.view_centre": "ビュー中心",
|
||||
"ui.viewport_status_clear": "{name}をオフにする",
|
||||
"ui.viewport_status_clear_hint": "{name}をオフにする · Esc",
|
||||
"ui.viewport_status_edges": "{count} エッジ",
|
||||
"ui.viewport_status_from": "方向 {direction}",
|
||||
"ui.viewport_status_key": "{name}の凡例を表示",
|
||||
"ui.viewport_status_minimum_radius": "最小半径",
|
||||
"ui.viewport_status_pairs": "{count} 組",
|
||||
"ui.viewport_status_section_hatch": "{setting} · ハッチング",
|
||||
"ui.viewport_status_section_plane": "現在の平面",
|
||||
"ui.viewport_status_section_tilted": "傾斜 · {offset}",
|
||||
"ui.viewport_status_stripes": "縞 {count} 本",
|
||||
"ui.viewport_status_summary_clear": "すべて解除",
|
||||
"ui.viewport_status_summary_heading": "このビュー内",
|
||||
"ui.viewport_status_summary_label": "{name} と他 {count} 項目",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "テーマに従う",
|
||||
"ui.visual_shaded_hidden_edges": "隠線付きシェーディング",
|
||||
"ui.visual_shaded_with_edges": "エッジ付きシェーディング",
|
||||
@@ -4572,7 +4776,9 @@
|
||||
"update.button": "アップデート",
|
||||
"update.button_version": "{version} にアップデート",
|
||||
"update.check_automatically": "アップデートを自動的に確認",
|
||||
"update.check_for_updates": "アップデートを確認",
|
||||
"update.check_now": "今すぐ確認",
|
||||
"update.check_unavailable": "このインストールではアップデートを確認できません。",
|
||||
"update.checking": "確認中…",
|
||||
"update.copy": "コピー",
|
||||
"update.dmg_opened": "ディスクイメージを検証して開きました: SolidCraft をアプリケーションフォルダにドラッグして古いものを置き換え、SolidCraft を再起動してください。",
|
||||
|
||||
@@ -711,11 +711,13 @@
|
||||
"cmd.appearance_pick_up": "모양 가져오기",
|
||||
"cmd.appearance_replace": "모양 바꾸기",
|
||||
"cmd.assembly_bom": "자재 명세서",
|
||||
"cmd.body.print_face": "출력 바닥면",
|
||||
"cmd.body_rename": "바디 이름 변경",
|
||||
"cmd.browser_group": "새 그룹",
|
||||
"cmd.browser_move": "브라우저 항목 이동",
|
||||
"cmd.browser_order": "브라우저 항목 정렬",
|
||||
"cmd.browser_rename_group": "그룹 이름 변경",
|
||||
"cmd.browser_reparent": "구성 요소로 이동",
|
||||
"cmd.browser_ungroup": "그룹 해제",
|
||||
"cmd.browser_visibility": "표시/숨기기",
|
||||
"cmd.canvas_calibrate": "캔버스 보정",
|
||||
@@ -738,6 +740,7 @@
|
||||
"cmd.component_metadata": "부품 속성",
|
||||
"cmd.component_metadata_set": "부품 속성 변경",
|
||||
"cmd.component_move_bodies": "바디를 구성 요소로 이동",
|
||||
"cmd.component_move_features": "특성을 구성 요소로 이동",
|
||||
"cmd.component_move_sketches": "스케치를 구성 요소로 이동",
|
||||
"cmd.component_paste_new": "새로 붙여넣기",
|
||||
"cmd.component_properties": "구성 요소 물리 속성",
|
||||
@@ -956,6 +959,16 @@
|
||||
"cmd.sheet_refold": "다시 접기",
|
||||
"cmd.sheet_rules": "판금 규칙 목록",
|
||||
"cmd.sheet_unfold": "펼치기",
|
||||
"cmd.sketch.construction_line": "보조 직선",
|
||||
"cmd.sketch.construction_line.angle": "각도 지정 보조 직선",
|
||||
"cmd.sketch.construction_line.bisector": "각의 이등분선",
|
||||
"cmd.sketch.construction_line.horizontal": "수평 보조 직선",
|
||||
"cmd.sketch.construction_line.parallel": "평행 보조 직선",
|
||||
"cmd.sketch.construction_line.perpendicular": "직교 보조 직선",
|
||||
"cmd.sketch.construction_line.tangent_at": "곡선 위 점에서의 접선",
|
||||
"cmd.sketch.construction_line.tangent_external": "외부 점을 지나는 접선",
|
||||
"cmd.sketch.construction_line.tangent_two": "공통 접선",
|
||||
"cmd.sketch.construction_line.vertical": "수직 보조 직선",
|
||||
"cmd.sketch_arc_center_point": "중심점 호",
|
||||
"cmd.sketch_arc_tangent": "접선 호",
|
||||
"cmd.sketch_arc_three_point": "3점 호",
|
||||
@@ -985,6 +998,8 @@
|
||||
"cmd.sketch_draw_dimensioned": "치수가 있는 스케치 개체 그리기",
|
||||
"cmd.sketch_edit": "스케치 편집",
|
||||
"cmd.sketch_edit_text": "텍스트 편집",
|
||||
"cmd.sketch_equation_curve": "방정식 곡선",
|
||||
"cmd.sketch_equation_curve_edit": "방정식 곡선 편집",
|
||||
"cmd.sketch_export_dxf": "DXF로 저장",
|
||||
"cmd.sketch_finish_auto_constrain": "자동 구속으로 완료",
|
||||
"cmd.sketch_fit_curves_to_section": "메시 단면에 곡선 맞추기",
|
||||
@@ -1079,6 +1094,7 @@
|
||||
"cmd.view.render_browser": "렌더 브라우저",
|
||||
"cmd.view.render_dock": "렌더 도크 이동",
|
||||
"cmd.view.render_focus": "렌더 집중 보기",
|
||||
"cmd.view.status_items": "뷰포트 상태 항목",
|
||||
"cmd.view_ambient_occlusion": "앰비언트 오클루전",
|
||||
"cmd.view_angle_readout": "뷰 각도",
|
||||
"cmd.view_apply": "이름 있는 보기 복원",
|
||||
@@ -1194,6 +1210,17 @@
|
||||
"help.mit": "MIT 라이선스",
|
||||
"help.notice": "NOTICE",
|
||||
"help.pointcloud.insert": "PLY, XYZ 또는 PTS 스캔을 모델 옆에 포인트 클라우드로 삽입합니다. 측정 데이터를 참고하여 모델링할 때 사용합니다.",
|
||||
"help.sketch.construction_line": "두 점을 지나는 무한 보조 직선을 만듭니다. 스케치 프로파일을 나누지 않고 작도할 수 있습니다.",
|
||||
"help.sketch.construction_line.angle": "스케치 X축을 기준으로 지정한 각도의 무한 보조 직선을 만듭니다. 점을 선택한 뒤 각도를 입력하거나 방향을 선택합니다.",
|
||||
"help.sketch.construction_line.bisector": "교차하는 두 스케치 직선을 선택한 뒤 두 각의 이등분선 중 하나를 선택합니다. 결과는 원본 직선의 편집을 따릅니다.",
|
||||
"help.sketch.construction_line.horizontal": "한 점을 지나는 무한 수평 보조 직선을 만듭니다. 나중에 편집해도 수평 구속이 유지됩니다.",
|
||||
"help.sketch.construction_line.parallel": "스케치 직선을 선택한 뒤 평행한 무한 보조 직선을 배치합니다. 다른 참조를 선택하려면 마우스 오른쪽 버튼을 클릭합니다.",
|
||||
"help.sketch.construction_line.perpendicular": "스케치 직선을 선택한 뒤 직교하는 무한 보조 직선을 배치합니다. 다른 참조를 선택하려면 마우스 오른쪽 버튼을 클릭합니다.",
|
||||
"help.sketch.construction_line.tangent_at": "원이나 원호 위의 점, 또는 열린 스플라인이나 원뿔 곡선의 끝점에 접선을 만듭니다. 곡선을 선택한 뒤 접점을 선택합니다.",
|
||||
"help.sketch.construction_line.tangent_external": "원 또는 원호, 외부 점, 접선 해를 차례로 선택합니다. 미리보기에는 그려진 원호 위의 접점만 표시됩니다.",
|
||||
"help.sketch.construction_line.tangent_two": "두 원 또는 원호를 선택한 뒤 미리보기에서 공통 접선을 선택합니다. 접점은 그려진 곡선 위에 있어야 합니다.",
|
||||
"help.sketch.construction_line.vertical": "한 점을 지나는 무한 수직 보조 직선을 만듭니다. 나중에 편집해도 수직 구속이 유지됩니다.",
|
||||
"help.sketch.equation_curve": "범위에 걸쳐 수식으로 곡선을 그립니다: x(t)와 y(t), 또는 y = f(x). 수식에 매개변수를 쓸 수 있으며 곡선이 그 값을 따라갑니다. 사인파, 나선, 기어 이의 인벌류트에 사용합니다.",
|
||||
"help.solid.chamfer": "선택한 모서리를 지정한 거리만큼 평평하게 깎습니다. 날카로운 모서리를 다듬거나 핀 또는 나사가 쉽게 들어가도록 할 때 사용합니다.",
|
||||
"help.solid.extrude": "스케치 프로파일을 지정한 거리만큼 3D로 밀어내 재료를 더하거나 제거합니다. 평면 윤곽을 블록, 보스 또는 포켓으로 만들 때 사용합니다.",
|
||||
"help.solid.fillet": "선택한 모서리를 지정한 반지름의 매끄러운 원호로 둥글게 만듭니다. 강도, 편의성 또는 외관을 위해 날카로운 모서리를 부드럽게 할 때 사용합니다.",
|
||||
@@ -1499,6 +1526,8 @@
|
||||
"prefs.bottom_centre": "하단 가운데",
|
||||
"prefs.bottom_right": "오른쪽 아래",
|
||||
"prefs.browser": "브라우저",
|
||||
"prefs.browser_eye_left": "표시 아이콘을 접기 화살표 옆에 표시",
|
||||
"prefs.browser_eye_left_note": "브라우저 행의 표시 아이콘을 행 오른쪽 끝의 열이 아니라 이전처럼 접기 화살표 옆에 표시합니다.",
|
||||
"prefs.built_in": "기본 제공",
|
||||
"prefs.button_left": "왼쪽 드래그",
|
||||
"prefs.button_middle": "가운데 드래그",
|
||||
@@ -1542,6 +1571,8 @@
|
||||
"prefs.graphics": "그래픽",
|
||||
"prefs.graphics_note": "속도와 부드러움 중에서 선택합니다. 각 선택의 효과가 샘플에 표시됩니다.",
|
||||
"prefs.graphics_presets_note": "프리셋은 아래의 선택 항목을 한 번에 설정합니다.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "축소 시 구속 조건 기호 숨기기",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "스케치를 충분히 축소하면 구속 조건 기호가 가려지지 않도록 숨깁니다. 끄기: 확대/축소와 관계없이 고정된 화면 크기를 유지합니다.",
|
||||
"prefs.history": "이력",
|
||||
"prefs.history_origin_bodies": "원점과 바디를 맨 위에 표시",
|
||||
"prefs.history_origin_bodies_note": "왼쪽 또는 브라우저 아래의 히스토리가 활성 구성 요소의 바디 폴더와 원점으로 시작하며, 브라우저처럼 표시 아이콘과 메뉴가 있습니다. 아래쪽 히스토리는 바뀌지 않습니다.",
|
||||
@@ -1560,6 +1591,8 @@
|
||||
"prefs.layout_note": "컴팩트는 패널을 창 가장자리에 고정합니다. 브라우저 반투명은 플로팅에서 사용할 수 있습니다. 어시스턴트 위치는 어시스턴트 페이지에서 바꿀 수 있습니다.",
|
||||
"prefs.left": "왼쪽",
|
||||
"prefs.left_click": "왼쪽 클릭",
|
||||
"prefs.line_drag_draws_one": "누른 채 드래그하면 선 하나 그리기",
|
||||
"prefs.line_drag_draws_one_note": "선 도구에서 누르고 드래그한 뒤 놓으면 누른 곳에서 놓은 곳까지 선 하나를 그리고 거기서 끝납니다. 클릭하면 이전처럼 이어지는 선을 그립니다. 끄면: 드래그는 클릭처럼 놓은 곳에 점을 둡니다.",
|
||||
"prefs.live_input": "실시간 입력",
|
||||
"prefs.live_preview": "실시간 미리보기",
|
||||
"prefs.max_file_size": "열 수 있는 최대 파일 크기",
|
||||
@@ -1584,7 +1617,12 @@
|
||||
"prefs.origin_plane_names": "원점 평면 이름",
|
||||
"prefs.origin_plane_names_note": "브라우저, 대화 상자, 목록에 표시되는 이름입니다. {top}은 XY, {front}는 XZ, {right}는 YZ이며 Z가 위쪽입니다. 명령, 스크립트, 저장된 디자인은 XY, XZ, YZ를 유지합니다.",
|
||||
"prefs.overall_speed": "전체 속도",
|
||||
"prefs.persistent_ribbon_pressed": "활성 리본 명령 강조 표시",
|
||||
"prefs.persistent_ribbon_pressed_help": "효과가 켜져 있는 동안 리본 명령을 강조 표시합니다. 끄면 이전의 중립적인 모양과 명령 도움말을 유지합니다.",
|
||||
"prefs.perspective_fov": "시야각",
|
||||
"prefs.preview_choices": "선택 항목 미리보기",
|
||||
"prefs.print_face_highlight": "출력 바닥면 강조",
|
||||
"prefs.print_face_highlight_tip": "뷰에서 바디의 출력 바닥면을 색칠하고 윤곽을 그리는 강도입니다. 0 %이면 강조하지 않습니다.",
|
||||
"prefs.project_options_dialog": "Project 옵션 대화상자",
|
||||
"prefs.project_options_dialog_note": "켜기: 투영 전에 지오메트리 또는 바디와 투영 링크를 선택합니다. 끄기: 기존 직접 선택 작업 흐름을 유지합니다.",
|
||||
"prefs.quality_default": "기본값",
|
||||
@@ -1600,13 +1638,24 @@
|
||||
"prefs.search_empty": "일치하는 설정이 없습니다",
|
||||
"prefs.select": "선택",
|
||||
"prefs.select_one_item": "항목 하나 선택",
|
||||
"prefs.select_other_hidden": "다른 항목 선택으로 숨겨진 형상 선택",
|
||||
"prefs.select_other_hidden_help": "켜짐: 포인터 근처의 숨겨진 바디, 스케치 및 가려진 모서리를 포함합니다. 꺼짐: 포인터 바로 아래에 보이는 형상만 포함하는 기존 목록을 사용합니다.",
|
||||
"prefs.selecting": "선택",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift는 추가만, Ctrl / Cmd는 토글",
|
||||
"prefs.shift_add_note": "켬: Shift는 추가, Ctrl / Cmd는 토글. 끔(기본값): 둘 다 토글.",
|
||||
"prefs.shortcuts": "단축키",
|
||||
"prefs.single_surface_analysis": "표면 분석 하나만 사용",
|
||||
"prefs.single_surface_analysis_help": "끄면 표면 음영 분석과 연속성 분석을 함께 유지할 수 있습니다. 켜면 마지막으로 시작하거나 변경한 분석만 유지됩니다.",
|
||||
"prefs.sketch_align_points": "그리는 동안 다른 스케치 점에 맞추기",
|
||||
"prefs.sketch_align_points_note": "그리는 동안 점이 한 스케치 점과 수평으로, 다른 점과 수직으로 동시에 맞춰지고 점선 안내선이 표시됩니다. 클릭하면 두 정렬이 모두 유지됩니다. 끄기: 이전 점에만, 한 번에 한 축씩 맞춥니다.",
|
||||
"prefs.sketch_conflict_colour": "충돌하는 기하를 충돌 색상으로 표시",
|
||||
"prefs.sketch_conflict_colour_note": "스케치의 구속 조건이 충돌하는 동안 실패한 구속 조건의 글리프나 치수뿐 아니라 그 구속 조건이 잡고 있는 곡선과 점도 충돌 색상으로 그립니다. 끄기: 평소 색상을 유지합니다.",
|
||||
"prefs.sketch_construction_lines": "확장 보조 직선 도구",
|
||||
"prefs.sketch_open_look_at": "스케치를 열 때 정면으로 돌리기",
|
||||
"prefs.sketch_open_look_at_note": "끄기: 스케치를 만들거나 편집해도 뷰가 그대로입니다. 필요할 때 '바라보기'로 스케치를 정면으로 봅니다.",
|
||||
"prefs.sketch_recent_snap": "최근 중심과 중점에 자동 스냅",
|
||||
"prefs.sketch_recent_snap_note": "그리는 동안 최근에 사용한 두 원의 중심 또는 직선 모서리 중점의 안내선이 만나는 위치로 커서를 스냅합니다. 끄기: 안내선은 보기만 하고 커서는 움직이지 않습니다.",
|
||||
"prefs.sketch_selection": "스케치 및 선택",
|
||||
"prefs.sketch_selection_heading": "스케치 및 선택",
|
||||
"prefs.sketch_selection_note": "스케치가 스냅되는 방식과 클릭으로 선택하는 방식입니다.",
|
||||
@@ -1655,17 +1704,31 @@
|
||||
"prefs.under_cursor": "커서 아래",
|
||||
"prefs.units_precision": "단위 및 정밀도",
|
||||
"prefs.updates": "업데이트",
|
||||
"prefs.value_boxes_in_view": "뷰에서 핸들 옆에 값 표시",
|
||||
"prefs.value_boxes_in_view_tip": "명령의 값(거리, 반경 등)을 모델 위 핸들 옆 상자에 표시합니다. 끄면 값은 명령 창에 입력하며, 선택 후 키보드 입력이 그 창으로 가고 모델을 가리는 것이 없습니다.",
|
||||
"prefs.view": "뷰 동작",
|
||||
"prefs.view_confirm_corner": "뷰 모서리에 확인 및 취소",
|
||||
"prefs.view_confirm_corner_note": "대화 상자나 스케치가 열려 있는 동안 뷰 오른쪽 위의 체크와 X 표시가 대화 상자의 확인과 취소와 같은 동작을 하거나 스케치를 마치고 취소합니다. 뷰 탐색기는 그 아래로 내려갑니다.",
|
||||
"prefs.viewport": "뷰포트",
|
||||
"prefs.viewport_analysis_status": "뷰포트 해석 상태 표시",
|
||||
"prefs.viewport_analysis_status_help": "활성 해석을 뷰포트 위에 표시하고 각 항목에서 범례를 엽니다. Esc로 최신 해석을 끕니다. 끄면 모서리 범례와 이전 Esc 동작으로 돌아갑니다.",
|
||||
"prefs.viewport_section_status": "뷰포트 단면 상태 표시",
|
||||
"prefs.viewport_section_status_help": "뷰포트에 단면 설정을 표시합니다. Escape 키와 활성 리본 버튼으로 단면을 끕니다. 비활성화하면 이전 단면 조작을 유지합니다.",
|
||||
"prefs.viewport_status_summary": "뷰포트 상태 항목 요약",
|
||||
"prefs.viewport_status_summary_help": "상태 항목이 3개 이상이면 하나의 요약 배지로 표시합니다. 비활성화하면 모든 항목을 기존 행에 표시합니다.",
|
||||
"prefs.wheel": "휠",
|
||||
"prefs.wheel_trackpad": "휠 및 트랙패드",
|
||||
"prefs.workspace": "작업 공간",
|
||||
"prefs.zoom_stop_at_model": "모델에서 확대/축소 멈추기",
|
||||
"prefs.zoom_stop_at_model_tip": "3D 마우스와 장치 앱은 뷰 중앙의 표면을 향해 확대/축소하고, 드래그 확대/축소는 드래그 시작점을 고정합니다. 끄면 모델을 통과할 수 있습니다. 휠과 핀치는 별도의 커서로 확대/축소 설정을 사용합니다",
|
||||
"prefs.zoom_toward_cursor": "확대/축소, 커서 방향으로",
|
||||
"properties.title": "속성: {name}",
|
||||
"recovery.days_ago": "{count}일 전",
|
||||
"recovery.detail": "{file} · 피처 {features}개 · {when} 자동 저장",
|
||||
"recovery.discard_all": "모두 버리기",
|
||||
"recovery.discard_all_detail": "이 작업은 되돌릴 수 없습니다.",
|
||||
"recovery.discard_all_title": "자동 저장 {count}개를 버리시겠습니까?",
|
||||
"recovery.discard_all_title_one": "자동 저장 1개를 버리시겠습니까?",
|
||||
"recovery.hours_ago": "{count}시간 전",
|
||||
"recovery.just_now": "방금",
|
||||
"recovery.min_ago": "{count}분 전",
|
||||
@@ -2217,7 +2280,9 @@
|
||||
"render.output_ready": "렌더링 준비 완료",
|
||||
"render.output_run_check": "검사 실행",
|
||||
"render.output_size_limit": "{method}: 한 변 최대 {dimension} px, 총 {pixels} 픽셀. 가능한 최대 크기: {width} × {height}.",
|
||||
"render.output_size_method_profile": "{width} × {height}을(를) 렌더링하려면 {method}와(과) {profile} CPU 리소스 프로필을 선택하거나 더 작은 크기를 선택하세요.",
|
||||
"render.output_size_ok": "크기 정상 · {width} × {height} px",
|
||||
"render.output_size_profile": "{width} × {height}을(를) 렌더링하려면 {profile} CPU 리소스 프로필이나 더 작은 크기를 선택하세요.",
|
||||
"render.output_tools_inspector": "출력 검사기에서 크기와 형식을 편집하세요.",
|
||||
"render.output_view_image": "이미지 보기",
|
||||
"render.paint_label": "칠하기",
|
||||
@@ -2349,6 +2414,7 @@
|
||||
"render.size_custom": "사용자 지정…",
|
||||
"render.size_full_hd": "풀 HD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · {profile} 필요",
|
||||
"render.size_presets": "크기 프리셋",
|
||||
"render.size_presets_pending": "출력 편집기와 함께 제공 예정",
|
||||
"render.size_preview": "미리보기",
|
||||
@@ -2556,6 +2622,7 @@
|
||||
"settings.display_quality_note": "세밀할수록 곡면과 모서리가 더 매끄럽게 표시되지만 메시 생성 시간이 늘어납니다. 뷰포트만 바뀌며 설계나 내보내기는 바뀌지 않습니다.",
|
||||
"settings.double_click_components": "구성 요소를 두 번 클릭하여 활성화하거나 연결된 구성 요소를 제자리에서 편집",
|
||||
"settings.frame_rate_note": "뷰의 오른쪽 아래에 초당 프레임 수를 표시합니다.",
|
||||
"settings.insert_lists_open_designs": "설계 삽입에서 다른 탭에 열린 설계를 먼저 표시",
|
||||
"settings.measure_axis_distances": "X/Y/Z 거리 표시",
|
||||
"settings.measure_axis_distances_help": "측정 대화상자가 열려 있는 동안 전체 거리와 함께 월드 축 방향 치수와 거리를 표시합니다.",
|
||||
"settings.msaa_applies_on_restart": "안티앨리어싱은 다음에 SolidCraft를 시작할 때 적용됩니다",
|
||||
@@ -2569,12 +2636,34 @@
|
||||
"sheet.flange_type_base": "베이스",
|
||||
"sheet.flange_type_contour": "윤곽",
|
||||
"sheet.flange_type_edge": "모서리",
|
||||
"sheet.personal_rules.confirm_delete": "삭제 확인",
|
||||
"sheet.personal_rules.delete": "삭제",
|
||||
"sheet.personal_rules.delete_prompt": "이 개인 규칙을 삭제할까요? 설계에 이미 있는 규칙은 바뀌지 않습니다.",
|
||||
"sheet.personal_rules.full": "개인 라이브러리에 이미 규칙이 64개 있습니다.",
|
||||
"sheet.personal_rules.invalid_name": "줄 바꿈이나 제어 문자가 없는 짧은 이름을 입력하세요.",
|
||||
"sheet.personal_rules.invalid_values": "규칙 값을 모두 입력하세요. 각 값은 이 설계에서 계산할 수 있어야 하며, 두께는 양수, K 계수는 0에서 1 사이여야 합니다.",
|
||||
"sheet.personal_rules.missing": "선택한 개인 규칙을 더 이상 사용할 수 없습니다.",
|
||||
"sheet.personal_rules.name": "규칙 이름",
|
||||
"sheet.personal_rules.name_exists": "같은 이름의 개인 규칙이 이미 있습니다. 다른 이름을 사용하세요.",
|
||||
"sheet.personal_rules.name_hint": "고유한 이름",
|
||||
"sheet.personal_rules.overwrite": "선택한 개인 규칙에 변경 사항 저장",
|
||||
"sheet.personal_rules.rename": "이름 바꾸기",
|
||||
"sheet.personal_rules.rule": "개인 규칙",
|
||||
"sheet.personal_rules.save": "새로 저장",
|
||||
"sheet.personal_rules.scope": "모든 설계에서 쓸 수 있도록 프로필에 저장됩니다.",
|
||||
"sheet.personal_rules.select": "규칙 선택",
|
||||
"sheet.personal_rules.title": "개인 규칙",
|
||||
"sheet.personal_rules.unsupported": "이 규칙에는 이 버전에서 사용할 수 없는 값이 있습니다.",
|
||||
"shortcut.json_error": "매개변수는 JSON 형식이어야 합니다: {error}",
|
||||
"shortcut.no_command": "`{id}` 명령이 없습니다. JSON 앞의 텍스트는 명령 ID여야 합니다",
|
||||
"shortcut.pin": "S 상자 맨 위에 고정",
|
||||
"shortcut.unpin": "고정 해제",
|
||||
"sketch is missing": "스케치가 없습니다",
|
||||
"sketch.degrees_of_freedom": "자유도 {count}개",
|
||||
"sketch.dimension_added_driven": "스케치가 이미 이 치수를 결정하므로 종속(참조) 치수로 추가했습니다",
|
||||
"sketch.dimension_applied": "치수를 적용했습니다",
|
||||
"sketch.dimension_applied_defined": "치수를 적용했습니다. 매개변수 `{name}`을(를) 정의했습니다",
|
||||
"sketch.dimension_applied_renamed": "치수를 적용했습니다. 매개변수 이름을 `{name}`(으)로 지정했습니다",
|
||||
"sketch.dof_left": "남은 자유도 {count}개",
|
||||
"sketch.dof_left_one": "남은 자유도 {count}개",
|
||||
"sketch.draw_curves": "{linetype}(으)로 그리기",
|
||||
@@ -2709,6 +2798,10 @@
|
||||
"ui.3d_mouse_offer": "3D 마우스를 보정하면 바뀌거나 반전된 축이 바로잡히고 속도와 조작감이 맞춰집니다.",
|
||||
"ui.3d_mouse_offer_never": "다시 표시하지 않음",
|
||||
"ui.3d_mouse_offer_swap": "Hidraw(직접 드라이버)로 전환",
|
||||
"ui.3d_mouse_orbit": "궤도 회전",
|
||||
"ui.3d_mouse_orbit_classic": "클래식",
|
||||
"ui.3d_mouse_orbit_tip": "추적: 회전을 시작할 때 뷰 가운데에 있는 모델 부분을 중심으로 3D 마우스가 뷰를 회전하며, 그 점을 희미한 구로 표시합니다. 클래식: 뷰의 중심을 기준으로",
|
||||
"ui.3d_mouse_orbit_traced": "추적",
|
||||
"ui.3d_mouse_reading": "읽은 값",
|
||||
"ui.3d_mouse_reset_axes": "축 지정 초기화",
|
||||
"ui.3d_mouse_reset_view": "뷰 초기화",
|
||||
@@ -2745,6 +2838,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "캡을 시계 반대 방향으로 돌려 유지한 다음 놓으세요.",
|
||||
"ui.3d_mouse_switch_cap": "중앙 복귀형으로 보정",
|
||||
"ui.3d_mouse_switch_trackball": "트랙볼로 보정",
|
||||
"ui.3d_mouse_use_direct": "직접 드라이버 사용",
|
||||
"ui.3d_mouse_use_direct_tip": "spacenavd를 거치지 않고 3D 마우스를 직접(hidraw) 읽습니다.",
|
||||
"ui.3d_mouse_view_axis": "뷰 축",
|
||||
"ui.3d_mouse_view_off": "끔",
|
||||
"ui.3d_mouse_view_off_tip": "3D 마우스 드라이버 프로필이 이 축을 끄므로, 이 축의 동작으로는 뷰가 움직이지 않습니다. 여기서 다른 축의 동작을 고르면 둘이 바뀌고, 그 동작은 더 이상 뷰를 움직이지 않습니다.",
|
||||
@@ -2860,6 +2955,8 @@
|
||||
"ui.agent_chat_remove": "대기열에서 제거",
|
||||
"ui.agent_chat_remove_file": "이 메시지에서 빼기",
|
||||
"ui.agent_chat_remove_imported": "이 메시지에서 빼기. 부품은 디자인에 남습니다 (실행 취소하면 제거됨)",
|
||||
"ui.agent_chat_reply_cut_off": "응답이 끝나기 전에 길이 한도에 도달해 불완전할 수 있습니다. 에이전트에게 계속하거나 더 짧게 답하라고 요청하세요.",
|
||||
"ui.agent_chat_reply_declined": "모델이 이 메시지에 대한 답변을 거절했습니다.",
|
||||
"ui.agent_chat_right": "오른쪽",
|
||||
"ui.agent_chat_save": "저장",
|
||||
"ui.agent_chat_send": "보내기",
|
||||
@@ -3008,6 +3105,7 @@
|
||||
"ui.circle": "원",
|
||||
"ui.circular_pattern": "원형 패턴",
|
||||
"ui.clear": "지우기",
|
||||
"ui.clear_print_face": "출력 바닥면 해제",
|
||||
"ui.clear_recent": "최근 항목 지우기",
|
||||
"ui.clear_the_selection": "선택 해제",
|
||||
"ui.click_selects_whole_bodies": "클릭하면 바디 전체 선택",
|
||||
@@ -3042,6 +3140,15 @@
|
||||
"ui.constant": "상수",
|
||||
"ui.constraints_conflict": "구속 조건 충돌",
|
||||
"ui.construction": "구성선",
|
||||
"ui.construction.angle_hint": "보조 직선: 점 클릭 후 각도 입력 또는 방향 선택",
|
||||
"ui.construction.bisector_hint": "이등분선: 교차하는 두 직선 선택 후 원하는 해 선택",
|
||||
"ui.construction.common_hint": "공통 접선: 두 원/원호 선택 후 원하는 해 선택",
|
||||
"ui.construction.contact_hint": "접선: 원/원호 또는 열린 스플라인/원뿔 곡선 선택 후 접점 선택 (자유 곡선은 끝점만)",
|
||||
"ui.construction.external_hint": "접선: 원 또는 원호, 외부 점, 원하는 해를 차례로 선택",
|
||||
"ui.construction.free_hint": "보조 직선: 두 점 클릭; 마우스 오른쪽 버튼으로 다시 시작",
|
||||
"ui.construction.point_hint": "보조 직선: 통과할 점 클릭",
|
||||
"ui.construction.reference_hint": "보조 직선: 직선 선택 후 점 선택; 마우스 오른쪽 버튼으로 참조 변경",
|
||||
"ui.construction.ribbon_label": "보조선",
|
||||
"ui.context_menu": "컨텍스트 메뉴",
|
||||
"ui.continuity_g0": "G0 꺾임",
|
||||
"ui.continuity_g1": "G1 접선",
|
||||
@@ -3130,6 +3237,14 @@
|
||||
"ui.end_scale": "끝 배율",
|
||||
"ui.entities": "요소",
|
||||
"ui.equal": "동일",
|
||||
"ui.equation_end": "끝",
|
||||
"ui.equation_explicit": "명시적",
|
||||
"ui.equation_form": "형식",
|
||||
"ui.equation_note": "변수는 단위가 없는 수입니다. sin(t)는 라디안으로 읽습니다. 단위가 없는 결과는 디자인 단위입니다.",
|
||||
"ui.equation_parametric": "매개변수식",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "등가 반지름",
|
||||
"ui.expand": "펼치기",
|
||||
"ui.exportDxf": "DXF 내보내기…",
|
||||
@@ -3188,6 +3303,7 @@
|
||||
"ui.heading_design": "디자인",
|
||||
"ui.heading_draft": "구배",
|
||||
"ui.heading_edit": "편집",
|
||||
"ui.heading_equation_curve": "방정식 곡선",
|
||||
"ui.heading_extrude": "돌출",
|
||||
"ui.heading_fillet": "필렛",
|
||||
"ui.heading_finish_editing": "편집 완료",
|
||||
@@ -3275,6 +3391,10 @@
|
||||
"ui.import_ellipsis": "가져오기…",
|
||||
"ui.infinite": "무한",
|
||||
"ui.insert": "삽입",
|
||||
"ui.insert_design.browse": "찾아보기…",
|
||||
"ui.insert_design.open_designs": "열린 설계",
|
||||
"ui.insert_design.saved_file": "{name}에 저장되지 않은 변경 사항이 있어 저장된 파일을 삽입했습니다. 저장한 다음 링크 업데이트로 변경 사항을 가져오세요.",
|
||||
"ui.insert_design.unsaved": "저장되지 않은 변경 사항",
|
||||
"ui.inspect": "검사",
|
||||
"ui.intersect": "교차",
|
||||
"ui.isolate": "분리 표시",
|
||||
@@ -3400,6 +3520,11 @@
|
||||
"ui.polygon": "다각형",
|
||||
"ui.preferences": "환경 설정",
|
||||
"ui.press_a_key": "키를 누르세요…",
|
||||
"ui.print_face_cleared": "{body}: 출력 바닥면을 해제했습니다",
|
||||
"ui.print_face_input": "출력 바닥면",
|
||||
"ui.print_face_one_body": "출력 바닥면은 바디마다 하나입니다. 변경하려면 그 바디만 보내십시오",
|
||||
"ui.print_face_pick": "솔리드 바디의 평면 하나를 선택하면 출력 바닥면이 됩니다",
|
||||
"ui.print_face_set": "{body}: 출력 바닥면을 설정했습니다. 슬라이서로 보내면 이 면이 아래로 놓입니다",
|
||||
"ui.profile": "프로파일",
|
||||
"ui.profile_plane": "프로파일 평면",
|
||||
"ui.profiles": "프로파일",
|
||||
@@ -3475,6 +3600,8 @@
|
||||
"ui.select": "선택",
|
||||
"ui.selectOther": "기타 선택…",
|
||||
"ui.selectTangentChain": "접선 체인 선택",
|
||||
"ui.select_all": "모두 선택",
|
||||
"ui.select_components_by_face": "구성요소 선택(면을 클릭하면 해당 구성요소 선택)",
|
||||
"ui.selection": "선택",
|
||||
"ui.selection_modifiers": "선택 보조 키",
|
||||
"ui.selection_shift_add_only": "Shift+클릭은 추가만 함",
|
||||
@@ -3603,10 +3730,19 @@
|
||||
"ui.view_centre": "뷰 중심",
|
||||
"ui.viewport_status_clear": "{name} 끄기",
|
||||
"ui.viewport_status_clear_hint": "{name} 끄기 · Esc",
|
||||
"ui.viewport_status_edges": "모서리 {count}개",
|
||||
"ui.viewport_status_from": "{direction} 방향에서",
|
||||
"ui.viewport_status_key": "{name} 범례 표시",
|
||||
"ui.viewport_status_minimum_radius": "최소 반지름",
|
||||
"ui.viewport_status_pairs": "{count}쌍",
|
||||
"ui.viewport_status_section_hatch": "{setting} · 해칭",
|
||||
"ui.viewport_status_section_plane": "현재 평면",
|
||||
"ui.viewport_status_section_tilted": "기울어짐 · {offset}",
|
||||
"ui.viewport_status_stripes": "줄무늬 {count}개",
|
||||
"ui.viewport_status_summary_clear": "모두 끄기",
|
||||
"ui.viewport_status_summary_heading": "이 뷰에서",
|
||||
"ui.viewport_status_summary_label": "{name} 외 {count}개 항목",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "테마 따르기",
|
||||
"ui.visual_shaded_hidden_edges": "음영 처리 및 숨겨진 모서리",
|
||||
"ui.visual_shaded_with_edges": "음영 처리 및 모서리",
|
||||
@@ -3638,7 +3774,9 @@
|
||||
"update.button": "업데이트",
|
||||
"update.button_version": "{version}(으)로 업데이트",
|
||||
"update.check_automatically": "업데이트 자동 확인",
|
||||
"update.check_for_updates": "업데이트 확인",
|
||||
"update.check_now": "지금 확인",
|
||||
"update.check_unavailable": "이 설치에서는 업데이트를 확인할 수 없습니다.",
|
||||
"update.checking": "확인 중…",
|
||||
"update.copy": "복사",
|
||||
"update.dmg_opened": "디스크 이미지를 확인하고 열었습니다: SolidCraft를 응용 프로그램 폴더로 끌어 기존 버전을 바꾼 뒤 SolidCraft를 다시 시작하세요.",
|
||||
|
||||
@@ -606,6 +606,7 @@
|
||||
"cmd.appearance_library": "Biblioteca de aparências",
|
||||
"cmd.appearance_list": "Listar aparências",
|
||||
"cmd.assembly_bom": "Lista de materiais",
|
||||
"cmd.body.print_face": "Face de impressão",
|
||||
"cmd.body_rename": "Renomear corpo",
|
||||
"cmd.browser_group": "Novo grupo",
|
||||
"cmd.browser_move": "Mover itens do navegador",
|
||||
@@ -815,6 +816,16 @@
|
||||
"cmd.sheet_refold": "Redobrar",
|
||||
"cmd.sheet_rules": "Listar regras de chapa metálica",
|
||||
"cmd.sheet_unfold": "Desdobrar",
|
||||
"cmd.sketch.construction_line": "Reta de construção",
|
||||
"cmd.sketch.construction_line.angle": "Reta de construção em ângulo",
|
||||
"cmd.sketch.construction_line.bisector": "Bissetriz",
|
||||
"cmd.sketch.construction_line.horizontal": "Reta de construção horizontal",
|
||||
"cmd.sketch.construction_line.parallel": "Reta de construção paralela",
|
||||
"cmd.sketch.construction_line.perpendicular": "Reta de construção perpendicular",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tangente em um ponto da curva",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tangente por um ponto externo",
|
||||
"cmd.sketch.construction_line.tangent_two": "Tangente comum",
|
||||
"cmd.sketch.construction_line.vertical": "Reta de construção vertical",
|
||||
"cmd.sketch_arc_center_point": "Arco por ponto central",
|
||||
"cmd.sketch_arc_tangent": "Arco tangente",
|
||||
"cmd.sketch_arc_three_point": "Arco por 3 pontos",
|
||||
@@ -1282,6 +1293,8 @@
|
||||
"prefs.orientation": "Orientação",
|
||||
"prefs.overall_speed": "Velocidade geral",
|
||||
"prefs.preview_choices": "Prévia das suas escolhas",
|
||||
"prefs.print_face_highlight": "Destaque da face de impressão",
|
||||
"prefs.print_face_highlight_tip": "Intensidade da cor e do contorno da face de impressão de um corpo na vista. 0 % não mostra destaque.",
|
||||
"prefs.quality_default": "padrão",
|
||||
"prefs.quality_fastest": "mais rápido",
|
||||
"prefs.quality_slowest": "mais lento",
|
||||
@@ -1561,6 +1574,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Gire a tampa no sentido anti-horário, segure e solte.",
|
||||
"ui.3d_mouse_switch_cap": "Calibrar como retorno ao centro",
|
||||
"ui.3d_mouse_switch_trackball": "Calibrar como trackball",
|
||||
"ui.3d_mouse_use_direct": "Usar driver direto",
|
||||
"ui.3d_mouse_use_direct_tip": "Ler o mouse 3D diretamente (hidraw) em vez de pelo spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "Eixo da vista",
|
||||
"ui.3d_mouse_view_off": "Desligado",
|
||||
"ui.3d_mouse_view_off_tip": "O perfil do driver do mouse 3D desliga este eixo, então o movimento dele não move a vista. Escolher aqui o movimento de outro eixo troca os dois, e esse movimento deixa de mover a vista.",
|
||||
@@ -1830,6 +1845,7 @@
|
||||
"ui.circle": "Círculo",
|
||||
"ui.circular_pattern": "Padrão circular",
|
||||
"ui.clear": "Limpar",
|
||||
"ui.clear_print_face": "Limpar face de impressão",
|
||||
"ui.clear_recent": "Limpar recentes",
|
||||
"ui.clear_the_selection": "Limpar a seleção",
|
||||
"ui.click_selects_whole_bodies": "O clique seleciona corpos inteiros",
|
||||
@@ -1864,6 +1880,7 @@
|
||||
"ui.constant": "Constante",
|
||||
"ui.constraints_conflict": "Restrições em conflito",
|
||||
"ui.construction": "Construção",
|
||||
"ui.construction.ribbon_label": "Linhas aux.",
|
||||
"ui.context_menu": "Menu de contexto",
|
||||
"ui.continuity_g0": "G0 vinco",
|
||||
"ui.continuity_g1": "G1 tangente",
|
||||
@@ -2187,6 +2204,11 @@
|
||||
"ui.polygon": "Polígono",
|
||||
"ui.preferences": "Preferências",
|
||||
"ui.press_a_key": "pressione uma tecla…",
|
||||
"ui.print_face_cleared": "{body}: face de impressão removida",
|
||||
"ui.print_face_input": "Face de impressão",
|
||||
"ui.print_face_one_body": "Uma face de impressão pertence a um único corpo: envie esse corpo sozinho para alterá-la",
|
||||
"ui.print_face_pick": "Selecione uma face plana de um corpo sólido para torná-la a face de impressão",
|
||||
"ui.print_face_set": "{body}: face de impressão definida; Enviar ao fatiador apoia o corpo sobre ela",
|
||||
"ui.profile": "Perfil",
|
||||
"ui.profile_plane": "Plano do perfil",
|
||||
"ui.profiles": "Perfis",
|
||||
@@ -2244,6 +2266,7 @@
|
||||
"ui.select": "Selecionar",
|
||||
"ui.selectOther": "Selecionar outro…",
|
||||
"ui.selectTangentChain": "Selecionar cadeia tangente",
|
||||
"ui.select_all": "Selecionar tudo",
|
||||
"ui.selection": "Seleção",
|
||||
"ui.selection_modifiers": "Modificadores de seleção",
|
||||
"ui.selection_shift_add_only": "Shift+clique adiciona sem remover",
|
||||
@@ -2376,7 +2399,9 @@
|
||||
"update.button": "Atualizar",
|
||||
"update.button_version": "Atualizar para {version}",
|
||||
"update.check_automatically": "Verificar atualizações automaticamente",
|
||||
"update.check_for_updates": "Verificar atualizações",
|
||||
"update.check_now": "Verificar agora",
|
||||
"update.check_unavailable": "A verificação de atualizações não está disponível para esta instalação.",
|
||||
"update.checking": "Verificando…",
|
||||
"update.copy": "Copiar",
|
||||
"update.dmg_opened": "A imagem de disco está aberta e verificada: arraste o SolidCraft para Aplicativos, substituindo a cópia antiga, e reinicie o SolidCraft.",
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
"Edges": "Ивице",
|
||||
"Edit": "Измени",
|
||||
"Edit Profile Sketch": "Измени скицу профила",
|
||||
"Edit shortcuts": "Измени пречице",
|
||||
"Enable rule": "Омогући правило",
|
||||
"Enabled": "Омогућено",
|
||||
"End Radius": "Крајњи полупречник",
|
||||
@@ -468,6 +469,7 @@
|
||||
"Radius": "Полупречник",
|
||||
"Radius Fit": "Уклапање полупречника",
|
||||
"Ratio": "Однос",
|
||||
"Read-only list: shortcuts can't be changed here.": "Списак само за читање: пречице се овде не могу мењати.",
|
||||
"Reattach selected face": "Поново причврсти изабрано лице",
|
||||
"Recover": "Опорави",
|
||||
"Recover unsaved design?": "Опоравити несачувани дизајн?",
|
||||
@@ -652,6 +654,7 @@
|
||||
"Third point": "Трећа тачка",
|
||||
"This child is shared. Deleting it removes it from every copy of its parent.": "Овај подређени елемент је дељен. Брисањем се уклања из сваке копије његовог родитеља.",
|
||||
"This child is shared. Position changes apply to every copy of its parent.": "Овај подређени елемент је дељен. Промене положаја примењују се на сваку копију његовог родитеља.",
|
||||
"This component is inside a subassembly placed more than once: aligning it moves it in every placement.": "Ова компонента је унутар подсклопа који је постављен више пута: њено поравнање је помера у сваком постављању.",
|
||||
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Ово лице не може дати трајно причвршћење. Изаберите друго лице или изричито користите фиксну раван.",
|
||||
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Ова слика још није приложена на GitHub-у. Копирајте је или сачувајте, а затим је приложите на GitHub-у.",
|
||||
"Thread depth": "Дубина навоја",
|
||||
@@ -772,6 +775,8 @@
|
||||
"at the face": "на лицу",
|
||||
"bom.group_children": "Подделови у реду свог дела",
|
||||
"browser.body_name": "Тело{number}",
|
||||
"browser.calibrate_click_a": "Кликните слику да зададете тачку A или упишите њене координате.",
|
||||
"browser.calibrate_click_b": "Кликните слику да зададете тачку B или упишите њене координате.",
|
||||
"browser.calibrate_title": "Калибриши: {name}",
|
||||
"browser.capture_many": "Померене компоненте без забележеног положаја: {count}.",
|
||||
"browser.capture_note": "Забележи задржава нови положај; Врати га враћа назад.",
|
||||
@@ -793,6 +798,11 @@
|
||||
"cam.roller": "Ваљак",
|
||||
"cam.roller_pick": "Ваљак (необавезно)",
|
||||
"cam.tip_pick": "Врх (необавезно)",
|
||||
"camera.shot_pitch": "Нагиб",
|
||||
"camera.shot_roll": "Ваљање",
|
||||
"camera.shot_yaw": "Скретање",
|
||||
"canvas.decal_place_hint": "Кликните лице да поставите налепницу",
|
||||
"canvas.place_hint": "Кликните раван или лице да поставите платно",
|
||||
"choose a profile": "изаберите профил",
|
||||
"choose the cam's and the follower's joints": "изаберите спојеве брега и пратиоца",
|
||||
"choose the joints to couple": "изаберите спојеве за спрезање",
|
||||
@@ -800,12 +810,16 @@
|
||||
"click sketch curves": "кликните на криве скице",
|
||||
"cmd.appearance_assign": "Изглед",
|
||||
"cmd.appearance_chain": "Ланац изгледа",
|
||||
"cmd.appearance_copy": "Копирај изглед",
|
||||
"cmd.appearance_favorite": "Омиљени изглед",
|
||||
"cmd.appearance_library": "Библиотека изгледа",
|
||||
"cmd.appearance_list": "Списак изгледа",
|
||||
"cmd.appearance_paint": "Обоји изгледом",
|
||||
"cmd.appearance_paste": "Налепи изглед",
|
||||
"cmd.appearance_pick_up": "Преузми изглед",
|
||||
"cmd.appearance_replace": "Замени изглед",
|
||||
"cmd.assembly_bom": "Саставница",
|
||||
"cmd.body.print_face": "Површина за штампу",
|
||||
"cmd.body_rename": "Преименуј тело",
|
||||
"cmd.browser_collapse_all": "Скупи све",
|
||||
"cmd.browser_expand_all": "Прошири све",
|
||||
@@ -813,6 +827,7 @@
|
||||
"cmd.browser_move": "Премести ставке стабла модела",
|
||||
"cmd.browser_order": "Поређај ставке стабла модела",
|
||||
"cmd.browser_rename_group": "Преименуј групу",
|
||||
"cmd.browser_reparent": "Премести у компоненту",
|
||||
"cmd.browser_ungroup": "Разгрупиши",
|
||||
"cmd.browser_visibility": "Прикажи/сакриј",
|
||||
"cmd.canvas_calibrate": "Калибриши платно",
|
||||
@@ -839,7 +854,9 @@
|
||||
"cmd.component_metadata": "Својства дела",
|
||||
"cmd.component_metadata_set": "Промени својства дела",
|
||||
"cmd.component_move_bodies": "Премести тела у компоненту",
|
||||
"cmd.component_move_features": "Премести операције у компоненту",
|
||||
"cmd.component_move_sketches": "Премести скице у компоненту",
|
||||
"cmd.component_paste_from_design": "Налепи из другог дизајна",
|
||||
"cmd.component_paste_new": "Налепи као ново",
|
||||
"cmd.component_properties": "Физичка својства компоненте",
|
||||
"cmd.component_relink": "Поново повежи извор",
|
||||
@@ -976,6 +993,7 @@
|
||||
"cmd.motion_trace": "Траг кретања",
|
||||
"cmd.motion_trace_edit": "Измени траг кретања",
|
||||
"cmd.motion_trace_keep": "Задржи траг кретања",
|
||||
"cmd.occurrence_align": "Поравнај примерак",
|
||||
"cmd.occurrence_copy": "Налепи (примерак)",
|
||||
"cmd.occurrence_drag": "Превуци примерак",
|
||||
"cmd.occurrence_ground": "Учврсти",
|
||||
@@ -1033,11 +1051,17 @@
|
||||
"cmd.render_library_surface_unbind": "Уклони везу површине",
|
||||
"cmd.render_library_targets": "Пронађи циљеве библиотеке рендеровања",
|
||||
"cmd.render_lights_add": "Додај светло",
|
||||
"cmd.render_lights_duplicate": "Дуплицирај светло рендеровања",
|
||||
"cmd.render_lights_list": "Списак светала рендеровања",
|
||||
"cmd.render_lights_mute": "Искључи светло",
|
||||
"cmd.render_lights_remove": "Уклони светло рендеровања",
|
||||
"cmd.render_lights_set": "Подеси светло рендеровања",
|
||||
"cmd.render_lights_solo": "Само ово светло",
|
||||
"cmd.render_optics_bind": "Сачувај оптичку везу",
|
||||
"cmd.render_optics_unbind": "Уклони оптичку везу",
|
||||
"cmd.render_output_size": "Подеси величину излаза рендеровања",
|
||||
"cmd.render_preflight": "Провери захтев за рендеровање",
|
||||
"cmd.render_preflight_copy": "Копирај извештај провере рендеровања",
|
||||
"cmd.render_preset_apply": "Примени изворни студио",
|
||||
"cmd.render_preset_resolve": "Прегледај изворни студио",
|
||||
"cmd.render_quality_prepare": "Прегледај фиксни буџет узорковања",
|
||||
@@ -1060,6 +1084,13 @@
|
||||
"cmd.render_start": "Рендеруј слику",
|
||||
"cmd.render_status": "Напредак рендеровања",
|
||||
"cmd.select_clear": "Поништи избор",
|
||||
"cmd.settings_profile_apply": "Примени профил подешавања",
|
||||
"cmd.settings_profile_delete": "Избриши профил подешавања",
|
||||
"cmd.settings_profile_export": "Извези профил подешавања",
|
||||
"cmd.settings_profile_import": "Увези профил подешавања",
|
||||
"cmd.settings_profile_list": "Профили подешавања",
|
||||
"cmd.settings_profile_rename": "Преименуј профил подешавања",
|
||||
"cmd.settings_profile_save": "Сачувај профил подешавања",
|
||||
"cmd.sheet_convert": "Претвори у лим",
|
||||
"cmd.sheet_export_bend_table": "Извези табелу савијања",
|
||||
"cmd.sheet_export_dxf": "Извези развијени облик као DXF",
|
||||
@@ -1073,6 +1104,16 @@
|
||||
"cmd.sheet_refold": "Поново пресавиј",
|
||||
"cmd.sheet_rules": "Списак правила за лим",
|
||||
"cmd.sheet_unfold": "Развиј",
|
||||
"cmd.sketch.construction_line": "Помоћна права",
|
||||
"cmd.sketch.construction_line.angle": "Помоћна права под углом",
|
||||
"cmd.sketch.construction_line.bisector": "Симетрала угла",
|
||||
"cmd.sketch.construction_line.horizontal": "Хоризонтална помоћна права",
|
||||
"cmd.sketch.construction_line.parallel": "Паралелна помоћна права",
|
||||
"cmd.sketch.construction_line.perpendicular": "Нормална помоћна права",
|
||||
"cmd.sketch.construction_line.tangent_at": "Тангента у тачки криве",
|
||||
"cmd.sketch.construction_line.tangent_external": "Тангента кроз спољашњу тачку",
|
||||
"cmd.sketch.construction_line.tangent_two": "Заједничка тангента",
|
||||
"cmd.sketch.construction_line.vertical": "Вертикална помоћна права",
|
||||
"cmd.sketch_arc3d": "3D лук",
|
||||
"cmd.sketch_arc_center_point": "Лук из центра",
|
||||
"cmd.sketch_arc_tangent": "Тангентни лук",
|
||||
@@ -1105,6 +1146,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Величина цртежа",
|
||||
"cmd.sketch_edit": "Измени скицу",
|
||||
"cmd.sketch_edit_text": "Измени текст",
|
||||
"cmd.sketch_equation_curve": "Крива по једначини",
|
||||
"cmd.sketch_equation_curve_edit": "Измени криву по једначини",
|
||||
"cmd.sketch_export_dxf": "Сачувај као DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "Заврши са аутоматским ограничењима",
|
||||
"cmd.sketch_fit_curves_to_section": "Уклопи криве у пресек мреже",
|
||||
@@ -1201,6 +1244,7 @@
|
||||
"cmd.view.render_browser": "Стабло рендеровања",
|
||||
"cmd.view.render_dock": "Премести панел рендеровања",
|
||||
"cmd.view.render_focus": "Фокусни приказ рендеровања",
|
||||
"cmd.view.status_items": "Ставке статуса у прозору приказа",
|
||||
"cmd.view_ambient_occlusion": "Амбијентална оклузија",
|
||||
"cmd.view_angle_readout": "Углови приказа",
|
||||
"cmd.view_apply": "Врати именовани приказ",
|
||||
@@ -1222,6 +1266,7 @@
|
||||
"cmd.view_normal_to": "Нормално на избор",
|
||||
"cmd.view_previous_tab": "Претходна картица",
|
||||
"cmd.view_rename": "Преименуј именовани приказ",
|
||||
"cmd.view_render_frame": "Водичи кадра рендеровања",
|
||||
"cmd.view_right": "Поглед здесна",
|
||||
"cmd.view_save": "Нови именовани приказ",
|
||||
"cmd.view_shots_strip": "Трака кадрова",
|
||||
@@ -1232,10 +1277,14 @@
|
||||
"color.copy": "Кликните да копирате вредности боје",
|
||||
"color.edit": "Кликните да измените боју",
|
||||
"color.gamma": "Приказ вредности боје у гама простору 0-255",
|
||||
"color.hex": "Hex",
|
||||
"color.hex_help": "Унесите #rrggbb или #rrggbbaa; шест цифара чува непрозирност",
|
||||
"color.hex_hint": "#rrggbb",
|
||||
"color.hue": "Нијанса",
|
||||
"color.linear": "Приказ вредности боје у линеарном простору 0-1",
|
||||
"color.saturation_value": "Засићеност и вредност",
|
||||
"color.selected": "Изабрана боја",
|
||||
"config.column_filter_empty": "Нема одговарајућих колона",
|
||||
"contact.components_count": "Компоненте: {count}",
|
||||
"contact.enabled_label": "омогућено",
|
||||
"coupling.gear_1": "Зупчаник 1",
|
||||
@@ -1350,8 +1399,20 @@
|
||||
"help.material.assign": "Одређује од чега су изабрана тела направљена, нпр. челик, алуминијум или ABS. Користите га да маса и тежина одговарају стварном делу.",
|
||||
"help.mit": "MIT лиценца",
|
||||
"help.notice": "NOTICE",
|
||||
"help.occurrence.move": "Помера део склопа само дуж слобода које дозвољавају његови спојеви. Изаберите лице дела, а затим превуците доступну стрелицу или лук.",
|
||||
"help.parameters.change": "Отвара табелу именованих вредности и израза који управљају котама дизајна. Користите је да промените меру на једном месту, а све операције које је користе је прате.",
|
||||
"help.pointcloud.insert": "Уметните PLY, XYZ или PTS скенирање као облак тачака поред модела. Користите га као референцу при изради модела на основу измерених података.",
|
||||
"help.sketch.construction_line": "Направите бесконачну помоћну праву кроз две тачке. Користите је да распоредите скицу без раздвајања профила.",
|
||||
"help.sketch.construction_line.angle": "Направите бесконачну помоћну праву под углом од осе X скице. Изаберите тачку и упишите угао или изаберите смер.",
|
||||
"help.sketch.construction_line.bisector": "Изаберите две праве линије скице које се секу, па једну од две симетрале угла. Резултат прати изворне линије.",
|
||||
"help.sketch.construction_line.horizontal": "Направите бесконачну хоризонталну помоћну праву кроз тачку. Њено ограничење хоризонталности остаје на снази при каснијим изменама.",
|
||||
"help.sketch.construction_line.parallel": "Изаберите праву линију скице, па поставите паралелну бесконачну помоћну праву. Десним кликом изаберите другу референцу.",
|
||||
"help.sketch.construction_line.perpendicular": "Изаберите праву линију скице, па поставите нормалну бесконачну помоћну праву. Десним кликом изаберите другу референцу.",
|
||||
"help.sketch.construction_line.tangent_at": "Направите тангенту у тачки на кругу или кружном луку, или у крајњој тачки отвореног сплајна или конике. Изаберите криву, па тачку додира.",
|
||||
"help.sketch.construction_line.tangent_external": "Изаберите круг или кружни лук, па спољашњу тачку и решење тангенте. Прегледи приказују само тачке додира на нацртаном луку.",
|
||||
"help.sketch.construction_line.tangent_two": "Изаберите два круга или кружна лука, па у прегледу изаберите заједничку тангенту. Тачке додира морају лежати на нацртаним кривама.",
|
||||
"help.sketch.construction_line.vertical": "Направите бесконачну вертикалну помоћну праву кроз тачку. Њено ограничење вертикалности остаје на снази при каснијим изменама.",
|
||||
"help.sketch.equation_curve": "Црта криву из формула: x(t) и y(t), или y = f(x), у задатом опсегу. Формуле могу да користе параметре и крива их прати: користите је за синусоиду, спиралу или евольвенту зупца зупчаника.",
|
||||
"help.solid.align": "Помера изабрана тела тако да се тачка, лице или раван на њима поклопи са тачком, лицем или равни негде другде. Користите га да поставите део уз други без мерења одмака.",
|
||||
"help.solid.chamfer": "Одсеца изабране ивице равним скошењем задатог растојања. Користите га да ублажите оштре ивице или олакшате увођење чивије или завртња.",
|
||||
"help.solid.combine": "Спаја тела, одузима их од циљног тела или задржава само заједничку запремину, а може да задржи и алатна тела. Користите га да спојите делове, да једним обликом одсечете други или да пронађете где се два тела преклапају.",
|
||||
@@ -1480,6 +1541,21 @@
|
||||
"joint.one_component": "Ови делови су тела једне компоненте: {bodies}. Спој помера једну компоненту у односу на другу, па сваки део треба своју компоненту.",
|
||||
"joint.rigid_group_one_component": "Сва тела ({count}) су у једној компоненти (или у самом дизајну): прво користите {command}.",
|
||||
"joint.rigid_group_select_components": "Изаберите две или више компоненти.",
|
||||
"joint_move.blocked_hint": "Проверите врсту споја (на пример Круто), учвршћивање, границе споја и вредности које покрећу параметри.",
|
||||
"joint_move.blocked_title": "Овај део се не може померити",
|
||||
"joint_move.coarse": "Корак ротације близу осе (°)",
|
||||
"joint_move.distance": "Растојање од почетка",
|
||||
"joint_move.done": "Готово",
|
||||
"joint_move.fine": "Корак ротације далеко од осе (°)",
|
||||
"joint_move.fixed": "Овај део нема покретну осу споја.",
|
||||
"joint_move.help": "Помери — превуците стрелицу или прстен. Esc отказује тренутно превлачење.",
|
||||
"joint_move.legacy_hint": "Искључите да бисте користили претходни панел Помери.",
|
||||
"joint_move.precision": "Повуците изван испрекиданог водича за фину ротацију.",
|
||||
"joint_move.rotation": "Ротација од почетка",
|
||||
"joint_move.select": "Изаберите лице или један део склопа, а затим изаберите Помери.",
|
||||
"joint_move.settings": "Померање у склопу",
|
||||
"joint_move.step": "Корак",
|
||||
"joint_move.use_handles": "Користи ручице кретања спојева за померање у склопу",
|
||||
"keymap.command_id": "ID команде",
|
||||
"keymap.empty": "Нема одговарајућих команди",
|
||||
"keymap.use_anyway": "Ипак користи {key} овде",
|
||||
@@ -1574,6 +1650,8 @@
|
||||
"nav.maya.help": "Alt+превлачење левим орбитира, Alt+средњи помера, Alt+десни зумира; превлачење средњим такође помера",
|
||||
"nav.openscad.help": "Превлачење левим дугметом по празном простору орбитира, Shift+превлачење левим бира оквиром, превлачење геометрије скице је мења; превлачење десним или средњим дугметом помера, Shift+десно или Shift+средње зумира",
|
||||
"nav.perspective.sketch": "Измена скице користи ортографски приказ. Завршите скицу да пребаците на перспективу.",
|
||||
"nav.right_drag_orbits.help": "Искључено: превлачење десним дугметом не дира камеру, а десно дугме само отвара контекстни мени. Избор SolidWorks мапирања миша га искључује.",
|
||||
"nav.right_drag_orbits.label": "Превлачење десним дугметом орбитира",
|
||||
"nav.solidworks.help": "Превлачење средњим дугметом орбитира, Ctrl+средње помера, Shift+средње зумира, превлачење десним орбитира",
|
||||
"nav.tinkercad.help": "Превлачење десним дугметом орбитира, превлачење средњим или Shift+десним помера",
|
||||
"nav.touchpad.help": "Држите Shift и померајте показивач за померање приказа; држите Alt/Option и померајте га за орбитирање. Дугме миша није потребно. Вертикално скроловање зумира.",
|
||||
@@ -1595,6 +1673,9 @@
|
||||
"navbar.custom.customise": "Прилагоди навигациону траку…",
|
||||
"navbar.custom.design": "Дизајн",
|
||||
"navbar.custom.duplicate": "Ово место је већ на траци.",
|
||||
"navbar.custom.edge": "Ивица",
|
||||
"navbar.custom.edge_bottom": "Доле",
|
||||
"navbar.custom.edge_top": "Горе",
|
||||
"navbar.custom.fade": "Избледи",
|
||||
"navbar.custom.full": "Уклоните једно место да бисте додали друго.",
|
||||
"navbar.custom.hidden_design": "Скривено у Дизајну",
|
||||
@@ -1701,6 +1782,7 @@
|
||||
"parts.dimension.thickness": "Дебљина",
|
||||
"parts.dimension.width": "Ширина",
|
||||
"parts.family.bearing": "Куглични лежај са дубоким жлебом (габарит)",
|
||||
"parts.family.button_head_cap_screw": "Завртањ са полуоблом главом и унутрашњим шестоугаоником",
|
||||
"parts.family.dowel_pin": "Паралелни клин (колчић)",
|
||||
"parts.family.hex_bolt": "Завртањ са шестоугаоном главом",
|
||||
"parts.family.hex_nut": "Шестоугаона навртка",
|
||||
@@ -1759,6 +1841,11 @@
|
||||
"prefs.bottom_centre": "Доле у средини",
|
||||
"prefs.bottom_right": "Доле десно",
|
||||
"prefs.browser": "Стабло модела",
|
||||
"prefs.browser_eye_left": "Око поред стрелице за скупљање",
|
||||
"prefs.browser_eye_left_note": "Редови стабла модела приказују око за приказивање/скривање поред стрелице за скупљање, као раније, уместо у колони на десном крају редова.",
|
||||
"prefs.browser_reveal_on_hover": "Прикажи при преласку мишем",
|
||||
"prefs.browser_show_note": "Приказано држи стабло модела на екрану. Прикажи при преласку мишем га скрива док показивач не дође на његово место или на танак језичак на његовој левој ивици, а остаје отворено док је показивач у њему или док је отворен мени из њега.",
|
||||
"prefs.browser_shown": "Приказано",
|
||||
"prefs.built_in": "Уграђено",
|
||||
"prefs.button_left": "Превлачење левим дугметом",
|
||||
"prefs.button_middle": "Превлачење средњим дугметом",
|
||||
@@ -1806,6 +1893,8 @@
|
||||
"prefs.graphics_card_restart": "Ступа на снагу након поновног покретања SolidCraft-а. WGPU_ADAPTER_NAME има предност над овим избором.",
|
||||
"prefs.graphics_note": "Жртвујте брзину за глаткоћу. Сваки избор показује свој учинак на примеру.",
|
||||
"prefs.graphics_presets_note": "Унапред подешене вредности подешавају све изборе испод одједном.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Сакриј симболе ограничења када је приказ умањен",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Симболи ограничења нестају из приказа када је скица толико умањена да би је затрпали. Искључено: остају фиксне величине на екрану при сваком зумирању.",
|
||||
"prefs.history": "Временска трака",
|
||||
"prefs.history_origin_bodies": "Прикажи исходиште и тела на врху",
|
||||
"prefs.history_origin_bodies_note": "Временска трака лево или испод стабла модела почиње фасциклом Тела активне компоненте и Исходиштем, са њиховим оком и менијима као у стаблу модела. Временска трака на дну остаје непромењена.",
|
||||
@@ -1829,6 +1918,8 @@
|
||||
"prefs.layout_note": "Компактно причвршћује панеле уз ивице прозора. Провидност стабла модела доступна је у опцији Плутајуће. Страну Асистента промените на страници Асистент.",
|
||||
"prefs.left": "Лево",
|
||||
"prefs.left_click": "Леви клик",
|
||||
"prefs.line_drag_draws_one": "Притисак и превлачење цртају једну линију",
|
||||
"prefs.line_drag_draws_one_note": "У алату Линија, притисак, превлачење и пуштање цртају једну линију од места притиска до места пуштања и ту се завршава. Кликови и даље цртају ланац. Искључено: превлачење поставља тачку где се пусти, као и клик.",
|
||||
"prefs.linked_designs": "Повезани дизајни",
|
||||
"prefs.live_input": "Улаз уживо",
|
||||
"prefs.live_preview": "Преглед уживо",
|
||||
@@ -1842,6 +1933,9 @@
|
||||
"prefs.max_file_size_step": "STEP и датотеке за увоз",
|
||||
"prefs.max_file_size_web": "Веб апликација отвара STEP и датотеке за увоз до 512 MB и дизајне до 256 MB: картица прегледача не може да садржи веће датотеке. Десктоп апликација може да повећа ова ограничења.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Велике иконе",
|
||||
"prefs.menu_list": "Списак",
|
||||
"prefs.menus": "Менији",
|
||||
"prefs.minutes": "минута",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "Миш и додирна табла",
|
||||
@@ -1861,14 +1955,40 @@
|
||||
"prefs.origin_plane_names": "Називи равни исходишта",
|
||||
"prefs.origin_plane_names_note": "Називи приказани у стаблу модела, дијалозима и листама. {top} је XY, {front} је XZ, а {right} је YZ, са Z нагоре. Команде, скрипте и сачувани дизајни задржавају XY, XZ и YZ.",
|
||||
"prefs.overall_speed": "Укупна брзина",
|
||||
"prefs.persistent_ribbon_pressed": "Истакни активне команде на траци",
|
||||
"prefs.persistent_ribbon_pressed_help": "Истиче команде на траци док су њихови ефекти укључени. Искључите да бисте задржали претходни неутрални изглед и помоћ за команде.",
|
||||
"prefs.perspective_fov": "Видно поље",
|
||||
"prefs.placement": "Постављање",
|
||||
"prefs.prefer_free_sketch_points": "Дај предност покретним тачкама скице када се тачке преклапају",
|
||||
"prefs.preview_choices": "Преглед ваших избора",
|
||||
"prefs.print_face_highlight": "Истицање површине за штампу",
|
||||
"prefs.print_face_highlight_tip": "Колико се јако површина за штампу тела боји и обрубљује у приказу. 0 % не приказује истицање.",
|
||||
"prefs.profile_active": "Активни профил",
|
||||
"prefs.profile_applied": "Профил је примењен.",
|
||||
"prefs.profile_changed": "Подешавања су промењена откако је профил сачуван. Притисните Сачувај да их задржите у њему.",
|
||||
"prefs.profile_deleted": "Профил је избрисан.",
|
||||
"prefs.profile_export": "Извези…",
|
||||
"prefs.profile_exported": "Профил је извезен.",
|
||||
"prefs.profile_imported": "Профил је увезен. Изаберите га под Активни профил да бисте прешли на њега.",
|
||||
"prefs.profile_name_hint": "Назив профила, нпр. Лаптоп",
|
||||
"prefs.profile_rename": "Преименуј",
|
||||
"prefs.profile_renamed": "Профил је преименован.",
|
||||
"prefs.profile_save": "Сачувај",
|
||||
"prefs.profile_saved": "Тренутна подешавања су сачувана у профил.",
|
||||
"prefs.profile_skipped": "Профил је примењен; подешавања која су задржала тренутну вредност: {n} (погледајте дневник).",
|
||||
"prefs.profiles": "Профили подешавања",
|
||||
"prefs.profiles_note": "Пречице, трака са алатима, навигација, радијални мени и подешавања интерфејса, чувани заједно под једним називом и мењани одједном.",
|
||||
"prefs.project_options_dialog": "Дијалог опција за Пројектуј",
|
||||
"prefs.project_options_dialog_note": "Укључено: пре пројектовања изаберите Геометрија или Тела и Веза пројекције. Искључено: задржава се претходни начин рада са директним избором.",
|
||||
"prefs.quality_default": "подразумевано",
|
||||
"prefs.quality_fastest": "најбрже",
|
||||
"prefs.quality_slowest": "најспорије",
|
||||
"prefs.quality_smoother": "глађе",
|
||||
"prefs.render_previous_geometry_budget": "Користи претходни буџет геометрије за преглед у Рендеровању",
|
||||
"prefs.render_previous_geometry_budget_help": "Враћа претходно фиксно ограничење геометрије (512 MiB на 64-битним десктоп рачунарима, 128 MiB другде) уместо буџета према уређају.",
|
||||
"prefs.reports_saved": "Сачувано: {n}",
|
||||
"prefs.ribbon_reveal": "Прикажи резултате претраге на траци",
|
||||
"prefs.ribbon_reveal_note": "Задржавање показивача изнад резултата у Претражи команде показује где се команда налази на траци: њену картицу, њено дугме или њен ред у падајућем менију панела. Команда покренута из претраге тамо трепери, а покренута команда из падајућег менија означава свој панел.",
|
||||
"prefs.right_click": "Десни клик",
|
||||
"prefs.saving": "Аутоматско чување и опоравак",
|
||||
"prefs.scale_note": "Такође Ctrl + / Ctrl − у прозору. Дугмад су 28 px при 100%.",
|
||||
@@ -1877,18 +1997,29 @@
|
||||
"prefs.search_empty": "Нема одговарајућих подешавања",
|
||||
"prefs.select": "Избор",
|
||||
"prefs.select_one_item": "Изабери једну ставку",
|
||||
"prefs.select_other_hidden": "Изабери скривену геометрију помоћу Изабери друго",
|
||||
"prefs.select_other_hidden_help": "Укључено: обухвата скривена тела, скице и заклоњене ивице у близини показивача. Искључено: користи се изворни списак видљиве геометрије испод показивача.",
|
||||
"prefs.selecting": "Бирање",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift само додаје; Ctrl / Cmd укључује и искључује",
|
||||
"prefs.shift_add_note": "Укључено: Shift додаје, Ctrl / Cmd укључује и искључује. Искључено (подразумевано): оба укључују и искључују.",
|
||||
"prefs.shortcuts": "Пречице",
|
||||
"prefs.single_surface_analysis": "Користи само једну анализу површи",
|
||||
"prefs.single_surface_analysis_help": "Када је искључено, сенчење површи и Континуитет могу остати укључени заједно. Када је укључено, остаје последња покренута или промењена анализа.",
|
||||
"prefs.sketch_align_points": "Поравнај са другим тачкама скице током цртања",
|
||||
"prefs.sketch_align_points_note": "Током цртања тачка се истовремено поравнава хоризонтално са једном тачком скице и вертикално са другом, уз тачкасти водич, а клик задржава оба поравнања. Искључено: само са претходном тачком, по једна оса.",
|
||||
"prefs.sketch_conflict_colour": "Геометрија у сукобу у боји сукоба",
|
||||
"prefs.sketch_conflict_colour_note": "Док су ограничења скице у сукобу, криве и тачке које држи ограничење које не успева исцртавају се такође у боји сукоба, а не само његов симбол или кота. Искључено: задржавају уобичајене боје.",
|
||||
"prefs.sketch_construction_lines": "Проширени алати за помоћне праве",
|
||||
"prefs.sketch_exit_view": "Када се скица заврши",
|
||||
"prefs.sketch_exit_view.keep": "Задржи тренутни приказ",
|
||||
"prefs.sketch_exit_view.previous": "Врати се на претходни приказ",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Врати се осим ако је ротирано",
|
||||
"prefs.sketch_exit_view_note": "Куда приказ иде након Заврши скицу, Откажи или двоструког Esc.",
|
||||
"prefs.sketch_open_look_at": "Окрени камеру према скици када се отвори",
|
||||
"prefs.sketch_open_look_at_note": "Искључено: када направите или измените скицу, приказ остаје онакав какав јесте. Погледај окреће приказ према скици када то желите.",
|
||||
"prefs.sketch_recent_snap": "Аутоматски привлачи на недавне центре и средишње тачке",
|
||||
"prefs.sketch_recent_snap_note": "Током цртања показивач се привлачи тамо где се секу водичи двају последњих центара кругова или средишњих тачака правих ивица. Искључено: ти водичи служе само за приказ и показивач се не помера.",
|
||||
"prefs.sketch_selection": "Скица и избор",
|
||||
"prefs.sketch_selection_heading": "Скица и избор",
|
||||
"prefs.sketch_selection_note": "Како се скице привлаче и како кликови бирају.",
|
||||
@@ -1933,7 +2064,14 @@
|
||||
"prefs.toast_place": "Обавештења",
|
||||
"prefs.toggle_item": "Додај ставку или је поново уклони",
|
||||
"prefs.toolbar": "Трака са алатима",
|
||||
"prefs.toolbar_tabs": "Картице траке са алатима",
|
||||
"prefs.top": "Горе",
|
||||
"prefs.trackpad_zoom_modifier": "Зумирај скроловањем са два прста док држите",
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "Држите само овај тастер да зумирате према показивачу вертикалним скроловањем. Искључено задржава постојеће понашање скроловања.",
|
||||
"prefs.trackpad_zoom_modifier.off": "Искључено",
|
||||
"prefs.translucent": "Провидно",
|
||||
"prefs.under_browser": "Испод стабла модела",
|
||||
"prefs.under_cursor": "Испод показивача",
|
||||
@@ -1943,13 +2081,24 @@
|
||||
"prefs.view_confirm_corner": "У реду и Откажи у углу приказа",
|
||||
"prefs.view_confirm_corner_note": "Док је отворен дијалог или скица, квачица и крстић горе десно у приказу раде исто што и дугмад У реду и Откажи у дијалогу, односно завршавају и отказују скицу. Навигатор приказа помера се испод њих.",
|
||||
"prefs.viewport": "Прозор приказа",
|
||||
"prefs.viewport_analysis_status": "Прикажи статус анализе у прозору приказа",
|
||||
"prefs.viewport_analysis_status_help": "Приказује активне анализе изнад прозора приказа, отвара њихове легенде из сваке ставке, а тастер Esc искључује најновију анализу. Искључите да бисте вратили легенде у угловима и претходно понашање тастера Esc.",
|
||||
"prefs.viewport_background": "Позадина",
|
||||
"prefs.viewport_background_colour": "Боја",
|
||||
"prefs.viewport_background_theme": "Градијент теме",
|
||||
"prefs.wheel": "Точкић",
|
||||
"prefs.wheel_trackpad": "Точкић и додирна табла",
|
||||
"prefs.workspace": "Радни простор",
|
||||
"prefs.zoom_stop_at_model": "Заустави зумирање на моделу",
|
||||
"prefs.zoom_stop_at_model_tip": "3D миш и апликација уређаја зумирају према површини у средини приказа; зумирање превлачењем држи тачку где је превлачење почело. Искључено: зумирање може да прође кроз модел. Точкић и штипање засебно користе Зумирање према показивачу",
|
||||
"prefs.zoom_toward_cursor": "Зумирање према показивачу",
|
||||
"properties.title": "Својства: {name}",
|
||||
"recovery.days_ago": "пре {count} дана",
|
||||
"recovery.detail": "{file} · операција: {features} · аутоматски сачувано {when}",
|
||||
"recovery.discard_all": "Одбаци све",
|
||||
"recovery.discard_all_detail": "Ово се не може поништити.",
|
||||
"recovery.discard_all_title": "Одбацити аутоматска чувања ({count})?",
|
||||
"recovery.discard_all_title_one": "Одбацити 1 аутоматско чување?",
|
||||
"recovery.hours_ago": "пре {count} h",
|
||||
"recovery.just_now": "управо сада",
|
||||
"recovery.min_ago": "пре {count} min",
|
||||
@@ -2034,6 +2183,7 @@
|
||||
"render.appearance_editor.weight": "Тежина",
|
||||
"render.appearance_physics_separate": "Визуелни изглед не додељује густину, топлотне податке нити друга инжењерска својства.",
|
||||
"render.appearances": "Изгледи",
|
||||
"render.assign_help": "Кликните да примените на избор; превуците за преглед и пустите, или кликните без избора да бојите.",
|
||||
"render.availability_native": "Изворни састав; прегледајте пре примене",
|
||||
"render.availability_projection": "Подржана пројекција; погледајте опсег и изоставке",
|
||||
"render.availability_reference": "Референтни подаци; није аутоматска додела",
|
||||
@@ -2072,6 +2222,7 @@
|
||||
"render.bloom_threshold": "Праг линеарних светлих делова",
|
||||
"render.browse_capabilities": "Прегледај комплетан каталог могућности",
|
||||
"render.browse_environments": "Прегледај изворна HDR окружења",
|
||||
"render.browse_looks": "Прегледај…",
|
||||
"render.browse_native_scenes": "Прегледај изворне студије",
|
||||
"render.browse_physical": "Прегледај физичке референце",
|
||||
"render.browse_quality": "Прегледај спецификације квалитета",
|
||||
@@ -2095,6 +2246,82 @@
|
||||
"render.check_opaque": "Провидност: само непрозирне површине; алфа позадине је подржана.",
|
||||
"render.check_sorted_alpha": "Провидност: апроксимација сортираном алфом.",
|
||||
"render.check_transmission": "Провидност: физичко пропуштање.",
|
||||
"render.children.absolute_floor": "Апсолутни доњи праг",
|
||||
"render.children.adaptive": "Адаптивно",
|
||||
"render.children.add_look_reason": "Додајте изглед да бисте мењали да ли је омогућен и његову јачину.",
|
||||
"render.children.all_shots": "Сви кадрови",
|
||||
"render.children.bloom": "Сјај",
|
||||
"render.children.check": "Провера",
|
||||
"render.children.check_now": "Провери сада",
|
||||
"render.children.chromatic": "Хроматски помак",
|
||||
"render.children.compact": "Компактно",
|
||||
"render.children.contrast": "Контраст",
|
||||
"render.children.copy_image": "Копирај",
|
||||
"render.children.copy_job": "Копирај JSON посла",
|
||||
"render.children.copy_request": "Копирај JSON захтева",
|
||||
"render.children.coverage_error": "Грешка покривености",
|
||||
"render.children.cpu": "CPU праћење зрака",
|
||||
"render.children.denoise": "Смањи шум на завршеној слици",
|
||||
"render.children.depth": "Дубина путање",
|
||||
"render.children.distortion": "Изобличење",
|
||||
"render.children.edge_samples": "Узорци ивица",
|
||||
"render.children.effects_banner": "Ови ефекти захтевају GPU праћење путања. Отварање овога никад не мења методу.",
|
||||
"render.children.enable_adaptive": "Омогућите независне пробне узорке да бисте мењали адаптивне границе.",
|
||||
"render.children.enable_bloom": "Омогућите сјај да бисте мењали његову јачину, праг и полупречник.",
|
||||
"render.children.finishing": "Завршна обрада",
|
||||
"render.children.flare": "Одсјај",
|
||||
"render.children.fresnel": "Fresnel-ови слојеви",
|
||||
"render.children.ghosts": "Духови прстенова",
|
||||
"render.children.glass": "Пренос кроз стакло",
|
||||
"render.children.go_to": "Иди на {editor}",
|
||||
"render.children.grain": "Зрно",
|
||||
"render.children.halo": "Ореол",
|
||||
"render.children.hdr": "HDR",
|
||||
"render.children.keep_master": "Задржи сирови линеарни мастер",
|
||||
"render.children.last_result": "Последњи: {number} · {width} × {height} · {phase}",
|
||||
"render.children.lens_effects": "Ефекти објектива",
|
||||
"render.children.look_summary": "{tone} · изгледи: {count}",
|
||||
"render.children.looks": "Креативни изгледи",
|
||||
"render.children.memory": "Меморија",
|
||||
"render.children.method": "Метода",
|
||||
"render.children.minimum": "Минимум",
|
||||
"render.children.needs_cpu": "Потребно је CPU праћење зрака. Отварање овога никад не мења методу.",
|
||||
"render.children.nested": "Потврђени угнежђени диелектрици",
|
||||
"render.children.not_checked": "Није проверено",
|
||||
"render.children.path": "Праћење путања",
|
||||
"render.children.pilots": "Пробни узорци",
|
||||
"render.children.preview": "Подаци прегледа",
|
||||
"render.children.progressive_reason": "Изаберите Прогресивно да бисте мењали број узорака и семе.",
|
||||
"render.children.radius": "Полупречник",
|
||||
"render.children.reflect_depth": "Дубина рефлексије",
|
||||
"render.children.reflect_samples": "Узорци рефлексије",
|
||||
"render.children.regrade": "Поновна градација",
|
||||
"render.children.relative_error": "Релативна грешка",
|
||||
"render.children.render": "Рендеровање",
|
||||
"render.children.render_shot": "Рендеруј кадар",
|
||||
"render.children.renderer": "Рендерер",
|
||||
"render.children.renderers": "Рендерери",
|
||||
"render.children.request": "Овај захтев",
|
||||
"render.children.reset_finishing": "Ресетуј завршну обраду",
|
||||
"render.children.review_quality": "Прегледај спецификацију квалитета…",
|
||||
"render.children.rgb_gain": "RGB појачање",
|
||||
"render.children.samples": "Узорци",
|
||||
"render.children.sampling": "Узорковање",
|
||||
"render.children.saturation": "Засићеност",
|
||||
"render.children.scene_summary": "тела: {bodies} · троуглови: {triangles}",
|
||||
"render.children.seed": "Семе",
|
||||
"render.children.sharpening": "Изоштравање",
|
||||
"render.children.single_image": "Једна слика",
|
||||
"render.children.soft_focus": "Меки фокус",
|
||||
"render.children.streak": "Пруга",
|
||||
"render.children.strength": "Јачина",
|
||||
"render.children.studio": "Студио",
|
||||
"render.children.threshold": "Праг",
|
||||
"render.children.tone": "Тон",
|
||||
"render.children.under_hood": "Испод хаубе",
|
||||
"render.children.vignette": "Вињета",
|
||||
"render.children.workstation": "Радна станица",
|
||||
"render.choose_look": "Прво изаберите изглед у Изгледима",
|
||||
"render.chromatic_offset": "Хроматски помак ивица",
|
||||
"render.clear_stage": "Уклони сачувану сцену",
|
||||
"render.copy_request": "Копирај JSON",
|
||||
@@ -2346,8 +2573,33 @@
|
||||
"render.flare_strength": "Јачина одсјаја светлих делова",
|
||||
"render.flare_threshold": "Линеарни праг одсјаја сцене",
|
||||
"render.fold_browser": "Скупи стабло модела",
|
||||
"render.frame_aspect": "Однос страница",
|
||||
"render.frame_centre_mark": "Ознака центра",
|
||||
"render.frame_copy_limit": "Нема слободног назива за дупликат кадра",
|
||||
"render.frame_copy_name": "{name} копија {number}",
|
||||
"render.frame_custom": "Прилагођено",
|
||||
"render.frame_distance_unit": " × величина",
|
||||
"render.frame_duplicate": "Дуплицирај",
|
||||
"render.frame_exposure": "Експозиција",
|
||||
"render.frame_fov": "Видно поље",
|
||||
"render.frame_guides": "Водичи",
|
||||
"render.frame_invalid_aspect": "Неисправан унапред подешен однос страница",
|
||||
"render.frame_lens": "FOV {fov}° · ≈ {mm} mm",
|
||||
"render.frame_name": "Назив",
|
||||
"render.frame_output_size": "Величина излаза",
|
||||
"render.frame_photo": "3:2 · Фотографија",
|
||||
"render.frame_portrait": "4:5 · Портрет",
|
||||
"render.frame_presets": "Унапред подешени кадрови",
|
||||
"render.frame_presets_pending": "Стиже са уређивачем кадрова",
|
||||
"render.frame_projection": "Пројекција",
|
||||
"render.frame_render_shot": "Рендеруј овај кадар",
|
||||
"render.frame_rule_thirds": "Правило трећина",
|
||||
"render.frame_safe_area": "Безбедна зона",
|
||||
"render.frame_shot_title": "Кадар · {name}",
|
||||
"render.frame_square": "1:1 · Квадрат",
|
||||
"render.frame_tall": "9:16 · Усправно",
|
||||
"render.frame_thirds": "Трећине",
|
||||
"render.frame_wide": "16:9 · Широки екран",
|
||||
"render.gpu_depth": "Максимална дубина путање",
|
||||
"render.gpu_options_help": "Узорци, дубина, семе и експозиција чувају се са овим подешавањем. Чува се само активна метода слике.",
|
||||
"render.gpu_path_failed": "GPU праћење путања није доступно",
|
||||
@@ -2375,6 +2627,7 @@
|
||||
"render.heading_results": "РЕЗУЛТАТИ",
|
||||
"render.heading_shots": "КАДРОВИ",
|
||||
"render.hide_shots_label": "Сакриј траку кадрова",
|
||||
"render.hover_look": "{object} · {look} · кликните за избор",
|
||||
"render.image_advanced": "Напредне GPU контроле",
|
||||
"render.image_cancelled": "Рендеровање је отказано",
|
||||
"render.image_cancelling": "Отказивање",
|
||||
@@ -2521,17 +2774,95 @@
|
||||
"render.library_uniform_ack": "Користи једноличну апроксимацију без просторних или напредних ефеката",
|
||||
"render.library_usable": "Извршне пројекције",
|
||||
"render.library_users": "Корисници",
|
||||
"render.light_aim": "Усмери ка",
|
||||
"render.light_anchor_pending": "Промена координатног система светла још није подржана.",
|
||||
"render.light_azimuth": "Азимут",
|
||||
"render.light_backend_limit": "Изаберите CPU праћење зрака или изричити GPU студио да бисте мењали светла. Светла старог GPU студија остају само за читање.",
|
||||
"render.light_behaviour": "ПОНАШАЊЕ",
|
||||
"render.light_default_fill": "Допунско",
|
||||
"render.light_default_key": "Главно",
|
||||
"render.light_default_number": "Светло {number}",
|
||||
"render.light_default_rim": "Рубно",
|
||||
"render.light_delete": "Избриши",
|
||||
"render.light_distance": "Растојање",
|
||||
"render.light_duplicate": "Дуплицирај",
|
||||
"render.light_elevation": "Елевација",
|
||||
"render.light_gpu_punctual": "Тачкаста светла и рефлектори доступни су уз CPU праћење зрака.",
|
||||
"render.light_hard_shadow": "Ово светло има оштре сенке; мекоћа емитера није доступна.",
|
||||
"render.light_intensity": "Интензитет",
|
||||
"render.light_missing": "Ово светло више не постоји. Изаберите светло у стаблу модела.",
|
||||
"render.light_place_highlight": "Постави према одсјају",
|
||||
"render.light_place_pending": "Постављање према одсјају захтева избор светла у прозору приказа и још није подржано.",
|
||||
"render.light_position": "ПОЛОЖАЈ",
|
||||
"render.light_preview_help": "Приказ уживо је без сенки; површинска светла користе апроксимацију узорком из центра. Рендеровање користи потпуни модел светла.",
|
||||
"render.light_product_centre": "Центар производа",
|
||||
"render.light_size": "Величина",
|
||||
"render.light_softness": "Мекоћа",
|
||||
"render.light_temperature": "Температура боје",
|
||||
"render.light_temperature_help": "Приближна нијанса црног тела; чува се као линеарни RGB.",
|
||||
"render.light_type": "Врста",
|
||||
"render.light_type_area": "Површинско",
|
||||
"render.light_type_point": "Тачкасто",
|
||||
"render.light_type_spot": "Рефлектор",
|
||||
"render.light_type_sun": "Сунце",
|
||||
"render.light_view_only": "Само једно светло и искључена светла утичу на овај приказ и његове рендере; никад се не чувају у дизајну.",
|
||||
"render.light_world_origin": "Исходиште света",
|
||||
"render.lighting_aim_point": "Тачка циљања",
|
||||
"render.lighting_apply": "Примени подешавање",
|
||||
"render.lighting_area_samples": "Узорци површинског светла",
|
||||
"render.lighting_budget": "Буџет",
|
||||
"render.lighting_budget_help": "Бројеви су само за читање. Додајте, дуплицирајте или избришите светла да бисте их променили; метода одређује ограничења.",
|
||||
"render.lighting_colour": "Боја",
|
||||
"render.lighting_consent": "Замени усмерена светла овим подешавањем",
|
||||
"render.lighting_custom": "Прилагођена светла",
|
||||
"render.lighting_custom_help": "Избор опције Прилагођено претвара подешавање у светла која се могу мењати, свако у свом реду у стаблу.",
|
||||
"render.lighting_direction": "Смер X Y Z",
|
||||
"render.lighting_direction_help": "Или упишите смер према светлу (X Y Z).",
|
||||
"render.lighting_distance_unit": " × величина",
|
||||
"render.lighting_edge_u": "Вектор странице U",
|
||||
"render.lighting_edge_v": "Вектор странице V",
|
||||
"render.lighting_falloff": "Слабљење",
|
||||
"render.lighting_falloff_help": "Интензитет је наведен на референтном растојању.",
|
||||
"render.lighting_height": "Висина V",
|
||||
"render.lighting_minimum": "Минимум",
|
||||
"render.lighting_mute": "Искључи ово светло",
|
||||
"render.lighting_point": "Тачка",
|
||||
"render.lighting_preset": "Подешавање студија",
|
||||
"render.lighting_preset_cpu": "Подешавања студија са усмереним светлима захтевају CPU праћење зрака. GPU осветљење користи изричита сунчева и површинска светла.",
|
||||
"render.lighting_preset_row": "Подешавање",
|
||||
"render.lighting_radiance": "Радијанса",
|
||||
"render.lighting_reference": "Референца",
|
||||
"render.lighting_review_help": "Замењује списак усмерених светала. Задржава тачкаста и површинска светла, окружење, сенке, камеру и сва остала подешавања кадра.",
|
||||
"render.lighting_review_title": "Прегледај подешавање осветљења",
|
||||
"render.lighting_samples_cpu": "Узорци површинског светла важе за CPU праћење зрака.",
|
||||
"render.lighting_samples_need_area": "Додајте CPU површинско светло да бисте подесили узорке површинског светла.",
|
||||
"render.lighting_samples_reason": "Узорци површинског светла морају бити 1, 4, 16 или 64.",
|
||||
"render.lighting_shadow_cpu": "Прекидач сенки захтева CPU праћење зрака. GPU праћење путања увек баца сенке.",
|
||||
"render.lighting_shadows": "Баци сенке",
|
||||
"render.lighting_shadows_section": "Сенке и узорковање",
|
||||
"render.lighting_shape": "Облик",
|
||||
"render.lighting_solo": "Само ово светло",
|
||||
"render.lighting_source": "Извор",
|
||||
"render.lighting_source_section": "Извор светла",
|
||||
"render.lighting_spot_preserved": "Ово тачкасто светло задржава сачувани конус рефлектора док му се не промени врста.",
|
||||
"render.lighting_sun_distance": "Смер сунца не зависи од растојања и тачке циљања.",
|
||||
"render.lighting_unsupported": "неподржано",
|
||||
"render.lighting_used": "{used} од {limit}",
|
||||
"render.lighting_width": "Ширина U",
|
||||
"render.lighting_world_position": "Светски X Y Z",
|
||||
"render.lights_fixed_to": "Светла везана за",
|
||||
"render.linear_help": "Задржава 32-битни флоат RGBA мастер пре уклањања шума, експозиције, мапирања тонова, филтера и позадине. Линеарни sRGB/D65; помножен покривеношћу. Додатна меморија се изричито одобрава. Без компресије и додатних пролаза.",
|
||||
"render.linear_retain": "Задржи сирови линеарни EXR",
|
||||
"render.linear_unavailable": "Изабрани завршени кадар нема задржани EXR. Омогућите задржавање пре рендеровања; старији PNG не може да врати сирову радијансу.",
|
||||
"render.look_add": "Додај изглед боје",
|
||||
"render.look_applied": "Примењено: {name}",
|
||||
"render.look_bleach": "По узору на bleach bypass",
|
||||
"render.look_cool": "Хладно",
|
||||
"render.look_cyanotype": "По узору на цијанотипију",
|
||||
"render.look_faded": "Избледели отисак",
|
||||
"render.look_material": "Материјал",
|
||||
"render.look_mono": "Једнобојно",
|
||||
"render.look_pasted": "Изглед је налепљен",
|
||||
"render.look_sepia": "Сепија",
|
||||
"render.look_strength": "Јачина изгледа",
|
||||
"render.look_teal_orange": "Тиркизно / наранџасто",
|
||||
@@ -2607,9 +2938,11 @@
|
||||
"render.output_advanced": "Напредно",
|
||||
"render.output_backend_ready": "Спремно",
|
||||
"render.output_check": "Провери",
|
||||
"render.output_check_failed": "Провера · грешка",
|
||||
"render.output_check_help": "Покрените проверу да бисте прегледали овај захтев без покретања рендеровања.",
|
||||
"render.output_check_summary": "Провера · Напомене: {count}",
|
||||
"render.output_copy": "Копирај",
|
||||
"render.output_copy_report": "Копирај извештај",
|
||||
"render.output_destination": "Одредиште",
|
||||
"render.output_destination_help": "Одредишну датотеку изаберите при извозу завршене слике.",
|
||||
"render.output_dimensions": "Величина",
|
||||
@@ -2619,6 +2952,7 @@
|
||||
"render.output_fit": "Уклопи",
|
||||
"render.output_format": "Формат",
|
||||
"render.output_format_status": "PNG је тачна завршена слика за приказ. Необавезни GPU EXR задржава сирову линеарну радијансу сцене у формату FLOAT32 пре филтера приказа. Извоз никад не замењује кеш прегледа ни други посао.",
|
||||
"render.output_grading": "Градација",
|
||||
"render.output_image": "Слика",
|
||||
"render.output_largest": "Највише {width} × {height}",
|
||||
"render.output_lock_ratio": "Закључај однос страница",
|
||||
@@ -2628,6 +2962,8 @@
|
||||
"render.output_quality_waiting": "чека се уговор о квалитету",
|
||||
"render.output_ratio_refused": "Повезана димензија премашује ограничење величине ове методе. Претходна величина се задржава; откључајте однос или изаберите мању вредност.",
|
||||
"render.output_ready": "Спремно за рендеровање",
|
||||
"render.output_run_check": "Покрени проверу",
|
||||
"render.output_size_limit": "{method}: до {dimension} px по страни и {pixels} пиксела. Највећа величина која стаје: {width} × {height}.",
|
||||
"render.output_size_ok": "Величина је у реду · {width} × {height} px",
|
||||
"render.output_swap_orientation": "Замени ширину и висину",
|
||||
"render.output_tools_inspector": "Величину и формат измените у инспектору Излаз.",
|
||||
@@ -2644,6 +2980,7 @@
|
||||
"render.page_output": "Излаз",
|
||||
"render.page_scene": "Сцена",
|
||||
"render.paint_label": "Обоји",
|
||||
"render.painting_with": "Бојење изгледом {name}",
|
||||
"render.passive_stage": "Подлога и пасивна сцена",
|
||||
"render.passive_stage_help": "Коначни пасивни панели припадају само рендерованим сликама. Не додају CAD тела ни масу. Постављање је фиксно након примене; пресецање граница производа се одбија. CPU не даје дифузно одбијено осветљење.",
|
||||
"render.perspective": "Перспективна камера",
|
||||
@@ -2665,6 +3002,7 @@
|
||||
"render.pick_help": "Изаберите Тело, Лице или Компонента. Кликните празан простор да очистите избор; Shift или Ctrl додаје или укључује/искључује. Истицања се појављују само у живом приказу производа.",
|
||||
"render.pick_label": "Изабери",
|
||||
"render.pick_up_label": "Преузми",
|
||||
"render.pick_up_prompt": "Кликните објекат да преузмете његов изглед",
|
||||
"render.pick_waiting": "Избор производа још није подржан.",
|
||||
"render.post_contrast": "Контраст",
|
||||
"render.post_gain_b": "Појачање плаве",
|
||||
@@ -2704,13 +3042,17 @@
|
||||
"render.radial_distortion": "Радијално изобличење",
|
||||
"render.radial_fit": "Уклопи производ",
|
||||
"render.radial_save": "Сачувај кадар",
|
||||
"render.recent_looks": "Недавни изгледи",
|
||||
"render.regrade_action": "Поновна градација сировог мастера (без уклањања шума)",
|
||||
"render.regrade_help": "Прави засебан PNG из изабраног завршеног сировог мастера, користећи ове контроле приказа. Не прати зраке, не мења забележену величину, камеру ни светла и не преписује EXR. Уклањање шума се не примењује поново: сирови мастери не чувају његове водиље. Изведена слика се и даље може извести истим контролама посла.",
|
||||
"render.regrade_label": "Поновна градација",
|
||||
"render.reload_settings": "Поново учитај сачувана подешавања",
|
||||
"render.remove_override": "Уклони надјачавање",
|
||||
"render.replace_all": "Замени све",
|
||||
"render.replace_ground": "Потврди замену постојеће сцене",
|
||||
"render.replace_label": "Замени",
|
||||
"render.replace_saved_surface": "Замени постојећу сачувану везу за овај циљ",
|
||||
"render.replace_with": "Замени са",
|
||||
"render.restore_camera": "Врати сачувану камеру",
|
||||
"render.result_actual": "100%",
|
||||
"render.result_actual_help": "Један пиксел слике по пикселу екрана.",
|
||||
@@ -2762,14 +3104,28 @@
|
||||
"render.saved_surface_remove": "Уклони сачувану везу",
|
||||
"render.saved_surfaces": "Сачуване везе површина",
|
||||
"render.saved_surfaces_help": "Фиксиране уграђене мапе прате изабрани примерак у локалним милиметрима. Замењен или недостајући циљ је грешка, никад аутоматска поновна додела.",
|
||||
"render.scene_all_shots": "Сви кадрови ({count})",
|
||||
"render.scene_apply": "Примени прегледани студио",
|
||||
"render.scene_batch_reason": "За Све кадрове потребан је ред чекања за рендеровање сачуваних кадрова, који још није доступан.",
|
||||
"render.scene_check_now": "Провери сада",
|
||||
"render.scene_check_passed": "Провера је прошла · напомене: {notes}",
|
||||
"render.scene_check_stale": "Провера је застарела · проверите поново",
|
||||
"render.scene_check_unchecked": "Још није проверено · напомене: 0",
|
||||
"render.scene_consent": "Потврди замену осветљења, окружења, експозиције и сцене",
|
||||
"render.scene_light_summary": "{environment} · светла: {lights}",
|
||||
"render.scene_look_summary": "изгледи: {looks} · надјачавања: {overrides}",
|
||||
"render.scene_open_check": "Отвори проверу",
|
||||
"render.scene_preserved_fields": "Камера, узорковање, димензије, оптичке везе, CAD геометрија и инжењерски материјали се чувају.",
|
||||
"render.scene_preserves_design": "Саставите осветљење и пасивну сцену за видљиви предмет. Геометрија, инжењерски материјали и камера остају одвојени.",
|
||||
"render.scene_ready": "Спремно за рендеровање",
|
||||
"render.scene_reminder": "Сцена чува дизајн. Геометрија, инжењерска својства и CAD никад се не мењају из Рендеровања.",
|
||||
"render.scene_reminders": "Подсетници",
|
||||
"render.scene_renderer_ready": "Спремно: {renderer}",
|
||||
"render.scene_replaces": "Замењује",
|
||||
"render.scene_review": "Разреши и прегледај",
|
||||
"render.scene_review_help": "Прегледајте комплетну изворну композицију пре примене. Невезане напредне SCENE спецификације се не замењују.",
|
||||
"render.scene_scope_details": "Опсег композиције",
|
||||
"render.scene_stages": "Фазе",
|
||||
"render.search_appearances": "Претражи {count} изгледа",
|
||||
"render.setup_legacy_environment": "Ово старије подешавање користи наслеђену ротацију или интензитет окружења. Те вредности се задржавају; изричито их претворите пре чувања пуног посла слике.",
|
||||
"render.setup_name": "Назив подешавања",
|
||||
@@ -2782,7 +3138,22 @@
|
||||
"render.shell_tab_camera": "КАМЕРА РЕНДЕРА",
|
||||
"render.shell_tab_lighting": "ОСВЕТЉЕЊЕ",
|
||||
"render.shell_tab_scene": "СЦЕНА РЕНДЕРА",
|
||||
"render.shot_aperture": "Отвор бленде",
|
||||
"render.shot_distance": "Растојање",
|
||||
"render.shot_dof": "Дубинска оштрина",
|
||||
"render.shot_duplicate": "Дуплицирај сачувани кадар",
|
||||
"render.shot_edit_output": "Измени у Излазу",
|
||||
"render.shot_exposure_reason": "Експозиција захтева CPU праћење зрака или GPU праћење путања.",
|
||||
"render.shot_exposure_section": "Експозиција",
|
||||
"render.shot_focus_distance": "Растојање фокуса",
|
||||
"render.shot_fov_reason": "Видно поље захтева перспективну пројекцију.",
|
||||
"render.shot_frame_subject": "Уоквири предмет",
|
||||
"render.shot_invalid_camera": "Вредности камере морају бити коначне и у дозвољеном опсегу.",
|
||||
"render.shot_lens": "Објектив",
|
||||
"render.shot_lens_enable_reason": "Омогућите дубинску оштрину да бисте мењали отвор бленде и растојање фокуса.",
|
||||
"render.shot_lens_gpu_reason": "Дубинска оштрина захтева GPU праћење путања.",
|
||||
"render.shot_lens_perspective_reason": "Дубинска оштрина захтева перспективну пројекцију.",
|
||||
"render.shot_look_selection": "Усмери на избор",
|
||||
"render.shot_manager": "Сачувани кадрови",
|
||||
"render.shot_new_name": "Назив новог кадра",
|
||||
"render.shot_remove": "Уклони сачувани кадар",
|
||||
@@ -2790,6 +3161,9 @@
|
||||
"render.shot_remove_title": "Уклонити сачувани кадар?",
|
||||
"render.shot_rename": "Преименуј сачувани кадар",
|
||||
"render.shot_saved_only": "Прво сачувајте тренутни нацрт. Дуплицирање и преименовање чувају тачне сачуване опције и референце на ресурсе.",
|
||||
"render.shot_selection_reason": "Изаберите тело или лице на које ћете усмерити камеру.",
|
||||
"render.shot_size": "Величина",
|
||||
"render.shot_target": "Циљ",
|
||||
"render.shots_camera_changed": "Камера је промењена откако је овај кадар сачуван",
|
||||
"render.shots_name_help": "Унесите јединствен назив за тренутни кадар.",
|
||||
"render.shots_no_result": "Још нема рендера",
|
||||
@@ -3052,6 +3426,7 @@
|
||||
"select an axis": "изаберите осу",
|
||||
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "прво изаберите осу, праву или кружну ивицу, или лице цилиндра, конуса или торуса",
|
||||
"select bodies first": "прво изаберите тела",
|
||||
"select components first": "прво изаберите компоненте",
|
||||
"select corner points, or the two lines of one corner": "изаберите тачке углова или две линије једног угла",
|
||||
"select one corner point, or the two lines of one corner": "изаберите једну тачку угла или две линије једног угла",
|
||||
"select sheet edges first": "прво изаберите ивице лима",
|
||||
@@ -3070,6 +3445,7 @@
|
||||
"settings.double_click_components": "Двоструки клик на компоненту је активира, а повезану компоненту мења на месту",
|
||||
"settings.frame_rate_details_note": "Додаје график времена последњих кадрова са бројем исцртаних троуглова, хистограм времена кадрова и шта је GPU нацртао. Кликните број кадрова у секунди у приказу да их прикажете или сакријете.",
|
||||
"settings.frame_rate_note": "Приказује број кадрова у секунди у доњем десном углу приказа.",
|
||||
"settings.insert_lists_open_designs": "Уметни дизајн прво наводи дизајне отворене у другим картицама",
|
||||
"settings.measure_axis_distances": "Прикажи растојања X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "Приказуј компоненте растојања по светским осама уз укупно растојање док је Мерење отворено.",
|
||||
"settings.msaa_applies_on_restart": "Углађивање ивица примењује се при следећем покретању SolidCraft-а",
|
||||
@@ -3094,6 +3470,10 @@
|
||||
"shortcut.unpin": "Откачи",
|
||||
"sketch is missing": "скица недостаје",
|
||||
"sketch.degrees_of_freedom": "Степени слободе: {count}",
|
||||
"sketch.dimension_added_driven": "Скица већ одређује ту коту, па је додата као изведена (референтна) кота",
|
||||
"sketch.dimension_applied": "Кота је примењена",
|
||||
"sketch.dimension_applied_defined": "Кота је примењена; параметар `{name}` је дефинисан",
|
||||
"sketch.dimension_applied_renamed": "Кота је примењена; параметар је назван `{name}`",
|
||||
"sketch.dof_left": "Преостали степени слободе: {count}",
|
||||
"sketch.dof_left_one": "Преостали степени слободе: {count}",
|
||||
"sketch.draw_curves": "Цртај као {linetype}",
|
||||
@@ -3128,6 +3508,8 @@
|
||||
"sketch_text.use_font_file": "Користи датотеку фонта {path}",
|
||||
"solid": "пуно",
|
||||
"status.editing": "Измена: {name}",
|
||||
"status.navigation": "Мапирање миша: {mapping}",
|
||||
"status.navigation_tip": "Како миш помера приказ. Кликните да изаберете друго мапирање",
|
||||
"status.under_constrained": "Недовољно ограничено (степени слободе: {count})",
|
||||
"status.under_constrained_one": "Недовољно ограничено ({count} степен слободе)",
|
||||
"status.units_tip": "Јединице дизајна. Кликните да их промените",
|
||||
@@ -3161,8 +3543,10 @@
|
||||
"timeline.delete_folders_tip": "Задржи њихове операције и угнежђене фасцикле у временској траци",
|
||||
"timeline.delete_folders_with_features_tip": "Избриши фасцикле са свим операцијама у њима и њихове угнежђене фасцикле",
|
||||
"timeline.delete_many": "Избриши изабране операције: {count}",
|
||||
"timeline.edited_rolled_back": "Операција {name} је промењена, али је после ознаке враћања, па није изграђена: померите ознаку иза ње да видите резултат",
|
||||
"timeline.feature_error": "Грешка: {message}",
|
||||
"timeline.feature_hint": "Двапут кликните за измену · превуците за промену редоследа · десни клик за више",
|
||||
"timeline.feature_rolled_back": "Враћено уназад: после ознаке враћања, па није изграђено",
|
||||
"timeline.feature_warning": "Упозорење: {message}",
|
||||
"timeline.group": "Нова фасцикла операција",
|
||||
"timeline.move_many": "Премести ставке временске траке",
|
||||
@@ -3244,6 +3628,10 @@
|
||||
"ui.3d_mouse_offer": "Калибрација 3D миша исправља замењене или обрнуте осе и подешава његову брзину и осећај.",
|
||||
"ui.3d_mouse_offer_never": "Не приказуј више",
|
||||
"ui.3d_mouse_offer_swap": "Пребаци на Hidraw (директни драјвер)",
|
||||
"ui.3d_mouse_orbit": "Орбитирање",
|
||||
"ui.3d_mouse_orbit_classic": "Класично",
|
||||
"ui.3d_mouse_orbit_tip": "Праћено: 3D миш окреће приказ око дела модела који је у средини приказа када окретање почне, означеног бледом куглом. Класично: око центра приказа",
|
||||
"ui.3d_mouse_orbit_traced": "Праћено",
|
||||
"ui.3d_mouse_reading": "Очитање",
|
||||
"ui.3d_mouse_reset_axes": "Ресетуј доделу оса",
|
||||
"ui.3d_mouse_reset_view": "Ресетуј приказ",
|
||||
@@ -3280,6 +3668,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Закрените капицу супротно од казаљке на сату, држите је, а затим пустите.",
|
||||
"ui.3d_mouse_switch_cap": "Калибриши као Повратак у центар",
|
||||
"ui.3d_mouse_switch_trackball": "Калибриши као трекбол",
|
||||
"ui.3d_mouse_use_direct": "Користи директни драјвер",
|
||||
"ui.3d_mouse_use_direct_tip": "Читај 3D миш директно (hidraw) уместо преко spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "Оса приказа",
|
||||
"ui.3d_mouse_view_off": "Искључено",
|
||||
"ui.3d_mouse_view_off_tip": "Профил драјвера 3D миша искључује ову осу, па њено кретање не помера приказ. Избор кретања друге осе овде их замењује, а то кретање престаје да помера приказ.",
|
||||
@@ -3596,6 +3986,7 @@
|
||||
"ui.circle": "Круг",
|
||||
"ui.circular_pattern": "Кружни низ",
|
||||
"ui.clear": "Очисти",
|
||||
"ui.clear_print_face": "Уклони површину за штампу",
|
||||
"ui.clear_recent": "Очисти недавно",
|
||||
"ui.clear_the_selection": "Поништи избор",
|
||||
"ui.click_selects_whole_bodies": "Клик бира цела тела",
|
||||
@@ -3630,6 +4021,15 @@
|
||||
"ui.constant": "Константно",
|
||||
"ui.constraints_conflict": "Ограничења су у сукобу",
|
||||
"ui.construction": "Помоћна",
|
||||
"ui.construction.angle_hint": "Помоћна права: кликните тачку, па упишите угао или изаберите смер",
|
||||
"ui.construction.bisector_hint": "Симетрала: изаберите две праве линије које се секу, па жељено решење",
|
||||
"ui.construction.common_hint": "Заједничка тангента: изаберите два круга или лука, па жељено решење",
|
||||
"ui.construction.contact_hint": "Тангента: изаберите круг/лук или отворени сплајн/конику, па тачку додира (криве слободног облика: крајње тачке)",
|
||||
"ui.construction.external_hint": "Тангента: изаберите круг или лук, спољашњу тачку, па жељено решење",
|
||||
"ui.construction.free_hint": "Помоћна права: кликните две тачке; десним кликом почните испочетка",
|
||||
"ui.construction.point_hint": "Помоћна права: кликните тачку кроз коју пролази",
|
||||
"ui.construction.reference_hint": "Помоћна права: изаберите праву линију, па тачку; десним кликом промените референцу",
|
||||
"ui.construction.ribbon_label": "Пом. праве",
|
||||
"ui.context_menu": "Контекстни мени",
|
||||
"ui.continuity_g0": "G0 прегиб",
|
||||
"ui.continuity_g1": "G1 тангентно",
|
||||
@@ -3670,6 +4070,7 @@
|
||||
"ui.design_properties.part_number": "Број дела",
|
||||
"ui.design_properties.project": "Пројекат",
|
||||
"ui.design_properties.revision": "Ревизија",
|
||||
"ui.design_saved": "Сачувано: {path}",
|
||||
"ui.diameter": "Пречник",
|
||||
"ui.dimension": "Кота",
|
||||
"ui.direct_interaction": "Директна интеракција",
|
||||
@@ -3720,6 +4121,14 @@
|
||||
"ui.end_scale": "Крајње скалирање",
|
||||
"ui.entities": "Елементи",
|
||||
"ui.equal": "Једнакост",
|
||||
"ui.equation_end": "Крај",
|
||||
"ui.equation_explicit": "Експлицитни",
|
||||
"ui.equation_form": "Облик",
|
||||
"ui.equation_note": "Променљива је обичан број: sin(t) је узима у радијанима. Резултат без јединице је у јединици дизајна.",
|
||||
"ui.equation_parametric": "Параметарски",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Еквивалентни полупречник",
|
||||
"ui.expand": "Прошири",
|
||||
"ui.exportDxf": "Извези DXF…",
|
||||
@@ -3785,6 +4194,7 @@
|
||||
"ui.heading_design": "ДИЗАЈН",
|
||||
"ui.heading_draft": "НАГИБ",
|
||||
"ui.heading_edit": "ИЗМЕНИ",
|
||||
"ui.heading_equation_curve": "КРИВА ПО ЈЕДНАЧИНИ",
|
||||
"ui.heading_extrude": "ЕКСТРУДИРАЈ",
|
||||
"ui.heading_fillet": "ЗАОБЉЕЊЕ",
|
||||
"ui.heading_finish_editing": "ЗАВРШИ ИЗМЕНУ",
|
||||
@@ -3876,6 +4286,10 @@
|
||||
"ui.import_ellipsis": "Увези…",
|
||||
"ui.infinite": "Бесконачно",
|
||||
"ui.insert": "Уметни",
|
||||
"ui.insert_design.browse": "Прегледај…",
|
||||
"ui.insert_design.open_designs": "Отворени дизајни",
|
||||
"ui.insert_design.saved_file": "Дизајн {name} има несачуване промене, па је уметнута његова сачувана датотека. Сачувајте га, а затим покрените Ажурирај везе да бисте унели промене.",
|
||||
"ui.insert_design.unsaved": "Несачуване промене",
|
||||
"ui.inspect": "Прегледај",
|
||||
"ui.intersect": "Пресек",
|
||||
"ui.isolate": "Изолуј",
|
||||
@@ -4019,12 +4433,29 @@
|
||||
"ui.polygon": "Полигон",
|
||||
"ui.preferences": "Подешавања",
|
||||
"ui.press_a_key": "притисните тастер…",
|
||||
"ui.print_face_cleared": "{body}: површина за штампу уклоњена",
|
||||
"ui.print_face_input": "Површина за штампу",
|
||||
"ui.print_face_one_body": "Површина за штампу припада једном телу: пошаљите то тело само да бисте је променили",
|
||||
"ui.print_face_pick": "Изаберите равну површину пуног тела да постане површина за штампу",
|
||||
"ui.print_face_set": "{body}: површина за штампу постављена; Пошаљи у слајсер полаже тело на њу",
|
||||
"ui.profile": "Профил",
|
||||
"ui.profile_plane": "Раван профила",
|
||||
"ui.profiles": "Профили",
|
||||
"ui.project": "Пројектуј",
|
||||
"ui.project_face_edges_sketch": "Пројектуј ивице лица у нове скице",
|
||||
"ui.properties": "Својства",
|
||||
"ui.properties.copy_matrix": "Копирај матрицу",
|
||||
"ui.properties.first_moments": "Статички моменти",
|
||||
"ui.properties.inertia": "Момент инерције",
|
||||
"ui.properties.inertia_note": "У односу на центар масе, у светским осама (g·{unit}²)",
|
||||
"ui.properties.inertia_unavailable": "Није доступно: мрежа једног тела није затворена.",
|
||||
"ui.properties.inertia_x": "Ixx, Ixy, Ixz",
|
||||
"ui.properties.inertia_y": "Iyx, Iyy, Iyz",
|
||||
"ui.properties.inertia_z": "Izx, Izy, Izz",
|
||||
"ui.properties.measuring": "Мерење…",
|
||||
"ui.properties.measuring_failed": "Мерење је заустављено пре завршетка.",
|
||||
"ui.properties.principal_axis": "Главна оса {number}",
|
||||
"ui.properties.principal_moments": "Главни моменти",
|
||||
"ui.pull_direction": "Смер вађења из калупа",
|
||||
"ui.quality": "Квалитет",
|
||||
"ui.quantity": "Број",
|
||||
@@ -4070,6 +4501,7 @@
|
||||
"ui.revolve": "Ротирај",
|
||||
"ui.ribbon_exit": "Изађи",
|
||||
"ui.ribbon_labels": "Прикажи текст испод икона на траци",
|
||||
"ui.ribbon_menus_skip_pinned": "Изостави прикачене команде из падајућих менија",
|
||||
"ui.ribbon_pin_footer": "Прикачене команде приказују се на траци. Задржите показивач изнад реда да га прикачите или откачите.",
|
||||
"ui.ribbon_workspace": "Радни простор",
|
||||
"ui.right": "Десно",
|
||||
@@ -4087,6 +4519,7 @@
|
||||
"ui.select": "Изабери",
|
||||
"ui.selectOther": "Изабери друго…",
|
||||
"ui.selectTangentChain": "Изабери тангентни ланац",
|
||||
"ui.select_all": "Изабери све",
|
||||
"ui.selection": "Избор",
|
||||
"ui.selection_modifiers": "Модификатори избора",
|
||||
"ui.selection_shift_add_only": "Shift+клик додаје без уклањања",
|
||||
@@ -4123,7 +4556,11 @@
|
||||
"ui.sketch": "Скица",
|
||||
"ui.sketch_dimension": "Кота скице",
|
||||
"ui.sketch_grid": "Мрежа скице",
|
||||
"ui.sketch_intersect_geometry": "Геометрија",
|
||||
"ui.sketch_intersect_projection_link": "Веза пројекције",
|
||||
"ui.sketch_intersect_selection_filter": "Филтер избора",
|
||||
"ui.sketch_modifiers": "Модификатори скице",
|
||||
"ui.sketch_project_geometry": "Геометрија",
|
||||
"ui.sketch_scale": "Скалирање скице",
|
||||
"ui.sketches": "Скице",
|
||||
"ui.slice": "Пресеци",
|
||||
@@ -4170,6 +4607,11 @@
|
||||
"ui.symmetric": "Симетрично",
|
||||
"ui.symmetry": "Симетрија",
|
||||
"ui.system": "Систем",
|
||||
"ui.tab_assemble": "Склоп",
|
||||
"ui.tab_manage": "Управљање",
|
||||
"ui.tab_sheet_metal": "Лим",
|
||||
"ui.tab_view": "Приказ",
|
||||
"ui.tab_weldments": "Заварене конструкције",
|
||||
"ui.tangent": "Тангентно",
|
||||
"ui.taper_angle": "Угао сужења",
|
||||
"ui.tapped": "Са навојем",
|
||||
@@ -4185,6 +4627,7 @@
|
||||
"ui.tip_angle": "Угао врха",
|
||||
"ui.to_object": "До објекта",
|
||||
"ui.tool_direction": "Смер алата",
|
||||
"ui.toolbar_tabs_hidden": "Све картице траке са алатима су скривене. Кликните + или кликните десним дугметом овде да прикажете неку.",
|
||||
"ui.top": "Одозго",
|
||||
"ui.top_diameter": "Горњи пречник",
|
||||
"ui.top_radius": "Горњи полупречник",
|
||||
@@ -4222,6 +4665,8 @@
|
||||
"ui.view_centre": "Центар приказа",
|
||||
"ui.viewport_status_clear": "Искључи {name}",
|
||||
"ui.viewport_status_clear_hint": "Искључи {name} · Esc",
|
||||
"ui.viewport_status_edges": "Ивица: {count}",
|
||||
"ui.viewport_status_from": "из смера {direction}",
|
||||
"ui.viewport_status_key": "Прикажи легенду за {name}",
|
||||
"ui.viewport_status_minimum_radius": "Минимални полупречник",
|
||||
"ui.viewport_status_pairs": "Парова: {count}",
|
||||
@@ -4231,6 +4676,7 @@
|
||||
"ui.visual_shaded_with_edges": "Осенчено са ивицама",
|
||||
"ui.visual_style": "Визуелни стил",
|
||||
"ui.visual_wireframe": "Жичани модел",
|
||||
"ui.wheel_zoom_speed": "Брзина зумирања точкићем миша",
|
||||
"ui.width": "Ширина",
|
||||
"ui.window_system": "Систем прозора",
|
||||
"ui.window_system_auto": "Аутоматски",
|
||||
@@ -4261,7 +4707,9 @@
|
||||
"update.button": "Ажурирај",
|
||||
"update.button_version": "Ажурирај на {version}",
|
||||
"update.check_automatically": "Аутоматски проверавај ажурирања",
|
||||
"update.check_for_updates": "Провери ажурирања",
|
||||
"update.check_now": "Провери сада",
|
||||
"update.check_unavailable": "Провера ажурирања није доступна за ову инсталацију.",
|
||||
"update.checking": "Провера…",
|
||||
"update.copy": "Копирај",
|
||||
"update.dmg_opened": "Слика диска је отворена и проверена: превуците SolidCraft у Applications, замените стару копију, а затим поново покрените SolidCraft.",
|
||||
@@ -4284,6 +4732,9 @@
|
||||
"update.prefs_managed": "Ово је SolidCraft {version}, којим управља {manager}. Провера пита GitHub за најновије издање и не шаље ништа друго; ажурирајте SolidCraft у {manager}.",
|
||||
"update.prefs_note": "Ово је SolidCraft {version} ({kind}). Провера пита GitHub за најновије издање и не шаље ништа друго.",
|
||||
"update.prefs_web": "Поново учитајте страницу да добијете најновију веб апликацију. Ако мрежа није доступна или се ажурирање не може преузети на време, отвара се сачувана верзија; преузимање у току наставља се за следеће поновно учитавање.",
|
||||
"update.refresh_checking": "Провера најновијег издања…",
|
||||
"update.refresh_fallback": "Није било могуће проверити да ли постоји новије издање; ажурирање на верзију {version}, пронађену раније.",
|
||||
"update.refresh_selected": "Ажурирање на {version}.",
|
||||
"update.release_page": "Отвори страницу издања",
|
||||
"update.restart": "Поново покрени сада",
|
||||
"update.restart_later": "Касније",
|
||||
|
||||
@@ -181,6 +181,8 @@
|
||||
"Designs you open or save appear here.": "Açtığınız veya kaydettiğiniz tasarımlar burada görünür.",
|
||||
"Determined by To Object. Choose Angle to edit the angular extent.": "Nesneye kadar seçeneğiyle belirlenir. Açısal kapsamı düzenlemek için Açı seçeneğini seçin.",
|
||||
"Diameter": "Çap",
|
||||
"Did this assembly open the wrong way up?": "Bu montaj yanlış yönde mi açıldı?",
|
||||
"Did this part open the wrong way up?": "Bu parça yanlış yönde mi açıldı?",
|
||||
"Dimension new shapes": "Yeni şekillere ölçü ver",
|
||||
"Direction": "Yön",
|
||||
"Discard": "At",
|
||||
@@ -204,6 +206,7 @@
|
||||
"Edges": "Kenarlar",
|
||||
"Edit": "Düzenle",
|
||||
"Edit Profile Sketch": "Profil eskizini düzenle",
|
||||
"Edit shortcuts": "Kısayolları düzenle",
|
||||
"Enable rule": "Kuralı etkinleştir",
|
||||
"Enabled": "Etkin",
|
||||
"End Radius": "Bitiş yarıçapı",
|
||||
@@ -466,6 +469,7 @@
|
||||
"Radius": "Yarıçap",
|
||||
"Radius Fit": "Yarıçap uydurma",
|
||||
"Ratio": "Oran",
|
||||
"Read-only list: shortcuts can't be changed here.": "Salt okunur liste: kısayollar burada değiştirilemez.",
|
||||
"Reattach selected face": "Seçili yüze yeniden bağla",
|
||||
"Recover": "Kurtar",
|
||||
"Recover unsaved design?": "Kaydedilmemiş tasarım kurtarılsın mı?",
|
||||
@@ -599,6 +603,7 @@
|
||||
"Square": "Kare",
|
||||
"Stand it up": "Dik çevir",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Dik çevir: X etrafında çeyrek tur; geri alınabilen tek bir Taşı özelliği olarak eklenir.",
|
||||
"Stand this assembly up?": "Bu montaj dik çevrilsin mi?",
|
||||
"Stand this part up?": "Bu parça dik çevrilsin mi?",
|
||||
"Start angle": "Başlangıç açısı",
|
||||
"Start bulge": "Başlangıç şişkinliği",
|
||||
@@ -649,6 +654,7 @@
|
||||
"Third point": "Üçüncü nokta",
|
||||
"This child is shared. Deleting it removes it from every copy of its parent.": "Bu alt öğe paylaşılıyor. Silindiğinde üst öğesinin tüm kopyalarından kaldırılır.",
|
||||
"This child is shared. Position changes apply to every copy of its parent.": "Bu alt öğe paylaşılıyor. Konum değişiklikleri üst öğesinin tüm kopyalarına uygulanır.",
|
||||
"This component is inside a subassembly placed more than once: aligning it moves it in every placement.": "Bu bileşen, birden fazla kez yerleştirilmiş bir alt montajın içinde: onu hizalamak, onu her yerleşimde taşır.",
|
||||
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Bu yüz kalıcı bir bağlama sağlayamaz. Başka bir yüz seçin veya açıkça sabit bir düzlem kullanın.",
|
||||
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Bu görüntü henüz GitHub'a eklenmedi. Kopyalayın veya kaydedin, ardından GitHub'a ekleyin.",
|
||||
"Thread depth": "Diş derinliği",
|
||||
@@ -769,6 +775,8 @@
|
||||
"at the face": "yüzde",
|
||||
"bom.group_children": "Alt parçalar kendi parçalarının satırında",
|
||||
"browser.body_name": "Gövde {number}",
|
||||
"browser.calibrate_click_a": "A Noktası için görüntüye tıklayın veya koordinatlarını yazın.",
|
||||
"browser.calibrate_click_b": "B Noktası için görüntüye tıklayın veya koordinatlarını yazın.",
|
||||
"browser.calibrate_title": "Kalibre et: {name}",
|
||||
"browser.capture_many": "{count} bileşen taşındı ancak konumları yakalanmadı.",
|
||||
"browser.capture_note": "Konumu yakala yeni konumu korur; Konumu geri al önceki konuma döndürür.",
|
||||
@@ -790,6 +798,11 @@
|
||||
"cam.roller": "Makara",
|
||||
"cam.roller_pick": "Makara (isteğe bağlı)",
|
||||
"cam.tip_pick": "Uç (isteğe bağlı)",
|
||||
"camera.shot_pitch": "Yatıklık",
|
||||
"camera.shot_roll": "Yuvarlanma",
|
||||
"camera.shot_yaw": "Sapma",
|
||||
"canvas.decal_place_hint": "Çıkartmayı yerleştirmek için bir yüze tıklayın",
|
||||
"canvas.place_hint": "Tuvali yerleştirmek için bir düzleme veya yüze tıklayın",
|
||||
"choose a profile": "bir profil seçin",
|
||||
"choose the cam's and the follower's joints": "kamın ve izleyicinin bağlantılarını seçin",
|
||||
"choose the joints to couple": "eşlenecek bağlantıları seçin",
|
||||
@@ -797,12 +810,16 @@
|
||||
"click sketch curves": "eskiz eğrilerine tıklayın",
|
||||
"cmd.appearance_assign": "Görünüm",
|
||||
"cmd.appearance_chain": "Görünüm zinciri",
|
||||
"cmd.appearance_copy": "Görünümü Kopyala",
|
||||
"cmd.appearance_favorite": "Favori Görünüm",
|
||||
"cmd.appearance_library": "Görünüm kitaplığı",
|
||||
"cmd.appearance_list": "Görünümleri listele",
|
||||
"cmd.appearance_paint": "Görünümü Boya",
|
||||
"cmd.appearance_paste": "Görünümü Yapıştır",
|
||||
"cmd.appearance_pick_up": "Görünümü Al",
|
||||
"cmd.appearance_replace": "Görünümü Değiştir",
|
||||
"cmd.assembly_bom": "Malzeme listesi",
|
||||
"cmd.body.print_face": "Baskı yüzeyi",
|
||||
"cmd.body_rename": "Gövdeyi yeniden adlandır",
|
||||
"cmd.browser_collapse_all": "Tümünü Daralt",
|
||||
"cmd.browser_expand_all": "Tümünü Genişlet",
|
||||
@@ -810,6 +827,7 @@
|
||||
"cmd.browser_move": "Tarayıcı öğelerini taşı",
|
||||
"cmd.browser_order": "Tarayıcı öğelerini sırala",
|
||||
"cmd.browser_rename_group": "Grubu yeniden adlandır",
|
||||
"cmd.browser_reparent": "Bileşene Taşı",
|
||||
"cmd.browser_ungroup": "Grubu çöz",
|
||||
"cmd.browser_visibility": "Göster/Gizle",
|
||||
"cmd.canvas_calibrate": "Tuvali kalibre et",
|
||||
@@ -836,7 +854,9 @@
|
||||
"cmd.component_metadata": "Parça özellikleri",
|
||||
"cmd.component_metadata_set": "Parça özelliklerini değiştir",
|
||||
"cmd.component_move_bodies": "Gövdeleri bileşene taşı",
|
||||
"cmd.component_move_features": "Özellikleri bileşene taşı",
|
||||
"cmd.component_move_sketches": "Eskizleri bileşene taşı",
|
||||
"cmd.component_paste_from_design": "Başka Bir Tasarımdan Yapıştır",
|
||||
"cmd.component_paste_new": "Yeni olarak yapıştır",
|
||||
"cmd.component_properties": "Bileşenin fiziksel özellikleri",
|
||||
"cmd.component_relink": "Kaynağı yeniden bağla",
|
||||
@@ -973,6 +993,7 @@
|
||||
"cmd.motion_trace": "Hareket izi",
|
||||
"cmd.motion_trace_edit": "Hareket İzini Düzenle",
|
||||
"cmd.motion_trace_keep": "Hareket izini koru",
|
||||
"cmd.occurrence_align": "Örneği Hizala",
|
||||
"cmd.occurrence_copy": "Yapıştır (örnek)",
|
||||
"cmd.occurrence_drag": "Tekrarı Taşı",
|
||||
"cmd.occurrence_ground": "Sabitle",
|
||||
@@ -1030,11 +1051,17 @@
|
||||
"cmd.render_library_surface_unbind": "Yüzey Bağlamını Kaldır",
|
||||
"cmd.render_library_targets": "Render Kitaplık Hedeflerini Bul",
|
||||
"cmd.render_lights_add": "Işık Ekle",
|
||||
"cmd.render_lights_duplicate": "Render Işığını Çoğalt",
|
||||
"cmd.render_lights_list": "Render Işıklarını Listele",
|
||||
"cmd.render_lights_mute": "Işığı Sustur",
|
||||
"cmd.render_lights_remove": "Render Işığını Kaldır",
|
||||
"cmd.render_lights_set": "Render Işığını Ayarla",
|
||||
"cmd.render_lights_solo": "Işığı Solo Yap",
|
||||
"cmd.render_optics_bind": "Optik Bağlamı Kaydet",
|
||||
"cmd.render_optics_unbind": "Optik Bağlamı Kaldır",
|
||||
"cmd.render_output_size": "Render Çıktı Boyutunu Ayarla",
|
||||
"cmd.render_preflight": "Render isteğini kontrol et",
|
||||
"cmd.render_preflight_copy": "Render Kontrol Raporunu Kopyala",
|
||||
"cmd.render_preset_apply": "Yerli Stüdyoyu Uygula",
|
||||
"cmd.render_preset_resolve": "Yerli Stüdyoyu İncele",
|
||||
"cmd.render_quality_prepare": "Sabit Örnekleme Bütçesini İncele",
|
||||
@@ -1057,6 +1084,13 @@
|
||||
"cmd.render_start": "Resmi render et",
|
||||
"cmd.render_status": "Render ilerlemesi",
|
||||
"cmd.select_clear": "Seçimi temizle",
|
||||
"cmd.settings_profile_apply": "Ayar Profilini Uygula",
|
||||
"cmd.settings_profile_delete": "Ayar Profilini Sil",
|
||||
"cmd.settings_profile_export": "Ayar Profilini Dışa Aktar",
|
||||
"cmd.settings_profile_import": "Ayar Profilini İçe Aktar",
|
||||
"cmd.settings_profile_list": "Ayar Profilleri",
|
||||
"cmd.settings_profile_rename": "Ayar Profilini Yeniden Adlandır",
|
||||
"cmd.settings_profile_save": "Ayar Profilini Kaydet",
|
||||
"cmd.sheet_convert": "Sac metale dönüştür",
|
||||
"cmd.sheet_export_bend_table": "Büküm tablosunu dışa aktar",
|
||||
"cmd.sheet_export_dxf": "Açınımı DXF olarak dışa aktar",
|
||||
@@ -1070,6 +1104,16 @@
|
||||
"cmd.sheet_refold": "Yeniden katla",
|
||||
"cmd.sheet_rules": "Sac metal kurallarını listele",
|
||||
"cmd.sheet_unfold": "Katlamayı aç",
|
||||
"cmd.sketch.construction_line": "Yardımcı doğru",
|
||||
"cmd.sketch.construction_line.angle": "Açılı yardımcı doğru",
|
||||
"cmd.sketch.construction_line.bisector": "Açıortay",
|
||||
"cmd.sketch.construction_line.horizontal": "Yatay yardımcı doğru",
|
||||
"cmd.sketch.construction_line.parallel": "Paralel yardımcı doğru",
|
||||
"cmd.sketch.construction_line.perpendicular": "Dik yardımcı doğru",
|
||||
"cmd.sketch.construction_line.tangent_at": "Eğri noktasındaki teğet",
|
||||
"cmd.sketch.construction_line.tangent_external": "Dış noktadan geçen teğet",
|
||||
"cmd.sketch.construction_line.tangent_two": "Ortak teğet",
|
||||
"cmd.sketch.construction_line.vertical": "Dikey yardımcı doğru",
|
||||
"cmd.sketch_arc3d": "3B Yay",
|
||||
"cmd.sketch_arc_center_point": "Merkez noktalı yay",
|
||||
"cmd.sketch_arc_tangent": "Teğet yay",
|
||||
@@ -1102,6 +1146,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Çizim Boyutu",
|
||||
"cmd.sketch_edit": "Eskizi düzenle",
|
||||
"cmd.sketch_edit_text": "Metni düzenle",
|
||||
"cmd.sketch_equation_curve": "Denklem Eğrisi",
|
||||
"cmd.sketch_equation_curve_edit": "Denklem Eğrisini Düzenle",
|
||||
"cmd.sketch_export_dxf": "DXF olarak kaydet",
|
||||
"cmd.sketch_finish_auto_constrain": "Otomatik kısıtlamayla bitir",
|
||||
"cmd.sketch_fit_curves_to_section": "Eğrileri ağ kesitine uydur",
|
||||
@@ -1198,6 +1244,7 @@
|
||||
"cmd.view.render_browser": "Render tarayıcısı",
|
||||
"cmd.view.render_dock": "Render panelini taşı",
|
||||
"cmd.view.render_focus": "Render odak görünümü",
|
||||
"cmd.view.status_items": "Görünüm Alanı Durum Öğeleri",
|
||||
"cmd.view_ambient_occlusion": "Ortam tıkanması",
|
||||
"cmd.view_angle_readout": "Görünüm açıları",
|
||||
"cmd.view_apply": "Adlandırılmış görünümü geri yükle",
|
||||
@@ -1219,6 +1266,7 @@
|
||||
"cmd.view_normal_to": "Seçime Dik",
|
||||
"cmd.view_previous_tab": "Önceki Sekme",
|
||||
"cmd.view_rename": "Adlandırılmış görünümü yeniden adlandır",
|
||||
"cmd.view_render_frame": "Render Kadraj Kılavuzları",
|
||||
"cmd.view_right": "Sağ Görünüm",
|
||||
"cmd.view_save": "Yeni adlandırılmış görünüm",
|
||||
"cmd.view_shots_strip": "Çekim Şeridi",
|
||||
@@ -1229,10 +1277,14 @@
|
||||
"color.copy": "Renk değerlerini kopyalamak için tıklayın",
|
||||
"color.edit": "Rengi düzenlemek için tıklayın",
|
||||
"color.gamma": "Renk değerleri 0-255 gama uzayında gösteriliyor",
|
||||
"color.hex": "Hex",
|
||||
"color.hex_help": "#rrggbb veya #rrggbbaa girin; altı hane opaklığı korur",
|
||||
"color.hex_hint": "#rrggbb",
|
||||
"color.hue": "Ton",
|
||||
"color.linear": "Renk değerleri 0-1 doğrusal uzayda gösteriliyor",
|
||||
"color.saturation_value": "Doygunluk ve değer",
|
||||
"color.selected": "Seçili renk",
|
||||
"config.column_filter_empty": "Eşleşen sütun yok",
|
||||
"contact.components_count": "{count} bileşen",
|
||||
"contact.enabled_label": "etkin",
|
||||
"coupling.gear_1": "Dişli 1",
|
||||
@@ -1350,6 +1402,17 @@
|
||||
"help.occurrence.move": "Montaj parçasını yalnızca eklemlerinin izin verdiği serbestliklerde taşır. Bir parça yüzü seçtikten sonra kullanılabilir oku veya yayı sürükleyin.",
|
||||
"help.parameters.change": "Tasarımın ölçülerini yöneten adlandırılmış değerlerin ve ifadelerin tablosunu açar. Bir ölçüyü tek yerden değiştirip onu kullanan her özelliğin buna uymasını sağlamak için kullanın.",
|
||||
"help.pointcloud.insert": "PLY, XYZ veya PTS taramasını modelin yanına nokta bulutu olarak ekler. Ölçülmüş verilerden model oluştururken referans olarak kullanın.",
|
||||
"help.sketch.construction_line": "İki noktadan geçen sonsuz bir yardımcı doğru oluşturun. Profilleri bölmeden bir eskizi kurgulamak için kullanın.",
|
||||
"help.sketch.construction_line.angle": "Eskizin X ekseninden belirli bir açıyla sonsuz bir yardımcı doğru oluşturun. Noktayı seçip açıyı yazın veya yönünü seçin.",
|
||||
"help.sketch.construction_line.bisector": "Kesişen iki düz eskiz çizgisini seçin, ardından iki açıortaydan birini seçin. Sonuç, kaynak çizgilerini izler.",
|
||||
"help.sketch.construction_line.horizontal": "Bir noktadan geçen sonsuz yatay bir yardımcı doğru oluşturun. Yatay kısıtlaması sonraki düzenlemelerde de korunur.",
|
||||
"help.sketch.construction_line.parallel": "Düz bir eskiz çizgisi seçin, ardından paralel bir sonsuz yardımcı doğru yerleştirin. Başka bir referans seçmek için sağ tıklayın.",
|
||||
"help.sketch.construction_line.perpendicular": "Düz bir eskiz çizgisi seçin, ardından dik bir sonsuz yardımcı doğru yerleştirin. Başka bir referans seçmek için sağ tıklayın.",
|
||||
"help.sketch.construction_line.tangent_at": "Bir daire veya dairesel yay üzerindeki bir noktada ya da açık bir spline veya konik eğrinin uç noktasında teğet oluşturun. Önce eğriyi, sonra değme noktasını seçin.",
|
||||
"help.sketch.construction_line.tangent_external": "Bir daire veya dairesel yay seçin, ardından bir dış nokta ve bir teğet çözümü seçin. Önizlemeler yalnızca çizilen yay üzerindeki değme noktalarını gösterir.",
|
||||
"help.sketch.construction_line.tangent_two": "İki daire veya dairesel yay seçin, ardından önizlemede ortak bir teğet seçin. Değme noktaları çizilen eğriler üzerinde olmalıdır.",
|
||||
"help.sketch.construction_line.vertical": "Bir noktadan geçen sonsuz dikey bir yardımcı doğru oluşturun. Dikey kısıtlaması sonraki düzenlemelerde de korunur.",
|
||||
"help.sketch.equation_curve": "Formüllerden bir eğri çizer: bir aralık boyunca x(t) ve y(t) ya da y = f(x). Formüller parametre kullanabilir ve eğri onları izler: sinüs dalgası, spiral veya bir dişli dişinin evolventi için kullanın.",
|
||||
"help.solid.align": "Seçili gövdeleri, üzerlerindeki bir nokta, yüz veya düzlem başka bir yerdeki nokta, yüz veya düzlemle buluşacak şekilde taşır. Ofseti ölçmeden bir parçayı diğerinin yanına yerleştirmek için kullanın.",
|
||||
"help.solid.chamfer": "Seçili kenarları, belirlediğiniz mesafede düz bir pahla keser. Keskin kenarları kırmak veya bir pim ya da vidanın girişini kolaylaştırmak için kullanın.",
|
||||
"help.solid.combine": "Gövdeleri birleştirir, bir hedef gövdeden çıkarır veya yalnızca paylaştıkları hacmi tutar ve araç gövdelerini tutabilir. Parçaları kaynaştırmak, bir şekli diğeriyle kesmek veya iki gövdenin örtüştüğü yeri bulmak için kullanın.",
|
||||
@@ -1376,6 +1439,8 @@
|
||||
"help.timeline.compute_all": "Zaman çizelgesindeki her özelliği baştan yeniden oluşturur. Modeli tazelemek ve hangi özelliklerin başarısız olduğunu görmek için kullanın.",
|
||||
"help.timeline.delete": "Seçili özellikleri zaman çizelgesinden siler; bir eskizi silmek ondan oluşturulan özellikleri de siler. Artık istenmeyen bir adımı kaldırmak için kullanın.",
|
||||
"help.timeline.play": "Kalan özellikleri, her yeniden hesaplamadan sonra yarım saniye bekleyerek tek tek yeniden oynatır. Durdurmak için bu komutu yeniden çalıştırın veya Esc tuşuna basın; Sona git hemen atlar.",
|
||||
"history.sketch_under_constrained": "Eksik kısıtlanmış ({count} serbestlik derecesi)",
|
||||
"history.sketch_under_constrained_one": "Eksik kısıtlanmış ({count} serbestlik derecesi)",
|
||||
"hole_presets.confirm_delete": "Silmeyi onayla",
|
||||
"hole_presets.delete": "Sil",
|
||||
"hole_presets.delete_prompt": "Bu kişisel ön ayar silinsin mi? Mevcut delikler değişmez.",
|
||||
@@ -1585,6 +1650,8 @@
|
||||
"nav.maya.help": "Alt+sol sürükleme döndürür, Alt+orta kaydırır, Alt+sağ yakınlaştırır; orta sürükleme ayrıca kaydırır",
|
||||
"nav.openscad.help": "Boşlukta sol sürükleme döndürür, Shift+sol sürükleme kutu seçimi yapar, eskiz geometrisi sürükleyerek düzenlenir; sağ veya orta sürükleme kaydırır, Shift+sağ veya Shift+orta sürükleme yakınlaştırır",
|
||||
"nav.perspective.sketch": "Eskiz düzenleme dik görünüm kullanır. Perspektife geçmek için eskizi bitirin.",
|
||||
"nav.right_drag_orbits.help": "Kapalı: sağ sürükleme kameraya dokunmaz ve sağ tuş yalnızca bağlam menüsünü açar. SolidWorks fare eşlemesini seçmek bunu kapatır.",
|
||||
"nav.right_drag_orbits.label": "Sağ sürükleme döndürür",
|
||||
"nav.solidworks.help": "Orta sürükleme döndürür, Ctrl+orta kaydırır, Shift+orta yakınlaştırır, sağ sürükleme döndürür",
|
||||
"nav.tinkercad.help": "Sağ sürükleme döndürür, orta veya Shift+sağ sürükleme kaydırır",
|
||||
"nav.touchpad.help": "Kaydırmak için Shift tuşunu basılı tutun ve imleci hareket ettirin; Alt/Option ile döndürün. Fare tuşu gerekmez. Dikey kaydırma yakınlaştırır.",
|
||||
@@ -1606,6 +1673,9 @@
|
||||
"navbar.custom.customise": "Gezinme çubuğunu özelleştir…",
|
||||
"navbar.custom.design": "Tasarım",
|
||||
"navbar.custom.duplicate": "Bu yuva zaten çubukta.",
|
||||
"navbar.custom.edge": "Kenar",
|
||||
"navbar.custom.edge_bottom": "Alt",
|
||||
"navbar.custom.edge_top": "Üst",
|
||||
"navbar.custom.fade": "Soldur",
|
||||
"navbar.custom.full": "Başka bir yuva eklemek için bir yuvayı kaldırın.",
|
||||
"navbar.custom.hidden_design": "Tasarımda gizli",
|
||||
@@ -1712,6 +1782,7 @@
|
||||
"parts.dimension.thickness": "Kalınlık",
|
||||
"parts.dimension.width": "Genişlik",
|
||||
"parts.family.bearing": "Derin oluklu bilyeli rulman (zarf)",
|
||||
"parts.family.button_head_cap_screw": "Mercimek başlı alyan cıvata",
|
||||
"parts.family.dowel_pin": "Silindirik pim (paralel)",
|
||||
"parts.family.hex_bolt": "Altıgen başlı cıvata / vida",
|
||||
"parts.family.hex_nut": "Altıgen somun",
|
||||
@@ -1770,6 +1841,11 @@
|
||||
"prefs.bottom_centre": "Alt orta",
|
||||
"prefs.bottom_right": "Sağ alt",
|
||||
"prefs.browser": "Tarayıcı",
|
||||
"prefs.browser_eye_left": "Göz, daraltma okunun yanında",
|
||||
"prefs.browser_eye_left_note": "Tarayıcı satırları göster/gizle gözünü, satırların sağ ucundaki bir sütun yerine eskiden olduğu gibi daraltma okunun yanında gösterir.",
|
||||
"prefs.browser_reveal_on_hover": "Üzerine gelince göster",
|
||||
"prefs.browser_show_note": "Görünür, tarayıcıyı ekranda tutar. Üzerine gelince göster, imleç onun yerine veya sol kenarındaki ince sekmeye gelene kadar onu gizli tutar; imleç içindeyken veya ondan açılan bir menü açıkken açık kalır.",
|
||||
"prefs.browser_shown": "Görünür",
|
||||
"prefs.built_in": "Yerleşik",
|
||||
"prefs.button_left": "Sol sürükleme",
|
||||
"prefs.button_middle": "Orta sürükleme",
|
||||
@@ -1817,6 +1893,8 @@
|
||||
"prefs.graphics_card_restart": "SolidCraft'ı yeniden başlattıktan sonra etkili olur. WGPU_ADAPTER_NAME bu seçimi geçersiz kılar.",
|
||||
"prefs.graphics_note": "Hızdan ödün verip pürüzsüzlük kazanın. Her seçenek, etkisini bir örnek üzerinde gösterir.",
|
||||
"prefs.graphics_presets_note": "Ön ayarlar aşağıdaki seçimleri birlikte belirler.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Uzaklaşıldığında kısıtlama simgelerini gizle",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Eskiz, kalabalık yaratacak kadar uzaklaştırıldığında kısıtlama simgeleri görünümden çıkar. Kapalıyken: her yakınlaştırma düzeyinde sabit ekran boyutunda kalırlar.",
|
||||
"prefs.history": "Geçmiş",
|
||||
"prefs.history_origin_bodies": "Başlangıç ve gövdeleri üstte göster",
|
||||
"prefs.history_origin_bodies_note": "Soldaki veya tarayıcının altındaki Geçmiş, etkin bileşenin Gövdeler klasörü ve Başlangıç ile başlar; gözleri ve menüleri tarayıcıdaki gibidir. Alttaki Geçmiş değişmez.",
|
||||
@@ -1840,6 +1918,8 @@
|
||||
"prefs.layout_note": "Sıkışık, panelleri pencere kenarlarına yerleştirir. Tarayıcı yarı saydamlığı Yüzen düzende kullanılabilir. Asistan tarafını Asistan sayfasından değiştirin.",
|
||||
"prefs.left": "Sol",
|
||||
"prefs.left_click": "Sol tıklama",
|
||||
"prefs.line_drag_draws_one": "Basıp sürüklemek tek çizgi çizer",
|
||||
"prefs.line_drag_draws_one_note": "Çizgi aracında basmak, sürüklemek ve bırakmak, basılan yerden bırakılan yere tek bir çizgi çizer ve çizim orada biter. Tıklamalar yine bir zincir çizer. Kapalı: sürükleme, tıklama gibi, bırakıldığı yere bir nokta koyar.",
|
||||
"prefs.linked_designs": "Bağlı tasarımlar",
|
||||
"prefs.live_input": "Canlı girdi",
|
||||
"prefs.live_preview": "Canlı önizleme",
|
||||
@@ -1853,6 +1933,9 @@
|
||||
"prefs.max_file_size_step": "STEP ve içe aktarma dosyaları",
|
||||
"prefs.max_file_size_web": "Web uygulaması 512 MB’a kadar STEP ve içe aktarma dosyalarını, 256 MB’a kadar tasarımları açar: tarayıcı sekmesi daha büyük dosyaları barındıramaz. Masaüstü uygulamasında bu sınırlar artırılabilir.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Büyük simgeler",
|
||||
"prefs.menu_list": "Liste",
|
||||
"prefs.menus": "Menüler",
|
||||
"prefs.minutes": "dakika",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "Fare ve trackpad",
|
||||
@@ -1872,14 +1955,40 @@
|
||||
"prefs.origin_plane_names": "Orijin düzlemi adları",
|
||||
"prefs.origin_plane_names_note": "Tarayıcıda, diyaloglarda ve listelerde gösterilen adlar. Z yukarı olmak üzere {top} XY, {front} XZ ve {right} YZ'dir. Komutlar, betikler ve kayıtlı tasarımlar XY, XZ ve YZ adlarını korur.",
|
||||
"prefs.overall_speed": "Genel hız",
|
||||
"prefs.persistent_ribbon_pressed": "Etkin şerit komutlarını vurgula",
|
||||
"prefs.persistent_ribbon_pressed_help": "Şerit komutlarını, etkileri açık olduğu sürece vurgula. Önceki nötr görünümü ve komut yardımını korumak için kapatın.",
|
||||
"prefs.perspective_fov": "Görüş alanı",
|
||||
"prefs.placement": "Yerleşim",
|
||||
"prefs.prefer_free_sketch_points": "Noktalar örtüştüğünde hareketli eskiz noktalarını tercih et",
|
||||
"prefs.preview_choices": "Seçimlerinizin önizlemesi",
|
||||
"prefs.print_face_highlight": "Baskı yüzeyi vurgusu",
|
||||
"prefs.print_face_highlight_tip": "Bir gövdenin baskı yüzeyinin görünümde ne kadar güçlü renklendirilip çerçeveleneceği. %0 vurgu göstermez.",
|
||||
"prefs.profile_active": "Etkin profil",
|
||||
"prefs.profile_applied": "Profil uygulandı.",
|
||||
"prefs.profile_changed": "Profil kaydedildikten sonra ayarlar değişti. Kaydet, onları profilde saklar.",
|
||||
"prefs.profile_deleted": "Profil silindi.",
|
||||
"prefs.profile_export": "Dışa aktar…",
|
||||
"prefs.profile_exported": "Profil dışa aktarıldı.",
|
||||
"prefs.profile_imported": "Profil içe aktarıldı. Ona geçmek için Etkin profil altında seçin.",
|
||||
"prefs.profile_name_hint": "Profil adı, ör. Dizüstü",
|
||||
"prefs.profile_rename": "Yeniden adlandır",
|
||||
"prefs.profile_renamed": "Profil yeniden adlandırıldı.",
|
||||
"prefs.profile_save": "Kaydet",
|
||||
"prefs.profile_saved": "Geçerli ayarlar profile kaydedildi.",
|
||||
"prefs.profile_skipped": "Profil uygulandı; {n} ayar geçerli değerini korudu (günlüğe bakın).",
|
||||
"prefs.profiles": "Ayar profilleri",
|
||||
"prefs.profiles_note": "Kısayollar, araç çubuğu, gezinme, radyal menü ve arayüz ayarları; tek bir ad altında birlikte saklanır ve tek seferde değiştirilir.",
|
||||
"prefs.project_options_dialog": "Yansıtma seçenekleri diyaloğu",
|
||||
"prefs.project_options_dialog_note": "Açık: yansıtmadan önce Geometri veya Gövdeler ile Yansıtma bağını seçin. Kapalı: önceki doğrudan seçim iş akışını korur.",
|
||||
"prefs.quality_default": "varsayılan",
|
||||
"prefs.quality_fastest": "en hızlı",
|
||||
"prefs.quality_slowest": "en yavaş",
|
||||
"prefs.quality_smoother": "daha pürüzsüz",
|
||||
"prefs.render_previous_geometry_budget": "Önceki Render önizleme geometri bütçesini kullan",
|
||||
"prefs.render_previous_geometry_budget_help": "Cihaza dayalı bütçe yerine önceki sabit geometri sınırını (64 bit masaüstünde 512 MiB, diğer yerlerde 128 MiB) geri getirir.",
|
||||
"prefs.reports_saved": "{n} kayıtlı",
|
||||
"prefs.ribbon_reveal": "Arama sonuçlarını şeritte göster",
|
||||
"prefs.ribbon_reveal_note": "Komutlarda ara içindeki bir sonucun üzerine gelmek, komutun şeritte nerede olduğunu gösterir: sekmesini, düğmesini veya bir panelin açılır menüsündeki satırını. Aramadan başlatılan bir komut orada yanıp söner ve bir açılır menüden çalışan bir komut panelini işaretler.",
|
||||
"prefs.right_click": "Sağ tıklama",
|
||||
"prefs.saving": "Otomatik kayıt ve kurtarma",
|
||||
"prefs.scale_note": "Pencerede ayrıca Ctrl + / Ctrl −. Düğmeler %100'de 28 px.",
|
||||
@@ -1888,21 +1997,34 @@
|
||||
"prefs.search_empty": "Eşleşen ayar yok",
|
||||
"prefs.select": "Seçim",
|
||||
"prefs.select_one_item": "Bir öğe seçin",
|
||||
"prefs.select_other_hidden": "Gizli geometriyi Diğerini seç ile seç",
|
||||
"prefs.select_other_hidden_help": "Açıkken: imlecin yakınındaki gizli gövdeleri, eskizleri ve örtülü kenarları da dahil eder. Kapalıyken: imlecin altındaki görünür geometrinin özgün listesini kullanır.",
|
||||
"prefs.selecting": "Seçme",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift yalnızca ekler; Ctrl / Cmd değiştirir",
|
||||
"prefs.shift_add_note": "Açık: Shift ekler, Ctrl / Cmd değiştirir. Kapalı (varsayılan): ikisi de değiştirir.",
|
||||
"prefs.shortcuts": "Kısayollar",
|
||||
"prefs.single_surface_analysis": "Tek bir yüzey analizi kullan",
|
||||
"prefs.single_surface_analysis_help": "Kapalıyken yüzey gölgelendirmesi ve Süreklilik birlikte açık kalabilir. Bunu açmak, en son başlatılan veya değiştirilen analizi tutar.",
|
||||
"prefs.sketch_align_points": "Çizerken diğer eskiz noktalarıyla hizala",
|
||||
"prefs.sketch_align_points_note": "Çizim sırasında bir nokta, noktalı bir kılavuzla aynı anda bir eskiz noktasıyla yatay, bir diğeriyle dikey olarak hizalanır ve tıklama her iki hizalamayı da korur. Kapalı: yalnızca önceki noktayla, her seferinde tek eksende.",
|
||||
"prefs.sketch_conflict_colour": "Çakışan geometri çakışma renginde",
|
||||
"prefs.sketch_conflict_colour_note": "Bir eskizin kısıtlamaları çakışırken, başarısız olan kısıtlamanın tuttuğu eğriler ve noktalar yalnızca simgesi veya ölçüsü değil, çakışma renginde de çizilir. Kapalıyken olağan renklerini korurlar.",
|
||||
"prefs.sketch_construction_lines": "Genişletilmiş yardımcı doğru araçları",
|
||||
"prefs.sketch_exit_view": "Bir eskiz bittiğinde",
|
||||
"prefs.sketch_exit_view.keep": "Geçerli görünümü koru",
|
||||
"prefs.sketch_exit_view.previous": "Önceki görünüme dön",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Döndürülmediyse dön",
|
||||
"prefs.sketch_exit_view_note": "Eskizi Bitir, İptal veya çift Esc sonrası görünümün nereye gittiği.",
|
||||
"prefs.sketch_open_look_at": "Eskiz açıldığında görünümü ona doğru döndür",
|
||||
"prefs.sketch_open_look_at_note": "Kapalı: eskiz oluşturmak veya düzenlemek görünümü olduğu gibi bırakır. Bak komutu, istediğinizde görünümü eskize çevirir.",
|
||||
"prefs.sketch_recent_snap": "Son merkezlere ve orta noktalara otomatik yapış",
|
||||
"prefs.sketch_recent_snap_note": "Çizim sırasında imleç, son iki daire merkezi veya düz kenar orta noktasından gelen kılavuzların kesiştiği yere yapışır. Kapalıyken bu kılavuzlar yalnızca görsel kalır ve imleç hareket etmez.",
|
||||
"prefs.sketch_selection": "Eskiz ve seçim",
|
||||
"prefs.sketch_selection_heading": "Eskiz ve seçim",
|
||||
"prefs.sketch_selection_note": "Eskizlerin nasıl yapıştığı ve tıklamaların nasıl seçtiği.",
|
||||
"prefs.sketch_state_icons": "Eskiz simgeleri durumlarının renginde",
|
||||
"prefs.sketch_state_icons_note": "Geçmiş'te ve tarayıcıda bir eskizin simgesi durumunun rengini alır (eksik kısıtlanmış, tam kısıtlı veya çakışan) ve araç ipucu durumu belirtir. Kapalıyken: her eskizin simgesi aynıdır.",
|
||||
"prefs.sketch_tab_always": "Eskiz sekmesini hep göster",
|
||||
"prefs.sketch_tab_always_note": "Hiçbir eskiz açık değilken Eskiz sekmesi şeritte, Model’den hemen sonra kalır. Çizim araçları bu durumda seçili düzlemde veya yüzde ya da bir sonra seçtiğiniz düzlemde, araç hazır olarak bir eskiz başlatır.",
|
||||
"prefs.sketch_tracking_guides": "Merkez ve orta nokta hizalama kılavuzları",
|
||||
@@ -1912,6 +2034,11 @@
|
||||
"prefs.source": "Kaynak",
|
||||
"prefs.speed": "Hız",
|
||||
"prefs.stand_up_note": "Bir STEP veya IGES dosyası Z yukarı açıldığında, X etrafında çeyrek tur öner.",
|
||||
"prefs.stand_up_unknown": "Bilinmeyen programlardan gelen dosyalar için",
|
||||
"prefs.stand_up_unknown.ask": "Diyalogda sor",
|
||||
"prefs.stand_up_unknown.note": "Not göster",
|
||||
"prefs.stand_up_unknown.off": "Önerme",
|
||||
"prefs.stand_up_unknown_note": "Dosyanın başlığı, Y yukarı olarak kaydettiği bilinen bir program belirtmediğinde önerinin nasıl sunulacağı. Not yalnızca dosya sırtüstü yatıyor gibi göründüğünde gösterilir; Diyalogda sor, daha önce olduğu gibi böyle her dosya için sorar.",
|
||||
"prefs.status_bar": "Durum çubuğu",
|
||||
"prefs.status_bar_note": "Pencerenin alt kenarındaki ince bir çubuk, nelerin düzenlendiğini, açık eskizin durumunu rengiyle ve tasarımın birimlerini gösterir; birimlere tıklamak onları değiştirir. Bu durumda eskizin durumu artık görünümün köşesinde gösterilmez.",
|
||||
"prefs.status_done": "Tamam",
|
||||
@@ -1937,7 +2064,14 @@
|
||||
"prefs.toast_place": "Bildirimler",
|
||||
"prefs.toggle_item": "Öğeyi ekleyin veya yeniden çıkarın",
|
||||
"prefs.toolbar": "Araç çubuğu",
|
||||
"prefs.toolbar_tabs": "Araç çubuğu sekmeleri",
|
||||
"prefs.top": "Üst",
|
||||
"prefs.trackpad_zoom_modifier": "İki parmakla kaydırarak yakınlaştırma tuşu",
|
||||
"prefs.trackpad_zoom_modifier.alt": "⌥ / Alt",
|
||||
"prefs.trackpad_zoom_modifier.cmd": "⌘",
|
||||
"prefs.trackpad_zoom_modifier.ctrl": "Ctrl",
|
||||
"prefs.trackpad_zoom_modifier.help": "Dikey kaydırmayla imlecin olduğu yere yakınlaştırmak için yalnızca bu tuşu basılı tutun. Kapalı, mevcut kaydırma davranışını korur.",
|
||||
"prefs.trackpad_zoom_modifier.off": "Kapalı",
|
||||
"prefs.translucent": "Yarı saydam",
|
||||
"prefs.under_browser": "Tarayıcının altında",
|
||||
"prefs.under_cursor": "İmlecin altında",
|
||||
@@ -1947,13 +2081,24 @@
|
||||
"prefs.view_confirm_corner": "Görünümün köşesinde Tamam ve İptal",
|
||||
"prefs.view_confirm_corner_note": "Bir diyalog veya eskiz açıkken, görünümün sağ üstündeki bir onay işareti ve çarpı işareti, diyalogun Tamam ve İptal düğmelerinin ya da eskizi bitirip iptal etmenin işini yapar. Görünüm yönlendiricileri bunların altına iner.",
|
||||
"prefs.viewport": "Görünüm alanı",
|
||||
"prefs.viewport_analysis_status": "Görünüm alanı analiz durumunu göster",
|
||||
"prefs.viewport_analysis_status_help": "Etkin analizleri görünüm alanının üstünde gösterir, her öğeden göstergesini açar ve en yeni analizi kapatmak için Esc tuşunu kullanır. Köşe göstergelerini ve Esc'in önceki davranışını geri yüklemek için kapatın.",
|
||||
"prefs.viewport_background": "Arka plan",
|
||||
"prefs.viewport_background_colour": "Renk",
|
||||
"prefs.viewport_background_theme": "Temanın degradesi",
|
||||
"prefs.wheel": "Tekerlek",
|
||||
"prefs.wheel_trackpad": "Tekerlek ve trackpad",
|
||||
"prefs.workspace": "Çalışma alanı",
|
||||
"prefs.zoom_stop_at_model": "Yakınlaştırmayı modelde durdur",
|
||||
"prefs.zoom_stop_at_model_tip": "3B fare ve cihaz uygulaması görünümün ortasındaki yüzeye doğru yakınlaştırır; sürükleyerek yakınlaştırma, sürüklemenin başladığı noktayı sabit tutar. Kapalı: yakınlaştırma modelin içinden geçebilir. Tekerlek ve iki parmakla sıkıştırma ayrı olarak İmlece doğru yakınlaştır ayarını kullanır",
|
||||
"prefs.zoom_toward_cursor": "Yakınlaştırma, imlece doğru",
|
||||
"properties.title": "Özellikler: {name}",
|
||||
"recovery.days_ago": "{count} gün önce",
|
||||
"recovery.detail": "{file} · {features} özellik · otomatik kaydedilen: {when}",
|
||||
"recovery.discard_all": "Tümünü at",
|
||||
"recovery.discard_all_detail": "Bu işlem geri alınamaz.",
|
||||
"recovery.discard_all_title": "{count} otomatik kayıt atılsın mı?",
|
||||
"recovery.discard_all_title_one": "1 otomatik kayıt atılsın mı?",
|
||||
"recovery.hours_ago": "{count} sa. önce",
|
||||
"recovery.just_now": "az önce",
|
||||
"recovery.min_ago": "{count} dk. önce",
|
||||
@@ -2038,6 +2183,7 @@
|
||||
"render.appearance_editor.weight": "Ağırlık",
|
||||
"render.appearance_physics_separate": "Görsel görünüm yoğunluk, termal veri veya diğer mühendislik özelliklerini atamaz.",
|
||||
"render.appearances": "Görünümler",
|
||||
"render.assign_help": "Seçime uygulamak için tıklayın; önizleyip bırakmak için sürükleyin veya hiçbir şey seçili değilken boyamak için tıklayın.",
|
||||
"render.availability_native": "Yerli kompozisyon; uygulamadan önce inceleyin",
|
||||
"render.availability_projection": "Desteklenen yansıtma; kapsama ve atlamalara bakın",
|
||||
"render.availability_reference": "Referans verisi; otomatik atama değildir",
|
||||
@@ -2076,6 +2222,7 @@
|
||||
"render.bloom_threshold": "Doğrusal vurgu eşiği",
|
||||
"render.browse_capabilities": "Tam yetenek kataloğunu incele",
|
||||
"render.browse_environments": "Orijinal HDR ortamlarına göz at",
|
||||
"render.browse_looks": "Göz at…",
|
||||
"render.browse_native_scenes": "Yerli stüdyolara göz at",
|
||||
"render.browse_physical": "Fiziksel referansları incele",
|
||||
"render.browse_quality": "Kalite özelliklerini incele",
|
||||
@@ -2099,6 +2246,82 @@
|
||||
"render.check_opaque": "Saydamlık: yalnızca opak yüzeyler; arka plan alfası desteklenir.",
|
||||
"render.check_sorted_alpha": "Saydamlık: sıralı alfa yaklaşımı.",
|
||||
"render.check_transmission": "Saydamlık: fiziksel geçirgenlik.",
|
||||
"render.children.absolute_floor": "Mutlak taban",
|
||||
"render.children.adaptive": "Adaptif",
|
||||
"render.children.add_look_reason": "Etkin durumunu ve şiddetini düzenlemek için bir görünüm ekleyin.",
|
||||
"render.children.all_shots": "Tüm çekimler",
|
||||
"render.children.bloom": "Bloom",
|
||||
"render.children.check": "Kontrol",
|
||||
"render.children.check_now": "Şimdi kontrol et",
|
||||
"render.children.chromatic": "Kromatik",
|
||||
"render.children.compact": "Sıkışık",
|
||||
"render.children.contrast": "Kontrast",
|
||||
"render.children.copy_image": "Kopyala",
|
||||
"render.children.copy_job": "İş JSON'unu kopyala",
|
||||
"render.children.copy_request": "İstek JSON'unu kopyala",
|
||||
"render.children.coverage_error": "Kapsama hatası",
|
||||
"render.children.cpu": "CPU ışın izleme",
|
||||
"render.children.denoise": "Bitmiş görüntüdeki gürültüyü azalt",
|
||||
"render.children.depth": "Yol derinliği",
|
||||
"render.children.distortion": "Bozulma",
|
||||
"render.children.edge_samples": "Kenar örnekleri",
|
||||
"render.children.effects_banner": "Bu efektler GPU yol izleme gerektirir. Bunu açmak yöntemi asla değiştirmez.",
|
||||
"render.children.enable_adaptive": "Adaptif sınırları düzenlemek için bağımsız pilotları etkinleştirin.",
|
||||
"render.children.enable_bloom": "Şiddetini, eşiğini ve yarıçapını düzenlemek için bloom'u etkinleştirin.",
|
||||
"render.children.finishing": "Sonlandırma",
|
||||
"render.children.flare": "Flare",
|
||||
"render.children.fresnel": "Fresnel tabakaları",
|
||||
"render.children.ghosts": "Hayalet halkalar",
|
||||
"render.children.glass": "Cam taşınımı",
|
||||
"render.children.go_to": "{editor} bölümüne git",
|
||||
"render.children.grain": "Gren",
|
||||
"render.children.halo": "Hale",
|
||||
"render.children.hdr": "HDR",
|
||||
"render.children.keep_master": "Ham doğrusal ana görüntüyü sakla",
|
||||
"render.children.last_result": "Son: {number} · {width} × {height} · {phase}",
|
||||
"render.children.lens_effects": "Mercek efektleri",
|
||||
"render.children.look_summary": "{tone} · {count} görünüm",
|
||||
"render.children.looks": "Yaratıcı görünümler",
|
||||
"render.children.memory": "Bellek",
|
||||
"render.children.method": "Yöntem",
|
||||
"render.children.minimum": "En az",
|
||||
"render.children.needs_cpu": "CPU ışın izleme gerektirir. Bunu açmak yöntemi asla değiştirmez.",
|
||||
"render.children.nested": "Sertifikalı iç içe dielektrikler",
|
||||
"render.children.not_checked": "Kontrol edilmedi",
|
||||
"render.children.path": "Yol izleme",
|
||||
"render.children.pilots": "Pilot örnekler",
|
||||
"render.children.preview": "Önizleme yükü",
|
||||
"render.children.progressive_reason": "Örnek sayısını ve tohumunu düzenlemek için Artımlı'yı seçin.",
|
||||
"render.children.radius": "Yarıçap",
|
||||
"render.children.reflect_depth": "Yansıma derinliği",
|
||||
"render.children.reflect_samples": "Yansıma örnekleri",
|
||||
"render.children.regrade": "Yeniden derecelendir",
|
||||
"render.children.relative_error": "Göreceli hata",
|
||||
"render.children.render": "Render",
|
||||
"render.children.render_shot": "Çekimi render et",
|
||||
"render.children.renderer": "İşleyici",
|
||||
"render.children.renderers": "İşleyiciler",
|
||||
"render.children.request": "Bu istek",
|
||||
"render.children.reset_finishing": "Sonlandırmayı sıfırla",
|
||||
"render.children.review_quality": "Bir kalite özelliğini incele…",
|
||||
"render.children.rgb_gain": "RGB kazancı",
|
||||
"render.children.samples": "Örnekler",
|
||||
"render.children.sampling": "Örnekleme",
|
||||
"render.children.saturation": "Doygunluk",
|
||||
"render.children.scene_summary": "{bodies} gövde · {triangles} üçgen",
|
||||
"render.children.seed": "Tohum",
|
||||
"render.children.sharpening": "Keskinleştirme",
|
||||
"render.children.single_image": "Tek görüntü",
|
||||
"render.children.soft_focus": "Yumuşak odak",
|
||||
"render.children.streak": "Çizgi",
|
||||
"render.children.strength": "Şiddet",
|
||||
"render.children.studio": "Stüdyo",
|
||||
"render.children.threshold": "Eşik",
|
||||
"render.children.tone": "Ton",
|
||||
"render.children.under_hood": "Perde arkası",
|
||||
"render.children.vignette": "Vinyet",
|
||||
"render.children.workstation": "İş istasyonu",
|
||||
"render.choose_look": "Önce Görünümler'de bir görünüm seçin",
|
||||
"render.chromatic_offset": "Kromatik kenar kayması",
|
||||
"render.clear_stage": "Kaydedilmiş sahneyi kaldır",
|
||||
"render.copy_request": "JSON kopyala",
|
||||
@@ -2350,8 +2573,33 @@
|
||||
"render.flare_strength": "Vurgu flare şiddeti",
|
||||
"render.flare_threshold": "Sahne-doğrusal flare eşiği",
|
||||
"render.fold_browser": "Tarayıcıyı daralt",
|
||||
"render.frame_aspect": "En-boy oranı",
|
||||
"render.frame_centre_mark": "Merkez işareti",
|
||||
"render.frame_copy_limit": "Kullanılabilir bir kopya çekim adı yok",
|
||||
"render.frame_copy_name": "{name} kopya {number}",
|
||||
"render.frame_custom": "Özel",
|
||||
"render.frame_distance_unit": " × boyut",
|
||||
"render.frame_duplicate": "Çoğalt",
|
||||
"render.frame_exposure": "Pozlama",
|
||||
"render.frame_fov": "Görüş alanı",
|
||||
"render.frame_guides": "Kılavuzlar",
|
||||
"render.frame_invalid_aspect": "Geçersiz en-boy oranı ön ayarı",
|
||||
"render.frame_lens": "FOV {fov}° · ≈ {mm} mm",
|
||||
"render.frame_name": "Ad",
|
||||
"render.frame_output_size": "Çıktı boyutu",
|
||||
"render.frame_photo": "3:2 · Fotoğraf",
|
||||
"render.frame_portrait": "4:5 · Portre",
|
||||
"render.frame_presets": "Kadraj ön ayarları",
|
||||
"render.frame_presets_pending": "Çekim düzenleyicisiyle gelecek",
|
||||
"render.frame_projection": "Projeksiyon",
|
||||
"render.frame_render_shot": "Bu çekimi render et",
|
||||
"render.frame_rule_thirds": "Üçler kuralı",
|
||||
"render.frame_safe_area": "Güvenli alan",
|
||||
"render.frame_shot_title": "Çekim · {name}",
|
||||
"render.frame_square": "1:1 · Kare",
|
||||
"render.frame_tall": "9:16 · Dikey",
|
||||
"render.frame_thirds": "Üçte birler",
|
||||
"render.frame_wide": "16:9 · Geniş ekran",
|
||||
"render.gpu_depth": "En fazla yol derinliği",
|
||||
"render.gpu_options_help": "Örnekler, derinlik, tohum ve pozlama bu kurulumla kaydedilir. Yalnızca etkin görüntü yöntemi kaydedilir.",
|
||||
"render.gpu_path_failed": "GPU yol izleyici kullanılamıyor",
|
||||
@@ -2379,6 +2627,7 @@
|
||||
"render.heading_results": "SONUÇLAR",
|
||||
"render.heading_shots": "ÇEKİMLER",
|
||||
"render.hide_shots_label": "Çekim şeridini gizle",
|
||||
"render.hover_look": "{object} · {look} · seçmek için tıklayın",
|
||||
"render.image_advanced": "Gelişmiş GPU kontrolleri",
|
||||
"render.image_cancelled": "Render iptal edildi",
|
||||
"render.image_cancelling": "İptal ediliyor",
|
||||
@@ -2525,17 +2774,95 @@
|
||||
"render.library_uniform_ack": "Uzamsal veya gelişmiş efektler olmadan tek biçimli yaklaşımı kullan",
|
||||
"render.library_usable": "Çalıştırılabilir yansıtmalar",
|
||||
"render.library_users": "Kullanan gövdeler",
|
||||
"render.light_aim": "Şuna yönelt",
|
||||
"render.light_anchor_pending": "Işık koordinat çerçevesini değiştirmek henüz desteklenmiyor.",
|
||||
"render.light_azimuth": "Azimut",
|
||||
"render.light_backend_limit": "Işıkları düzenlemek için CPU ışın izleme veya açık bir GPU stüdyosu seçin. Eski GPU stüdyo ışıkları salt okunur kalır.",
|
||||
"render.light_behaviour": "DAVRANIŞ",
|
||||
"render.light_default_fill": "Dolgu ışığı",
|
||||
"render.light_default_key": "Ana ışık",
|
||||
"render.light_default_number": "Işık {number}",
|
||||
"render.light_default_rim": "Kenar ışığı",
|
||||
"render.light_delete": "Sil",
|
||||
"render.light_distance": "Mesafe",
|
||||
"render.light_duplicate": "Çoğalt",
|
||||
"render.light_elevation": "Yükseklik açısı",
|
||||
"render.light_gpu_punctual": "Nokta ve Spot ışıklar CPU ışın izleme ile kullanılabilir.",
|
||||
"render.light_hard_shadow": "Bu ışığın gölgeleri serttir; ışık veren yumuşaklığı kullanılamıyor.",
|
||||
"render.light_intensity": "Şiddet",
|
||||
"render.light_missing": "Bu ışık artık yok. Tarayıcıda bir ışık seçin.",
|
||||
"render.light_place_highlight": "Vurguya göre yerleştir",
|
||||
"render.light_place_pending": "Vurguya göre yerleştirme, görünüm alanında ışık seçmeyi gerektirir ve henüz desteklenmiyor.",
|
||||
"render.light_position": "KONUM",
|
||||
"render.light_preview_help": "Canlı görünüm gölgesizdir; Alan ışıkları merkez örnekli bir yaklaşım kullanır. Render, tam ışık modelini kullanır.",
|
||||
"render.light_product_centre": "Ürün merkezi",
|
||||
"render.light_size": "Boyut",
|
||||
"render.light_softness": "Yumuşaklık",
|
||||
"render.light_temperature": "Renk sıcaklığı",
|
||||
"render.light_temperature_help": "Yaklaşık kara cisim tonu; doğrusal RGB olarak kaydedilir.",
|
||||
"render.light_type": "Tür",
|
||||
"render.light_type_area": "Alan",
|
||||
"render.light_type_point": "Nokta",
|
||||
"render.light_type_spot": "Spot",
|
||||
"render.light_type_sun": "Güneş",
|
||||
"render.light_view_only": "Solo ve susturma bu görünümü ve render'larını etkiler; tasarıma asla kaydedilmez.",
|
||||
"render.light_world_origin": "Dünya orijini",
|
||||
"render.lighting_aim_point": "Hedef noktası",
|
||||
"render.lighting_apply": "Ön ayarı uygula",
|
||||
"render.lighting_area_samples": "Alan örnekleri",
|
||||
"render.lighting_budget": "Bütçe",
|
||||
"render.lighting_budget_help": "Sayılar salt okunurdur. Değiştirmek için ışık ekleyin, çoğaltın veya silin; sınırları yöntem belirler.",
|
||||
"render.lighting_colour": "Renk",
|
||||
"render.lighting_consent": "Yönlü ışıkları bu ön ayarla değiştir",
|
||||
"render.lighting_custom": "Özel ışıklar",
|
||||
"render.lighting_custom_help": "Özel'i seçmek, ön ayarı düzenlenebilir ışıklara dönüştürür; ağaçta her biri için bir satır.",
|
||||
"render.lighting_direction": "Yön X Y Z",
|
||||
"render.lighting_direction_help": "Ya da ışığa doğru bir yön yazın (X Y Z).",
|
||||
"render.lighting_distance_unit": " × boyut",
|
||||
"render.lighting_edge_u": "Kenar U vektörü",
|
||||
"render.lighting_edge_v": "Kenar V vektörü",
|
||||
"render.lighting_falloff": "Zayıflama",
|
||||
"render.lighting_falloff_help": "Şiddet, referans mesafede belirtilir.",
|
||||
"render.lighting_height": "Yükseklik V",
|
||||
"render.lighting_minimum": "En az",
|
||||
"render.lighting_mute": "Bu ışığı sustur",
|
||||
"render.lighting_point": "Nokta",
|
||||
"render.lighting_preset": "Stüdyo ön ayarı",
|
||||
"render.lighting_preset_cpu": "Yönlü stüdyo ön ayarları CPU ışın izleme gerektirir. GPU aydınlatması açık Güneş ve Alan ışıkları kullanır.",
|
||||
"render.lighting_preset_row": "Ön ayar",
|
||||
"render.lighting_radiance": "Işınım",
|
||||
"render.lighting_reference": "Referans",
|
||||
"render.lighting_review_help": "Yönlü ışık listesinin yerini alır. Nokta ve alan ışıklarını, ortamı, gölgeleri, kamerayı ve diğer tüm çekim ayarlarını korur.",
|
||||
"render.lighting_review_title": "Aydınlatma ön ayarını incele",
|
||||
"render.lighting_samples_cpu": "Alan ışığı örnekleri CPU ışın izlemeye uygulanır.",
|
||||
"render.lighting_samples_need_area": "Alan örneklerini ayarlamak için bir CPU alan ışığı ekleyin.",
|
||||
"render.lighting_samples_reason": "Alan örnekleri 1, 4, 16 veya 64 olmalıdır.",
|
||||
"render.lighting_shadow_cpu": "Gölge anahtarı CPU ışın izleme gerektirir. GPU yol izleme her zaman gölge düşürür.",
|
||||
"render.lighting_shadows": "Gölge düşürsün",
|
||||
"render.lighting_shadows_section": "Gölgeler ve örnekleme",
|
||||
"render.lighting_shape": "Şekil",
|
||||
"render.lighting_solo": "Bu ışığı solo yap",
|
||||
"render.lighting_source": "Kaynak",
|
||||
"render.lighting_source_section": "Işık kaynağı",
|
||||
"render.lighting_spot_preserved": "Bu nokta ışık, türü değiştirilene kadar kaydedilmiş spot konisini korur.",
|
||||
"render.lighting_sun_distance": "Güneş yönü mesafeden ve hedef noktasından bağımsızdır.",
|
||||
"render.lighting_unsupported": "desteklenmiyor",
|
||||
"render.lighting_used": "{used} / {limit}",
|
||||
"render.lighting_width": "Genişlik U",
|
||||
"render.lighting_world_position": "Dünya X Y Z",
|
||||
"render.lights_fixed_to": "Işıklar şuna sabit",
|
||||
"render.linear_help": "Giderme, pozlama, ton eşleme, filtreler ve arka plandan önce 32 bit float RGBA ana görüntüyü saklar. Doğrusal sRGB/D65; kapsama ile ön çarpımlı. Ek bellek açıkça kabul edilir. Sıkıştırma veya ek geçiş yoktur.",
|
||||
"render.linear_retain": "Ham doğrusal EXR'ı sakla",
|
||||
"render.linear_unavailable": "Seçilen tamamlanmış karede saklanmış EXR yok. Render'dan önce saklamayı etkinleştirin; eski bir PNG ham ışınımı geri getiremez.",
|
||||
"render.look_add": "Renk görünümü ekle",
|
||||
"render.look_applied": "{name} uygulandı",
|
||||
"render.look_bleach": "Bleach-bypass esinli",
|
||||
"render.look_cool": "Soğuk",
|
||||
"render.look_cyanotype": "Siyanotip esinli",
|
||||
"render.look_faded": "Solmuş baskı",
|
||||
"render.look_material": "Malzeme",
|
||||
"render.look_mono": "Tek renk",
|
||||
"render.look_pasted": "Görünüm yapıştırıldı",
|
||||
"render.look_sepia": "Sepya",
|
||||
"render.look_strength": "Görünüm şiddeti",
|
||||
"render.look_teal_orange": "Turkuaz / turuncu",
|
||||
@@ -2611,9 +2938,11 @@
|
||||
"render.output_advanced": "Gelişmiş",
|
||||
"render.output_backend_ready": "Hazır",
|
||||
"render.output_check": "Kontrol",
|
||||
"render.output_check_failed": "Kontrol · hata",
|
||||
"render.output_check_help": "Render başlatmadan bu isteği gözden geçirmek için Kontrol'ü çalıştırın.",
|
||||
"render.output_check_summary": "Kontrol · Notlar: {count}",
|
||||
"render.output_copy": "Kopyala",
|
||||
"render.output_copy_report": "Raporu kopyala",
|
||||
"render.output_destination": "Hedef",
|
||||
"render.output_destination_help": "Tamamlanan görüntüyü dışa aktarırken hedef dosyayı seçin.",
|
||||
"render.output_dimensions": "Boyut",
|
||||
@@ -2623,6 +2952,7 @@
|
||||
"render.output_fit": "Sığdır",
|
||||
"render.output_format": "Biçim",
|
||||
"render.output_format_status": "PNG, tamamlanmış tam görüntü görüntüsüdür. İsteğe bağlı GPU EXR, görüntü filtrelerinden önce ham sahne-doğrusal FLOAT32 ışınımını saklar. Dışa aktarma, önizleme önbelleğini veya başka bir işi asla ikame etmez.",
|
||||
"render.output_grading": "Derecelendirme",
|
||||
"render.output_image": "Görüntü",
|
||||
"render.output_largest": "En çok {width} × {height}",
|
||||
"render.output_lock_ratio": "En-boy oranını kilitle",
|
||||
@@ -2632,6 +2962,8 @@
|
||||
"render.output_quality_waiting": "kalite sözleşmesi bekleniyor",
|
||||
"render.output_ratio_refused": "Bağlı boyut, bu yöntemin boyut sınırını aşıyor. Önceki boyut korunur; oranı kilitten çıkarın veya daha küçük bir değer seçin.",
|
||||
"render.output_ready": "Render için hazır",
|
||||
"render.output_run_check": "Kontrolü çalıştır",
|
||||
"render.output_size_limit": "{method}: kenar başına en fazla {dimension} px ve {pixels} piksel. Sığan en büyük boyut: {width} × {height}.",
|
||||
"render.output_size_ok": "Boyut uygun · {width} × {height} px",
|
||||
"render.output_swap_orientation": "Genişlik ve yüksekliği değiştir",
|
||||
"render.output_tools_inspector": "Boyutu ve biçimi Çıktı denetçisinde düzenleyin.",
|
||||
@@ -2648,6 +2980,7 @@
|
||||
"render.page_output": "Çıktı",
|
||||
"render.page_scene": "Sahne",
|
||||
"render.paint_label": "Boya",
|
||||
"render.painting_with": "{name} ile boyanıyor",
|
||||
"render.passive_stage": "Zemin ve pasif sahne",
|
||||
"render.passive_stage_help": "Sonlu pasif paneller yalnızca render görüntülerine aittir. CAD gövdesi veya kütle eklemezler. Uygulamadan sonra yerleşim sabittir; ürün sınırlarıyla kesişen reddedilir. CPU dağınık sekme aydınlatması sağlamaz.",
|
||||
"render.perspective": "Perspektif kamera",
|
||||
@@ -2669,6 +3002,7 @@
|
||||
"render.pick_help": "Gövde, Yüz veya Bileşen seçin. Temizlemek için boş alana tıklayın; Shift veya Ctrl ekler ya da seçimi tersine çevirir. Vurgular yalnızca canlı ürün görünümünde görünür.",
|
||||
"render.pick_label": "Seç",
|
||||
"render.pick_up_label": "Al",
|
||||
"render.pick_up_prompt": "Görünümünü almak için bir nesneye tıklayın",
|
||||
"render.pick_waiting": "Ürün seçimi henüz desteklenmiyor.",
|
||||
"render.post_contrast": "Kontrast",
|
||||
"render.post_gain_b": "Mavi kazancı",
|
||||
@@ -2708,13 +3042,17 @@
|
||||
"render.radial_distortion": "Radyal bozulma",
|
||||
"render.radial_fit": "Ürünü Sığdır",
|
||||
"render.radial_save": "Çekimi Kaydet",
|
||||
"render.recent_looks": "Son görünümler",
|
||||
"render.regrade_action": "Ham ana görüntüyü yeniden derecelendir (giderme yok)",
|
||||
"render.regrade_help": "Bu sunum kontrollerini kullanarak seçilen tamamlanmış ham ana görüntüden ayrı bir PNG oluşturur. Işın izlemez, yakalanan boyutu/kamerayı/ışıkları değiştirmez veya EXR'ın üzerine yazmaz. Giderme yeniden uygulanmaz: ham ana görüntüler onun kılavuzlarını saklamaz. Türev, aynı iş kontrollerinden dışa aktarılabilir kalır.",
|
||||
"render.regrade_label": "Yeniden derecelendir",
|
||||
"render.reload_settings": "Kaydedilmiş ayarları yükle",
|
||||
"render.remove_override": "Geçersiz Kılmayı Kaldır",
|
||||
"render.replace_all": "Tümünü Değiştir",
|
||||
"render.replace_ground": "Mevcut sahnenin değiştirilmesini onayla",
|
||||
"render.replace_label": "Değiştir",
|
||||
"render.replace_saved_surface": "Bu hedef için mevcut kaydedilmiş bağlamın yerini al",
|
||||
"render.replace_with": "Şununla değiştir",
|
||||
"render.restore_camera": "Kaydedilmiş kamerayı yükle",
|
||||
"render.result_actual": "%100",
|
||||
"render.result_actual_help": "Ekran pikseli başına bir görüntü pikseli.",
|
||||
@@ -2766,14 +3104,28 @@
|
||||
"render.saved_surface_remove": "Kaydedilmiş bağlamı kaldır",
|
||||
"render.saved_surfaces": "Kaydedilmiş yüzey bağlamları",
|
||||
"render.saved_surfaces_help": "Sabitlenmiş yerleşik haritalar, yerel milimetrelerde seçilen tekrarı izler. Değiştirilmiş veya eksik hedef bir hatadır, asla otomatik yeniden atama değildir.",
|
||||
"render.scene_all_shots": "Tüm çekimler ({count})",
|
||||
"render.scene_apply": "İncelenen stüdyoyu uygula",
|
||||
"render.scene_batch_reason": "Tüm çekimler, henüz kullanılamayan kayıtlı çekim render kuyruğunu gerektirir.",
|
||||
"render.scene_check_now": "Şimdi kontrol et",
|
||||
"render.scene_check_passed": "Kontrol geçti · {notes} not",
|
||||
"render.scene_check_stale": "Kontrol güncel değil · yeniden kontrol edin",
|
||||
"render.scene_check_unchecked": "Henüz kontrol edilmedi · 0 not",
|
||||
"render.scene_consent": "Aydınlatma, ortam, pozlama ve sahne değiştirmeyi onayla",
|
||||
"render.scene_light_summary": "{environment} · {lights} ışık",
|
||||
"render.scene_look_summary": "{looks} görünüm · {overrides} geçersiz kılma",
|
||||
"render.scene_open_check": "Kontrolü Aç",
|
||||
"render.scene_preserved_fields": "Kamera, örnekleme, boyutlar, optik bağlamlar, CAD geometrisi ve mühendislik malzemeleri korunur.",
|
||||
"render.scene_preserves_design": "Görünen konu için aydınlatma ve pasif bir sahne oluşturun. Geometri, mühendislik malzemeleri ve kamera ayrı kalır.",
|
||||
"render.scene_ready": "Render için hazır",
|
||||
"render.scene_reminder": "Sahne tasarımı korur. Geometri, mühendislik özellikleri ve CAD, Render'dan asla değiştirilmez.",
|
||||
"render.scene_reminders": "Hatırlatmalar",
|
||||
"render.scene_renderer_ready": "{renderer} hazır",
|
||||
"render.scene_replaces": "Şunların yerini alır",
|
||||
"render.scene_review": "Çöz ve incele",
|
||||
"render.scene_review_help": "Uygulamadan önce tam yerli kompozisyonu inceleyin. Bağlanmamış gelişmiş SCENE özellikleri ikame edilmez.",
|
||||
"render.scene_scope_details": "Kompozisyon kapsama alanı",
|
||||
"render.scene_stages": "Aşamalar",
|
||||
"render.search_appearances": "{count} görünümde ara",
|
||||
"render.setup_legacy_environment": "Bu eski kurulum, eski ortam dönüşü veya şiddeti kullanıyor. O değerler korunur; tam bir görüntü işi kaydetmeden önce onları açıkça dönüştürün.",
|
||||
"render.setup_name": "Kurulumun adı",
|
||||
@@ -2786,7 +3138,22 @@
|
||||
"render.shell_tab_camera": "RENDER KAMERASI",
|
||||
"render.shell_tab_lighting": "AYDINLATMA",
|
||||
"render.shell_tab_scene": "RENDER SAHNESİ",
|
||||
"render.shot_aperture": "Diyafram",
|
||||
"render.shot_distance": "Mesafe",
|
||||
"render.shot_dof": "Alan derinliği",
|
||||
"render.shot_duplicate": "Kaydedilmiş çekimi çoğalt",
|
||||
"render.shot_edit_output": "Çıktı'da düzenle",
|
||||
"render.shot_exposure_reason": "Pozlama, CPU ışın izleme veya GPU yol izleme gerektirir.",
|
||||
"render.shot_exposure_section": "Pozlama",
|
||||
"render.shot_focus_distance": "Odak mesafesi",
|
||||
"render.shot_fov_reason": "Görüş alanı perspektif projeksiyon gerektirir.",
|
||||
"render.shot_frame_subject": "Konuyu çerçevele",
|
||||
"render.shot_invalid_camera": "Kamera değerleri sonlu ve aralık içinde olmalıdır.",
|
||||
"render.shot_lens": "Mercek",
|
||||
"render.shot_lens_enable_reason": "Diyaframı ve odak mesafesini düzenlemek için alan derinliğini etkinleştirin.",
|
||||
"render.shot_lens_gpu_reason": "Alan derinliği GPU yol izleme gerektirir.",
|
||||
"render.shot_lens_perspective_reason": "Alan derinliği perspektif projeksiyon gerektirir.",
|
||||
"render.shot_look_selection": "Seçime bak",
|
||||
"render.shot_manager": "Kaydedilmiş çekimler",
|
||||
"render.shot_new_name": "Yeni çekim adı",
|
||||
"render.shot_remove": "Kaydedilmiş çekimi kaldır",
|
||||
@@ -2794,6 +3161,9 @@
|
||||
"render.shot_remove_title": "Kaydedilmiş çekim kaldırılsın mı?",
|
||||
"render.shot_rename": "Kaydedilmiş çekimi yeniden adlandır",
|
||||
"render.shot_saved_only": "Önce geçerli taslağı kaydedin. Çoğalt ve yeniden adlandır, tam kaydedilmiş seçenekleri ve kaynak referanslarını korur.",
|
||||
"render.shot_selection_reason": "Hedeflemek için bir gövde veya yüz seçin.",
|
||||
"render.shot_size": "Boyut",
|
||||
"render.shot_target": "Hedef",
|
||||
"render.shots_camera_changed": "Bu çekim kaydedildikten sonra kamera değişti",
|
||||
"render.shots_name_help": "Geçerli çekim için benzersiz bir ad girin.",
|
||||
"render.shots_no_result": "Henüz render yok",
|
||||
@@ -3016,6 +3386,13 @@
|
||||
"render.wait_pick_up": "henüz desteklenmiyor: ürün seçimi ve görünüm örnekleme",
|
||||
"render.wait_replace": "henüz desteklenmiyor: bir görünümün tüm kullanımlarını değiştirme",
|
||||
"render.wait_solo": "henüz desteklenmiyor: ışık görünürlüğü ve solo denetimleri",
|
||||
"render.wear_applies_to": "Uygulandığı yer",
|
||||
"render.wear_layer_count": "{count} katman",
|
||||
"render.wear_layer_one": "{count} katman",
|
||||
"render.wear_layers": "Katmanlar",
|
||||
"render.wear_no_layers": "Katman yok",
|
||||
"render.wear_selected_layer": "Seçili katman",
|
||||
"render.wear_title": "Aşınma",
|
||||
"sample.bracket.about": "2 mm sac metal kuralına göre kenar flanşları ve bir kenet içeren taban flanşı",
|
||||
"sample.bracket.name": "Sac metal köşebent",
|
||||
"sample.enclosure.about": "Dudak, vida göbekleri, dayanak ve geçmeli bağlantı içeren, içi boşaltılmış blok",
|
||||
@@ -3049,6 +3426,7 @@
|
||||
"select an axis": "bir eksen seçin",
|
||||
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "önce bir eksen, düz veya dairesel bir kenar ya da silindir, koni veya torus yüzü seçin",
|
||||
"select bodies first": "önce gövdeleri seçin",
|
||||
"select components first": "önce bileşenleri seçin",
|
||||
"select corner points, or the two lines of one corner": "köşe noktalarını veya bir köşenin iki çizgisini seçin",
|
||||
"select one corner point, or the two lines of one corner": "bir köşe noktasını veya bir köşenin iki çizgisini seçin",
|
||||
"select sheet edges first": "önce sac kenarlarını seçin",
|
||||
@@ -3067,6 +3445,7 @@
|
||||
"settings.double_click_components": "Bir bileşeni etkinleştirmek veya bağlı bir bileşeni yerinde düzenlemek için çift tıklayın",
|
||||
"settings.frame_rate_details_note": "Son karelerin sürelerinin grafiğini üzerine çizilen üçgenlerle, bir kare süresi histogramını ve GPU'nun çizdiklerini ekler. Göstermek veya gizlemek için görünümdeki kare hızına tıklayın.",
|
||||
"settings.frame_rate_note": "Görünümün sağ alt köşesinde saniyedeki kare sayısını gösterir.",
|
||||
"settings.insert_lists_open_designs": "Tasarım ekle, diğer sekmelerde açık olan tasarımları önce listeler",
|
||||
"settings.measure_axis_distances": "X/Y/Z mesafelerini göster",
|
||||
"settings.measure_axis_distances_help": "Ölç açıkken toplam mesafenin yanında dünya ekseni bileşen ölçülerini gösterir.",
|
||||
"settings.msaa_applies_on_restart": "Kenar yumuşatma, SolidCraft bir sonraki başlatıldığında uygulanır",
|
||||
@@ -3091,6 +3470,10 @@
|
||||
"shortcut.unpin": "Sabitlemeyi kaldır",
|
||||
"sketch is missing": "eskiz eksik",
|
||||
"sketch.degrees_of_freedom": "{count} serbestlik derecesi",
|
||||
"sketch.dimension_added_driven": "Eskiz bu ölçüyü zaten belirliyor, bu yüzden türetilmiş (referans) ölçü olarak eklendi",
|
||||
"sketch.dimension_applied": "Ölçü uygulandı",
|
||||
"sketch.dimension_applied_defined": "Ölçü uygulandı; `{name}` parametresi tanımlandı",
|
||||
"sketch.dimension_applied_renamed": "Ölçü uygulandı; parametreye `{name}` adı verildi",
|
||||
"sketch.dof_left": "Kalan serbestlik derecesi: {count}",
|
||||
"sketch.dof_left_one": "Kalan serbestlik derecesi: {count}",
|
||||
"sketch.draw_curves": "{linetype} olarak çiz",
|
||||
@@ -3125,6 +3508,8 @@
|
||||
"sketch_text.use_font_file": "{path} yazı tipi dosyasını kullan",
|
||||
"solid": "katı",
|
||||
"status.editing": "{name} düzenleniyor",
|
||||
"status.navigation": "Fare eşlemesi: {mapping}",
|
||||
"status.navigation_tip": "Farenin görünümü nasıl hareket ettirdiği. Başka bir eşleme seçmek için tıklayın",
|
||||
"status.under_constrained": "Eksik kısıtlanmış ({count} serbestlik derecesi)",
|
||||
"status.under_constrained_one": "Eksik kısıtlanmış ({count} serbestlik derecesi)",
|
||||
"status.units_tip": "Tasarımın birimleri. Değiştirmek için tıklayın",
|
||||
@@ -3158,16 +3543,20 @@
|
||||
"timeline.delete_folders_tip": "Özelliklerini ve iç içe klasörlerini geçmişte tut",
|
||||
"timeline.delete_folders_with_features_tip": "Klasörleri, içlerindeki her özellikle ve iç içe klasörleriyle birlikte sil",
|
||||
"timeline.delete_many": "{count} Seçili Özelliği Sil",
|
||||
"timeline.edited_rolled_back": "{name} değişti, ancak geçmiş işaretçisinden sonra olduğu için oluşturulmadı: sonucu görmek için işaretçiyi onun ötesine taşıyın",
|
||||
"timeline.feature_error": "Hata: {message}",
|
||||
"timeline.feature_hint": "Düzenlemek için çift tıklayın · sıralamak için sürükleyin · daha fazlası için sağ tıklayın",
|
||||
"timeline.feature_rolled_back": "Geri sarıldı: geçmiş işaretçisinden sonra, bu yüzden oluşturulmadı",
|
||||
"timeline.feature_warning": "Uyarı: {message}",
|
||||
"timeline.group": "Yeni özellik klasörü oluştur",
|
||||
"timeline.move_many": "Zaman çizelgesi öğelerini taşı",
|
||||
"timeline.move_to_group": "Özellikleri klasöre taşı",
|
||||
"timeline.rename_group": "Özellik klasörünü yeniden adlandır",
|
||||
"timeline.reorder_many": "Özellikleri yeniden sırala",
|
||||
"timeline.suppress_features": "Özellikleri bastır",
|
||||
"timeline.suppress_folders_tip": "Klasörlerdeki ve iç içe klasörlerindeki her özelliği bastır veya bastırmayı kaldır",
|
||||
"timeline.ungroup": "Özellik klasörünü kaldır",
|
||||
"timeline.unsuppress_features": "Özelliklerin bastırmasını kaldır",
|
||||
"to the face": "yüze kadar",
|
||||
"to the next face": "sonraki yüze kadar",
|
||||
"toolbar.customize_note": "{tab} sekmesi. Bir komuta araç çubuğu düğmesi eklemek için komutu işaretleyin. Ayrıca panelin açılır menüsündeki bir satırı araç çubuğuna sürükleyebilir, bir düğmeyi kaldırmak için araç çubuğunun dışına sürükleyebilir veya açılır menü satırındaki raptiyeyi kullanabilirsiniz.",
|
||||
@@ -3239,6 +3628,10 @@
|
||||
"ui.3d_mouse_offer": "3D farenizi kalibre etmek, yer değiştirmiş veya ters dönmüş eksenleri düzeltir; hızını ve hissini ayarlar.",
|
||||
"ui.3d_mouse_offer_never": "Bir daha gösterme",
|
||||
"ui.3d_mouse_offer_swap": "Hidraw'a geç (doğrudan sürücü)",
|
||||
"ui.3d_mouse_orbit": "Döndürme",
|
||||
"ui.3d_mouse_orbit_classic": "Klasik",
|
||||
"ui.3d_mouse_orbit_tip": "İzlenen: 3B fare, dönüş başladığında görünümü, görünümün ortasındaki model kısmının etrafında döndürür; bu kısım soluk bir topla işaretlenir. Klasik: görünümün merkezi etrafında",
|
||||
"ui.3d_mouse_orbit_traced": "İzlenen",
|
||||
"ui.3d_mouse_reading": "Okunan değer",
|
||||
"ui.3d_mouse_reset_axes": "Eksen atamasını sıfırla",
|
||||
"ui.3d_mouse_reset_view": "Görünümü sıfırla",
|
||||
@@ -3275,6 +3668,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Başlığı saat yönünün tersine çevirin, tutun, sonra bırakın.",
|
||||
"ui.3d_mouse_switch_cap": "Merkeze dönüş olarak kalibre et",
|
||||
"ui.3d_mouse_switch_trackball": "İztopu olarak kalibre et",
|
||||
"ui.3d_mouse_use_direct": "Doğrudan sürücüyü kullan",
|
||||
"ui.3d_mouse_use_direct_tip": "3D fareyi spacenavd yerine doğrudan (hidraw) oku.",
|
||||
"ui.3d_mouse_view_axis": "Görünüm ekseni",
|
||||
"ui.3d_mouse_view_off": "Kapalı",
|
||||
"ui.3d_mouse_view_off_tip": "3D fare sürücüsünün profili bu ekseni kapatıyor, bu yüzden hareketi görünümü oynatmaz. Burada başka bir eksenin hareketini seçerseniz ikisi yer değiştirir ve o hareket görünümü oynatmayı bırakır.",
|
||||
@@ -3581,6 +3976,8 @@
|
||||
"ui.cancel": "İptal",
|
||||
"ui.canvases": "Tuvaller",
|
||||
"ui.center": "Merkez",
|
||||
"ui.center_arc_follows_cursor": "Merkez noktalı yay imlecin yönünü izler",
|
||||
"ui.center_arc_follows_cursor_tip": "Merkez noktalı yay, imlecin merkezinin etrafında dönüş yönüne göre saat yönünde veya saat yönünün tersine ilerler. Kapalıyken: başlangıçtan itibaren her zaman saat yönünün tersine.",
|
||||
"ui.centerline": "Merkez çizgisi",
|
||||
"ui.chain": "Zincir",
|
||||
"ui.chamfer": "Pah",
|
||||
@@ -3589,6 +3986,7 @@
|
||||
"ui.circle": "Daire",
|
||||
"ui.circular_pattern": "Dairesel desen",
|
||||
"ui.clear": "Temizle",
|
||||
"ui.clear_print_face": "Baskı yüzeyini temizle",
|
||||
"ui.clear_recent": "Son kullanılanları temizle",
|
||||
"ui.clear_the_selection": "Seçimi temizle",
|
||||
"ui.click_selects_whole_bodies": "Tıklama tüm gövdeyi seçer",
|
||||
@@ -3623,6 +4021,15 @@
|
||||
"ui.constant": "Sabit",
|
||||
"ui.constraints_conflict": "Kısıtlamalar çakışıyor",
|
||||
"ui.construction": "Yapı çizgisi",
|
||||
"ui.construction.angle_hint": "Yardımcı doğru: bir noktaya tıklayın, ardından bir açı yazın veya bir yön seçin",
|
||||
"ui.construction.bisector_hint": "Açıortay: kesişen iki düz çizgiyi, ardından istenen çözümü seçin",
|
||||
"ui.construction.common_hint": "Ortak teğet: iki daire/yay, ardından istenen çözümü seçin",
|
||||
"ui.construction.contact_hint": "Teğet: bir daire/yay veya açık spline/konik eğri, ardından değme noktasını seçin (serbest biçimli eğriler: uç noktalar)",
|
||||
"ui.construction.external_hint": "Teğet: bir daire veya yay, bir dış nokta, ardından istenen çözümü seçin",
|
||||
"ui.construction.free_hint": "Yardımcı doğru: iki noktaya tıklayın; yeniden başlamak için sağ tıklayın",
|
||||
"ui.construction.point_hint": "Yardımcı doğru: geçeceği noktaya tıklayın",
|
||||
"ui.construction.reference_hint": "Yardımcı doğru: düz bir çizgi, ardından bir nokta seçin; referansı değiştirmek için sağ tıklayın",
|
||||
"ui.construction.ribbon_label": "Yardımcılar",
|
||||
"ui.context_menu": "Bağlam menüsü",
|
||||
"ui.continuity_g0": "G0 kırık",
|
||||
"ui.continuity_g1": "G1 teğet",
|
||||
@@ -3714,6 +4121,14 @@
|
||||
"ui.end_scale": "Bitiş ölçeği",
|
||||
"ui.entities": "Öğeler",
|
||||
"ui.equal": "Eşit",
|
||||
"ui.equation_end": "Bitiş",
|
||||
"ui.equation_explicit": "Açık fonksiyon",
|
||||
"ui.equation_form": "Biçim",
|
||||
"ui.equation_note": "Değişken düz bir sayıdır: sin(t) onu radyan olarak alır. Birimi olmayan bir sonuç tasarımın birimindedir.",
|
||||
"ui.equation_parametric": "Parametrik",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Eşdeğer yarıçap",
|
||||
"ui.expand": "Genişlet",
|
||||
"ui.exportDxf": "DXF olarak dışa aktar…",
|
||||
@@ -3779,6 +4194,7 @@
|
||||
"ui.heading_design": "TASARIM",
|
||||
"ui.heading_draft": "KONİKLİK",
|
||||
"ui.heading_edit": "DÜZENLE",
|
||||
"ui.heading_equation_curve": "DENKLEM EĞRİSİ",
|
||||
"ui.heading_extrude": "EKSTRÜZYON",
|
||||
"ui.heading_fillet": "YUVARLATMA",
|
||||
"ui.heading_finish_editing": "DÜZENLEMEYİ BİTİR",
|
||||
@@ -3870,6 +4286,10 @@
|
||||
"ui.import_ellipsis": "İçe aktar…",
|
||||
"ui.infinite": "Sonsuz",
|
||||
"ui.insert": "Ekle",
|
||||
"ui.insert_design.browse": "Göz at…",
|
||||
"ui.insert_design.open_designs": "Açık tasarımlar",
|
||||
"ui.insert_design.saved_file": "{name} kaydedilmemiş değişiklikler içeriyor, bu yüzden kaydedilmiş dosyası eklendi. Değişiklikleri almak için onu kaydedin, ardından Bağları güncelle'yi çalıştırın.",
|
||||
"ui.insert_design.unsaved": "Kaydedilmemiş değişiklikler",
|
||||
"ui.inspect": "İncele",
|
||||
"ui.intersect": "Kesişim",
|
||||
"ui.isolate": "Yalıt",
|
||||
@@ -4013,12 +4433,29 @@
|
||||
"ui.polygon": "Çokgen",
|
||||
"ui.preferences": "Ayarlar",
|
||||
"ui.press_a_key": "bir tuşa basın…",
|
||||
"ui.print_face_cleared": "{body}: baskı yüzeyi temizlendi",
|
||||
"ui.print_face_input": "Baskı yüzeyi",
|
||||
"ui.print_face_one_body": "Baskı yüzeyi tek bir gövdeye aittir: değiştirmek için o gövdeyi tek başına gönderin",
|
||||
"ui.print_face_pick": "Baskı yüzeyi yapmak için katı bir gövdenin düz bir yüzeyini seçin",
|
||||
"ui.print_face_set": "{body}: baskı yüzeyi ayarlandı; Dilimleyiciye gönder gövdeyi bu yüzeyin üzerine koyar",
|
||||
"ui.profile": "Profil",
|
||||
"ui.profile_plane": "Profil düzlemi",
|
||||
"ui.profiles": "Profiller",
|
||||
"ui.project": "Yansıt",
|
||||
"ui.project_face_edges_sketch": "Yüz kenarlarını yeni eskizlere yansıt",
|
||||
"ui.properties": "Özellikler",
|
||||
"ui.properties.copy_matrix": "Matrisi kopyala",
|
||||
"ui.properties.first_moments": "Birinci momentler",
|
||||
"ui.properties.inertia": "Eylemsizlik momenti",
|
||||
"ui.properties.inertia_note": "Kütle merkezine göre, dünya eksenlerinde (g·{unit}²)",
|
||||
"ui.properties.inertia_unavailable": "Kullanılamıyor: bir gövdenin ağı kapalı değil.",
|
||||
"ui.properties.inertia_x": "Ixx, Ixy, Ixz",
|
||||
"ui.properties.inertia_y": "Iyx, Iyy, Iyz",
|
||||
"ui.properties.inertia_z": "Izx, Izy, Izz",
|
||||
"ui.properties.measuring": "Ölçülüyor…",
|
||||
"ui.properties.measuring_failed": "Ölçüm tamamlanmadan durdu.",
|
||||
"ui.properties.principal_axis": "Asal eksen {number}",
|
||||
"ui.properties.principal_moments": "Asal momentler",
|
||||
"ui.pull_direction": "Kalıptan çıkarma yönü",
|
||||
"ui.quality": "Kalite",
|
||||
"ui.quantity": "Adet",
|
||||
@@ -4064,6 +4501,7 @@
|
||||
"ui.revolve": "Döndür",
|
||||
"ui.ribbon_exit": "Çıkış",
|
||||
"ui.ribbon_labels": "Şerit simgelerinin altında metin göster",
|
||||
"ui.ribbon_menus_skip_pinned": "Sabitlenen komutları açılır menülerin dışında bırak",
|
||||
"ui.ribbon_pin_footer": "Sabitlenen komutlar şeritte görünür. Sabitlemek veya kaldırmak için bir satırın üzerine gelin.",
|
||||
"ui.ribbon_workspace": "Çalışma alanı",
|
||||
"ui.right": "Sağ",
|
||||
@@ -4081,6 +4519,7 @@
|
||||
"ui.select": "Seç",
|
||||
"ui.selectOther": "Diğerini seç…",
|
||||
"ui.selectTangentChain": "Teğet zinciri seç",
|
||||
"ui.select_all": "Tümünü seç",
|
||||
"ui.selection": "Seçim",
|
||||
"ui.selection_modifiers": "Seçim değiştiricileri",
|
||||
"ui.selection_shift_add_only": "Shift+tıklama kaldırmadan ekler",
|
||||
@@ -4117,7 +4556,11 @@
|
||||
"ui.sketch": "Eskiz",
|
||||
"ui.sketch_dimension": "Eskiz ölçüsü",
|
||||
"ui.sketch_grid": "Eskiz ızgarası",
|
||||
"ui.sketch_intersect_geometry": "Geometri",
|
||||
"ui.sketch_intersect_projection_link": "Yansıtma bağı",
|
||||
"ui.sketch_intersect_selection_filter": "Seçim filtresi",
|
||||
"ui.sketch_modifiers": "Eskiz değiştiricileri",
|
||||
"ui.sketch_project_geometry": "Geometri",
|
||||
"ui.sketch_scale": "Eskiz ölçeği",
|
||||
"ui.sketches": "Eskizler",
|
||||
"ui.slice": "Dilim",
|
||||
@@ -4168,6 +4611,7 @@
|
||||
"ui.tab_manage": "Yönet",
|
||||
"ui.tab_sheet_metal": "Sac Metal",
|
||||
"ui.tab_view": "Görünüm",
|
||||
"ui.tab_weldments": "Kaynak",
|
||||
"ui.tangent": "Teğet",
|
||||
"ui.taper_angle": "Konik açı",
|
||||
"ui.tapped": "Kılavuzlu",
|
||||
@@ -4183,6 +4627,7 @@
|
||||
"ui.tip_angle": "Uç açısı",
|
||||
"ui.to_object": "Nesneye kadar",
|
||||
"ui.tool_direction": "Takım yönü",
|
||||
"ui.toolbar_tabs_hidden": "Tüm araç çubuğu sekmeleri gizli. Birini göstermek için + işaretine tıklayın veya buraya sağ tıklayın.",
|
||||
"ui.top": "Üst",
|
||||
"ui.top_diameter": "Üst çap",
|
||||
"ui.top_radius": "Üst yarıçap",
|
||||
@@ -4220,6 +4665,8 @@
|
||||
"ui.view_centre": "Görünüm merkezi",
|
||||
"ui.viewport_status_clear": "Kapat: {name}",
|
||||
"ui.viewport_status_clear_hint": "Kapat: {name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} kenar",
|
||||
"ui.viewport_status_from": "{direction} yönünden",
|
||||
"ui.viewport_status_key": "Göstergeyi göster: {name}",
|
||||
"ui.viewport_status_minimum_radius": "Minimum yarıçap",
|
||||
"ui.viewport_status_pairs": "{count} çift",
|
||||
@@ -4229,6 +4676,7 @@
|
||||
"ui.visual_shaded_with_edges": "Kenarlarla gölgeli",
|
||||
"ui.visual_style": "Görsel stil",
|
||||
"ui.visual_wireframe": "Tel kafes",
|
||||
"ui.wheel_zoom_speed": "Fare tekerleği yakınlaştırma hızı",
|
||||
"ui.width": "Genişlik",
|
||||
"ui.window_system": "Pencere sistemi",
|
||||
"ui.window_system_auto": "Otomatik",
|
||||
@@ -4259,7 +4707,9 @@
|
||||
"update.button": "Güncelle",
|
||||
"update.button_version": "{version} sürümüne güncelle",
|
||||
"update.check_automatically": "Güncellemeleri otomatik denetle",
|
||||
"update.check_for_updates": "Güncellemeleri denetle",
|
||||
"update.check_now": "Şimdi denetle",
|
||||
"update.check_unavailable": "Bu kurulum için güncelleme denetimi kullanılamıyor.",
|
||||
"update.checking": "Denetleniyor…",
|
||||
"update.copy": "Kopyala",
|
||||
"update.dmg_opened": "Disk görüntüsü açıldı ve doğrulandı: SolidCraft'ı “Uygulamalar” klasörüne sürükleyin, eski sürümü değiştirin ve SolidCraft'ı yeniden başlatın.",
|
||||
@@ -4273,13 +4723,18 @@
|
||||
"update.installed": "SolidCraft {version} yüklendi. Kullanmak için yeniden başlatın.",
|
||||
"update.installer_started": "Yükleme programı, SolidCraft kapatıldığında başlar.",
|
||||
"update.later": "Daha sonra hatırlat",
|
||||
"update.managed": "Güncelleme mevcut: SolidCraft'ı {manager} üzerinden güncelleyin",
|
||||
"update.no_notes": "Bu sürüm için not bulunmuyor.",
|
||||
"update.package_hint": "Bu kurulum bir {kind} kaynağından geliyor. Yeni paketi indirip şu komutla yükleyin:",
|
||||
"update.prefs_dev": "Bu bir geliştirme derlemesi ({version}): güncelleme aramaz.",
|
||||
"update.prefs_flatpak": "Bu kurulum ({version}) Flatpak tarafından güncellenir: {command} komutunu çalıştırın veya yazılım yöneticisini kullanın. SolidCraft kendisi denetlemez.",
|
||||
"update.prefs_label": "Güncellemeler",
|
||||
"update.prefs_managed": "Bu, {manager} tarafından yönetilen SolidCraft {version}. Denetim, GitHub'a en yeni sürümü sorar ve başka hiçbir şey göndermez; SolidCraft'ı {manager} üzerinden güncelleyin.",
|
||||
"update.prefs_note": "Bu, SolidCraft {version} ({kind}). Denetim, GitHub'a en yeni sürümü sorar ve başka hiçbir şey göndermez.",
|
||||
"update.prefs_web": "En yeni web uygulamasını almak için sayfayı yeniden yükleyin. Ağ kullanılamazsa veya güncelleme indirmesi zamanında bitiremezse bunun yerine kaydedilmiş sürüm açılır; süren bir indirme bir sonraki yeniden yükleme için devam eder.",
|
||||
"update.refresh_checking": "En yeni sürüm denetleniyor…",
|
||||
"update.refresh_fallback": "Daha yeni bir sürüm denetlenemedi; daha önce bulunan {version} sürümüne güncelleniyor.",
|
||||
"update.refresh_selected": "{version} sürümüne güncelleniyor.",
|
||||
"update.release_page": "Sürüm sayfasını aç",
|
||||
"update.restart": "Şimdi yeniden başlat",
|
||||
"update.restart_later": "Daha sonra",
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "MẶT NỐI MƯỢT",
|
||||
"BOUNDARY SURFACE": "BỀ MẶT BIÊN DẠNG",
|
||||
"BROWSER": "CÂY ĐỐI TƯỢNG",
|
||||
"Back to the original order": "Trở về thứ tự ban đầu",
|
||||
"Ball": "Cầu",
|
||||
"Bar": "Thép thanh",
|
||||
"Base Center": "Tâm đáy",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "Các cạnh",
|
||||
"Edit": "Sửa",
|
||||
"Edit Profile Sketch": "Chỉnh sửa phác thảo biên dạng",
|
||||
"Edit shortcuts": "Sửa phím tắt",
|
||||
"Enable rule": "Bật quy tắc",
|
||||
"Enabled": "Đã kích hoạt",
|
||||
"End Radius": "Bán kính kết thúc",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "Bán kính",
|
||||
"Radius Fit": "Bán kính vừa vặn",
|
||||
"Ratio": "Tỷ lệ",
|
||||
"Read-only list: shortcuts can't be changed here.": "Danh sách chỉ đọc: không thể thay đổi phím tắt ở đây.",
|
||||
"Reattach selected face": "Gắn lại bề mặt đã chọn",
|
||||
"Recover": "Khôi phục",
|
||||
"Recover unsaved design?": "Khôi phục thiết kế chưa lưu?",
|
||||
@@ -593,6 +596,8 @@
|
||||
"Snap to face and edge centres": "Bắt vào tâm mặt và tâm cạnh",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "SolidCraft không thể gửi báo cáo trực tiếp. Hãy gửi trên GitHub; ứng dụng không cần mã truy cập.",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft đã đóng trước khi các thiết kế này được lưu. Bạn có thể mở bản tự động lưu gần nhất của chúng.",
|
||||
"Sort A to Z": "Sắp xếp từ A đến Z",
|
||||
"Sort Z to A": "Sắp xếp từ Z đến A",
|
||||
"Spacing 2 must be a non-zero number": "Khoảng cách 2 phải là một số khác 0",
|
||||
"Spacing must be a non-zero number": "Khoảng cách phải là một số khác 0",
|
||||
"Specialise": "Chuyên biệt hóa",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "tại bề mặt",
|
||||
"bom.group_children": "Chi tiết con trong hàng của chi tiết cha",
|
||||
"browser.body_name": "Thân khối{number}",
|
||||
"browser.calibrate_click_a": "Nhấp vào ảnh để chọn điểm A, hoặc nhập tọa độ của điểm đó.",
|
||||
"browser.calibrate_click_b": "Nhấp vào ảnh để chọn điểm B, hoặc nhập tọa độ của điểm đó.",
|
||||
"browser.calibrate_title": "Hiệu chuẩn: {name}",
|
||||
"browser.capture_many": "{count} chi tiết đã được di chuyển nhưng vị trí chưa được ghi lại.",
|
||||
"browser.capture_note": "Ghi vị trí sẽ giữ vị trí mới; Hoàn nguyên sẽ đặt lại như cũ.",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "Lấy diện mạo",
|
||||
"cmd.appearance_replace": "Thay diện mạo",
|
||||
"cmd.assembly_bom": "Bảng kê vật tư (BOM)",
|
||||
"cmd.body.print_face": "Mặt in",
|
||||
"cmd.body_rename": "Đổi tên thân khối",
|
||||
"cmd.browser_collapse_all": "Thu gọn tất cả",
|
||||
"cmd.browser_expand_all": "Mở rộng tất cả",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "Di chuyển mục trong cây đối tượng",
|
||||
"cmd.browser_order": "Sắp xếp các mục trong cây đối tượng",
|
||||
"cmd.browser_rename_group": "Đổi tên nhóm",
|
||||
"cmd.browser_reparent": "Chuyển sang Cụm chi tiết",
|
||||
"cmd.browser_ungroup": "Hủy nhóm",
|
||||
"cmd.browser_visibility": "Hiển thị/Ẩn",
|
||||
"cmd.canvas_calibrate": "Hiệu chuẩn hình ảnh Canvas",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "Thuộc tính chi tiết",
|
||||
"cmd.component_metadata_set": "Thay đổi thuộc tính chi tiết",
|
||||
"cmd.component_move_bodies": "Di chuyển các thân khối vào cụm chi tiết",
|
||||
"cmd.component_move_features": "Di chuyển các tính năng vào cụm chi tiết",
|
||||
"cmd.component_move_sketches": "Di chuyển các phác thảo vào cụm chi tiết",
|
||||
"cmd.component_paste_from_design": "Dán từ thiết kế khác",
|
||||
"cmd.component_paste_new": "Dán Tạo mới",
|
||||
"cmd.component_properties": "Thuộc tính cơ lý của cụm chi tiết",
|
||||
"cmd.component_relink": "Liên kết lại nguồn",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "Bắt đầu kết xuất hình ảnh",
|
||||
"cmd.render_status": "Tiến độ kết xuất hình ảnh",
|
||||
"cmd.select_clear": "Hủy chọn tất cả",
|
||||
"cmd.settings_profile_apply": "Áp dụng hồ sơ cài đặt",
|
||||
"cmd.settings_profile_delete": "Xóa hồ sơ cài đặt",
|
||||
"cmd.settings_profile_export": "Xuất hồ sơ cài đặt",
|
||||
"cmd.settings_profile_import": "Nhập hồ sơ cài đặt",
|
||||
"cmd.settings_profile_list": "Hồ sơ cài đặt",
|
||||
"cmd.settings_profile_rename": "Đổi tên hồ sơ cài đặt",
|
||||
"cmd.settings_profile_save": "Lưu hồ sơ cài đặt",
|
||||
"cmd.sheet_convert": "Chuyển thành kim loại tấm",
|
||||
"cmd.sheet_export_bend_table": "Xuất bảng thông số chấn uốn (Bend Table)",
|
||||
"cmd.sheet_export_dxf": "Xuất bản trải phẳng dạng DXF",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "Gập lại tấm kim loại",
|
||||
"cmd.sheet_rules": "Danh sách quy tắc kim loại tấm",
|
||||
"cmd.sheet_unfold": "Trải phẳng tạm thời",
|
||||
"cmd.sketch.construction_line": "Đường thẳng dựng hình",
|
||||
"cmd.sketch.construction_line.angle": "Đường dựng hình theo góc",
|
||||
"cmd.sketch.construction_line.bisector": "Đường phân giác",
|
||||
"cmd.sketch.construction_line.horizontal": "Đường dựng hình nằm ngang",
|
||||
"cmd.sketch.construction_line.parallel": "Đường dựng hình song song",
|
||||
"cmd.sketch.construction_line.perpendicular": "Đường dựng hình vuông góc",
|
||||
"cmd.sketch.construction_line.tangent_at": "Tiếp tuyến tại điểm trên đường cong",
|
||||
"cmd.sketch.construction_line.tangent_external": "Tiếp tuyến qua điểm ngoài",
|
||||
"cmd.sketch.construction_line.tangent_two": "Tiếp tuyến chung",
|
||||
"cmd.sketch.construction_line.vertical": "Đường dựng hình thẳng đứng",
|
||||
"cmd.sketch_arc3d": "Cung tròn 3D",
|
||||
"cmd.sketch_arc_center_point": "Cung tròn xác định bởi tâm và điểm",
|
||||
"cmd.sketch_arc_tangent": "Cung tròn tiếp tuyến",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "Kích thước bản vẽ",
|
||||
"cmd.sketch_edit": "Chỉnh sửa phác thảo",
|
||||
"cmd.sketch_edit_text": "Chỉnh sửa văn bản",
|
||||
"cmd.sketch_equation_curve": "Đường cong phương trình",
|
||||
"cmd.sketch_equation_curve_edit": "Sửa đường cong phương trình",
|
||||
"cmd.sketch_export_dxf": "Lưu dưới dạng DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "Hoàn tất với tự động ràng buộc",
|
||||
"cmd.sketch_fit_curves_to_section": "Khớp đường cong vào mặt cắt lưới",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "Trình duyệt kết xuất",
|
||||
"cmd.view.render_dock": "Di chuyển neo kết xuất",
|
||||
"cmd.view.render_focus": "Chế độ xem tập trung kết xuất",
|
||||
"cmd.view.status_items": "Các mục trạng thái khung nhìn",
|
||||
"cmd.view_ambient_occlusion": "Đổ bóng che khuất môi trường (AO)",
|
||||
"cmd.view_angle_readout": "Góc hướng nhìn",
|
||||
"cmd.view_apply": "Áp dụng góc nhìn đã lưu",
|
||||
@@ -1374,6 +1405,18 @@
|
||||
"help.occurrence.move": "Chỉ di chuyển chi tiết lắp ráp theo các bậc tự do mà khớp nối cho phép. Chọn một mặt của chi tiết, rồi kéo mũi tên hoặc cung tròn có thể sử dụng.",
|
||||
"help.parameters.change": "Mở bảng các giá trị có tên và biểu thức điều khiển kích thước của thiết kế. Dùng để sửa một kích thước ở một chỗ và mọi tính năng dùng nó sẽ cập nhật theo.",
|
||||
"help.pointcloud.insert": "Chèn bản quét PLY, XYZ hoặc PTS dưới dạng đám mây điểm bên cạnh mô hình. Dùng làm tham chiếu khi dựng mô hình từ dữ liệu đo.",
|
||||
"help.sketch.construction_line": "Tạo đường thẳng dựng hình vô hạn qua hai điểm để bố trí phác thảo mà không chia tách biên dạng.",
|
||||
"help.sketch.construction_line.angle": "Tạo đường dựng hình vô hạn theo góc so với trục X của phác thảo. Chọn điểm rồi nhập góc hoặc chọn hướng.",
|
||||
"help.sketch.construction_line.bisector": "Chọn hai đường thẳng giao nhau trong phác thảo rồi chọn một trong hai đường phân giác. Kết quả thay đổi theo các đường gốc.",
|
||||
"help.sketch.construction_line.horizontal": "Tạo đường dựng hình nằm ngang vô hạn qua một điểm. Ràng buộc ngang được giữ khi chỉnh sửa sau này.",
|
||||
"help.sketch.construction_line.parallel": "Chọn đường thẳng trong phác thảo rồi đặt đường dựng hình vô hạn song song. Nhấp chuột phải để đổi tham chiếu.",
|
||||
"help.sketch.construction_line.perpendicular": "Chọn đường thẳng trong phác thảo rồi đặt đường dựng hình vô hạn vuông góc. Nhấp chuột phải để đổi tham chiếu.",
|
||||
"help.sketch.construction_line.tangent_at": "Tạo tiếp tuyến tại một điểm trên đường tròn hoặc cung tròn, hoặc tại đầu mút của spline hay đường conic hở. Chọn đường cong rồi chọn tiếp điểm.",
|
||||
"help.sketch.construction_line.tangent_external": "Chọn đường tròn hoặc cung tròn, một điểm ngoài rồi chọn nghiệm tiếp tuyến. Bản xem trước chỉ hiển thị tiếp điểm trên cung đã vẽ.",
|
||||
"help.sketch.construction_line.tangent_two": "Chọn hai đường tròn hoặc cung tròn rồi chọn tiếp tuyến chung trong bản xem trước. Tiếp điểm phải nằm trên các đường cong đã vẽ.",
|
||||
"help.sketch.construction_line.vertical": "Tạo đường dựng hình thẳng đứng vô hạn qua một điểm. Ràng buộc đứng được giữ khi chỉnh sửa sau này.",
|
||||
"help.sketch.equation_curve": "Vẽ một đường cong từ công thức trên một khoảng: x(t) và y(t), hoặc y = f(x). Công thức có thể dùng tham số và đường cong thay đổi theo: dùng cho sóng sin, đường xoắn ốc hay đường thân khai của răng bánh răng.",
|
||||
"help.sketch.inspect": "Mở báo cáo về bản phác thảo đang mở: còn bao nhiêu bậc tự do và đã ràng buộc hoàn toàn chưa. Dùng nó để biết phần nào vẫn còn di chuyển được trước khi hoàn tất bản phác thảo.",
|
||||
"help.solid.align": "Di chuyển các khối đã chọn để một điểm, mặt hoặc mặt phẳng trên chúng gặp một điểm, mặt hoặc mặt phẳng ở nơi khác. Dùng để đặt chi tiết áp vào chi tiết khác mà không cần đo khoảng cách.",
|
||||
"help.solid.chamfer": "Vát các cạnh đã chọn theo khoảng cách bạn thiết lập. Dùng để triệt tiêu cạnh sắc hoặc giúp lắp chốt, bu lông dễ dàng hơn.",
|
||||
"help.solid.combine": "Hợp nhất các khối, cắt trừ khỏi khối đích, hoặc chỉ giữ lại phần thể tích giao nhau, đồng thời có thể giữ lại các khối công cụ. Dùng để gộp chi tiết, dùng hình này cắt hình kia hoặc tìm vị trí hai khối giao nhau.",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "Các vật liệu khác nhau",
|
||||
"measure.at": "Tại",
|
||||
"measure.item": "Mục {number}",
|
||||
"measure.quick_copied": "Đã sao chép số đo",
|
||||
"measure.quick_copy": "Nhấp để sao chép số đo",
|
||||
"measure.quick_edges": "{count} cạnh",
|
||||
"measure.quick_faces": "{count} mặt",
|
||||
"messages.ago_h": "{n} giờ trước",
|
||||
"messages.ago_min": "{n} phút trước",
|
||||
"messages.ago_s": "{n} giây trước",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "không phải một phép di chuyển",
|
||||
"not a number": "không phải là số",
|
||||
"open a sketch first": "hãy mở một phác thảo trước",
|
||||
"parameters.apply_live": "Áp dụng mỗi thay đổi khi rời khỏi ô của nó",
|
||||
"parameters.apply_live_tip": "Tắt: các thay đổi chờ đến khi nhấn Áp dụng hoặc OK, rồi thiết kế được dựng lại một lần cho tất cả. Hủy hoặc Escape sẽ bỏ chúng.",
|
||||
"parameters.held": "{count} thay đổi đang chờ Áp dụng",
|
||||
"parameters.held_hint": "Sửa biểu thức và đơn vị. Thay đổi chờ đến khi nhấn Áp dụng hoặc OK.",
|
||||
"parameters.held_one": "1 thay đổi đang chờ Áp dụng",
|
||||
"parts.automatic_name": "tự động",
|
||||
"parts.dimension.across_flats": "Cỡ cờ lê",
|
||||
"parts.dimension.bore": "Đường kính lỗ",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "Độ dày",
|
||||
"parts.dimension.width": "Bề rộng",
|
||||
"parts.family.bearing": "Ổ bi cầu rãnh sâu (bao ngoài)",
|
||||
"parts.family.button_head_cap_screw": "Vít đầu tròn lục giác chìm",
|
||||
"parts.family.dowel_pin": "Chốt trụ",
|
||||
"parts.family.hex_bolt": "Bu lông đầu lục giác",
|
||||
"parts.family.hex_nut": "Đai ốc lục giác",
|
||||
"parts.family.set_screw": "Vít trí lục giác chìm, đầu bằng",
|
||||
"parts.family.socket_head_cap_screw": "Bu lông lục giác chìm đầu trụ",
|
||||
"parts.family.washer": "Vòng đệm phẳng",
|
||||
"parts.holes": "Lỗ (tùy chọn)",
|
||||
"parts.placement_hint": "chọn một hoặc nhiều lỗ để lắp một chi tiết vào mỗi lỗ, hoặc nhấn OK để đặt tại gốc tọa độ",
|
||||
"pattern.alignment_2": "Căn chỉnh 2",
|
||||
"pattern.alignment_hint": "Số lượng bao gồm cả bản gốc. Căn giữa sẽ cân bằng các bản sao; Đổi hướng sẽ chọn phía bổ sung cho tổng số chẵn.",
|
||||
"pattern.direction_1": "Hướng 1",
|
||||
@@ -1801,6 +1856,8 @@
|
||||
"prefs.bottom_centre": "Giữa phía dưới",
|
||||
"prefs.bottom_right": "Góc dưới bên phải",
|
||||
"prefs.browser": "Cây thư mục",
|
||||
"prefs.browser_eye_left": "Biểu tượng mắt cạnh mũi tên thu gọn",
|
||||
"prefs.browser_eye_left_note": "Các hàng trong cây thư mục hiển thị biểu tượng mắt bật/tắt cạnh mũi tên thu gọn như trước đây, thay vì trong một cột ở đầu bên phải của các hàng.",
|
||||
"prefs.browser_reveal_on_hover": "Hiện khi di chuột",
|
||||
"prefs.browser_show_note": "Hiển thị giữ trình duyệt trên màn hình. Hiện khi di chuột ẩn nó cho đến khi con trỏ đến vị trí của nó hoặc thẻ mảnh ở cạnh trái, và nó vẫn mở khi con trỏ ở bên trong hoặc một menu của nó đang mở.",
|
||||
"prefs.browser_shown": "Hiển thị",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "Có hiệu lực sau khi khởi động lại SolidCraft. Biến môi trường WGPU_ADAPTER_NAME sẽ ghi đè lựa chọn này.",
|
||||
"prefs.graphics_note": "Cân đối giữa tốc độ và độ mượt mà. Mỗi tùy chọn đều hiển thị hiệu ứng trực quan trên mẫu thử.",
|
||||
"prefs.graphics_presets_note": "Các cấu hình định sẵn sẽ thiết lập đồng thời các tùy chọn bên dưới.",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "Ẩn biểu tượng ràng buộc khi thu nhỏ",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "Biểu tượng ràng buộc biến mất khi bản phác được thu nhỏ đủ xa để không làm rối khung nhìn. Tắt: chúng giữ kích thước màn hình cố định ở mọi mức thu phóng.",
|
||||
"prefs.history": "Lịch sử",
|
||||
"prefs.history_origin_bodies": "Hiển thị gốc tọa độ và thân khối ở trên cùng",
|
||||
"prefs.history_origin_bodies_note": "Cây Lịch sử ở bên trái hoặc dưới cây thư mục sẽ bắt đầu với thư mục Thân khối và Gốc tọa độ của cụm chi tiết đang kích hoạt, cùng biểu tượng mắt bật/tắt và trình đơn tương tự như trong cây thư mục. Dòng Lịch sử ở cạnh dưới không thay đổi.",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "Chế độ Gọn (Compact) gắn các bảng vào mép cửa sổ. Độ trong suốt của Cây thư mục chỉ khả dụng ở chế độ Nổi (Floating). Thay đổi vị trí của Trợ lý trong trang Trợ lý.",
|
||||
"prefs.left": "Bên trái",
|
||||
"prefs.left_click": "Nhấp chuột trái",
|
||||
"prefs.line_drag_draws_one": "Nhấn và kéo vẽ một đường",
|
||||
"prefs.line_drag_draws_one_note": "Trong công cụ Đường, nhấn, kéo rồi thả sẽ vẽ một đường từ điểm nhấn đến điểm thả, và kết thúc ở đó. Nhấp vẫn vẽ một chuỗi. Tắt: kéo đặt một điểm tại nơi thả, như một lần nhấp.",
|
||||
"prefs.linked_designs": "Thiết kế liên kết",
|
||||
"prefs.live_input": "Nhập liệu trực tiếp",
|
||||
"prefs.live_preview": "Xem trước trực tiếp",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "Tệp STEP và tệp nhập",
|
||||
"prefs.max_file_size_web": "Ứng dụng web mở tệp STEP và tệp nhập tối đa 512 MB, thiết kế tối đa 256 MB: thẻ trình duyệt không chứa được tệp lớn hơn. Ứng dụng máy tính cho phép tăng các giới hạn này.",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "Biểu tượng lớn",
|
||||
"prefs.menu_list": "Danh sách",
|
||||
"prefs.menus": "Menu",
|
||||
"prefs.minutes": "phút",
|
||||
"prefs.minutes_suffix": " phút",
|
||||
"prefs.mouse": "Chuột và bàn di cảm ứng",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "Tên các mặt phẳng gốc",
|
||||
"prefs.origin_plane_names_note": "Tên hiển thị trong trình duyệt, hộp thoại và danh sách. {top} là XY, {front} là XZ và {right} là YZ, với Z hướng lên. Lệnh, script và thiết kế đã lưu vẫn dùng XY, XZ và YZ.",
|
||||
"prefs.overall_speed": "Tốc độ tổng thể",
|
||||
"prefs.parameter_list_rows": "Số dòng danh sách tham số",
|
||||
"prefs.parameter_list_rows_tip": "Phím mũi tên xuống trong ô giá trị trống liệt kê các tham số, mục yêu thích trước, tối đa số này. Ít hơn giúp danh sách nhẹ trong thiết kế lớn.",
|
||||
"prefs.persistent_ribbon_pressed": "Tô sáng lệnh đang bật trên dải băng",
|
||||
"prefs.persistent_ribbon_pressed_help": "Tô sáng các lệnh trên dải băng khi hiệu ứng của chúng đang bật. Tắt tùy chọn này để giữ giao diện trung tính và trợ giúp lệnh như trước.",
|
||||
"prefs.perspective_fov": "Trường nhìn",
|
||||
"prefs.placement": "Vị trí đặt",
|
||||
"prefs.prefer_free_sketch_points": "Ưu tiên điểm phác thảo có thể di chuyển khi các điểm chồng lên nhau",
|
||||
"prefs.preview_choices": "Xem trước các lựa chọn của bạn",
|
||||
"prefs.print_face_highlight": "Tô sáng mặt in",
|
||||
"prefs.print_face_highlight_tip": "Mức tô màu và viền mặt in của thân trong khung nhìn. 0 % không tô sáng.",
|
||||
"prefs.profile_active": "Hồ sơ đang dùng",
|
||||
"prefs.profile_applied": "Đã áp dụng hồ sơ.",
|
||||
"prefs.profile_changed": "Cài đặt đã thay đổi kể từ khi lưu hồ sơ. “Lưu” sẽ ghi chúng vào hồ sơ.",
|
||||
"prefs.profile_deleted": "Đã xóa hồ sơ.",
|
||||
"prefs.profile_export": "Xuất tệp…",
|
||||
"prefs.profile_exported": "Đã xuất hồ sơ.",
|
||||
"prefs.profile_imported": "Đã nhập hồ sơ. Chọn hồ sơ trong “Hồ sơ đang dùng” để chuyển sang.",
|
||||
"prefs.profile_name_hint": "Tên hồ sơ, ví dụ Laptop",
|
||||
"prefs.profile_rename": "Đổi tên",
|
||||
"prefs.profile_renamed": "Đã đổi tên hồ sơ.",
|
||||
"prefs.profile_save": "Lưu",
|
||||
"prefs.profile_saved": "Đã lưu cài đặt hiện tại vào hồ sơ.",
|
||||
"prefs.profile_skipped": "Đã áp dụng hồ sơ; {n} cài đặt giữ nguyên giá trị hiện tại (xem nhật ký).",
|
||||
"prefs.profiles": "Hồ sơ cài đặt",
|
||||
"prefs.profiles_note": "Phím tắt, thanh công cụ, điều hướng, menu dạng vòng và cài đặt giao diện, được lưu cùng nhau dưới một tên và chuyển đổi cùng lúc.",
|
||||
"prefs.project_options_dialog": "Hộp thoại tùy chọn Project",
|
||||
"prefs.project_options_dialog_note": "Bật: chọn Hình học hoặc Thân và Liên kết chiếu trước khi chiếu. Tắt: giữ quy trình chọn trực tiếp trước đây.",
|
||||
"prefs.quality_default": "mặc định",
|
||||
"prefs.quality_fastest": "nhanh nhất",
|
||||
"prefs.quality_slowest": "chậm nhất (chất lượng cao nhất)",
|
||||
"prefs.quality_smoother": "mượt mà hơn",
|
||||
"prefs.quick_measure": "Đo nhanh ở góc khung nhìn",
|
||||
"prefs.quick_measure_note": "Hiển thị kích thước của đối tượng được chọn ở góc dưới bên phải khung nhìn, phía trên Lịch sử: chiều dài của cạnh (hoặc Ø và R với cạnh tròn), diện tích của mặt, vị trí của điểm, khoảng cách và góc giữa hai đối tượng, tổng của nhiều cạnh hoặc mặt. Nhấp để sao chép.",
|
||||
"prefs.render_previous_geometry_budget": "Dùng ngân sách hình học trước đây cho bản xem trước kết xuất",
|
||||
"prefs.render_previous_geometry_budget_help": "Khôi phục giới hạn hình học cố định trước đây (512 MiB trên máy tính 64 bit, 128 MiB trên các nền tảng khác) thay cho ngân sách dựa trên thiết bị.",
|
||||
"prefs.reports_saved": "Đã lưu {n}",
|
||||
"prefs.ribbon_reveal": "Hiện kết quả tìm kiếm trên ribbon",
|
||||
"prefs.ribbon_reveal_note": "Khi rê chuột lên một kết quả trong Tìm lệnh, ribbon cho biết lệnh nằm ở đâu: tab, nút hoặc dòng của nó trong menu thả xuống của một bảng. Lệnh bắt đầu từ tìm kiếm sẽ nhấp nháy ở đó, và lệnh đang chạy từ menu thả xuống sẽ đánh dấu bảng của nó.",
|
||||
"prefs.right_click": "Nhấp chuột phải",
|
||||
"prefs.saving": "Tự động lưu và khôi phục",
|
||||
"prefs.scale_note": "Cũng có thể dùng Ctrl + / Ctrl − trong cửa sổ. Các nút có kích thước 28 px ở mức 100%.",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "Không có cài đặt nào khớp",
|
||||
"prefs.select": "Chọn",
|
||||
"prefs.select_one_item": "Chọn một mục",
|
||||
"prefs.select_other_hidden": "Chọn hình học ẩn bằng Chọn đối tượng khác",
|
||||
"prefs.select_other_hidden_help": "Bật: bao gồm các khối, bản phác thảo ẩn và cạnh bị che gần con trỏ. Tắt: dùng danh sách ban đầu chỉ gồm hình học đang hiển thị ngay dưới con trỏ.",
|
||||
"prefs.selecting": "Đang chọn",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift chỉ thêm; Ctrl / Cmd đảo trạng thái chọn",
|
||||
"prefs.shift_add_note": "Bật: Shift để thêm vào vùng chọn, Ctrl / Cmd để đảo chọn. Tắt (mặc định): cả hai đều đảo trạng thái chọn.",
|
||||
"prefs.shortcuts": "Phím tắt",
|
||||
"prefs.single_surface_analysis": "Chỉ dùng một phân tích bề mặt",
|
||||
"prefs.single_surface_analysis_help": "Khi tắt, phân tích tô bóng bề mặt và phân tích tính liên tục có thể cùng hoạt động. Khi bật, chỉ giữ phân tích được bắt đầu hoặc thay đổi gần nhất.",
|
||||
"prefs.sketch_align_points": "Căn theo các điểm phác thảo khác khi vẽ",
|
||||
"prefs.sketch_align_points_note": "Khi vẽ, một điểm được căn ngang theo một điểm phác thảo và căn dọc theo điểm khác cùng lúc, kèm đường dẫn chấm; cú nhấp giữ cả hai ràng buộc căn. Tắt: chỉ căn theo điểm trước, mỗi lần một trục.",
|
||||
"prefs.sketch_conflict_colour": "Hình học xung đột theo màu xung đột",
|
||||
"prefs.sketch_conflict_colour_note": "Khi các ràng buộc của bản phác xung đột, các đường cong và điểm mà một ràng buộc lỗi giữ cũng được vẽ bằng màu xung đột, không chỉ ký hiệu hay kích thước của nó. Tắt: chúng giữ màu thường.",
|
||||
"prefs.sketch_construction_lines": "Công cụ đường dựng hình mở rộng",
|
||||
"prefs.sketch_exit_view": "Khi kết thúc phác thảo",
|
||||
"prefs.sketch_exit_view.keep": "Giữ góc nhìn hiện tại",
|
||||
"prefs.sketch_exit_view.previous": "Trở về góc nhìn trước đó",
|
||||
"prefs.sketch_exit_view.unless_rotated": "Trở về góc nhìn trước trừ khi đã xoay",
|
||||
"prefs.sketch_exit_view_note": "Góc nhìn sẽ chuyển đến đâu sau khi bấm Hoàn tất phác thảo, Hủy bỏ hoặc bấm phím Esc hai lần.",
|
||||
"prefs.sketch_open_look_at": "Xoay góc nhìn trực diện phác thảo khi mở",
|
||||
"prefs.sketch_open_look_at_note": "Tắt: tạo hoặc chỉnh sửa phác thảo sẽ giữ nguyên góc nhìn. Dùng Nhìn trực diện để nhìn thẳng vào phác thảo khi cần.",
|
||||
"prefs.sketch_recent_snap": "Tự động bắt điểm vào tâm và trung điểm gần đây",
|
||||
"prefs.sketch_recent_snap_note": "Khi vẽ, con trỏ được bắt vào nơi các đường dẫn của hai tâm đường tròn hoặc trung điểm cạnh thẳng gần nhất cắt nhau. Tắt: các đường dẫn chỉ để xem và con trỏ không di chuyển.",
|
||||
"prefs.sketch_selection": "Phác thảo & chọn đối tượng",
|
||||
"prefs.sketch_selection_heading": "Phác thảo và lựa chọn",
|
||||
"prefs.sketch_selection_note": "Cách phác thảo bắt dính và cách nhấp chuột chọn đối tượng.",
|
||||
@@ -1995,20 +2096,34 @@
|
||||
"prefs.under_cursor": "Dưới con trỏ chuột",
|
||||
"prefs.units_precision": "Đơn vị và độ chính xác",
|
||||
"prefs.updates": "Cập nhật ứng dụng",
|
||||
"prefs.value_boxes_in_view": "Hiện giá trị cạnh tay nắm trong khung nhìn",
|
||||
"prefs.value_boxes_in_view_tip": "Giá trị của lệnh (Khoảng cách, Bán kính…) trong một ô cạnh tay nắm, phía trên mô hình. Tắt: bạn nhập giá trị trong cửa sổ lệnh, cửa sổ này nhận bàn phím sau khi chọn, và không có gì che mô hình.",
|
||||
"prefs.view": "Hành vi góc nhìn",
|
||||
"prefs.view_confirm_corner": "Nút Đồng ý và Hủy bỏ ở góc khung nhìn",
|
||||
"prefs.view_confirm_corner_note": "Khi hộp thoại hoặc môi trường phác thảo đang mở, dấu tích và dấu chéo ở góc trên bên phải khung nhìn có chức năng tương tự nút Đồng ý và Hủy bỏ của hộp thoại, hoặc để hoàn tất và hủy phác thảo. Khối điều hướng góc nhìn sẽ dời xuống bên dưới chúng.",
|
||||
"prefs.viewport": "Khung nhìn 3D",
|
||||
"prefs.viewport_analysis_status": "Hiện trạng thái phân tích trong khung nhìn",
|
||||
"prefs.viewport_analysis_status_help": "Hiện các phân tích đang bật phía trên khung nhìn và mở chú giải từ từng mục. Esc tắt phân tích mới nhất. Tắt tùy chọn để khôi phục chú giải ở góc và hành vi Esc trước đây.",
|
||||
"prefs.viewport_background": "Nền",
|
||||
"prefs.viewport_background_colour": "Màu",
|
||||
"prefs.viewport_background_theme": "Dải màu của chủ đề",
|
||||
"prefs.viewport_section_status": "Hiện trạng thái mặt cắt trong khung nhìn",
|
||||
"prefs.viewport_section_status_help": "Hiện thiết lập mặt cắt trong khung nhìn. Escape và nút dải công cụ đang bật sẽ tắt mặt cắt. Tắt tùy chọn để giữ cách điều khiển mặt cắt trước đây.",
|
||||
"prefs.viewport_status_summary": "Tóm tắt các mục trạng thái khung nhìn",
|
||||
"prefs.viewport_status_summary_help": "Gộp từ ba mục trạng thái khung nhìn trở lên thành một huy hiệu tóm tắt. Tắt để giữ mọi mục trong hàng đầy đủ.",
|
||||
"prefs.wheel": "Con lăn chuột",
|
||||
"prefs.wheel_trackpad": "Con lăn chuột và bàn di cảm ứng",
|
||||
"prefs.workspace": "Không gian làm việc",
|
||||
"prefs.zoom_stop_at_model": "Dừng thu phóng tại mô hình",
|
||||
"prefs.zoom_stop_at_model_tip": "Chuột 3D và ứng dụng thiết bị thu phóng về phía bề mặt ở giữa khung nhìn; thu phóng bằng cách kéo giữ nguyên điểm bắt đầu kéo. Khi tắt, có thể thu phóng xuyên qua mô hình. Con lăn và cử chỉ chụm dùng riêng tùy chọn Thu phóng về con trỏ",
|
||||
"prefs.zoom_toward_cursor": "Thu phóng về phía con trỏ chuột",
|
||||
"properties.title": "Thuộc tính: {name}",
|
||||
"recovery.days_ago": "{count} ngày trước",
|
||||
"recovery.detail": "{file} · {features} tính năng · tự động lưu {when}",
|
||||
"recovery.discard_all": "Hủy bỏ tất cả",
|
||||
"recovery.discard_all_detail": "Không thể hoàn tác thao tác này.",
|
||||
"recovery.discard_all_title": "Hủy bỏ {count} bản tự động lưu?",
|
||||
"recovery.discard_all_title_one": "Hủy bỏ 1 bản tự động lưu?",
|
||||
"recovery.hours_ago": "{count} giờ trước",
|
||||
"recovery.just_now": "vừa xong",
|
||||
"recovery.min_ago": "{count} phút trước",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "Sẵn sàng kết xuất",
|
||||
"render.output_run_check": "Chạy kiểm tra",
|
||||
"render.output_size_limit": "{method}: tối đa {dimension} px mỗi cạnh và {pixels} điểm ảnh. Kích thước lớn nhất vừa khít: {width} × {height}.",
|
||||
"render.output_size_method_profile": "Để kết xuất {width} × {height}, hãy chọn {method} với cấu hình tài nguyên CPU {profile} hoặc một kích thước nhỏ hơn.",
|
||||
"render.output_size_ok": "Kích thước ổn · {width} × {height} px",
|
||||
"render.output_size_profile": "Để kết xuất {width} × {height}, hãy chọn cấu hình tài nguyên CPU {profile} hoặc một kích thước nhỏ hơn.",
|
||||
"render.output_swap_orientation": "Hoán đổi chiều rộng và chiều cao",
|
||||
"render.output_tools_inspector": "Chỉnh kích thước và định dạng trong bảng thuộc tính Đầu ra.",
|
||||
"render.output_view_image": "Xem ảnh",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "Tùy chỉnh…",
|
||||
"render.size_full_hd": "Full HD",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · cần {profile}",
|
||||
"render.size_presets": "Cỡ đặt sẵn",
|
||||
"render.size_presets_pending": "Sẽ có cùng trình chỉnh Đầu ra",
|
||||
"render.size_preview": "Xem trước",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "Nhấp đúp vào một thành phần để kích hoạt nó, hoặc chỉnh sửa tại chỗ một thành phần liên kết",
|
||||
"settings.frame_rate_details_note": "Bổ sung biểu đồ thời gian các khung hình gần nhất xếp chồng số tam giác đã vẽ, biểu đồ phân bố thời gian khung hình và nội dung GPU đã vẽ. Bấm vào tốc độ khung hình trên khung nhìn để ẩn/hiện.",
|
||||
"settings.frame_rate_note": "Hiển thị số khung hình trên giây (FPS) ở góc dưới bên phải khung nhìn.",
|
||||
"settings.insert_lists_open_designs": "Chèn thiết kế vào cụm liệt kê trước các thiết kế đang mở ở các thẻ khác",
|
||||
"settings.measure_axis_distances": "Hiển thị khoảng cách theo trục X/Y/Z",
|
||||
"settings.measure_axis_distances_help": "Hiển thị kích thước thành phần theo các trục tọa độ cùng với khoảng cách tổng thể khi mở công cụ Đo lường.",
|
||||
"settings.msaa_applies_on_restart": "Khử răng cưa sẽ áp dụng vào lần khởi động tiếp theo của SolidCraft",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "Đường viền",
|
||||
"sheet.flange_type_edge": "Cạnh",
|
||||
"sheet.no_body": "chưa có khối tấm kim loại: hãy bắt đầu bằng Cánh gập > Cơ sở (Base), hoặc chuyển một tấm phẳng thành tấm kim loại bằng lệnh 'Chuyển thành tấm kim loại' (chọn mặt phẳng lớn của nó)",
|
||||
"sheet.personal_rules.confirm_delete": "Xác nhận xóa",
|
||||
"sheet.personal_rules.delete": "Xóa",
|
||||
"sheet.personal_rules.delete_prompt": "Xóa quy tắc cá nhân này? Các quy tắc đã có trong thiết kế sẽ không thay đổi.",
|
||||
"sheet.personal_rules.full": "Thư viện cá nhân đã chứa tối đa 64 quy tắc.",
|
||||
"sheet.personal_rules.invalid_name": "Nhập một tên ngắn gọn, không chứa ký tự xuống dòng hoặc ký tự điều khiển.",
|
||||
"sheet.personal_rules.invalid_values": "Hãy điền đủ các giá trị của quy tắc: mỗi giá trị phải tính được trong thiết kế này, với độ dày dương và hệ số K từ 0 đến 1.",
|
||||
"sheet.personal_rules.missing": "Quy tắc cá nhân đã chọn không còn khả dụng.",
|
||||
"sheet.personal_rules.name": "Tên quy tắc",
|
||||
"sheet.personal_rules.name_exists": "Quy tắc cá nhân với tên này đã tồn tại. Vui lòng sử dụng tên khác.",
|
||||
"sheet.personal_rules.name_hint": "Tên duy nhất",
|
||||
"sheet.personal_rules.overwrite": "Lưu các thay đổi vào quy tắc cá nhân đã chọn",
|
||||
"sheet.personal_rules.rename": "Đổi tên",
|
||||
"sheet.personal_rules.rule": "Quy tắc cá nhân",
|
||||
"sheet.personal_rules.save": "Lưu mới",
|
||||
"sheet.personal_rules.scope": "Được lưu trong hồ sơ cá nhân của bạn cho tất cả thiết kế.",
|
||||
"sheet.personal_rules.select": "Chọn một quy tắc",
|
||||
"sheet.personal_rules.title": "Quy tắc cá nhân",
|
||||
"sheet.personal_rules.unsupported": "Quy tắc này có các giá trị mà phiên bản hiện tại không thể sử dụng.",
|
||||
"shortcut.json_error": "tham số phải là JSON: {error}",
|
||||
"shortcut.no_command": "không có lệnh `{id}`; văn bản trước JSON phải là mã lệnh",
|
||||
"shortcut.pin": "Ghim lên đầu hộp S",
|
||||
"shortcut.unpin": "Bỏ ghim",
|
||||
"sketch is missing": "thiếu phác thảo",
|
||||
"sketch.degrees_of_freedom": "{count} bậc tự do",
|
||||
"sketch.dimension_added_driven": "Bản phác thảo đã xác định kích thước đó, nên nó được thêm vào dưới dạng kích thước tham chiếu",
|
||||
"sketch.dimension_applied": "Đã áp dụng kích thước",
|
||||
"sketch.dimension_applied_defined": "Đã áp dụng kích thước; đã định nghĩa tham số `{name}`",
|
||||
"sketch.dimension_applied_renamed": "Đã áp dụng kích thước; tham số được đặt tên là `{name}`",
|
||||
"sketch.dof_left": "Còn {count} bậc tự do",
|
||||
"sketch.dof_left_one": "Còn {count} bậc tự do",
|
||||
"sketch.draw_curves": "Vẽ dưới dạng {linetype}",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "Phải",
|
||||
"sketch_text.bold": "In đậm",
|
||||
"sketch_text.builtin_font": "{family} (tích hợp sẵn)",
|
||||
"sketch_text.formula": "Bắt đầu bằng = để tạo chữ từ các tham số: ='W' + number(Width)",
|
||||
"sketch_text.italic": "In nghiêng",
|
||||
"sketch_text.loading_fonts": "Đang tìm kiếm các phông chữ đã cài đặt…",
|
||||
"sketch_text.on_path": "Văn bản đi theo đường dẫn: đường cong định vị văn bản",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "Giữ lại các tính năng và thư mục lồng nhau trong lịch sử",
|
||||
"timeline.delete_folders_with_features_tip": "Xóa các thư mục cùng mọi tính năng trong đó và các thư mục lồng bên trong",
|
||||
"timeline.delete_many": "Xóa {count} tính năng đã chọn",
|
||||
"timeline.edited_rolled_back": "{name} đã thay đổi, nhưng nó nằm sau dấu mốc lịch sử nên chưa được dựng: kéo dấu mốc qua nó để xem kết quả",
|
||||
"timeline.feature_error": "Lỗi: {message}",
|
||||
"timeline.feature_hint": "Bấm đúp để sửa · kéo rê để đổi thứ tự · bấm chuột phải để xem thêm",
|
||||
"timeline.feature_rolled_back": "Đã lùi lại: nằm sau dấu mốc lịch sử nên chưa được dựng",
|
||||
"timeline.feature_warning": "Cảnh báo: {message}",
|
||||
"timeline.group": "Thư mục tính năng mới",
|
||||
"timeline.move_many": "Di chuyển các mục trong lịch sử thiết kế",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "Hiệu chuẩn chuột 3D sẽ sửa các trục bị hoán đổi hoặc đảo ngược và chỉnh tốc độ cũng như cảm giác.",
|
||||
"ui.3d_mouse_offer_never": "Không hiện lại",
|
||||
"ui.3d_mouse_offer_swap": "Chuyển sang Hidraw (điều khiển trực tiếp)",
|
||||
"ui.3d_mouse_orbit": "Quỹ đạo",
|
||||
"ui.3d_mouse_orbit_classic": "Cổ điển",
|
||||
"ui.3d_mouse_orbit_tip": "Theo dấu: chuột 3D xoay khung nhìn quanh phần mô hình ở giữa khung nhìn lúc bắt đầu xoay, được đánh dấu bằng một quả cầu mờ. Cổ điển: quanh tâm khung nhìn",
|
||||
"ui.3d_mouse_orbit_traced": "Theo dấu",
|
||||
"ui.3d_mouse_reading": "Giá trị đọc",
|
||||
"ui.3d_mouse_reset_axes": "Đặt lại phép gán trục",
|
||||
"ui.3d_mouse_reset_view": "Đặt lại khung nhìn",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "Chuột 3D",
|
||||
"ui.3d_mouse_show_in_view": "Hiện chuột 3D trong khung nhìn 3D",
|
||||
"ui.3d_mouse_show_in_view_tip": "Hình chuột 3D của bạn ở góc dưới bên trái, chuyển động theo bạn.",
|
||||
"ui.3d_mouse_sketch_orbit": "Xoay bản phác thảo bằng chuột 3D",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "Chuột 3D cũng xoay khung nhìn khi bản phác thảo đang mở và được nhìn thẳng, như chuột thường. Tắt: chỉ di chuyển và thu phóng bản phác thảo cho đến khi bạn nghiêng khung nhìn.",
|
||||
"ui.3d_mouse_skip": "Thiết bị của tôi không làm được điều này",
|
||||
"ui.3d_mouse_skip_tip": "Bỏ qua chuyển động này theo cả hai chiều; việc hiệu chuẩn sẽ không dùng nó.",
|
||||
"ui.3d_mouse_speed": "Tốc độ chuột 3D",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "Xoay núm điều khiển ngược chiều kim đồng hồ, giữ nguyên, rồi thả ra.",
|
||||
"ui.3d_mouse_switch_cap": "Hiệu chuẩn theo kiểu trở về giữa",
|
||||
"ui.3d_mouse_switch_trackball": "Hiệu chuẩn như bi xoay",
|
||||
"ui.3d_mouse_use_direct": "Dùng trình điều khiển trực tiếp",
|
||||
"ui.3d_mouse_use_direct_tip": "Đọc chuột 3D trực tiếp (hidraw) thay vì qua spacenavd.",
|
||||
"ui.3d_mouse_view_axis": "Trục khung nhìn",
|
||||
"ui.3d_mouse_view_off": "Tắt",
|
||||
"ui.3d_mouse_view_off_tip": "Hồ sơ của trình điều khiển chuột 3D tắt trục này, nên chuyển động của nó không làm khung nhìn di chuyển. Chọn chuyển động của trục khác ở đây sẽ hoán đổi hai trục, và chuyển động đó không còn di chuyển khung nhìn.",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "Xóa khỏi hàng đợi",
|
||||
"ui.agent_chat_remove_file": "Bỏ tệp này khỏi tin nhắn",
|
||||
"ui.agent_chat_remove_imported": "Gỡ khỏi tin nhắn này; chi tiết vẫn nằm trong thiết kế (sử dụng Hoàn tác để xóa)",
|
||||
"ui.agent_chat_reply_cut_off": "Câu trả lời đã chạm giới hạn độ dài trước khi xong nên có thể chưa đầy đủ. Hãy yêu cầu AI Agent tiếp tục, hoặc trả lời ngắn hơn.",
|
||||
"ui.agent_chat_reply_declined": "Mô hình đã từ chối trả lời tin nhắn này.",
|
||||
"ui.agent_chat_retry": "Thử lại",
|
||||
"ui.agent_chat_right": "Phải (Hình chiếu cạnh)",
|
||||
"ui.agent_chat_save": "Lưu",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "Hình tròn",
|
||||
"ui.circular_pattern": "Mảng tròn quanh trục",
|
||||
"ui.clear": "Xóa",
|
||||
"ui.clear_print_face": "Xóa mặt in",
|
||||
"ui.clear_recent": "Xóa danh sách gần đây",
|
||||
"ui.clear_the_selection": "Hủy chọn",
|
||||
"ui.click_selects_whole_bodies": "Nhấp chuột chọn toàn bộ thân khối",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "Hằng số",
|
||||
"ui.constraints_conflict": "Xung đột ràng buộc",
|
||||
"ui.construction": "Đường gióng dựng hình",
|
||||
"ui.construction.angle_hint": "Đường dựng hình: nhấp một điểm rồi nhập góc hoặc chọn hướng",
|
||||
"ui.construction.bisector_hint": "Phân giác: chọn hai đường thẳng giao nhau rồi chọn nghiệm mong muốn",
|
||||
"ui.construction.common_hint": "Tiếp tuyến chung: chọn hai đường tròn/cung rồi chọn nghiệm mong muốn",
|
||||
"ui.construction.contact_hint": "Tiếp tuyến: chọn đường tròn/cung hoặc spline/conic hở rồi chọn tiếp điểm (đường cong tự do: chỉ đầu mút)",
|
||||
"ui.construction.external_hint": "Tiếp tuyến: chọn đường tròn hoặc cung, điểm ngoài rồi chọn nghiệm mong muốn",
|
||||
"ui.construction.free_hint": "Đường dựng hình: nhấp hai điểm; nhấp chuột phải để bắt đầu lại",
|
||||
"ui.construction.point_hint": "Đường dựng hình: nhấp điểm đi qua",
|
||||
"ui.construction.reference_hint": "Đường dựng hình: chọn đường thẳng rồi chọn điểm; nhấp chuột phải để đổi tham chiếu",
|
||||
"ui.construction.ribbon_label": "Đường phụ",
|
||||
"ui.context_menu": "Menu ngữ cảnh",
|
||||
"ui.continuity_g0": "Nếp gập G0",
|
||||
"ui.continuity_g1": "G1 tiếp tuyến",
|
||||
@@ -4008,6 +4172,14 @@
|
||||
"ui.end_scale": "Tỷ lệ đầu cuối",
|
||||
"ui.entities": "Các thực thể",
|
||||
"ui.equal": "Bằng nhau",
|
||||
"ui.equation_end": "Kết thúc",
|
||||
"ui.equation_explicit": "Tường minh",
|
||||
"ui.equation_form": "Dạng",
|
||||
"ui.equation_note": "Biến là một số không có đơn vị: sin(t) hiểu nó theo radian. Kết quả không có đơn vị dùng đơn vị của thiết kế.",
|
||||
"ui.equation_parametric": "Tham số",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "Bán kính tương đương",
|
||||
"ui.expand": "Mở rộng",
|
||||
"ui.exportDxf": "Xuất tệp DXF…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "THIẾT KẾ",
|
||||
"ui.heading_draft": "ĐỘ DỐC THOÁT KHUÔN",
|
||||
"ui.heading_edit": "CHỈNH SỬA",
|
||||
"ui.heading_equation_curve": "ĐƯỜNG CONG PHƯƠNG TRÌNH",
|
||||
"ui.heading_extrude": "ĐÙN KHỐI",
|
||||
"ui.heading_fillet": "BO TRÒN",
|
||||
"ui.heading_finish_editing": "HOÀN TẤT CHỈNH SỬA",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "Nhập tệp…",
|
||||
"ui.infinite": "Vô hạn",
|
||||
"ui.insert": "Chèn",
|
||||
"ui.insert_design.browse": "Duyệt…",
|
||||
"ui.insert_design.open_designs": "Thiết kế đang mở",
|
||||
"ui.insert_design.saved_file": "{name} có thay đổi chưa lưu, nên tệp đã lưu của nó đã được chèn. Hãy lưu nó, rồi dùng Cập nhật liên kết để đưa các thay đổi vào.",
|
||||
"ui.insert_design.unsaved": "Thay đổi chưa lưu",
|
||||
"ui.inspect": "Kiểm tra",
|
||||
"ui.intersect": "Giao nhau",
|
||||
"ui.isolate": "Cô lập đối tượng",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "Không thể đọc {count} thư mục.",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "Điểm",
|
||||
"ui.point_cloud_add_filter": "Thêm bộ lọc…",
|
||||
"ui.point_cloud_auto_range": "Phạm vi tự động",
|
||||
"ui.point_cloud_color_by": "Tô màu theo",
|
||||
"ui.point_cloud_file_colors": "Màu trong tệp",
|
||||
"ui.point_cloud_filter_by": "Lọc theo",
|
||||
"ui.point_cloud_height_high": "Cao nhất",
|
||||
"ui.point_cloud_height_low": "Thấp nhất",
|
||||
"ui.point_cloud_legend_filter": "Hiện và ẩn trong chú giải ở trên",
|
||||
"ui.point_cloud_no_file_colors": "Tệp không có màu",
|
||||
"ui.point_cloud_pause": "Tạm dừng",
|
||||
"ui.point_cloud_play": "Phát",
|
||||
"ui.point_cloud_single_color": "Một màu",
|
||||
"ui.point_cloud_size": "Kích thước điểm",
|
||||
"ui.point_cloud_units": "Đơn vị của tệp",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "Đa giác",
|
||||
"ui.preferences": "Tùy chọn cài đặt",
|
||||
"ui.press_a_key": "nhấn một phím…",
|
||||
"ui.print_face_cleared": "{body}: đã xóa mặt in",
|
||||
"ui.print_face_input": "Mặt in",
|
||||
"ui.print_face_one_body": "Mặt in được chọn cho một thân: hãy gửi riêng thân đó để thay đổi",
|
||||
"ui.print_face_pick": "Chọn một mặt phẳng của thân đặc để đặt làm mặt in",
|
||||
"ui.print_face_set": "{body}: đã đặt mặt in; Gửi đến Slicer sẽ đặt thân lên mặt này",
|
||||
"ui.profile": "Biên dạng",
|
||||
"ui.profile_plane": "Mặt phẳng biên dạng",
|
||||
"ui.profiles": "Các biên dạng",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "Xoay tròn tạo khối",
|
||||
"ui.ribbon_exit": "Thoát",
|
||||
"ui.ribbon_labels": "Hiển thị văn bản bên dưới biểu tượng dải băng",
|
||||
"ui.ribbon_menus_skip_pinned": "Không lặp lại các lệnh đã ghim trong menu thả xuống",
|
||||
"ui.ribbon_pin_footer": "Các lệnh đã ghim hiển thị trên ruy-băng. Rê chuột lên một hàng để ghim hoặc bỏ ghim.",
|
||||
"ui.ribbon_workspace": "Không gian làm việc",
|
||||
"ui.right": "Phải (Hình chiếu cạnh)",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "Chọn",
|
||||
"ui.selectOther": "Chọn đối tượng khác…",
|
||||
"ui.selectTangentChain": "Chọn chuỗi tiếp tuyến",
|
||||
"ui.select_all": "Chọn tất cả",
|
||||
"ui.select_components_by_face": "Chọn thành phần (chọn một mặt sẽ chọn thành phần chứa mặt đó)",
|
||||
"ui.selection": "Vùng chọn",
|
||||
"ui.selection_modifiers": "Phím bổ trợ chọn",
|
||||
"ui.selection_shift_add_only": "Shift+nhấp chỉ thêm, không bỏ chọn",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "Bộ lọc lựa chọn",
|
||||
"ui.sketch_modifiers": "Phím bổ trợ phác thảo",
|
||||
"ui.sketch_project_geometry": "Hình học",
|
||||
"ui.sketch_report.all_constrained": "Mọi thứ đã được ràng buộc hoàn toàn.",
|
||||
"ui.sketch_report.dof": "Bậc tự do",
|
||||
"ui.sketch_report.loose": "Chưa ràng buộc hoàn toàn",
|
||||
"ui.sketch_report.status": "Trạng thái",
|
||||
"ui.sketch_report.title": "Báo cáo phác thảo",
|
||||
"ui.sketch_scale": "Tỷ lệ phác thảo",
|
||||
"ui.sketches": "Các phác thảo",
|
||||
"ui.slice": "Cắt lát",
|
||||
@@ -4532,10 +4727,19 @@
|
||||
"ui.view_centre": "Tâm góc nhìn",
|
||||
"ui.viewport_status_clear": "Tắt {name}",
|
||||
"ui.viewport_status_clear_hint": "Tắt {name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} cạnh",
|
||||
"ui.viewport_status_from": "từ {direction}",
|
||||
"ui.viewport_status_key": "Hiển thị chú giải cho {name}",
|
||||
"ui.viewport_status_minimum_radius": "Bán kính nhỏ nhất",
|
||||
"ui.viewport_status_pairs": "{count} cặp",
|
||||
"ui.viewport_status_section_hatch": "{setting} · gạch mặt cắt",
|
||||
"ui.viewport_status_section_plane": "Mặt phẳng hiện tại",
|
||||
"ui.viewport_status_section_tilted": "nghiêng · {offset}",
|
||||
"ui.viewport_status_stripes": "{count} sọc",
|
||||
"ui.viewport_status_summary_clear": "Tắt tất cả",
|
||||
"ui.viewport_status_summary_heading": "Trong khung nhìn này",
|
||||
"ui.viewport_status_summary_label": "{name} và {count} mục khác",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "Theo chủ đề giao diện",
|
||||
"ui.visual_shaded_hidden_edges": "Tô bóng kèm nét khuất",
|
||||
"ui.visual_shaded_with_edges": "Tô bóng kèm hiển thị cạnh",
|
||||
@@ -4572,7 +4776,9 @@
|
||||
"update.button": "Cập nhật",
|
||||
"update.button_version": "Cập nhật lên {version}",
|
||||
"update.check_automatically": "Tự động kiểm tra bản cập nhật",
|
||||
"update.check_for_updates": "Kiểm tra bản cập nhật",
|
||||
"update.check_now": "Kiểm tra ngay",
|
||||
"update.check_unavailable": "Không thể kiểm tra bản cập nhật cho bản cài đặt này.",
|
||||
"update.checking": "Đang kiểm tra…",
|
||||
"update.copy": "Sao chép",
|
||||
"update.dmg_opened": "Ảnh đĩa đã mở và được xác thực: kéo SolidCraft vào thư mục Applications để thay thế bản cũ, sau đó khởi động lại SolidCraft.",
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"BLEND SURFACE": "混合曲面",
|
||||
"BOUNDARY SURFACE": "边界曲面",
|
||||
"BROWSER": "浏览器",
|
||||
"Back to the original order": "恢复原始顺序",
|
||||
"Ball": "球",
|
||||
"Bar": "扁钢",
|
||||
"Base Center": "底面中心",
|
||||
@@ -206,6 +207,7 @@
|
||||
"Edges": "边",
|
||||
"Edit": "编辑",
|
||||
"Edit Profile Sketch": "编辑轮廓草图",
|
||||
"Edit shortcuts": "编辑快捷键",
|
||||
"Enable rule": "启用规则",
|
||||
"Enabled": "已启用",
|
||||
"End Radius": "结束半径",
|
||||
@@ -468,6 +470,7 @@
|
||||
"Radius": "半径",
|
||||
"Radius Fit": "半径拟合",
|
||||
"Ratio": "比率",
|
||||
"Read-only list: shortcuts can't be changed here.": "只读列表:此处无法更改快捷键。",
|
||||
"Reattach selected face": "重新附着所选面",
|
||||
"Recover": "恢复",
|
||||
"Recover unsaved design?": "恢复未保存的设计?",
|
||||
@@ -593,6 +596,8 @@
|
||||
"Snap to face and edge centres": "捕捉到面和边的中心",
|
||||
"SolidCraft cannot submit reports directly. Submit on GitHub; no token is needed in the app.": "SolidCraft 无法直接提交报告。请在 GitHub 上提交;应用中不需要令牌。",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft 在这些设计保存前已关闭。可以打开它们的上次自动保存。",
|
||||
"Sort A to Z": "升序排序",
|
||||
"Sort Z to A": "降序排序",
|
||||
"Spacing 2 must be a non-zero number": "间距 2 必须是非零数字",
|
||||
"Spacing must be a non-zero number": "间距必须是非零数字",
|
||||
"Specialise": "专用操作",
|
||||
@@ -773,6 +778,8 @@
|
||||
"at the face": "在面上",
|
||||
"bom.group_children": "子零件并入所属零件的行",
|
||||
"browser.body_name": "实体{number}",
|
||||
"browser.calibrate_click_a": "点击图像选取点 A,或输入其坐标。",
|
||||
"browser.calibrate_click_b": "点击图像选取点 B,或输入其坐标。",
|
||||
"browser.calibrate_title": "校准:{name}",
|
||||
"browser.capture_many": "{count} 个组件已移动,但尚未捕获其位置。",
|
||||
"browser.capture_note": "“捕获位置”保留新位置;“恢复位置”还原原先的位置。",
|
||||
@@ -815,6 +822,7 @@
|
||||
"cmd.appearance_pick_up": "拾取外观",
|
||||
"cmd.appearance_replace": "替换外观",
|
||||
"cmd.assembly_bom": "物料清单",
|
||||
"cmd.body.print_face": "打印底面",
|
||||
"cmd.body_rename": "重命名实体",
|
||||
"cmd.browser_collapse_all": "全部折叠",
|
||||
"cmd.browser_expand_all": "全部展开",
|
||||
@@ -822,6 +830,7 @@
|
||||
"cmd.browser_move": "移动浏览器项目",
|
||||
"cmd.browser_order": "排列浏览器项目",
|
||||
"cmd.browser_rename_group": "重命名组",
|
||||
"cmd.browser_reparent": "移动到组件",
|
||||
"cmd.browser_ungroup": "取消编组",
|
||||
"cmd.browser_visibility": "显示/隐藏",
|
||||
"cmd.canvas_calibrate": "校准画布",
|
||||
@@ -848,7 +857,9 @@
|
||||
"cmd.component_metadata": "零件属性",
|
||||
"cmd.component_metadata_set": "更改零件属性",
|
||||
"cmd.component_move_bodies": "将实体移至组件",
|
||||
"cmd.component_move_features": "将特征移至组件",
|
||||
"cmd.component_move_sketches": "将草图移至组件",
|
||||
"cmd.component_paste_from_design": "从其他设计粘贴",
|
||||
"cmd.component_paste_new": "粘贴为新对象",
|
||||
"cmd.component_properties": "组件物理属性",
|
||||
"cmd.component_relink": "重新链接源文件",
|
||||
@@ -1076,6 +1087,13 @@
|
||||
"cmd.render_start": "渲染图像",
|
||||
"cmd.render_status": "渲染进度",
|
||||
"cmd.select_clear": "清除选择",
|
||||
"cmd.settings_profile_apply": "应用设置配置文件",
|
||||
"cmd.settings_profile_delete": "删除设置配置文件",
|
||||
"cmd.settings_profile_export": "导出设置配置文件",
|
||||
"cmd.settings_profile_import": "导入设置配置文件",
|
||||
"cmd.settings_profile_list": "设置配置文件",
|
||||
"cmd.settings_profile_rename": "重命名设置配置文件",
|
||||
"cmd.settings_profile_save": "保存设置配置文件",
|
||||
"cmd.sheet_convert": "转换为钣金",
|
||||
"cmd.sheet_export_bend_table": "导出折弯表",
|
||||
"cmd.sheet_export_dxf": "将展开图导出为 DXF",
|
||||
@@ -1089,6 +1107,16 @@
|
||||
"cmd.sheet_refold": "重新折弯",
|
||||
"cmd.sheet_rules": "列出钣金规则",
|
||||
"cmd.sheet_unfold": "展开",
|
||||
"cmd.sketch.construction_line": "构造直线",
|
||||
"cmd.sketch.construction_line.angle": "指定角度构造直线",
|
||||
"cmd.sketch.construction_line.bisector": "角平分线",
|
||||
"cmd.sketch.construction_line.horizontal": "水平构造直线",
|
||||
"cmd.sketch.construction_line.parallel": "平行构造直线",
|
||||
"cmd.sketch.construction_line.perpendicular": "垂直构造直线",
|
||||
"cmd.sketch.construction_line.tangent_at": "曲线上点处的切线",
|
||||
"cmd.sketch.construction_line.tangent_external": "过外部点的切线",
|
||||
"cmd.sketch.construction_line.tangent_two": "公切线",
|
||||
"cmd.sketch.construction_line.vertical": "竖直构造直线",
|
||||
"cmd.sketch_arc3d": "三维圆弧",
|
||||
"cmd.sketch_arc_center_point": "中心点圆弧",
|
||||
"cmd.sketch_arc_tangent": "相切圆弧",
|
||||
@@ -1121,6 +1149,8 @@
|
||||
"cmd.sketch_drawing_bounds": "图纸尺寸",
|
||||
"cmd.sketch_edit": "编辑草图",
|
||||
"cmd.sketch_edit_text": "编辑文字",
|
||||
"cmd.sketch_equation_curve": "方程曲线",
|
||||
"cmd.sketch_equation_curve_edit": "编辑方程曲线",
|
||||
"cmd.sketch_export_dxf": "另存为 DXF",
|
||||
"cmd.sketch_finish_auto_constrain": "使用自动约束完成",
|
||||
"cmd.sketch_fit_curves_to_section": "将曲线拟合到网格截面",
|
||||
@@ -1217,6 +1247,7 @@
|
||||
"cmd.view.render_browser": "渲染浏览器",
|
||||
"cmd.view.render_dock": "移动渲染停靠面板",
|
||||
"cmd.view.render_focus": "渲染专注视图",
|
||||
"cmd.view.status_items": "视口状态项",
|
||||
"cmd.view_ambient_occlusion": "环境光遮蔽",
|
||||
"cmd.view_angle_readout": "视图角度",
|
||||
"cmd.view_apply": "还原命名视图",
|
||||
@@ -1374,6 +1405,18 @@
|
||||
"help.occurrence.move": "仅沿关节允许的自由度移动装配零部件。选中零部件的面后,拖动可用的箭头或圆弧。",
|
||||
"help.parameters.change": "打开驱动设计尺寸的命名数值和表达式表。用于在一处修改尺寸,让所有引用它的特征随之更新。",
|
||||
"help.pointcloud.insert": "将 PLY、XYZ 或 PTS 扫描作为点云插入到模型旁。根据测量数据建模时,可将其用作参考。",
|
||||
"help.sketch.construction_line": "创建经过两点的无限构造直线,用于辅助绘制草图而不分割轮廓。",
|
||||
"help.sketch.construction_line.angle": "创建与草图X轴成指定角度的无限构造直线。选择一点后输入角度或选择方向。",
|
||||
"help.sketch.construction_line.bisector": "选择两条相交的草图直线,再选择所需的角平分线。结果随原直线的编辑而变化。",
|
||||
"help.sketch.construction_line.horizontal": "创建经过指定点的无限水平构造直线。后续编辑时保持水平约束。",
|
||||
"help.sketch.construction_line.parallel": "选择草图直线,然后放置与其平行的无限构造直线。右键单击可更换参照。",
|
||||
"help.sketch.construction_line.perpendicular": "选择草图直线,然后放置与其垂直的无限构造直线。右键单击可更换参照。",
|
||||
"help.sketch.construction_line.tangent_at": "在圆或圆弧上的点处,或开放样条曲线、圆锥曲线的端点处创建切线。先选曲线,再选接点。",
|
||||
"help.sketch.construction_line.tangent_external": "依次选择圆或圆弧、外部点和所需切线。预览仅显示接点位于已绘圆弧上的解。",
|
||||
"help.sketch.construction_line.tangent_two": "选择两个圆或圆弧,再从预览中选择公切线。接点必须位于已绘曲线上。",
|
||||
"help.sketch.construction_line.vertical": "创建经过指定点的无限竖直构造直线。后续编辑时保持竖直约束。",
|
||||
"help.sketch.equation_curve": "在一个范围内按公式绘制曲线:x(t) 和 y(t),或 y = f(x)。公式可以使用参数,曲线随参数变化。适用于正弦波、螺旋线或齿轮的渐开线。",
|
||||
"help.sketch.inspect": "打开当前草图的报告:显示剩余的自由度以及是否已完全约束。在完成草图之前,用它找出仍然可以移动的部分。",
|
||||
"help.solid.align": "移动所选实体,使其上的点、面或平面与别处的点、面或平面对齐。用于把一个零件贴靠到另一个零件上,而无需测量距离。",
|
||||
"help.solid.chamfer": "用指定的距离在所选边上切出一个平直的斜面。用于去除锐边,或使销钉、螺钉更容易插入。",
|
||||
"help.solid.combine": "将多个实体合并、从目标实体中切除,或只保留它们共有的体积,还可以保留工具实体。用于合并零件、用一个形体切割另一个形体,或找出两个实体重叠的位置。",
|
||||
@@ -1576,6 +1619,10 @@
|
||||
"material.selection.mixed": "不同材料",
|
||||
"measure.at": "位置",
|
||||
"measure.item": "项目 {number}",
|
||||
"measure.quick_copied": "已复制测量值",
|
||||
"measure.quick_copy": "点击复制测量值",
|
||||
"measure.quick_edges": "{count} 条边",
|
||||
"measure.quick_faces": "{count} 个面",
|
||||
"messages.ago_h": "{n} 小时前",
|
||||
"messages.ago_min": "{n} 分钟前",
|
||||
"messages.ago_s": "{n} 秒前",
|
||||
@@ -1728,6 +1775,11 @@
|
||||
"not a move": "不是移动",
|
||||
"not a number": "不是数字",
|
||||
"open a sketch first": "请先打开一个草图",
|
||||
"parameters.apply_live": "离开字段时立即应用每项更改",
|
||||
"parameters.apply_live_tip": "关闭时:更改会等到“应用”或“确定”,然后设计只为所有更改重建一次。“取消”或 Esc 会放弃这些更改。",
|
||||
"parameters.held": "{count} 项更改等待应用",
|
||||
"parameters.held_hint": "编辑表达式和单位。更改将等到“应用”或“确定”时生效。",
|
||||
"parameters.held_one": "1 项更改等待应用",
|
||||
"parts.automatic_name": "自动",
|
||||
"parts.dimension.across_flats": "对边宽度",
|
||||
"parts.dimension.bore": "内径",
|
||||
@@ -1743,12 +1795,15 @@
|
||||
"parts.dimension.thickness": "厚度",
|
||||
"parts.dimension.width": "宽度",
|
||||
"parts.family.bearing": "深沟球轴承(外形)",
|
||||
"parts.family.button_head_cap_screw": "圆头内六角螺钉",
|
||||
"parts.family.dowel_pin": "圆柱销",
|
||||
"parts.family.hex_bolt": "六角头螺栓",
|
||||
"parts.family.hex_nut": "六角螺母",
|
||||
"parts.family.set_screw": "内六角平端紧定螺钉",
|
||||
"parts.family.socket_head_cap_screw": "内六角圆柱头螺钉",
|
||||
"parts.family.washer": "平垫圈",
|
||||
"parts.holes": "孔(可选)",
|
||||
"parts.placement_hint": "选择一个或多个孔,在每个孔中各装一个零件;或按确定将其放在原点",
|
||||
"pattern.alignment_2": "对齐 2",
|
||||
"pattern.alignment_hint": "数量包含原始图形。居中时副本分布在两侧;数量为偶数时,反转可切换多一个副本的一侧。",
|
||||
"pattern.direction_1": "方向 1",
|
||||
@@ -1801,6 +1856,8 @@
|
||||
"prefs.bottom_centre": "底部居中",
|
||||
"prefs.bottom_right": "右下角",
|
||||
"prefs.browser": "浏览器",
|
||||
"prefs.browser_eye_left": "显示切换位于折叠箭头旁",
|
||||
"prefs.browser_eye_left_note": "浏览器各行的显示切换像以前一样位于折叠箭头旁,而不是在行右端的一列中。",
|
||||
"prefs.browser_reveal_on_hover": "悬停时显示",
|
||||
"prefs.browser_show_note": "“显示”让浏览器始终留在屏幕上。“悬停时显示”会将其隐藏,直到指针移到它的位置或其左边缘的细标签上;指针在其中或其菜单打开时,它保持打开。",
|
||||
"prefs.browser_shown": "显示",
|
||||
@@ -1851,6 +1908,8 @@
|
||||
"prefs.graphics_card_restart": "重启 SolidCraft 后生效。WGPU_ADAPTER_NAME 优先于此选择。",
|
||||
"prefs.graphics_note": "在速度与平滑度之间取舍。每个选项均以示例展示效果。",
|
||||
"prefs.graphics_presets_note": "预设会同时设置以下选项。",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out": "缩小时隐藏约束符号",
|
||||
"prefs.hide_constraint_glyphs_zoomed_out_note": "草图缩小到一定程度时隐藏约束符号,以免遮挡草图。关闭:任意缩放比例下符号仍保持固定屏幕大小。",
|
||||
"prefs.history": "历史",
|
||||
"prefs.history_origin_bodies": "在顶部显示原点和实体",
|
||||
"prefs.history_origin_bodies_note": "左侧或浏览器下方的历史以活动组件的实体文件夹和原点开头,并带有与浏览器相同的显示切换和菜单。底部的历史保持不变。",
|
||||
@@ -1874,6 +1933,8 @@
|
||||
"prefs.layout_note": "紧凑模式将面板停靠在窗口边缘。浏览器半透明仅适用于浮动模式。助手面板的位置在助手页面中设置。",
|
||||
"prefs.left": "左侧",
|
||||
"prefs.left_click": "左键单击",
|
||||
"prefs.line_drag_draws_one": "按下并拖动绘制一条直线",
|
||||
"prefs.line_drag_draws_one_note": "在直线工具中,按下、拖动再松开,会从按下处到松开处绘制一条直线并在此结束。单击仍会绘制连续的直线。关闭时:拖动与单击一样,在松开处放置一个点。",
|
||||
"prefs.linked_designs": "链接设计",
|
||||
"prefs.live_input": "实时输入",
|
||||
"prefs.live_preview": "实时预览",
|
||||
@@ -1887,6 +1948,9 @@
|
||||
"prefs.max_file_size_step": "STEP 和导入文件",
|
||||
"prefs.max_file_size_web": "网页版可打开最大 512 MB 的 STEP 和导入文件,以及最大 256 MB 的设计:浏览器标签页无法容纳更大的文件。桌面版可提高这些上限。",
|
||||
"prefs.megabytes": "MB",
|
||||
"prefs.menu_grid": "大图标",
|
||||
"prefs.menu_list": "列表",
|
||||
"prefs.menus": "菜单",
|
||||
"prefs.minutes": "分钟",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.mouse": "鼠标与触控板",
|
||||
@@ -1906,18 +1970,44 @@
|
||||
"prefs.origin_plane_names": "原点平面名称",
|
||||
"prefs.origin_plane_names_note": "浏览器、对话框和列表中显示的名称。{top} 即 XY,{front} 即 XZ,{right} 即 YZ(Z 轴朝上)。命令、脚本和已保存的设计仍使用 XY、XZ 和 YZ。",
|
||||
"prefs.overall_speed": "整体速度",
|
||||
"prefs.parameter_list_rows": "参数列表行数",
|
||||
"prefs.parameter_list_rows_tip": "在空的数值框中按下箭头会列出参数(收藏的在前),最多列出此数量。数量越少,大型设计中的列表越轻。",
|
||||
"prefs.persistent_ribbon_pressed": "突出显示已启用的功能区命令",
|
||||
"prefs.persistent_ribbon_pressed_help": "在效果启用时突出显示相应的功能区命令。关闭此选项可保留原来的中性外观和命令帮助。",
|
||||
"prefs.perspective_fov": "视场角",
|
||||
"prefs.placement": "放置",
|
||||
"prefs.prefer_free_sketch_points": "草图点重合时优先选择可移动的点",
|
||||
"prefs.preview_choices": "所选设置预览",
|
||||
"prefs.print_face_highlight": "打印底面高亮",
|
||||
"prefs.print_face_highlight_tip": "视图中实体打印底面的着色和轮廓强度。0 % 不显示高亮。",
|
||||
"prefs.profile_active": "当前配置文件",
|
||||
"prefs.profile_applied": "已应用配置文件。",
|
||||
"prefs.profile_changed": "保存配置文件后设置已更改。“保存”会将其写入配置文件。",
|
||||
"prefs.profile_deleted": "已删除配置文件。",
|
||||
"prefs.profile_export": "导出…",
|
||||
"prefs.profile_exported": "已导出配置文件。",
|
||||
"prefs.profile_imported": "已导入配置文件。在“当前配置文件”中选择它即可切换。",
|
||||
"prefs.profile_name_hint": "配置文件名称,例如 笔记本",
|
||||
"prefs.profile_rename": "重命名",
|
||||
"prefs.profile_renamed": "已重命名配置文件。",
|
||||
"prefs.profile_save": "保存",
|
||||
"prefs.profile_saved": "已将当前设置保存到配置文件。",
|
||||
"prefs.profile_skipped": "已应用配置文件;{n} 项设置保留了当前值(见日志)。",
|
||||
"prefs.profiles": "设置配置文件",
|
||||
"prefs.profiles_note": "将快捷键、工具栏、导航、径向菜单和界面设置一起以名称保存,并一次切换。",
|
||||
"prefs.project_options_dialog": "Project 选项对话框",
|
||||
"prefs.project_options_dialog_note": "开启:投影前选择“几何体”或“实体”以及“投影链接”。关闭:保留原有的直接选择工作流。",
|
||||
"prefs.quality_default": "默认",
|
||||
"prefs.quality_fastest": "最快",
|
||||
"prefs.quality_slowest": "最慢",
|
||||
"prefs.quality_smoother": "更平滑",
|
||||
"prefs.quick_measure": "在视图角落显示快速测量",
|
||||
"prefs.quick_measure_note": "在视图右下角、历史记录上方显示所选对象的尺寸:边的长度(圆形边显示 Ø 和 R)、面的面积、点的位置、两个对象之间的距离和角度、多条边或多个面的总和。点击即可复制。",
|
||||
"prefs.render_previous_geometry_budget": "使用先前的渲染预览几何内存预算",
|
||||
"prefs.render_previous_geometry_budget_help": "恢复先前的固定几何内存上限(64位桌面为512 MiB,其他平台为128 MiB),替代基于设备的预算。",
|
||||
"prefs.reports_saved": "已保存 {n} 份",
|
||||
"prefs.ribbon_reveal": "在功能区中显示搜索结果",
|
||||
"prefs.ribbon_reveal_note": "将指针悬停在“搜索命令”的结果上时,会显示该命令在功能区中的位置:其选项卡、按钮或面板下拉菜单中的行。从搜索启动的命令会在那里闪烁,从下拉菜单运行的命令会标记其面板。",
|
||||
"prefs.right_click": "右键单击",
|
||||
"prefs.saving": "自动保存和恢复",
|
||||
"prefs.scale_note": "也可在窗口中使用 Ctrl + / Ctrl −。100% 时按钮高度为 28 像素。",
|
||||
@@ -1926,18 +2016,29 @@
|
||||
"prefs.search_empty": "没有匹配的设置",
|
||||
"prefs.select": "选择",
|
||||
"prefs.select_one_item": "选择一个项目",
|
||||
"prefs.select_other_hidden": "使用“选择其他”选择隐藏几何体",
|
||||
"prefs.select_other_hidden_help": "开启:包括指针附近的隐藏实体、草图和被遮挡的边。关闭:恢复原来的列表,仅包含指针正下方的可见几何体。",
|
||||
"prefs.selecting": "选择",
|
||||
"prefs.shift": "Shift",
|
||||
"prefs.shift_add_ctrl_toggle": "Shift 仅添加;Ctrl / Cmd 切换选择",
|
||||
"prefs.shift_add_note": "开启:Shift 添加,Ctrl / Cmd 切换选择。关闭(默认):两者均切换选择。",
|
||||
"prefs.shortcuts": "快捷键",
|
||||
"prefs.single_surface_analysis": "仅使用一个曲面分析",
|
||||
"prefs.single_surface_analysis_help": "关闭时,曲面着色分析和连续性分析可以同时保持启用。开启时,仅保留最后启动或修改的分析。",
|
||||
"prefs.sketch_align_points": "绘制时与其他草图点对齐",
|
||||
"prefs.sketch_align_points_note": "绘制时,点可同时与一个草图点水平对齐、与另一个草图点竖直对齐,并显示虚线参考线;单击后保留两个对齐约束。关闭:仅与上一点对齐,每次一个方向。",
|
||||
"prefs.sketch_conflict_colour": "以冲突颜色显示冲突的几何图形",
|
||||
"prefs.sketch_conflict_colour_note": "草图约束冲突时,不仅失败约束的符号或尺寸,该约束所约束的曲线和点也以冲突颜色绘制。关闭:它们保持平常的颜色。",
|
||||
"prefs.sketch_construction_lines": "扩展构造直线工具",
|
||||
"prefs.sketch_exit_view": "草图结束时的视图",
|
||||
"prefs.sketch_exit_view.keep": "保持当前视图",
|
||||
"prefs.sketch_exit_view.previous": "返回之前的视图",
|
||||
"prefs.sketch_exit_view.unless_rotated": "未旋转时返回",
|
||||
"prefs.sketch_exit_view_note": "“完成草图”、取消或连按两次 Esc 后视图的去向。",
|
||||
"prefs.sketch_open_look_at": "打开草图时转向正对草图",
|
||||
"prefs.sketch_open_look_at_note": "关闭:创建或编辑草图时视图保持不变。需要时用“朝向”正对草图。",
|
||||
"prefs.sketch_recent_snap": "自动吸附到最近的圆心和中点",
|
||||
"prefs.sketch_recent_snap_note": "绘图时,将光标吸附到最近两个圆心或直线边中点的辅助线相交处。关闭:辅助线仅作显示,光标不会移动。",
|
||||
"prefs.sketch_selection": "草图与选择",
|
||||
"prefs.sketch_selection_heading": "草图和选择",
|
||||
"prefs.sketch_selection_note": "草图如何捕捉,以及单击如何选择。",
|
||||
@@ -1995,20 +2096,34 @@
|
||||
"prefs.under_cursor": "光标下方",
|
||||
"prefs.units_precision": "单位与精度",
|
||||
"prefs.updates": "更新",
|
||||
"prefs.value_boxes_in_view": "在视图中于手柄旁显示数值",
|
||||
"prefs.value_boxes_in_view_tip": "命令的数值(距离、半径等)显示在模型上方手柄旁的框中。关闭后,在命令窗口中输入数值,选取后键盘输入会进入该窗口,模型不会被遮挡。",
|
||||
"prefs.view": "视图行为",
|
||||
"prefs.view_confirm_corner": "在视图角落显示确定和取消",
|
||||
"prefs.view_confirm_corner_note": "打开对话框或草图时,视图右上角的勾号和叉号与对话框的确定和取消作用相同,或完成和取消草图。视图导航器会下移到它们下方。",
|
||||
"prefs.viewport": "视口",
|
||||
"prefs.viewport_analysis_status": "显示视口分析状态",
|
||||
"prefs.viewport_analysis_status_help": "在视口上方显示启用的分析,从各项目打开图例,并按 Esc 关闭最近启用的分析。关闭此选项可恢复角落图例和原来的 Esc 行为。",
|
||||
"prefs.viewport_background": "背景",
|
||||
"prefs.viewport_background_colour": "颜色",
|
||||
"prefs.viewport_background_theme": "主题渐变",
|
||||
"prefs.viewport_section_status": "显示视口剖面状态",
|
||||
"prefs.viewport_section_status_help": "在视口中显示剖面设置。按 Escape 或单击活动的功能区按钮可关闭剖面。禁用以保留原有剖面控件。",
|
||||
"prefs.viewport_status_summary": "汇总视口状态项",
|
||||
"prefs.viewport_status_summary_help": "将三个或更多视口状态项折叠为一个汇总徽章。禁用后,所有项目仍显示在完整的一行中。",
|
||||
"prefs.wheel": "滚轮",
|
||||
"prefs.wheel_trackpad": "滚轮与触控板",
|
||||
"prefs.workspace": "工作区",
|
||||
"prefs.zoom_stop_at_model": "缩放到模型表面时停止",
|
||||
"prefs.zoom_stop_at_model_tip": "3D 鼠标和设备应用向视图中央的表面缩放;拖动缩放固定拖动开始时的点。关闭后可穿过模型。滚轮和捏合手势单独使用向光标缩放设置",
|
||||
"prefs.zoom_toward_cursor": "朝光标缩放",
|
||||
"properties.title": "属性:{name}",
|
||||
"recovery.days_ago": "{count} 天前",
|
||||
"recovery.detail": "{file} · {features} 个特征 · 自动保存于 {when}",
|
||||
"recovery.discard_all": "全部放弃",
|
||||
"recovery.discard_all_detail": "此操作无法撤消。",
|
||||
"recovery.discard_all_title": "放弃 {count} 个自动保存?",
|
||||
"recovery.discard_all_title_one": "放弃 1 个自动保存?",
|
||||
"recovery.hours_ago": "{count} 小时前",
|
||||
"recovery.just_now": "刚刚",
|
||||
"recovery.min_ago": "{count} 分钟前",
|
||||
@@ -2874,7 +2989,9 @@
|
||||
"render.output_ready": "已就绪,可渲染",
|
||||
"render.output_run_check": "运行检查",
|
||||
"render.output_size_limit": "{method}:每边最多 {dimension} px,总计 {pixels} 像素。可用的最大尺寸:{width} × {height}。",
|
||||
"render.output_size_method_profile": "要渲染 {width} × {height},请选择 {method} 和“{profile}”CPU 资源配置,或选择更小的尺寸。",
|
||||
"render.output_size_ok": "尺寸正常 · {width} × {height} px",
|
||||
"render.output_size_profile": "要渲染 {width} × {height},请选择“{profile}”CPU 资源配置,或选择更小的尺寸。",
|
||||
"render.output_swap_orientation": "交换宽度和高度",
|
||||
"render.output_tools_inspector": "请在输出检查器中编辑尺寸和格式。",
|
||||
"render.output_view_image": "查看图像",
|
||||
@@ -3087,6 +3204,7 @@
|
||||
"render.size_custom": "自定义…",
|
||||
"render.size_full_hd": "全高清",
|
||||
"render.size_hd": "HD",
|
||||
"render.size_needs_profile": "{size} · 需要“{profile}”",
|
||||
"render.size_presets": "尺寸预设",
|
||||
"render.size_presets_pending": "随输出编辑器推出",
|
||||
"render.size_preview": "预览",
|
||||
@@ -3355,6 +3473,7 @@
|
||||
"settings.double_click_components": "双击组件以激活它,或在原位编辑链接组件",
|
||||
"settings.frame_rate_details_note": "添加最近各帧耗时的图表(叠加绘制的三角形数)、帧耗时直方图以及 GPU 绘制的内容。点击视图中的帧率可显示或隐藏。",
|
||||
"settings.frame_rate_note": "在视图右下角显示每秒帧数。",
|
||||
"settings.insert_lists_open_designs": "插入设计时先列出其他标签页中打开的设计",
|
||||
"settings.measure_axis_distances": "显示 X/Y/Z 距离",
|
||||
"settings.measure_axis_distances_help": "测量对话框打开时,在总距离之外显示沿世界坐标轴方向的尺寸线和距离。",
|
||||
"settings.msaa_applies_on_restart": "抗锯齿将在下次启动 SolidCraft 时生效",
|
||||
@@ -3373,12 +3492,34 @@
|
||||
"sheet.flange_type_contour": "轮廓",
|
||||
"sheet.flange_type_edge": "边线",
|
||||
"sheet.no_body": "没有钣金实体:请使用法兰 > Base 创建,或使用转换为钣金将板材转换为钣金(选择其较大的平面)。",
|
||||
"sheet.personal_rules.confirm_delete": "确认删除",
|
||||
"sheet.personal_rules.delete": "删除",
|
||||
"sheet.personal_rules.delete_prompt": "删除此个人规则?设计中已有的规则不会改变。",
|
||||
"sheet.personal_rules.full": "个人库中已有64条规则。",
|
||||
"sheet.personal_rules.invalid_name": "请输入不含换行符或控制字符的简短名称。",
|
||||
"sheet.personal_rules.invalid_values": "请填写完整的规则值:每个值都必须能在此设计中计算,厚度为正,K 因子在 0 到 1 之间。",
|
||||
"sheet.personal_rules.missing": "所选个人规则已不可用。",
|
||||
"sheet.personal_rules.name": "规则名称",
|
||||
"sheet.personal_rules.name_exists": "同名个人规则已存在,请使用其他名称。",
|
||||
"sheet.personal_rules.name_hint": "唯一名称",
|
||||
"sheet.personal_rules.overwrite": "保存对所选个人规则的修改",
|
||||
"sheet.personal_rules.rename": "重命名",
|
||||
"sheet.personal_rules.rule": "个人规则",
|
||||
"sheet.personal_rules.save": "另存为新规则",
|
||||
"sheet.personal_rules.scope": "保存在您的配置中,适用于所有设计。",
|
||||
"sheet.personal_rules.select": "选择规则",
|
||||
"sheet.personal_rules.title": "个人规则",
|
||||
"sheet.personal_rules.unsupported": "此规则包含当前版本无法使用的值。",
|
||||
"shortcut.json_error": "参数必须采用 JSON 格式:{error}",
|
||||
"shortcut.no_command": "没有命令 `{id}`;JSON 前的文本必须是命令 ID",
|
||||
"shortcut.pin": "固定到 S 框顶部",
|
||||
"shortcut.unpin": "取消固定",
|
||||
"sketch is missing": "草图不存在",
|
||||
"sketch.degrees_of_freedom": "{count} 个自由度",
|
||||
"sketch.dimension_added_driven": "草图已确定该尺寸,因此已将其添加为被驱动(参考)尺寸",
|
||||
"sketch.dimension_applied": "已应用尺寸",
|
||||
"sketch.dimension_applied_defined": "已应用尺寸;已定义参数 `{name}`",
|
||||
"sketch.dimension_applied_renamed": "已应用尺寸;参数已命名为 `{name}`",
|
||||
"sketch.dof_left": "剩余 {count} 个自由度",
|
||||
"sketch.dof_left_one": "剩余 {count} 个自由度",
|
||||
"sketch.draw_curves": "绘制为 {linetype}",
|
||||
@@ -3405,6 +3546,7 @@
|
||||
"sketch_text.align_right": "右对齐",
|
||||
"sketch_text.bold": "粗体",
|
||||
"sketch_text.builtin_font": "{family}(内置)",
|
||||
"sketch_text.formula": "以 = 开头即可用参数组成文字:='W' + number(Width)",
|
||||
"sketch_text.italic": "斜体",
|
||||
"sketch_text.loading_fonts": "正在查找已安装字体…",
|
||||
"sketch_text.on_path": "文字沿路径排列:由曲线放置",
|
||||
@@ -3448,8 +3590,10 @@
|
||||
"timeline.delete_folders_tip": "在历史记录中保留其中的特征和嵌套文件夹",
|
||||
"timeline.delete_folders_with_features_tip": "删除文件夹及其中的所有特征和嵌套文件夹",
|
||||
"timeline.delete_many": "删除所选的 {count} 个特征",
|
||||
"timeline.edited_rolled_back": "{name} 已更改,但它位于历史标记之后,因此未构建:将标记移到其后即可查看结果",
|
||||
"timeline.feature_error": "错误:{message}",
|
||||
"timeline.feature_hint": "双击编辑 · 拖动以重新排序 · 右键查看更多操作",
|
||||
"timeline.feature_rolled_back": "已回退:位于历史标记之后,因此未构建",
|
||||
"timeline.feature_warning": "警告:{message}",
|
||||
"timeline.group": "新建特征文件夹",
|
||||
"timeline.move_many": "移动时间线项目",
|
||||
@@ -3531,6 +3675,10 @@
|
||||
"ui.3d_mouse_offer": "校准 3D 鼠标可以修正互换或反向的轴,并调整它的速度和手感。",
|
||||
"ui.3d_mouse_offer_never": "不再显示",
|
||||
"ui.3d_mouse_offer_swap": "切换到 Hidraw(直接驱动)",
|
||||
"ui.3d_mouse_orbit": "环绕",
|
||||
"ui.3d_mouse_orbit_classic": "经典",
|
||||
"ui.3d_mouse_orbit_tip": "追踪:3D 鼠标围绕开始旋转时视图中间的模型部分旋转视图,并用一个淡色小球标出该点。经典:围绕视图中心旋转",
|
||||
"ui.3d_mouse_orbit_traced": "追踪",
|
||||
"ui.3d_mouse_reading": "读数",
|
||||
"ui.3d_mouse_reset_axes": "重置轴分配",
|
||||
"ui.3d_mouse_reset_view": "重置视图",
|
||||
@@ -3539,6 +3687,8 @@
|
||||
"ui.3d_mouse_section": "3D 鼠标",
|
||||
"ui.3d_mouse_show_in_view": "在 3D 视图中显示 3D 鼠标",
|
||||
"ui.3d_mouse_show_in_view_tip": "在左下角显示你的 3D 鼠标图示,随你的操作而动。",
|
||||
"ui.3d_mouse_sketch_orbit": "用 3D 鼠标旋转草图",
|
||||
"ui.3d_mouse_sketch_orbit_tip": "草图打开并正对视图时,3D 鼠标也能旋转视图,与鼠标一样。关闭:在你倾斜视图之前,只平移和缩放草图。",
|
||||
"ui.3d_mouse_skip": "我的设备做不到",
|
||||
"ui.3d_mouse_skip_tip": "在两个方向上都跳过这个动作,校准时不包含它。",
|
||||
"ui.3d_mouse_speed": "3D 鼠标速度",
|
||||
@@ -3567,6 +3717,8 @@
|
||||
"ui.3d_mouse_step_twist_counterclockwise": "逆时针扭转摇杆帽,保持住,然后松开。",
|
||||
"ui.3d_mouse_switch_cap": "按回中类型校准",
|
||||
"ui.3d_mouse_switch_trackball": "按轨迹球校准",
|
||||
"ui.3d_mouse_use_direct": "使用直接驱动",
|
||||
"ui.3d_mouse_use_direct_tip": "直接读取 3D 鼠标(hidraw),不经过 spacenavd。",
|
||||
"ui.3d_mouse_view_axis": "视图轴",
|
||||
"ui.3d_mouse_view_off": "关闭",
|
||||
"ui.3d_mouse_view_off_tip": "3D 鼠标驱动程序的配置文件关闭了此轴,因此它的动作不会移动视图。在此选择另一个轴的动作会将两者互换,该动作将不再移动视图。",
|
||||
@@ -3700,6 +3852,8 @@
|
||||
"ui.agent_chat_remove": "从队列中移除",
|
||||
"ui.agent_chat_remove_file": "从这条消息中移除",
|
||||
"ui.agent_chat_remove_imported": "从这条消息中移除;零件仍保留在设计中(撤销可将其删除)",
|
||||
"ui.agent_chat_reply_cut_off": "回复在完成前达到了长度上限,可能不完整。请让智能体继续,或请它回答得更简短。",
|
||||
"ui.agent_chat_reply_declined": "模型拒绝回答这条消息。",
|
||||
"ui.agent_chat_retry": "重试",
|
||||
"ui.agent_chat_right": "右侧",
|
||||
"ui.agent_chat_save": "保存",
|
||||
@@ -3883,6 +4037,7 @@
|
||||
"ui.circle": "圆",
|
||||
"ui.circular_pattern": "圆形阵列",
|
||||
"ui.clear": "清除",
|
||||
"ui.clear_print_face": "清除打印底面",
|
||||
"ui.clear_recent": "清除最近",
|
||||
"ui.clear_the_selection": "清除选择",
|
||||
"ui.click_selects_whole_bodies": "单击选择整个实体",
|
||||
@@ -3917,6 +4072,15 @@
|
||||
"ui.constant": "恒定",
|
||||
"ui.constraints_conflict": "约束冲突",
|
||||
"ui.construction": "构造",
|
||||
"ui.construction.angle_hint": "构造直线:单击一点,然后输入角度或选择方向",
|
||||
"ui.construction.bisector_hint": "角平分线:选择两条相交直线,再选择所需解",
|
||||
"ui.construction.common_hint": "公切线:选择两个圆/圆弧,再选择所需解",
|
||||
"ui.construction.contact_hint": "切线:先选圆/圆弧或开放样条曲线/圆锥曲线,再选接点(自由曲线仅支持端点)",
|
||||
"ui.construction.external_hint": "切线:依次选择圆或圆弧、外部点和所需解",
|
||||
"ui.construction.free_hint": "构造直线:单击两点;右键单击重新开始",
|
||||
"ui.construction.point_hint": "构造直线:单击要经过的点",
|
||||
"ui.construction.reference_hint": "构造直线:先选直线,再选一点;右键单击更换参照",
|
||||
"ui.construction.ribbon_label": "辅助线",
|
||||
"ui.context_menu": "上下文菜单",
|
||||
"ui.continuity_g0": "G0 折痕",
|
||||
"ui.continuity_g1": "G1 相切",
|
||||
@@ -4008,6 +4172,14 @@
|
||||
"ui.end_scale": "末端缩放",
|
||||
"ui.entities": "实体",
|
||||
"ui.equal": "相等",
|
||||
"ui.equation_end": "结束",
|
||||
"ui.equation_explicit": "显式",
|
||||
"ui.equation_form": "形式",
|
||||
"ui.equation_note": "变量是不带单位的数:sin(t) 按弧度计算。不带单位的结果采用设计的单位。",
|
||||
"ui.equation_parametric": "参数式",
|
||||
"ui.equation_x_of_t": "x(t)",
|
||||
"ui.equation_y_of_t": "y(t)",
|
||||
"ui.equation_y_of_x": "y(x)",
|
||||
"ui.equivalent_radius": "等效半径",
|
||||
"ui.expand": "展开",
|
||||
"ui.exportDxf": "导出 DXF…",
|
||||
@@ -4073,6 +4245,7 @@
|
||||
"ui.heading_design": "设计",
|
||||
"ui.heading_draft": "拔模",
|
||||
"ui.heading_edit": "编辑",
|
||||
"ui.heading_equation_curve": "方程曲线",
|
||||
"ui.heading_extrude": "拉伸",
|
||||
"ui.heading_fillet": "圆角",
|
||||
"ui.heading_finish_editing": "完成编辑",
|
||||
@@ -4164,6 +4337,10 @@
|
||||
"ui.import_ellipsis": "导入…",
|
||||
"ui.infinite": "无限",
|
||||
"ui.insert": "插入",
|
||||
"ui.insert_design.browse": "浏览…",
|
||||
"ui.insert_design.open_designs": "已打开的设计",
|
||||
"ui.insert_design.saved_file": "{name} 有未保存的更改,因此插入的是其已保存的文件。请先保存,再使用“更新链接”导入这些更改。",
|
||||
"ui.insert_design.unsaved": "未保存的更改",
|
||||
"ui.inspect": "检查",
|
||||
"ui.intersect": "相交",
|
||||
"ui.isolate": "隔离",
|
||||
@@ -4293,12 +4470,17 @@
|
||||
"ui.plugins_skipped": "有 {count} 个文件夹无法读取。",
|
||||
"ui.plugins_version": "{version}",
|
||||
"ui.point": "点",
|
||||
"ui.point_cloud_add_filter": "添加筛选…",
|
||||
"ui.point_cloud_auto_range": "自动范围",
|
||||
"ui.point_cloud_color_by": "着色方式",
|
||||
"ui.point_cloud_file_colors": "文件颜色",
|
||||
"ui.point_cloud_filter_by": "筛选依据",
|
||||
"ui.point_cloud_height_high": "最高高度",
|
||||
"ui.point_cloud_height_low": "最低高度",
|
||||
"ui.point_cloud_legend_filter": "在上方图例中显示或隐藏",
|
||||
"ui.point_cloud_no_file_colors": "文件中没有颜色",
|
||||
"ui.point_cloud_pause": "暂停",
|
||||
"ui.point_cloud_play": "播放",
|
||||
"ui.point_cloud_single_color": "单色",
|
||||
"ui.point_cloud_size": "点大小",
|
||||
"ui.point_cloud_units": "文件单位",
|
||||
@@ -4307,6 +4489,11 @@
|
||||
"ui.polygon": "多边形",
|
||||
"ui.preferences": "首选项",
|
||||
"ui.press_a_key": "按一个键…",
|
||||
"ui.print_face_cleared": "{body}:已清除打印底面",
|
||||
"ui.print_face_input": "打印底面",
|
||||
"ui.print_face_one_body": "打印底面属于单个实体:请单独发送该实体以更改它",
|
||||
"ui.print_face_pick": "选择实体的一个平面,将其设为打印底面",
|
||||
"ui.print_face_set": "{body}:已设置打印底面;发送到切片软件时实体将放在此面上",
|
||||
"ui.profile": "轮廓",
|
||||
"ui.profile_plane": "轮廓平面",
|
||||
"ui.profiles": "轮廓",
|
||||
@@ -4370,6 +4557,7 @@
|
||||
"ui.revolve": "旋转",
|
||||
"ui.ribbon_exit": "退出",
|
||||
"ui.ribbon_labels": "显示功能区图标下的文字",
|
||||
"ui.ribbon_menus_skip_pinned": "下拉菜单中不再列出已固定的命令",
|
||||
"ui.ribbon_pin_footer": "固定的命令显示在功能区中。将指针悬停在行上可固定或取消固定。",
|
||||
"ui.ribbon_workspace": "工作区",
|
||||
"ui.right": "右视",
|
||||
@@ -4387,6 +4575,8 @@
|
||||
"ui.select": "选择",
|
||||
"ui.selectOther": "选择其他…",
|
||||
"ui.selectTangentChain": "选择相切链",
|
||||
"ui.select_all": "全选",
|
||||
"ui.select_components_by_face": "选择组件(单击面即选择其所属组件)",
|
||||
"ui.selection": "选择",
|
||||
"ui.selection_modifiers": "选择修饰键",
|
||||
"ui.selection_shift_add_only": "Shift+点击仅添加、不取消选择",
|
||||
@@ -4428,6 +4618,11 @@
|
||||
"ui.sketch_intersect_selection_filter": "选择过滤器",
|
||||
"ui.sketch_modifiers": "草图修饰键",
|
||||
"ui.sketch_project_geometry": "几何体",
|
||||
"ui.sketch_report.all_constrained": "全部已完全约束。",
|
||||
"ui.sketch_report.dof": "自由度",
|
||||
"ui.sketch_report.loose": "未完全约束",
|
||||
"ui.sketch_report.status": "状态",
|
||||
"ui.sketch_report.title": "草图报告",
|
||||
"ui.sketch_scale": "草图比例",
|
||||
"ui.sketches": "草图",
|
||||
"ui.slice": "切片",
|
||||
@@ -4532,10 +4727,19 @@
|
||||
"ui.view_centre": "视图中心",
|
||||
"ui.viewport_status_clear": "关闭{name}",
|
||||
"ui.viewport_status_clear_hint": "关闭{name} · Esc",
|
||||
"ui.viewport_status_edges": "{count} 条边",
|
||||
"ui.viewport_status_from": "从 {direction}",
|
||||
"ui.viewport_status_key": "显示{name}的图例",
|
||||
"ui.viewport_status_minimum_radius": "最小半径",
|
||||
"ui.viewport_status_pairs": "{count} 对",
|
||||
"ui.viewport_status_section_hatch": "{setting} · 填充线",
|
||||
"ui.viewport_status_section_plane": "当前平面",
|
||||
"ui.viewport_status_section_tilted": "倾斜 · {offset}",
|
||||
"ui.viewport_status_stripes": "{count} 条条纹",
|
||||
"ui.viewport_status_summary_clear": "全部关闭",
|
||||
"ui.viewport_status_summary_heading": "此视图中",
|
||||
"ui.viewport_status_summary_label": "{name} 和其他 {count} 项",
|
||||
"ui.viewport_status_summary_more": "+{count}",
|
||||
"ui.viewport_theme_follow": "跟随主题",
|
||||
"ui.visual_shaded_hidden_edges": "带隐藏边的着色",
|
||||
"ui.visual_shaded_with_edges": "带边着色",
|
||||
@@ -4572,7 +4776,9 @@
|
||||
"update.button": "更新",
|
||||
"update.button_version": "更新到 {version}",
|
||||
"update.check_automatically": "自动检查更新",
|
||||
"update.check_for_updates": "检查更新",
|
||||
"update.check_now": "立即检查",
|
||||
"update.check_unavailable": "此安装版本无法检查更新。",
|
||||
"update.checking": "正在检查…",
|
||||
"update.copy": "复制",
|
||||
"update.dmg_opened": "磁盘映像已校验并打开:将 SolidCraft 拖到“应用程序”替换旧版本,然后重启 SolidCraft。",
|
||||
|
||||
@@ -243,6 +243,44 @@ fn pushed(z: f32) -> f32 {
|
||||
return clamp(z - select(-push, push, reversed()), 0.0, 1.0);
|
||||
}
|
||||
|
||||
/// A far wall seen through the cut where another body's face lying on it was drawn in front of
|
||||
/// it (a shaft in its bore, #9407): its cap colour again, at its depth pulled toward the eye by
|
||||
/// `touch_depth`, so it wins over that face, which is faceted another way.
|
||||
@fragment
|
||||
fn fs_solid_touch(i: TOut, @builtin(front_facing) front: bool) -> CutOut {
|
||||
var o: CutOut;
|
||||
// Derivatives (in `touch_depth`) first, before `solid` may discard.
|
||||
o.depth = touch_depth(i.wp, i.pos.z);
|
||||
o.c = solid(i, front);
|
||||
return o;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_solid_touch_flat(i: FOut, @builtin(front_facing) front: bool) -> CutOut {
|
||||
let t = flat_fragment(i, front);
|
||||
var o: CutOut;
|
||||
o.depth = touch_depth(t.wp, t.pos.z);
|
||||
o.c = solid(t, front);
|
||||
return o;
|
||||
}
|
||||
|
||||
/// The depth of `wp` (depth `z`) pulled toward the eye by what may part two faceted copies of
|
||||
/// one surface: 3 pixels' width along the view ray (display refinement keeps a facet's sag about
|
||||
/// a pixel) and 2 pixels of the face's own depth slope (more where it turns from the eye).
|
||||
fn touch_depth(wp: vec3<f32>, z: f32) -> f32 {
|
||||
let px = min(length(dpdx(wp)), length(dpdy(wp)));
|
||||
let slope = max(abs(dpdx(z)), abs(dpdy(z)));
|
||||
var dir = -u.back.xyz;
|
||||
if (u.eye.w > 0.5) { dir = wp - u.eye.xyz; }
|
||||
let len = length(dir);
|
||||
if (len < 1e-12) { return z; }
|
||||
let c = u.vp * vec4<f32>(wp - dir * (3.0 * px / len), 1.0);
|
||||
if (c.w <= 0.0) { return z; }
|
||||
let pulled = c.z / c.w;
|
||||
if (reversed()) { return clamp(max(pulled, z) + 2.0 * slope, 0.0, 1.0); }
|
||||
return clamp(min(pulled, z) - 2.0 * slope, 0.0, 1.0);
|
||||
}
|
||||
|
||||
/// Depth of the section plane on the view ray through `wp` (a far wall seen through the cut),
|
||||
/// never behind the wall itself (`z`).
|
||||
fn cap_depth(wp: vec3<f32>, z: f32) -> f32 {
|
||||
@@ -697,38 +735,96 @@ fn fs_line_all(i: LOut) -> @location(0) vec4<f32> {
|
||||
return out_color(i.c);
|
||||
}
|
||||
|
||||
// Point clouds: each point is a round dot a few pixels across, facing the screen, depth-tested
|
||||
// and written like the model's faces, so the model hides the points behind it and they hide it.
|
||||
// The colour's alpha carries the dot's size (eighths of a pixel).
|
||||
// Point clouds (`view/clouds.rs`): each point is a round dot a few pixels across, facing the
|
||||
// screen, depth-tested and written like the model's faces, so the model hides the points behind
|
||||
// it and they hide it. The cloud's style colours them by their own colour, a ramp or a palette,
|
||||
// and shows only those whose filtered values lie in its ranges or sets.
|
||||
|
||||
struct POut {
|
||||
struct Cloud {
|
||||
style: vec4<f32>, // x: colour (0 own, 1 ramp, 2 palette), y: dot size (px), z, w: ramp range
|
||||
filters: array<vec4<f32>, 4>, // x: kind (0 off, 1 range y…z, 2 whole values y + i for the bits i of w)
|
||||
};
|
||||
@group(1) @binding(3) var<uniform> cloud: Cloud;
|
||||
|
||||
struct CIn {
|
||||
@location(0) p: vec3<f32>,
|
||||
@location(1) v: f32,
|
||||
@location(2) f: vec4<f32>,
|
||||
@location(3) rgb: vec4<f32>,
|
||||
};
|
||||
|
||||
struct COut {
|
||||
@builtin(position) pos: vec4<f32>,
|
||||
@location(0) c: vec4<f32>,
|
||||
@location(1) wp: vec3<f32>,
|
||||
@location(2) at: vec2<f32>,
|
||||
@location(0) wp: vec3<f32>,
|
||||
@location(1) v: f32,
|
||||
@location(2) f: vec4<f32>,
|
||||
@location(3) rgb: vec3<f32>,
|
||||
@location(4) at: vec2<f32>, // the place on its disc
|
||||
@location(5) @interpolate(flat) has: u32,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_point(@builtin(vertex_index) vi: u32, @location(0) p: vec3<f32>, @location(1) c: vec4<f32>) -> POut {
|
||||
fn vs_cloud_dot(@builtin(vertex_index) vi: u32, i: CIn) -> COut {
|
||||
var xs = array<f32, 6>(-1.0, 1.0, 1.0, -1.0, 1.0, -1.0);
|
||||
var ys = array<f32, 6>(-1.0, -1.0, 1.0, -1.0, 1.0, 1.0);
|
||||
let at = vec2<f32>(xs[vi], ys[vi]);
|
||||
let size = max(c.a * 255.0 / 8.0, 1.0);
|
||||
let centre = u.vp * vec4<f32>(p, 1.0);
|
||||
let half = u.screen.xy * 0.5;
|
||||
var o: POut;
|
||||
o.pos = vec4<f32>(centre.xy + at * size * 0.5 / half * centre.w, centre.z, centre.w);
|
||||
let size = max(cloud.style.y, 1.0);
|
||||
let centre = u.vp * vec4<f32>(i.p, 1.0);
|
||||
var o: COut;
|
||||
o.pos = vec4<f32>(centre.xy + at * size / u.screen.xy * centre.w, centre.z, centre.w);
|
||||
// Behind the eye: nothing.
|
||||
if (near_z(centre) < 0.0) { o.pos = vec4<f32>(0.0, 0.0, 0.0, -1.0); }
|
||||
o.c = vec4<f32>(c.rgb, 1.0);
|
||||
o.wp = p;
|
||||
o.wp = i.p;
|
||||
o.v = i.v;
|
||||
o.f = i.f;
|
||||
o.rgb = i.rgb.rgb;
|
||||
o.has = u32(round(i.rgb.a * 255.0));
|
||||
// Dots under two pixels are squares: a disc that small loses its centre pixel.
|
||||
o.at = at * select(1.0, 0.0, size < 2.0);
|
||||
return o;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_point(i: POut) -> @location(0) vec4<f32> {
|
||||
if (clipped(i.wp) || dot(i.at, i.at) > 1.0) { discard; }
|
||||
return out_color(i.c);
|
||||
/// Whether filter `f` keeps the value `v`.
|
||||
fn cloud_keeps(f: vec4<f32>, v: f32) -> bool {
|
||||
if (f.x < 0.5) { return true; }
|
||||
if (f.x < 1.5) { return v >= f.y && v <= f.z; }
|
||||
let k = i32(round(v)) - i32(round(f.y));
|
||||
return k >= 0 && k < 32 && ((bitcast<u32>(f.w) >> u32(k)) & 1u) != 0u;
|
||||
}
|
||||
|
||||
fn cloud_ramp(t: f32) -> vec3<f32> {
|
||||
var stops = array<vec3<f32>, 5>(
|
||||
vec3<f32>(40.0, 70.0, 200.0), vec3<f32>(30.0, 170.0, 230.0), vec3<f32>(60.0, 200.0, 90.0),
|
||||
vec3<f32>(240.0, 220.0, 60.0), vec3<f32>(230.0, 70.0, 50.0));
|
||||
let k = clamp(t, 0.0, 1.0) * 4.0;
|
||||
let j = min(u32(k), 3u);
|
||||
return mix(stops[j], stops[j + 1u], k - f32(j)) / 255.0;
|
||||
}
|
||||
|
||||
fn cloud_palette(v: f32) -> vec3<f32> {
|
||||
var colours = array<vec3<f32>, 10>(
|
||||
vec3<f32>(240.0, 140.0, 40.0), vec3<f32>(245.0, 205.0, 65.0), vec3<f32>(230.0, 65.0, 65.0),
|
||||
vec3<f32>(165.0, 75.0, 190.0), vec3<f32>(65.0, 190.0, 115.0), vec3<f32>(75.0, 150.0, 220.0),
|
||||
vec3<f32>(240.0, 120.0, 180.0), vec3<f32>(140.0, 105.0, 75.0), vec3<f32>(120.0, 215.0, 215.0),
|
||||
vec3<f32>(190.0, 190.0, 80.0));
|
||||
if (v < -0.5) { return vec3<f32>(150.0, 160.0, 176.0) / 255.0; }
|
||||
return colours[u32(round(v)) % 10u] / 255.0;
|
||||
}
|
||||
|
||||
|
||||
@fragment
|
||||
fn fs_cloud(o: COut) -> @location(0) vec4<f32> {
|
||||
var out = clipped(o.wp) || dot(o.at, o.at) > 1.0;
|
||||
for (var k = 0u; k < 4u; k++) {
|
||||
out = out || (((o.has >> k) & 1u) != 0u && !cloud_keeps(cloud.filters[k], o.f[k]));
|
||||
}
|
||||
if (out) { discard; }
|
||||
var c = o.rgb;
|
||||
let mode = cloud.style.x;
|
||||
if ((o.has & 16u) != 0u && mode > 1.5) {
|
||||
c = cloud_palette(o.v);
|
||||
} else if ((o.has & 16u) != 0u && mode > 0.5) {
|
||||
c = cloud_ramp((o.v - cloud.style.z) / max(cloud.style.w - cloud.style.z, 1e-12));
|
||||
}
|
||||
return out_color(vec4<f32>(c, 1.0));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
//! The browser's groups as a tree: how deep a group sits, who holds whom, and pruning what a
|
||||
//! saved design says about the browser down to what still exists.
|
||||
use crate::document::{BROWSER_FOLDERS, BrowserEntry, BrowserGroup, Document, MAX_GROUP_NESTING};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
impl Document {
|
||||
pub fn browser_group(&self, id: u64) -> Option<&BrowserGroup> {
|
||||
self.browser_groups.iter().find(|g| g.id == id)
|
||||
}
|
||||
|
||||
/// The level of a group: 1 for a top-level group, 2 for a child of one, and so on. A chain
|
||||
/// that loops or runs past the limit counts as one level too deep.
|
||||
pub fn group_level(&self, id: u64) -> usize {
|
||||
let mut level = 0;
|
||||
let mut at = Some(id);
|
||||
while let Some(g) = at {
|
||||
level += 1;
|
||||
if level > MAX_GROUP_NESTING {
|
||||
return level;
|
||||
}
|
||||
at = self.browser_group(g).and_then(|g| g.parent);
|
||||
}
|
||||
level
|
||||
}
|
||||
|
||||
/// Whether `ancestor` is `id` or holds it, at any depth.
|
||||
pub fn group_within(&self, id: u64, ancestor: u64) -> bool {
|
||||
let mut at = Some(id);
|
||||
for _ in 0..=MAX_GROUP_NESTING {
|
||||
match at {
|
||||
Some(g) if g == ancestor => return true,
|
||||
Some(g) => at = self.browser_group(g).and_then(|g| g.parent),
|
||||
None => return false,
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// How many levels the group and the groups under it take: 1 for a group with no child group.
|
||||
pub fn group_height(&self, id: u64) -> usize {
|
||||
fn height(d: &Document, id: u64, left: usize) -> usize {
|
||||
if left == 0 {
|
||||
return 1;
|
||||
}
|
||||
1 + d.browser_groups.iter().filter(|g| g.parent == Some(id)).map(|g| height(d, g.id, left - 1)).max().unwrap_or(0)
|
||||
}
|
||||
height(self, id, MAX_GROUP_NESTING + 1)
|
||||
}
|
||||
|
||||
/// The entries of a holder's list in display order: a group's contents, or the folder's top
|
||||
/// level when `holder` is `None`. Groups the list names come where it names them. The child
|
||||
/// groups it does not name (in creation order) go just after the last group it names, or
|
||||
/// first when it names none, so they sit above the items as they always have. Entries for
|
||||
/// groups that are not the holder's children are dropped.
|
||||
pub fn ordered_entries(&self, component: u64, folder: &str, holder: Option<u64>) -> Vec<BrowserEntry> {
|
||||
let listed: &[BrowserEntry] = match holder {
|
||||
Some(g) => self.browser_group(g).map_or(&[], |g| &g.items),
|
||||
None => self.browser_order.get(&format!("{component}/{folder}")).map_or(&[], Vec::as_slice),
|
||||
};
|
||||
let mine: Vec<u64> =
|
||||
self.browser_groups.iter().filter(|g| g.component == component && g.folder == folder && g.parent == holder).map(|g| g.id).collect();
|
||||
let mut out: Vec<BrowserEntry> = Vec::with_capacity(listed.len() + mine.len());
|
||||
for e in listed {
|
||||
match e {
|
||||
BrowserEntry::Group(id) if !mine.contains(id) || out.contains(e) => {}
|
||||
_ => out.push(e.clone()),
|
||||
}
|
||||
}
|
||||
let at = out.iter().rposition(|e| matches!(e, BrowserEntry::Group(_))).map_or(0, |i| i + 1);
|
||||
let unlisted: Vec<BrowserEntry> = mine.iter().map(|id| BrowserEntry::Group(*id)).filter(|e| !out.contains(e)).collect();
|
||||
out.splice(at..at, unlisted);
|
||||
out
|
||||
}
|
||||
|
||||
/// The items in a group and in the groups inside it.
|
||||
pub fn group_item_keys(&self, id: u64) -> Vec<String> {
|
||||
let inside = self.browser_groups.iter().filter(|g| self.group_within(g.id, id));
|
||||
inside.flat_map(|g| g.item_keys().map(str::to_string)).collect()
|
||||
}
|
||||
|
||||
/// The group holding the item directly, in a component's folder.
|
||||
pub fn group_of_item(&self, component: u64, folder: &str, key: &str) -> Option<&BrowserGroup> {
|
||||
self.browser_groups.iter().find(|g| g.component == component && g.folder == folder && g.has_item(key))
|
||||
}
|
||||
|
||||
/// Only the browser's groups and order changed (a group made, nested, moved into, ordered):
|
||||
/// nothing is evaluated and no placement moves. The same whole-Document proof as
|
||||
/// [`Document::differs_only_in_render`]; `next_id` may differ, as a new group takes an id.
|
||||
pub fn differs_only_in_browser(&self, previous: &Document) -> bool {
|
||||
if self.browser_groups == previous.browser_groups && self.browser_order == previous.browser_order {
|
||||
return false;
|
||||
}
|
||||
let mut normalized = previous.clone();
|
||||
normalized.browser_groups.clone_from(&self.browser_groups);
|
||||
normalized.browser_order.clone_from(&self.browser_order);
|
||||
normalized.next_id = self.next_id;
|
||||
*self == normalized
|
||||
}
|
||||
|
||||
/// What [`Document::browser_pruned`] depends on, cheaply: it can only find something to drop
|
||||
/// after a feature, placement, component or group was added or removed. Ids are never
|
||||
/// reused, so a removal followed by an addition still moves `next_id`.
|
||||
pub fn browser_stamp(&self) -> [u64; 6] {
|
||||
let n = |len: usize| u64::try_from(len).unwrap_or(u64::MAX);
|
||||
[
|
||||
self.next_id,
|
||||
n(self.features.len()),
|
||||
n(self.occurrences.len()),
|
||||
n(self.components.len()),
|
||||
n(self.browser_groups.len()),
|
||||
n(self.browser_order.len()),
|
||||
]
|
||||
}
|
||||
|
||||
/// The groups and order lists with what they name that is gone dropped, or `None` when
|
||||
/// nothing is: groups of a missing component or folder, a parent that is missing, elsewhere
|
||||
/// or loops, entries for groups and sketches, construction items and placements that no
|
||||
/// longer exist, repeats, and order lists of missing components. Body names are left alone:
|
||||
/// only an evaluated model knows them.
|
||||
pub fn browser_pruned(&self) -> Option<(Vec<BrowserGroup>, BTreeMap<String, Vec<BrowserEntry>>)> {
|
||||
if self.browser_groups.is_empty() && self.browser_order.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let components: BTreeSet<u64> = self.components.iter().map(|c| c.id).collect();
|
||||
let features: BTreeSet<u64> = self.features.iter().map(|f| f.id).collect();
|
||||
let placed_in: BTreeMap<u64, u64> = self.occurrences.iter().map(|o| (o.id, o.parent)).collect();
|
||||
let component_exists = |c: u64| c == 0 || components.contains(&c);
|
||||
let placed = |component: u64, key: &str| key.parse::<u64>().ok().and_then(|o| placed_in.get(&o)) == Some(&component);
|
||||
// Body names cannot be checked here; the other folders hold feature ids.
|
||||
let item_exists = |folder: &str, component: u64, key: &str| match folder {
|
||||
"bodies" => true,
|
||||
"components" => placed(component, key),
|
||||
_ => key.parse::<u64>().is_ok_and(|id| features.contains(&id)),
|
||||
};
|
||||
let mut groups = self.browser_groups.clone();
|
||||
let mut order = self.browser_order.clone();
|
||||
groups.retain(|g| component_exists(g.component) && BROWSER_FOLDERS.contains(&g.folder.as_str()));
|
||||
let known: BTreeMap<u64, (u64, String)> = groups.iter().map(|g| (g.id, (g.component, g.folder.clone()))).collect();
|
||||
let parents: BTreeMap<u64, Option<u64>> = groups
|
||||
.iter()
|
||||
.map(|g| (g.id, g.parent.filter(|p| *p != g.id && known.get(p).is_some_and(|(c, f)| *c == g.component && *f == g.folder))))
|
||||
.collect();
|
||||
// A loop, or a chain too deep, is cut at the group that makes it.
|
||||
let too_deep = |id: u64| std::iter::successors(Some(id), |g| parents.get(g).copied().flatten()).nth(MAX_GROUP_NESTING).is_some();
|
||||
let kept: BTreeMap<u64, Option<u64>> = parents.iter().map(|(id, p)| (*id, if too_deep(*id) { None } else { *p })).collect();
|
||||
for g in &mut groups {
|
||||
g.parent = kept[&g.id];
|
||||
}
|
||||
let mut taken: BTreeSet<(u64, String, String)> = BTreeSet::new();
|
||||
for g in &mut groups {
|
||||
let (component, folder, id) = (g.component, g.folder.clone(), g.id);
|
||||
let mut seen = BTreeSet::new();
|
||||
g.items.retain(|e| match e {
|
||||
BrowserEntry::Group(c) => kept.get(c) == Some(&Some(id)) && seen.insert(*c),
|
||||
BrowserEntry::Item(k) => item_exists(&folder, component, k) && taken.insert((component, folder.clone(), k.clone())),
|
||||
});
|
||||
}
|
||||
let top = |c: u64, folder: &str, id: u64| kept.get(&id) == Some(&None) && known.get(&id).is_some_and(|(kc, kf)| *kc == c && kf == folder);
|
||||
order.retain(|key, list| {
|
||||
let Some((c, folder)) = key.split_once('/') else { return false };
|
||||
let Some(c) = c.parse::<u64>().ok().filter(|c| component_exists(*c)) else { return false };
|
||||
if !BROWSER_FOLDERS.contains(&folder) {
|
||||
return false;
|
||||
}
|
||||
let mut seen = BTreeSet::new();
|
||||
list.retain(|e| match e {
|
||||
BrowserEntry::Group(id) => top(c, folder, *id) && seen.insert(e.clone()),
|
||||
BrowserEntry::Item(k) => item_exists(folder, c, k) && seen.insert(e.clone()),
|
||||
});
|
||||
!list.is_empty()
|
||||
});
|
||||
(groups != self.browser_groups || order != self.browser_order).then_some((groups, order))
|
||||
}
|
||||
|
||||
/// Put placements of one component in the order the browser shows them: the saved
|
||||
/// `components` order, then the rest as they were.
|
||||
pub fn sort_placements(&self, parent: u64, ids: &mut [u64]) {
|
||||
let Some(order) = self.browser_order.get(&format!("{parent}/components")) else { return };
|
||||
let rank: BTreeMap<&str, usize> = order.iter().enumerate().filter_map(|(i, e)| Some((e.as_item()?, i))).collect();
|
||||
ids.sort_by_cached_key(|id| rank.get(id.to_string().as_str()).copied().unwrap_or(usize::MAX));
|
||||
}
|
||||
}
|
||||
@@ -176,6 +176,8 @@ pub(crate) fn remap_link(
|
||||
remap_link(b, ids, names, bodies, depth + 1);
|
||||
}
|
||||
LinkSource::Plane { name } => mapped_name(name, names),
|
||||
// A construction axis, by name (#9324); the origin axes are no feature's.
|
||||
LinkSource::Axis { name } if !matches!(name.as_str(), "X" | "Y" | "Z") => mapped_name(name, names),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +255,12 @@ impl crate::Feature {
|
||||
for e in sketch.text_exprs_mut() {
|
||||
*e = clone_expression(e, parameters);
|
||||
}
|
||||
// An equation curve's variable is its own: a parameter of that name is not renamed in it.
|
||||
for (variable, e) in sketch.equation_exprs_mut() {
|
||||
let others: BTreeMap<String, String> =
|
||||
parameters.iter().filter(|(old, _)| old.as_str() != variable).map(|(o, n)| (o.clone(), n.clone())).collect();
|
||||
*e = clone_expression(e, &others);
|
||||
}
|
||||
for link in &mut sketch.links {
|
||||
remap_link(&mut link.source, ids, names, bodies, 0);
|
||||
for n in link.face_name.iter_mut().chain(&mut link.edge_name) {
|
||||
|
||||
@@ -344,10 +344,13 @@ fn model_line(st: &ModelState, g: &GeoRef) -> Result<(Vec3, Vec3)> {
|
||||
_ => Err(bad("the face is not a cylinder, cone or torus")),
|
||||
}
|
||||
}
|
||||
_ => Err(bad("pick a straight or circular edge, or a cylinder, cone or torus face")),
|
||||
_ => Err(bad(MODEL_AXIS_REFS)),
|
||||
}
|
||||
}
|
||||
|
||||
/// What [`model_axis`] says about a reference that is neither an edge nor a face.
|
||||
pub const MODEL_AXIS_REFS: &str = "pick a straight or circular edge, or a cylinder, cone or torus face";
|
||||
|
||||
/// The axis a feature turns about when an edge or face of the model is picked for it (a revolve,
|
||||
/// a circular pattern, a plane at an angle), as [`model_line`] finds it. The direction is
|
||||
/// oriented the same way however the edge or surface runs (its largest component positive), so
|
||||
|
||||
@@ -2736,6 +2736,9 @@ pub struct Document {
|
||||
/// Physical material per body (by body name); others use the default.
|
||||
#[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
|
||||
pub materials: std::collections::BTreeMap<String, String>,
|
||||
/// The flat face per body (by body name) that a slicer export lays on the print bed.
|
||||
#[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
|
||||
pub print_faces: std::collections::BTreeMap<String, crate::config::ConfigFaceTarget>,
|
||||
/// Physical materials defined in this design (`material.create`), next to the built-in ones.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub user_materials: Vec<UserMaterial>,
|
||||
@@ -2756,9 +2759,11 @@ pub struct Document {
|
||||
/// order; feature ids remain the source of truth when features are renamed or reordered.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub timeline_groups: Vec<TimelineGroup>,
|
||||
/// Browser item order per component folder (`"<component>/<folder>"` → item keys).
|
||||
/// Browser order per component folder (`"<component>/<folder>"` → groups and item keys).
|
||||
/// The `components` folder orders a component's sub-components (by placement id); it is not
|
||||
/// drawn as a folder.
|
||||
#[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
|
||||
pub browser_order: std::collections::BTreeMap<String, Vec<String>>,
|
||||
pub browser_order: std::collections::BTreeMap<String, Vec<BrowserEntry>>,
|
||||
/// Named views: saved cameras.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub named_views: Vec<NamedView>,
|
||||
@@ -2847,8 +2852,69 @@ pub struct BrowserGroup {
|
||||
#[serde(default)]
|
||||
pub component: u64,
|
||||
pub folder: String,
|
||||
/// The group that holds this one; `None` is the top level of its folder.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub parent: Option<u64>,
|
||||
/// The group's items and child groups in display order. A child group missing here still
|
||||
/// belongs to it (its `parent` says so) and is listed after the ones that are here.
|
||||
#[serde(default)]
|
||||
pub items: Vec<String>,
|
||||
pub items: Vec<BrowserEntry>,
|
||||
}
|
||||
|
||||
/// One line of a browser order list: a group (a number in a saved design) or an item (a string:
|
||||
/// an item key or body name, so a body named `"1"` never clashes with group 1).
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BrowserEntry {
|
||||
Group(u64),
|
||||
Item(String),
|
||||
}
|
||||
|
||||
impl From<&str> for BrowserEntry {
|
||||
fn from(key: &str) -> Self {
|
||||
BrowserEntry::Item(key.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for BrowserEntry {
|
||||
fn from(key: String) -> Self {
|
||||
BrowserEntry::Item(key)
|
||||
}
|
||||
}
|
||||
|
||||
impl BrowserEntry {
|
||||
pub fn item(key: &str) -> Self {
|
||||
BrowserEntry::Item(key.to_string())
|
||||
}
|
||||
|
||||
pub fn as_item(&self) -> Option<&str> {
|
||||
match self {
|
||||
BrowserEntry::Item(k) => Some(k),
|
||||
BrowserEntry::Group(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_item(&self, key: &str) -> bool {
|
||||
self.as_item() == Some(key)
|
||||
}
|
||||
}
|
||||
|
||||
/// How many groups may sit inside one another (a top-level group is level 1).
|
||||
pub const MAX_GROUP_NESTING: usize = 8;
|
||||
|
||||
/// The folders a browser group or order list can be for. `components` only orders sub-components.
|
||||
pub const BROWSER_FOLDERS: [&str; 4] = ["bodies", "sketches", "construction", "components"];
|
||||
|
||||
impl BrowserGroup {
|
||||
/// The keys of the items directly in this group, in order.
|
||||
pub fn item_keys(&self) -> impl Iterator<Item = &str> {
|
||||
self.items.iter().filter_map(BrowserEntry::as_item)
|
||||
}
|
||||
|
||||
/// Whether this group holds the item directly.
|
||||
pub fn has_item(&self, key: &str) -> bool {
|
||||
self.items.iter().any(|e| e.is_item(key))
|
||||
}
|
||||
}
|
||||
|
||||
/// A saved history folder. Folders may nest; each feature or joint belongs to at most one folder.
|
||||
@@ -2982,6 +3048,7 @@ impl Document {
|
||||
body_components: Default::default(),
|
||||
body_offsets: Default::default(),
|
||||
materials: Default::default(),
|
||||
print_faces: Default::default(),
|
||||
user_materials: Vec::new(),
|
||||
appearances: Default::default(),
|
||||
favorites: Default::default(),
|
||||
@@ -2997,7 +3064,7 @@ impl Document {
|
||||
}
|
||||
|
||||
/// Rename body `old` to `new` where the design keeps things by body name outside its
|
||||
/// features: materials, appearances, plastic rules, configuration columns, offsets, components and the
|
||||
/// features: materials, print faces, appearances, plastic rules, configuration columns, offsets, components and the
|
||||
/// browser's groups and order. (The features are the rename command's to change.)
|
||||
///
|
||||
/// A name the design numbered (`Body1`) is not used again after the rename: the design's
|
||||
@@ -3013,6 +3080,10 @@ impl Document {
|
||||
if let Some(m) = self.materials.remove(old) {
|
||||
self.materials.insert(new.to_string(), m);
|
||||
}
|
||||
if let Some(mut face) = self.print_faces.remove(old) {
|
||||
face.body = new.to_string();
|
||||
self.print_faces.insert(new.to_string(), face);
|
||||
}
|
||||
if let Some(rule) = self.plastic.assigned.remove(old) {
|
||||
self.plastic.assigned.insert(new.to_string(), rule);
|
||||
}
|
||||
@@ -3039,15 +3110,16 @@ impl Document {
|
||||
if let Some(c) = self.body_components.remove(old) {
|
||||
self.body_components.insert(new.to_string(), c);
|
||||
}
|
||||
for g in self.browser_groups.iter_mut().filter(|g| g.folder == "bodies") {
|
||||
for k in g.items.iter_mut().filter(|k| *k == old) {
|
||||
*k = new.to_string();
|
||||
let rename = |e: &mut BrowserEntry| {
|
||||
if e.is_item(old) {
|
||||
*e = BrowserEntry::item(new);
|
||||
}
|
||||
};
|
||||
for g in self.browser_groups.iter_mut().filter(|g| g.folder == "bodies") {
|
||||
g.items.iter_mut().for_each(rename);
|
||||
}
|
||||
for (_, v) in self.browser_order.iter_mut().filter(|(k, _)| k.ends_with("/bodies")) {
|
||||
for k in v.iter_mut().filter(|k| *k == old) {
|
||||
*k = new.to_string();
|
||||
}
|
||||
v.iter_mut().for_each(rename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3366,10 +3438,14 @@ impl Document {
|
||||
/// Read a design file's JSON (any format this build knows; older ones are upgraded).
|
||||
pub fn from_json(s: &str) -> Result<Document> {
|
||||
crate::render_resources::check_json_budget(s)?;
|
||||
let d = crate::format::read(s)?;
|
||||
let mut d = crate::format::read(s)?;
|
||||
if d.features.len() > MAX_FEATURES || d.params.len() > MAX_PARAMS {
|
||||
return Err(DocError::Invalid("document too large".into()));
|
||||
}
|
||||
// A design from elsewhere may nest groups too deep, loop, or name things that are gone.
|
||||
if let Some((groups, order)) = d.browser_pruned() {
|
||||
(d.browser_groups, d.browser_order) = (groups, order);
|
||||
}
|
||||
Ok(d)
|
||||
}
|
||||
pub fn to_json(&self) -> String {
|
||||
@@ -3705,7 +3781,7 @@ impl Document {
|
||||
}
|
||||
|
||||
/// Add or change a parameter. Fails if the result would not evaluate. A new parameter
|
||||
/// without a unit takes the unit of its value (mm, deg or none).
|
||||
/// without a unit takes the unit of its value (a length in the design's units, deg or none).
|
||||
pub fn set_param(&mut self, name: &str, expr_s: &str, unit: Option<&str>, comment: Option<&str>) -> Result<()> {
|
||||
// A text parameter: one with the text unit, or an existing one when no unit is given.
|
||||
match (unit.map(crate::text_params::is_text_unit), self.text_param(name).is_some()) {
|
||||
@@ -3889,10 +3965,11 @@ impl Document {
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply parameter values to every dimension in a sketch, and to its points placed by
|
||||
/// parameters (in place).
|
||||
/// Apply parameter values to every dimension in a sketch, to its points placed by parameters
|
||||
/// and to its equation curves (in place).
|
||||
pub fn apply_dimension_values(&self, vals: &std::collections::BTreeMap<String, expr::Value>, sk: &mut Sketch) -> Result<()> {
|
||||
self.apply_point_values(vals, sk)?;
|
||||
self.apply_equation_values(vals, sk)?;
|
||||
self.apply_pattern_values(vals, sk)?;
|
||||
for c in &mut sk.constraints {
|
||||
if let Some(p) = &c.param {
|
||||
@@ -4013,7 +4090,7 @@ impl Document {
|
||||
return Err(DocError::Invalid("a text's height must be positive".into()));
|
||||
}
|
||||
if let Some(e) = &exprs.text {
|
||||
let words = self.eval_words(e).map_err(|error| DocError::Expr(format!("text: {error}")))?;
|
||||
let words = self.eval_words(e, vals).map_err(|error| DocError::Expr(format!("text: {error}")))?;
|
||||
if words.trim().is_empty() || words.chars().count() > solidcraft_sketch::MAX_TEXT_CHARS {
|
||||
return Err(DocError::Invalid(format!("text: `{e}` gives no words, or too many")));
|
||||
}
|
||||
|
||||
@@ -792,6 +792,11 @@ fn split_piece_of(name: &str) -> Option<&str> {
|
||||
(!n.starts_with('0') && n.parse::<u32>().is_ok()).then_some(base)
|
||||
}
|
||||
|
||||
/// The warning of a sketch whose profile search was cut short (#6896).
|
||||
fn profiles_cut_short_note() -> String {
|
||||
format!("some profiles may be missing: a group of touching curves is cut into more than {} pieces", solidcraft_sketch::MAX_PROFILE_EDGES)
|
||||
}
|
||||
|
||||
/// Add `note` to a feature's warning.
|
||||
fn append_warning(warning: &mut Option<String>, note: String) {
|
||||
*warning = Some(match warning.take() {
|
||||
@@ -2153,7 +2158,14 @@ impl Model {
|
||||
feature_component.entry(f.id).or_insert(f.component);
|
||||
}
|
||||
let watched = crate::progress::begin(doc.features.len());
|
||||
// The features that failed so far in this pass, by id: their names and errors (#9075).
|
||||
let mut failed: std::collections::HashMap<u64, (String, String)> = std::collections::HashMap::new();
|
||||
for (i, f) in doc.features.iter().enumerate() {
|
||||
if let Some(r) = out.last()
|
||||
&& let Some(e) = &r.error
|
||||
{
|
||||
failed.insert(r.id, (r.name.clone(), e.clone()));
|
||||
}
|
||||
self.placement_local = self.placement_local && placement_reuse::local_geometry(f, &feature_component);
|
||||
let rolled_back = i >= marker;
|
||||
// Retain at most one active result per rolled-back feature, even across several
|
||||
@@ -2213,6 +2225,33 @@ impl Model {
|
||||
if state.reserved_body_names != reserved {
|
||||
Arc::make_mut(&mut state).reserved_body_names.clone_from(&reserved);
|
||||
}
|
||||
// A sketch the feature is built from failed earlier in this pass: the feature fails naming
|
||||
// that sketch, with its error, as one using a failed parameter does (#9075), not as a
|
||||
// sketch that must come earlier in the timeline. Never cached: the cache key holds
|
||||
// neither the sketch's name nor its error (a rename, another failing value).
|
||||
let failed_sketch = if failed.is_empty() {
|
||||
None
|
||||
} else {
|
||||
f.kind.input_sketches().into_iter().find_map(|id| failed.get(&id)).map(|(name, e)| format!("sketch `{name}` failed: {e}"))
|
||||
};
|
||||
if let Some(e) = failed_sketch {
|
||||
recomputed += 1;
|
||||
reuse = false;
|
||||
out.push(FeatureResult {
|
||||
id: f.id,
|
||||
name: f.name.clone(),
|
||||
error: Some(e),
|
||||
warning: None,
|
||||
boolean_diagnostics: Default::default(),
|
||||
ms: 0.0,
|
||||
skipped: false,
|
||||
stale: false,
|
||||
fingerprint: fp,
|
||||
unkept: false,
|
||||
state: state.clone(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// The same feature on the same inputs: its earlier result.
|
||||
let key =
|
||||
cache_key(f, fp, fingerprint(doc, 0, f, &vals, false, &self.step_digests) ^ placement_digest(doc, f, Some(&state)), ctx, &state);
|
||||
@@ -2523,13 +2562,40 @@ fn point(vals: &BTreeMap<String, Value>, p: &crate::PointExpr) -> Result<Vec3> {
|
||||
|
||||
pub(crate) fn val(vals: &BTreeMap<String, Value>, e: &str, k: Kind) -> Result<f64> {
|
||||
let scale = vals.get(DESIGN_LEN).map(|x| x.v).unwrap_or(1.0);
|
||||
// Non-literal lengths (a parameter ± a bare number) must read that bare number in the design's
|
||||
// units during the expression, not only when the whole result is unit-less (#9015).
|
||||
if k == Kind::Length && scale != 1.0 && !expr::is_literal(e) {
|
||||
let v = expr::eval_with(e, &|n| vals.get(n).copied().ok_or_else(|| DocError::Expr(format!("unknown parameter `{n}`"))))?;
|
||||
return v.to_kind_in(k, expr::Defaults { len: scale, ..expr::Defaults::default() });
|
||||
let defaults = expr::Defaults { len: scale, ..expr::Defaults::default() };
|
||||
let look = |n: &str| vals.get(n).copied().ok_or_else(|| DocError::Expr(format!("unknown parameter `{n}`")));
|
||||
return expr::eval_with_defaults(e, &look, defaults)?.to_kind_in(k, defaults);
|
||||
}
|
||||
Document::eval_in(vals, e, k)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod design_unit_val_tests {
|
||||
use super::*;
|
||||
use expr::Value;
|
||||
|
||||
/// #9015: with inches as the design unit, `baseLength - 1` subtracts one inch (not one mm).
|
||||
#[test]
|
||||
fn bare_offsets_beside_a_length_follow_the_design_units() {
|
||||
let mut vals = BTreeMap::new();
|
||||
vals.insert(DESIGN_LEN.into(), Value::num(25.4));
|
||||
vals.insert("baseLength".into(), Value::length(76.0 * 25.4));
|
||||
let got = val(&vals, "baseLength - 1", Kind::Length).unwrap();
|
||||
assert!((got - 75.0 * 25.4).abs() < 1e-9, "got {got} mm, want 75 in");
|
||||
let got = val(&vals, "baseLength - 1.5", Kind::Length).unwrap();
|
||||
assert!((got - 74.5 * 25.4).abs() < 1e-9, "got {got} mm, want 74.5 in");
|
||||
// An explicit millimetre still wins.
|
||||
let got = val(&vals, "baseLength - 1 mm", Kind::Length).unwrap();
|
||||
assert!((got - (76.0 * 25.4 - 1.0)).abs() < 1e-9, "got {got}");
|
||||
// A bare literal stays millimetres (feature inputs write the design unit in when typed).
|
||||
let got = val(&vals, "2", Kind::Length).unwrap();
|
||||
assert!((got - 2.0).abs() < 1e-12, "got {got}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Collapsing the outline and its holes onto one apex cannot make a manifold solid.
|
||||
fn refuse_loft_holes(r: &Region2) -> Result<()> {
|
||||
if r.holes.is_empty() {
|
||||
@@ -7196,7 +7262,13 @@ fn eval_feature(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature, st:
|
||||
*warning = Some(warns.join("; "));
|
||||
}
|
||||
sk.validate_periodic_splines()?;
|
||||
let profiles = find_profiles(&sk);
|
||||
// A group of touching curves too large to search whole says so, rather than
|
||||
// leaving profiles out silently (#6896).
|
||||
let search = solidcraft_sketch::find_profiles_checked(&sk);
|
||||
if search.incomplete {
|
||||
append_warning(warning, profiles_cut_short_note());
|
||||
}
|
||||
let profiles = search.profiles;
|
||||
let ends = solidcraft_sketch::loose_ends(&sk);
|
||||
st.sketches.retain(|s| s.feature != f.id);
|
||||
st.sketches.push(Arc::new(SolvedSketch { feature: f.id, name: f.name.clone(), plane, sketch: sk, report, profiles, ends }));
|
||||
|
||||
@@ -647,3 +647,65 @@ fn shared_evaluation_refreshes_live_sketches_and_keeps_unknown_features_conserva
|
||||
assert!(model.results.iter().all(|r| r.error.is_none()));
|
||||
assert!(model.evaluate_shared(&doc), "an unclassified feature must keep the ordinary evaluation path");
|
||||
}
|
||||
|
||||
/// A saved model writes each set of sketch keys once, as the keys it sets and drops relative to
|
||||
/// the set written before it (every state repeating its whole set made a 5,484-feature design's
|
||||
/// model too large for its file, which then kept only some states and evaluated the rest on
|
||||
/// opening). Every state reads back the keys it was evaluated with, also in a model thinned to
|
||||
/// fewer states; a set that names no set before it is refused.
|
||||
#[test]
|
||||
fn saved_states_read_back_their_sketch_keys() {
|
||||
let mut doc = Document::new("Sketch keys");
|
||||
for i in 0..4 {
|
||||
doc.add_feature(line_sketch(PlaneRef::Origin { name: "XY".into() }, Vec2::new(f64::from(i) + 1.0, 1.0)), None).unwrap();
|
||||
for j in 0..3 {
|
||||
let corner = point_expr(Vec3::new(f64::from(i) * 20.0, f64::from(j) * 20.0, 0.0));
|
||||
let kind = FeatureKind::Box { corner, length: "5".into(), width: "5".into(), height: "5".into(), operation: Operation::NewBody };
|
||||
doc.add_feature(kind, None).unwrap();
|
||||
}
|
||||
}
|
||||
let mut model = Model::new();
|
||||
model.evaluate(&doc);
|
||||
let keys = |m: &Model| m.results.iter().map(|r| r.state.sketch_keys.clone()).collect::<Vec<_>>();
|
||||
assert_eq!(model.state().sketch_keys.len(), 4);
|
||||
let saved = model.saved(&doc).unwrap();
|
||||
assert_eq!(saved.records["sketch_key_sets"].as_array().unwrap().len(), 4, "one set per sketch");
|
||||
assert_eq!(saved.records["states"].as_array().unwrap().len(), doc.features.len());
|
||||
assert_eq!(keys(&Model::adopt(&doc, &saved).unwrap()), keys(&model));
|
||||
// The final state alone (every body costs more than the budget): the sets are all kept.
|
||||
let pieces: Vec<Vec<(usize, usize)>> = (0..saved.bodies.len()).map(|i| vec![(i, 1 << 20)]).collect();
|
||||
let (thinned, _, _) = saved.thinned(&pieces, 0).unwrap();
|
||||
assert_eq!(thinned.records["states"].as_array().unwrap().len(), 1);
|
||||
assert_eq!(thinned.final_state().unwrap().sketch_keys, model.state().sketch_keys);
|
||||
assert_eq!(keys(&Model::adopt(&doc, &thinned).unwrap()), keys(&model));
|
||||
// Sets and drops read as written; a base that is not an earlier set is refused.
|
||||
let with_sets = |sets: serde_json::Value| SavedModel {
|
||||
records: {
|
||||
let mut r = saved.records.clone();
|
||||
r["sketch_key_sets"] = sets;
|
||||
r
|
||||
},
|
||||
bodies: saved.bodies.clone(),
|
||||
};
|
||||
let first = *model.state().sketch_keys.keys().next().unwrap();
|
||||
let dropped = with_sets(serde_json::json!([
|
||||
{"set": [[first, "0000000000000001"], [7, "0000000000000002"]], "drop": []},
|
||||
{"base": 0, "set": [], "drop": []},
|
||||
{"base": 1, "set": [[8, "0000000000000003"]], "drop": [first]},
|
||||
{"base": 0, "set": [[7, "00000000000000ff"]], "drop": []},
|
||||
]));
|
||||
let want: BTreeMap<u64, u64> = [(7, 0xff), (first, 1)].into();
|
||||
assert_eq!(dropped.final_state().unwrap().sketch_keys, want);
|
||||
let dropped = with_sets(serde_json::json!([
|
||||
{"set": [[first, "0000000000000001"], [7, "0000000000000002"]], "drop": []},
|
||||
{"base": 0, "set": [], "drop": []},
|
||||
{"base": 0, "set": [], "drop": []},
|
||||
{"base": 1, "set": [[8, "0000000000000003"]], "drop": [first]},
|
||||
]));
|
||||
assert_eq!(dropped.final_state().unwrap().sketch_keys, [(7, 2), (8, 3)].into());
|
||||
for base in [3, 4] {
|
||||
let sets =
|
||||
serde_json::json!([{"set": [], "drop": []}, {"set": [], "drop": []}, {"set": [], "drop": []}, {"base": base, "set": [], "drop": []}]);
|
||||
assert!(with_sets(sets).final_state().is_err(), "base {base}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,12 @@ pub const FUNCTIONS: &[(&str, &str)] = &[
|
||||
("ceil", "ceil(x)"),
|
||||
("round", "round(x)"),
|
||||
("exp", "exp(x)"),
|
||||
("sinh", "sinh(x)"),
|
||||
("cosh", "cosh(x)"),
|
||||
("tanh", "tanh(x)"),
|
||||
("asinh", "asinh(x)"),
|
||||
("acosh", "acosh(x), x ≥ 1"),
|
||||
("atanh", "atanh(x), −1 < x < 1"),
|
||||
("ln", "ln(x)"),
|
||||
("log", "log(x) (base 10)"),
|
||||
("log10", "log10(x)"),
|
||||
@@ -344,8 +350,9 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
let at = |i: usize| cs.get(i).map(|x| x.0).unwrap_or(s.len());
|
||||
let mut i = 0;
|
||||
let mut out = Vec::new();
|
||||
// Parentheses open at this point: a comma outside them can only be a decimal comma.
|
||||
let mut depth = 0usize;
|
||||
// Parentheses open at this point, innermost last, true for a function call's: a comma directly
|
||||
// in a call separates its arguments, and anywhere else can only be a decimal comma (#9408).
|
||||
let mut parens: Vec<bool> = Vec::new();
|
||||
// A single leading `=` marks the text as a formula (`=d3`, #4681) and is not part of it.
|
||||
if let Some(k) = cs.iter().position(|(_, c)| !c.is_whitespace())
|
||||
&& cs.get(k).is_some_and(|(_, c)| *c == '=')
|
||||
@@ -363,7 +370,7 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
while let Some(&(_, c)) = cs.get(i) {
|
||||
if c.is_whitespace() {
|
||||
i += 1;
|
||||
} else if c.is_ascii_digit() || c == '.' || leading_decimal_comma(&cs, i, depth, out.last()) {
|
||||
} else if c.is_ascii_digit() || c == '.' || leading_decimal_comma(&cs, i, in_call(&parens), out.last()) {
|
||||
let st = i;
|
||||
// A leading decimal comma (`,5` for 0,5, #2966) starts the number as `.5` would.
|
||||
let leading_comma = c == ',';
|
||||
@@ -374,11 +381,17 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
i += 1;
|
||||
}
|
||||
// A decimal comma (`2,5 mm`, as typed with a numeric keypad in many locales, #1347):
|
||||
// a comma between digits, in a number with no point, outside any parentheses (inside
|
||||
// them a comma separates a function's arguments: `max(1,2)`).
|
||||
// a comma between digits, in a number with no point, not directly in a function call
|
||||
// (there a comma separates arguments: `max(1,2)`).
|
||||
let digit = |k: usize| cs.get(k).is_some_and(|(_, c)| c.is_ascii_digit());
|
||||
let has_point = cs.get(st..i).is_some_and(|ds| ds.iter().any(|(_, c)| *c == '.'));
|
||||
if depth == 0 && !leading_comma && !has_point && digit(i.wrapping_sub(1)) && cs.get(i).is_some_and(|(_, c)| *c == ',') && digit(i + 1) {
|
||||
if !in_call(&parens)
|
||||
&& !leading_comma
|
||||
&& !has_point
|
||||
&& digit(i.wrapping_sub(1))
|
||||
&& cs.get(i).is_some_and(|(_, c)| *c == ',')
|
||||
&& digit(i + 1)
|
||||
{
|
||||
i += 1;
|
||||
while digit(i) {
|
||||
i += 1;
|
||||
@@ -400,7 +413,7 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
// A mixed number, as imperial sizes are written (`2 1/8"` is 2.125 in, #1802): a whole
|
||||
// number, then a proper fraction of whole numbers, is one value, not `2 × 1/8`.
|
||||
if t.chars().all(|c| c.is_ascii_digit())
|
||||
&& let Some((fraction, end)) = mixed_fraction(&cs, i, depth)
|
||||
&& let Some((fraction, end)) = mixed_fraction(&cs, i, in_call(&parens))
|
||||
{
|
||||
out.push((Tok::Num(v + fraction), at(st), at(end)));
|
||||
i = end;
|
||||
@@ -438,8 +451,10 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
i += 1;
|
||||
} else if "+-*/^(),%".contains(c) {
|
||||
match c {
|
||||
'(' => depth += 1,
|
||||
')' => depth = depth.saturating_sub(1),
|
||||
'(' => parens.push(matches!(out.last(), Some((Tok::Id(_), _, _)))),
|
||||
')' => {
|
||||
parens.pop();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
out.push((Tok::Op(c), at(i), at(i + 1)));
|
||||
@@ -451,27 +466,32 @@ fn lex_spans(s: &str) -> Result<Vec<(Tok, usize, usize)>, DocError> {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Whether the innermost open parenthesis is a function call's.
|
||||
fn in_call(parens: &[bool]) -> bool {
|
||||
parens.last() == Some(&true)
|
||||
}
|
||||
|
||||
/// Whether the comma at `i` starts a number, as a leading decimal comma (`,5` for 0,5, #2966).
|
||||
/// It must be outside parentheses (inside them a comma separates arguments, as for any decimal
|
||||
/// comma), be followed by a digit, and stand where an operand is expected: at the start or right
|
||||
/// after `+ - * / ^`. A comma after a number, name, `)` or `%` keeps its meaning (`2 ,5` and
|
||||
/// `1,5,3` stay errors).
|
||||
fn leading_decimal_comma(cs: &[(usize, char)], i: usize, depth: usize, prev: Option<&(Tok, usize, usize)>) -> bool {
|
||||
depth == 0
|
||||
/// It must not be directly in a function call (`in_call`: there a comma separates arguments, as
|
||||
/// for any decimal comma), be followed by a digit, and stand where an operand is expected: at the
|
||||
/// start or right after `( + - * / ^`. A comma after a number, name, `)` or `%` keeps its meaning
|
||||
/// (`2 ,5` and `1,5,3` stay errors).
|
||||
fn leading_decimal_comma(cs: &[(usize, char)], i: usize, in_call: bool, prev: Option<&(Tok, usize, usize)>) -> bool {
|
||||
!in_call
|
||||
&& cs.get(i).is_some_and(|(_, c)| *c == ',')
|
||||
&& cs.get(i + 1).is_some_and(|(_, c)| c.is_ascii_digit())
|
||||
&& match prev {
|
||||
None => true,
|
||||
Some((Tok::Op(op), _, _)) => "+-*/^".contains(*op),
|
||||
Some((Tok::Op(op), _, _)) => "(+-*/^".contains(*op),
|
||||
Some(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// The proper fraction of a mixed number whose whole part ends at `i`: spaces, digits, `/`,
|
||||
/// digits, with nothing after them that would continue the number (`2 1/8.5`, `2 1/8e3`, a
|
||||
/// decimal comma outside parentheses: `2 1/8,5`). Its value and where it ends. `depth`: the
|
||||
/// parentheses open there (inside them a comma separates arguments: `max(2 1/8,1)`).
|
||||
fn mixed_fraction(cs: &[(usize, char)], mut i: usize, depth: usize) -> Option<(f64, usize)> {
|
||||
/// decimal comma: `2 1/8,5`). Its value and where it ends. `in_call`: directly in a function call
|
||||
/// there (a comma separates arguments: `max(2 1/8,1)`).
|
||||
fn mixed_fraction(cs: &[(usize, char)], mut i: usize, in_call: bool) -> Option<(f64, usize)> {
|
||||
let digits = |from: usize| cs.get(from..).map_or(0, |rest| rest.iter().take_while(|(_, c)| c.is_ascii_digit()).count());
|
||||
let space = i;
|
||||
while cs.get(i).is_some_and(|(_, c)| *c == ' ' || *c == '\t') {
|
||||
@@ -485,7 +505,7 @@ fn mixed_fraction(cs: &[(usize, char)], mut i: usize, depth: usize) -> Option<(f
|
||||
let end = i + numerator + 1 + denominator;
|
||||
let next = |k: usize| cs.get(end + k).map(|(_, c)| *c);
|
||||
let continues = matches!(next(0), Some('.'))
|
||||
|| (depth == 0 && matches!(next(0), Some(',')) && next(1).is_some_and(|c| c.is_ascii_digit()))
|
||||
|| (!in_call && matches!(next(0), Some(',')) && next(1).is_some_and(|c| c.is_ascii_digit()))
|
||||
|| (matches!(next(0), Some('e' | 'E')) && next(1).is_some_and(|c| c.is_ascii_digit() || c == '-' || c == '+'));
|
||||
if denominator == 0 || continues {
|
||||
return None;
|
||||
@@ -589,9 +609,11 @@ pub fn is_literal(s: &str) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Is the expression a bare number without a unit, like `20` or `-1.5`?
|
||||
/// Is the expression a bare number without a unit, like `20` or `-1.5`? A leading `=` only marks
|
||||
/// a formula (#4681), so `=20` is the same bare number.
|
||||
pub fn is_bare_number(s: &str) -> bool {
|
||||
is_literal(s) && s.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok()
|
||||
let number = s.trim().strip_prefix('=').unwrap_or(s);
|
||||
is_literal(s) && number.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok()
|
||||
}
|
||||
|
||||
/// Is `s` shaped like a parameter name: a letter or `_`, then letters, digits and `_`? The shape
|
||||
@@ -943,6 +965,24 @@ fn call(f: &str, args: &[Value], d: Defaults) -> Result<Value, DocError> {
|
||||
unit_fn(r * if scale != 0.0 { scale } else { 1.0 }, a)
|
||||
}
|
||||
"exp" => Value::num(num(one()?)?.exp()),
|
||||
"sinh" => Value::num(num(one()?)?.sinh()),
|
||||
"cosh" => Value::num(num(one()?)?.cosh()),
|
||||
"tanh" => Value::num(num(one()?)?.tanh()),
|
||||
"asinh" => Value::num(num(one()?)?.asinh()),
|
||||
"acosh" => {
|
||||
let x = num(one()?)?;
|
||||
if !(x >= 1.0) {
|
||||
return Err(DocError::Expr("`acosh` needs a number of at least 1".into()));
|
||||
}
|
||||
Value::num(x.acosh())
|
||||
}
|
||||
"atanh" => {
|
||||
let x = num(one()?)?;
|
||||
if !(x > -1.0 && x < 1.0) {
|
||||
return Err(DocError::Expr("`atanh` needs a number between -1 and 1, both excluded".into()));
|
||||
}
|
||||
Value::num(x.atanh())
|
||||
}
|
||||
"ln" | "log" | "log10" => {
|
||||
let x = num(one()?)?;
|
||||
if x <= 0.0 {
|
||||
@@ -1214,7 +1254,13 @@ mod tests {
|
||||
// Inside parentheses a comma still separates a function's arguments.
|
||||
assert_eq!(ev("max(1,2)", Kind::Unitless).unwrap(), 2.0);
|
||||
assert_eq!(ev("max(1 mm, 3, 2)", Kind::Length).unwrap(), 3.0);
|
||||
assert_eq!(ev("(2,5)", Kind::Unitless).ok(), None, "a comma inside parentheses is not a decimal comma");
|
||||
// Plain parentheses have no arguments to separate (#9408), also inside a call.
|
||||
assert_eq!(ev("(2,5)", Kind::Unitless).unwrap(), 2.5);
|
||||
assert_eq!(ev("-(width-0,5)/2", Kind::Length).unwrap(), -19.75);
|
||||
assert_eq!(ev("(,5)", Kind::Unitless).unwrap(), 0.5);
|
||||
assert_eq!(ev("(2 1/8,5)", Kind::Unitless).unwrap(), 2.0 / 8.5);
|
||||
assert_eq!(ev("max((1,5), 1)", Kind::Unitless).unwrap(), 1.5);
|
||||
assert_eq!(ev("(max(1,2))", Kind::Unitless).unwrap(), 2.0);
|
||||
// Not between two digits, or a second comma: still an error.
|
||||
for bad in ["2,", "2 ,5", "2, 5", "1,5,3", "1.5,3", ",5,3", ",5.3", "width ,5", "(1) ,5"] {
|
||||
assert!(ev(bad, Kind::Unitless).is_err(), "{bad}");
|
||||
@@ -1328,6 +1374,15 @@ mod tests {
|
||||
assert!((ev("atan2(1; 1)", Kind::Angle).unwrap() - std::f64::consts::FRAC_PI_4).abs() < 1e-12);
|
||||
assert!((ev("exp(ln(5))", Kind::Unitless).unwrap() - 5.0).abs() < 1e-12);
|
||||
assert!((ev("log(1000)", Kind::Unitless).unwrap() - 3.0).abs() < 1e-12);
|
||||
// Hyperbolic functions (#9332): their definitions in exp, identities and inverses.
|
||||
assert!((ev("cosh(1.5) - (exp(1.5) + exp(-1.5)) / 2", Kind::Unitless).unwrap()).abs() < 1e-12);
|
||||
assert!((ev("sinh(1.5) - (exp(1.5) - exp(-1.5)) / 2", Kind::Unitless).unwrap()).abs() < 1e-12);
|
||||
assert!((ev("tanh(0.7) - sinh(0.7) / cosh(0.7)", Kind::Unitless).unwrap()).abs() < 1e-12);
|
||||
assert!((ev("cosh(2) ^ 2 - sinh(2) ^ 2", Kind::Unitless).unwrap() - 1.0).abs() < 1e-12);
|
||||
assert!((ev("asinh(sinh(1.25))", Kind::Unitless).unwrap() - 1.25).abs() < 1e-12);
|
||||
assert!((ev("acosh(cosh(1.25))", Kind::Unitless).unwrap() - 1.25).abs() < 1e-12);
|
||||
assert!((ev("atanh(tanh(0.5))", Kind::Unitless).unwrap() - 0.5).abs() < 1e-12);
|
||||
assert_eq!(ev("cosh(0) + sinh(0) + tanh(0) + asinh(0) + acosh(1) + atanh(0)", Kind::Unitless).unwrap(), 1.0);
|
||||
assert_eq!(ev("floor(2.7) + ceil(0.2) + round(1.5) + abs(-1)", Kind::Unitless).unwrap(), 6.0);
|
||||
assert!((ev("1 rad", Kind::Angle).unwrap() - 1.0).abs() < 1e-12);
|
||||
assert!((ev("acos(0)", Kind::Angle).unwrap() - std::f64::consts::FRAC_PI_2).abs() < 1e-12);
|
||||
@@ -1337,6 +1392,22 @@ mod tests {
|
||||
assert_eq!(ev("width^2 / width", Kind::Length).unwrap(), 40.0);
|
||||
}
|
||||
|
||||
/// The hyperbolic functions (#9332) take a unit-less number, and the inverses refuse what lies
|
||||
/// outside their domain, as `asin` and `ln` do.
|
||||
#[test]
|
||||
fn hyperbolic_functions_refuse_units_and_numbers_outside_their_domain() {
|
||||
for (e, says) in [
|
||||
("cosh(2 mm)", "`cosh` needs a unit-less number"),
|
||||
("tanh(30 deg)", "`tanh` needs a unit-less number"),
|
||||
("acosh(0.5)", "`acosh` needs a number of at least 1"),
|
||||
("atanh(1)", "`atanh` needs a number between -1 and 1"),
|
||||
("atanh(-1.5)", "`atanh` needs a number between -1 and 1"),
|
||||
] {
|
||||
let err = ev(e, Kind::Unitless).map(|v| v.to_string()).unwrap_or_else(|e| e.to_string());
|
||||
assert!(err.contains(says), "{e}: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
/// A count from a length (`(L - 20) / 210`, the 210 read as unit-less) names the fix (#5901).
|
||||
#[test]
|
||||
fn a_length_where_a_count_is_expected_says_to_divide_by_a_length() {
|
||||
@@ -1449,6 +1520,8 @@ mod tests {
|
||||
assert!(is_literal("20") && is_literal("-1.5 in") && is_literal("3 deg"));
|
||||
assert!(!is_literal("d1") && !is_literal("2 * 3") && !is_literal("2 width"));
|
||||
assert!(is_bare_number(" -1.5 ") && is_bare_number("+2") && !is_bare_number("20 mm") && !is_bare_number("(2)"));
|
||||
// A leading `=` only marks a formula (#4681): `=5` is the bare number `5`, not `==5`.
|
||||
assert!(is_bare_number("=5") && is_bare_number(" = -1.5") && !is_bare_number("=5 mm") && !is_bare_number("==5") && !is_bare_number("=d3"));
|
||||
assert_eq!((length_unit_or_mm(" in "), length_unit_or_mm("deg"), length_unit_or_mm("")), ("in", "mm", "mm"));
|
||||
}
|
||||
|
||||
|
||||
@@ -172,32 +172,7 @@ impl Document {
|
||||
author: u64,
|
||||
author_path: &[u64],
|
||||
) -> Result<FaceAnchor> {
|
||||
// A construction certificate that names this face alone, else its exact history name.
|
||||
let certified = body
|
||||
.body
|
||||
.face_plane(index)
|
||||
.ok_or_else(|| DocError::Invalid("this face has no exact planar source; choose a fixed plane instead".into()))
|
||||
.and_then(|source| {
|
||||
let target = self.strong_face_target(body, index, source.origin)?;
|
||||
if target.certificate.is_none() {
|
||||
return Err(DocError::Invalid("this face has no supported construction certificate; choose a fixed plane instead".into()));
|
||||
}
|
||||
let indices = self.configuration_face_indices(body, &target)?;
|
||||
// A copy a pattern or mirror made on the same body carries its seed's certificate,
|
||||
// which finds the seed's face: the copy is attached by its own history name below.
|
||||
if !indices.contains(&index) {
|
||||
return Err(DocError::Invalid("this face has no supported construction certificate; choose a fixed plane instead".into()));
|
||||
}
|
||||
self.coplanar_pieces(body, &indices, |_| true)?;
|
||||
Ok(target)
|
||||
});
|
||||
let target = match certified {
|
||||
Ok(target) => target,
|
||||
Err(error) => match body.body.planar_face(index).and_then(|plane| self.lineage_face_target(body, index, plane.origin)) {
|
||||
Some(target) => target,
|
||||
None => return Err(error),
|
||||
},
|
||||
};
|
||||
let target = self.flat_face_target(body, index)?;
|
||||
let source = self
|
||||
.anchor_face_plane(body, index, target.certificate.as_ref())
|
||||
.ok_or_else(|| DocError::Invalid("this face has no exact planar source; choose a fixed plane instead".into()))?;
|
||||
@@ -220,6 +195,34 @@ impl Document {
|
||||
Ok(anchor)
|
||||
}
|
||||
|
||||
/// A target for flat face `index` of `body` that a rebuild finds again: a construction
|
||||
/// certificate that names this face alone, else its exact history name. What a sketch on a
|
||||
/// face and a print face hold.
|
||||
pub(crate) fn flat_face_target(&self, body: &ModelBody, index: usize) -> Result<ConfigFaceTarget> {
|
||||
let certified = body
|
||||
.body
|
||||
.face_plane(index)
|
||||
.ok_or_else(|| DocError::Invalid("this face has no exact planar source; choose a fixed plane instead".into()))
|
||||
.and_then(|source| {
|
||||
let target = self.strong_face_target(body, index, source.origin)?;
|
||||
if target.certificate.is_none() {
|
||||
return Err(DocError::Invalid("this face has no supported construction certificate; choose a fixed plane instead".into()));
|
||||
}
|
||||
let indices = self.configuration_face_indices(body, &target)?;
|
||||
// A copy a pattern or mirror made on the same body carries its seed's certificate,
|
||||
// which finds the seed's face: the copy is attached by its own history name below.
|
||||
if !indices.contains(&index) {
|
||||
return Err(DocError::Invalid("this face has no supported construction certificate; choose a fixed plane instead".into()));
|
||||
}
|
||||
self.coplanar_pieces(body, &indices, |_| true)?;
|
||||
Ok(target)
|
||||
});
|
||||
match certified {
|
||||
Ok(target) => Ok(target),
|
||||
Err(error) => body.body.planar_face(index).and_then(|plane| self.lineage_face_target(body, index, plane.origin)).ok_or(error),
|
||||
}
|
||||
}
|
||||
|
||||
/// The faces an attachment stands for, and a note when they were found by fallback.
|
||||
///
|
||||
/// An extrude's cap is certified by the loop of sketch curves around it, so editing that
|
||||
|
||||
@@ -46,6 +46,17 @@ impl FeatureKind {
|
||||
found
|
||||
}
|
||||
|
||||
/// Bodies the feature works on (by name).
|
||||
pub fn input_bodies(&self) -> Vec<String> {
|
||||
let mut v = Vec::new();
|
||||
self.walk_refs(&mut |r| {
|
||||
if let Ref::Body(name) = r {
|
||||
v.push(name.as_ref().to_string());
|
||||
}
|
||||
});
|
||||
v
|
||||
}
|
||||
|
||||
/// Point references to sketches and features (both by id) at their copies, and references
|
||||
/// that are still keyed by name at a feature's new name (`timeline.rename`).
|
||||
pub fn remap_refs(&mut self, ids: &BTreeMap<u64, u64>, names: &BTreeMap<String, String>) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
//! A sketch saves its equation curves (#8352) in `equations`: for each, the fit point spline it
|
||||
//! places, its formulas (x(t) and y(t), or y = f(x) without `x`), the range of the variable and
|
||||
//! the tolerance its points were chosen for. An older design has none, and its sketches mean
|
||||
//! what they meant. The last release refuses a design that has them (it asks for an update)
|
||||
//! instead of opening the splines as plain fixed splines that no longer follow their formulas.
|
||||
@@ -0,0 +1,6 @@
|
||||
//! Browser groups can nest and be ordered. A group saves its `parent` group (omitted at the top
|
||||
//! level); a group's items and a folder's `browser_order` list may name groups as numbers beside
|
||||
//! item keys as strings; and `browser_order` has a `"<component>/components"` list ordering a
|
||||
//! component's sub-components by placement id. Older designs read unchanged: they have no
|
||||
//! parents and no group entries. The last release refuses the newer format and asks for an
|
||||
//! update instead of dropping the nesting and the order.
|
||||
@@ -0,0 +1,7 @@
|
||||
//! A point cloud keeps the other properties its file gives its points (#8816): named numbers per
|
||||
//! point in `complex` (`columns`, each whole-numbered or not, and the `names` a whole-numbered one's
|
||||
//! values carry), and it can be coloured by one of them (`color_by: "property"`, with
|
||||
//! `color_property`, the ramp over `height_range`) and shown only where `filters` keep it (ranges,
|
||||
//! or sets of named values). Older designs need no transformation: their clouds have no other
|
||||
//! properties and no filters. The last release refuses a design saved with this (the newer format
|
||||
//! number) instead of opening its clouds without their properties, colouring and filters.
|
||||
@@ -0,0 +1,5 @@
|
||||
//! A design saves the print face of its bodies (`print_faces`, by body name): the flat face a
|
||||
//! slicer export lays on the print bed, held by the same face target a sketch on a face holds.
|
||||
//! An older design has none, and every body is exported as it lies, as before. The last
|
||||
//! release refuses a design that has print faces and asks for an update, instead of opening it
|
||||
//! and losing them on the next save.
|
||||
@@ -191,7 +191,11 @@ impl Document {
|
||||
}
|
||||
let mut out = Vec::with_capacity(found.defs.len());
|
||||
for d in found.defs {
|
||||
next.add_user_param(&d.name, &d.expression, d.unit.as_deref(), None)
|
||||
// A value of no fixed kind (a joint's) is evaluated without the design's units, so
|
||||
// its bare number stays a millimetre length whatever they are (#8865): `w = 5` is
|
||||
// what `5` is there.
|
||||
let unit = d.unit.unwrap_or_else(|| Self::infer_unit_in(&next.param_values().0, &d.expression, "mm"));
|
||||
next.add_user_param(&d.name, &d.expression, Some(&unit), None)
|
||||
.map_err(|e| DocError::Invalid(format!("`{} = {}`: {e}", d.name, d.expression)))?;
|
||||
let unit = next.param(&d.name).map(|p| p.unit.clone()).unwrap_or_default();
|
||||
out.push(Defined { name: d.name, expression: d.expression, unit });
|
||||
|
||||
@@ -10,6 +10,7 @@ pub mod appearance_pack;
|
||||
mod assembly;
|
||||
mod body_transfer;
|
||||
mod body_transfer_sheet;
|
||||
mod browser_tree;
|
||||
pub mod pbr_appearance;
|
||||
pub use body_transfer::{valid_transfer_matrix, validate_body_transfer};
|
||||
pub mod canvas;
|
||||
@@ -53,6 +54,8 @@ pub mod physical_material;
|
||||
mod piece_names;
|
||||
pub mod pipe_thread_catalog;
|
||||
pub mod point_cloud;
|
||||
mod point_cloud_complex;
|
||||
pub mod point_cloud_distribution;
|
||||
mod points;
|
||||
mod profile_refs;
|
||||
pub mod progress;
|
||||
@@ -61,6 +64,8 @@ pub use thread_catalog::{TappedThread, TappedThreadFamily, parse_tapped_thread,
|
||||
mod walk;
|
||||
pub use profile_refs::{capture_profile_selection, profile_fallback_notes, profile_selection_indices, profile_selection_indices_lenient};
|
||||
pub mod plastic;
|
||||
mod print_face;
|
||||
pub use print_face::PrintFace;
|
||||
pub mod project;
|
||||
mod project3d;
|
||||
pub mod render_aging;
|
||||
@@ -71,6 +76,7 @@ pub mod render_settings;
|
||||
pub mod render_surface;
|
||||
pub use project3d::iso_grid;
|
||||
pub mod sheet;
|
||||
pub mod sketch_equation;
|
||||
pub mod text_params;
|
||||
|
||||
pub use assembly::{
|
||||
|
||||
@@ -22,7 +22,8 @@ pub struct SavedModel {
|
||||
|
||||
/// Records refer to these at most.
|
||||
const MAX_ITEMS: usize = 1_000_000;
|
||||
/// Bodies, sketches and sheet bodies all the states hold together, at most (a state is a list of clones).
|
||||
/// Bodies, sketches, sheet bodies and sketch keys all the states hold together, at most (a state is
|
||||
/// a list of clones).
|
||||
const MAX_HELD: usize = 50_000_000;
|
||||
/// Longest text a record holds (bytes). A feature's warning can quote every generated name of
|
||||
/// the edges it picked: 122,701 characters in one design, whose saved model was refused, so it
|
||||
@@ -48,6 +49,11 @@ fn unhex(v: &Json) -> Result<u64> {
|
||||
v.as_str().and_then(|s| u64::from_str_radix(s, 16).ok()).ok_or_else(|| bad("saved model: key"))
|
||||
}
|
||||
|
||||
/// A sketch-key set's list `key` (`set` or `drop`).
|
||||
fn keys_list<'a>(set: &'a Json, key: &str) -> Result<&'a Vec<Json>> {
|
||||
set.get(key).and_then(Json::as_array).filter(|l| l.len() <= MAX_ITEMS).ok_or_else(|| bad("saved model: sketch keys"))
|
||||
}
|
||||
|
||||
fn bad(what: &str) -> DocError {
|
||||
DocError::Invalid(what.into())
|
||||
}
|
||||
@@ -128,9 +134,36 @@ struct Writer {
|
||||
sheet_index: HashMap<String, usize>,
|
||||
states: Vec<Json>,
|
||||
state_index: HashMap<usize, usize>,
|
||||
/// The states' sketch keys, each distinct map once, written as the changes from the set
|
||||
/// written before it: every state used to repeat the whole map (one entry per solved sketch),
|
||||
/// 85 % of a 5,484-feature design's records, which then did not fit the cache's manifest.
|
||||
sketch_key_sets: Vec<Json>,
|
||||
sketch_key_index: HashMap<BTreeMap<u64, u64>, usize>,
|
||||
last_sketch_keys: Option<(BTreeMap<u64, u64>, usize)>,
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
/// The place of `keys` among the sketch-key sets, written the first time a state holds them
|
||||
/// (as the changes from the set written last: a later state mostly adds a sketch or two).
|
||||
fn sketch_key_set(&mut self, keys: &BTreeMap<u64, u64>) -> usize {
|
||||
if let Some(i) = self.sketch_key_index.get(keys) {
|
||||
return *i;
|
||||
}
|
||||
let record = match &self.last_sketch_keys {
|
||||
Some((base, at)) => {
|
||||
let set: Vec<Json> = keys.iter().filter(|(f, k)| base.get(f) != Some(k)).map(|(f, k)| json!([f, hex(*k)])).collect();
|
||||
let drop: Vec<u64> = base.keys().filter(|f| !keys.contains_key(f)).copied().collect();
|
||||
json!({"base": at, "set": set, "drop": drop})
|
||||
}
|
||||
None => json!({"set": keys.iter().map(|(f, k)| json!([f, hex(*k)])).collect::<Vec<_>>(), "drop": []}),
|
||||
};
|
||||
self.sketch_key_sets.push(record);
|
||||
let i = self.sketch_key_sets.len() - 1;
|
||||
self.sketch_key_index.insert(keys.clone(), i);
|
||||
self.last_sketch_keys = Some((keys.clone(), i));
|
||||
i
|
||||
}
|
||||
|
||||
fn names(&mut self, b: &ModelBody) -> usize {
|
||||
let id = b.names.id();
|
||||
if let Some(i) = self.names_index.get(&id) {
|
||||
@@ -144,9 +177,6 @@ impl Writer {
|
||||
}
|
||||
|
||||
fn model_body(&mut self, b: &ModelBody) -> Option<usize> {
|
||||
if b.body.is_mesh() {
|
||||
return None;
|
||||
}
|
||||
let key = BodyKey::of(b);
|
||||
if let Some(i) = self.model_body_index.get(&key) {
|
||||
return Some(*i);
|
||||
@@ -216,7 +246,7 @@ impl Writer {
|
||||
"reserved_body_names": st.reserved_body_names.iter().collect::<Vec<_>>(),
|
||||
"sheets": sheets, "construct": serde_json::to_value(&st.construct).ok()?,
|
||||
"threads": serde_json::to_value(&st.threads).ok()?,
|
||||
"sketch_keys": st.sketch_keys.iter().map(|(f, k)| json!([f, hex(*k)])).collect::<Vec<_>>(),
|
||||
"sketch_key_set": self.sketch_key_set(&st.sketch_keys),
|
||||
"blend_edges": serde_json::to_value(&st.blend_edges).ok()?, "fitted": serde_json::to_value(&st.fitted).ok()?,
|
||||
"tapered": serde_json::to_value(&st.tapered).ok()?,
|
||||
});
|
||||
@@ -228,7 +258,7 @@ impl Writer {
|
||||
|
||||
impl Model {
|
||||
/// The model as a design file keeps it: `None` unless it is `doc`'s evaluation without an
|
||||
/// error, holds no mesh bodies, and `doc` keeps no names saved before format 14. Works out
|
||||
/// error and `doc` keeps no names saved before format 14. Works out
|
||||
/// the face names not asked for yet (a saved model keeps them as worked out).
|
||||
pub fn saved(&self, doc: &Document) -> Option<SavedModel> {
|
||||
if self.results.is_empty() || self.results.iter().any(|r| r.error.is_some()) || !self.is_current(doc) || has_legacy_names(doc) {
|
||||
@@ -250,7 +280,7 @@ impl Model {
|
||||
}
|
||||
let records = json!({
|
||||
"features": features, "states": w.states, "model_bodies": w.model_bodies, "names": w.names, "sketches": w.sketches,
|
||||
"sheets": w.sheets,
|
||||
"sheets": w.sheets, "sketch_key_sets": w.sketch_key_sets,
|
||||
});
|
||||
Ok(SavedModel { records, bodies: w.bodies })
|
||||
})
|
||||
@@ -331,9 +361,49 @@ impl SavedModel {
|
||||
for s in list("sheets")? {
|
||||
sheets.push(serde_json::from_value::<crate::sheet::SheetBody>(s.clone()).map_err(|_| bad("saved model: sheet"))?);
|
||||
}
|
||||
let mut states = Vec::new();
|
||||
// The sketch-key sets, each the changes from an earlier one (`base`): a short record can
|
||||
// stand for a large set, so what they hold counts towards MAX_HELD as they are built.
|
||||
let mut key_sets: Vec<BTreeMap<u64, u64>> = Vec::new();
|
||||
let mut held = 0usize;
|
||||
for s in list("states")? {
|
||||
for k in list("sketch_key_sets")? {
|
||||
// A set is the changes from one before it.
|
||||
let base = match k.get("base") {
|
||||
Some(b) => Some(key_sets.get(index(Some(b), key_sets.len())?).ok_or_else(|| bad("saved model: sketch keys"))?),
|
||||
None => None,
|
||||
};
|
||||
let (drop, set) = (keys_list(k, "drop")?, keys_list(k, "set")?);
|
||||
// Counted before the base is copied: at most what the set can hold.
|
||||
held = held.saturating_add(base.map_or(0, BTreeMap::len)).saturating_add(set.len());
|
||||
if held > MAX_HELD {
|
||||
return Err(bad("saved model: sketch keys"));
|
||||
}
|
||||
let mut keys = base.cloned().unwrap_or_default();
|
||||
for f in drop {
|
||||
keys.remove(&f.as_u64().ok_or_else(|| bad("saved model: sketch keys"))?);
|
||||
}
|
||||
for e in set {
|
||||
keys.insert(e.get(0).and_then(Json::as_u64).ok_or_else(|| bad("saved model: sketch keys"))?, unhex(e.get(1).unwrap_or(&Json::Null))?);
|
||||
}
|
||||
key_sets.push(keys);
|
||||
}
|
||||
let records = list("states")?;
|
||||
// What every state holds, counted from its runs and its sketch-key set before any is
|
||||
// built (a hostile file cannot make the states clone more than MAX_HELD items).
|
||||
for s in records {
|
||||
for key in ["bodies", "sketches"] {
|
||||
for run in s.get(key).and_then(Json::as_array).ok_or_else(|| bad("saved model: state"))? {
|
||||
held = held.saturating_add(run.get(1).and_then(Json::as_u64).and_then(|n| usize::try_from(n).ok()).unwrap_or(usize::MAX));
|
||||
}
|
||||
}
|
||||
held = held.saturating_add(s.get("sheets").and_then(Json::as_array).map_or(0, Vec::len));
|
||||
held = held.saturating_add(key_sets.get(index(s.get("sketch_key_set"), key_sets.len())?).map_or(0, BTreeMap::len));
|
||||
if held > MAX_HELD {
|
||||
return Err(bad("saved model: states"));
|
||||
}
|
||||
}
|
||||
// Each state is independent of the others once the records they share are read: built
|
||||
// on threads (a 5,484-feature design spent 3.5 s building them one after another).
|
||||
let built = kernel::map_on_threads(records, 16, |s: &Json| -> Result<ModelState> {
|
||||
// Runs of consecutive indices, each within the list it indexes.
|
||||
let ids = |key: &str, len: usize| -> Result<Vec<usize>> {
|
||||
let mut out = Vec::new();
|
||||
@@ -349,12 +419,8 @@ impl SavedModel {
|
||||
};
|
||||
let field = |key: &str| parse(s.get(key));
|
||||
let invalid = |_| bad("saved model: state");
|
||||
let mut sketch_keys = BTreeMap::new();
|
||||
for k in s.get("sketch_keys").and_then(Json::as_array).ok_or_else(|| bad("saved model: state"))? {
|
||||
sketch_keys
|
||||
.insert(k.get(0).and_then(Json::as_u64).ok_or_else(|| bad("saved model: state"))?, unhex(k.get(1).unwrap_or(&Json::Null))?);
|
||||
}
|
||||
let st = ModelState {
|
||||
let sketch_keys = key_sets.get(index(s.get("sketch_key_set"), key_sets.len())?).cloned().ok_or_else(|| bad("saved model: state"))?;
|
||||
Ok(ModelState {
|
||||
frame_bodies: Default::default(),
|
||||
bodies: ids("bodies", model_bodies.len())?.into_iter().filter_map(|i| model_bodies.get(i).cloned()).collect(),
|
||||
sketches: ids("sketches", sketches.len())?.into_iter().filter_map(|i| sketches.get(i).cloned()).collect(),
|
||||
@@ -377,13 +443,9 @@ impl SavedModel {
|
||||
blend_edges: serde_json::from_value(field("blend_edges")?).map_err(invalid)?,
|
||||
fitted: serde_json::from_value(field("fitted")?).map_err(invalid)?,
|
||||
tapered: serde_json::from_value(field("tapered")?).map_err(invalid)?,
|
||||
};
|
||||
held = held.saturating_add(st.bodies.len()).saturating_add(st.sketches.len()).saturating_add(st.sheets.len());
|
||||
if held > MAX_HELD {
|
||||
return Err(bad("saved model: states"));
|
||||
}
|
||||
states.push(Arc::new(st));
|
||||
}
|
||||
})
|
||||
});
|
||||
let states = built.into_iter().map(|r| r.unwrap_or_else(|| Err(bad("saved model: state"))).map(Arc::new)).collect::<Result<Vec<_>>>()?;
|
||||
Ok(states)
|
||||
}
|
||||
|
||||
@@ -457,7 +519,8 @@ impl SavedModel {
|
||||
let mut stored = std::collections::HashSet::new();
|
||||
// The sheet bodies, each written once and named by place in the states: all kept.
|
||||
let sheets = list("sheets").cloned().unwrap_or_default();
|
||||
let mut used = bytes(sheets.as_slice()).iter().fold(0usize, |t, b| t.saturating_add(*b));
|
||||
let key_sets = list("sketch_key_sets").cloned().unwrap_or_default();
|
||||
let mut used = bytes(sheets.as_slice()).iter().chain(bytes(key_sets.as_slice()).iter()).fold(0usize, |t, b| t.saturating_add(*b));
|
||||
for s in std::iter::once(last).chain(order) {
|
||||
let (mut adds, mut new_names, mut new_sketches) = (HashMap::new(), std::collections::HashSet::new(), std::collections::HashSet::new());
|
||||
let mut records = *state_bytes.get(s)?;
|
||||
@@ -549,7 +612,7 @@ impl SavedModel {
|
||||
}
|
||||
let records = json!({
|
||||
"features": out_features, "states": out_states, "model_bodies": out_bodies, "names": kept_of(names.as_slice(), &names_used),
|
||||
"sketches": kept_of(sketches.as_slice(), &sketches_used), "sheets": sheets,
|
||||
"sketches": kept_of(sketches.as_slice(), &sketches_used), "sheets": sheets, "sketch_key_sets": key_sets,
|
||||
});
|
||||
let kept: Vec<usize> = (0..self.bodies.len()).filter(|i| kernel_used.get(*i) == Some(&true)).collect();
|
||||
let bodies = kept.iter().filter_map(|i| self.bodies.get(*i).cloned()).collect();
|
||||
|
||||
@@ -268,7 +268,7 @@ impl Document {
|
||||
.filter(|(_, _, k)| *k == Kind::Length)
|
||||
.map(|(_, e, _)| {
|
||||
let d = if expr::is_literal(&e) { expr::Defaults::default() } else { expr::Defaults { len: scale, ..expr::Defaults::default() } };
|
||||
expr::eval_with(&e, &look).and_then(|v| v.to_kind_in(Kind::Length, d)).ok()
|
||||
expr::eval_with_defaults(&e, &look, d).and_then(|v| v.to_kind_in(Kind::Length, d)).ok()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -585,7 +585,7 @@ impl Document {
|
||||
}
|
||||
let unit = match unit {
|
||||
Some(u) => u.trim().to_string(),
|
||||
None => Self::infer_unit_in(vals, expr_s),
|
||||
None => Self::infer_unit_in(vals, expr_s, &self.units),
|
||||
};
|
||||
self.params.push(crate::Param {
|
||||
name: name.into(),
|
||||
@@ -696,18 +696,19 @@ impl Document {
|
||||
}
|
||||
|
||||
/// The unit for a new parameter with this expression: that of its value; a bare number is
|
||||
/// a length (mm).
|
||||
/// a length in the design's units, as a typed length reads it (#8865).
|
||||
pub(crate) fn infer_unit(&self, e: &str) -> String {
|
||||
Self::infer_unit_in(&self.param_values().0, e)
|
||||
Self::infer_unit_in(&self.param_values().0, e, &self.units)
|
||||
}
|
||||
|
||||
/// [`Document::infer_unit`] against parameter values already worked out.
|
||||
fn infer_unit_in(vals: &BTreeMap<String, Value>, e: &str) -> String {
|
||||
/// [`Document::infer_unit`] against parameter values already worked out, a length taking
|
||||
/// `units` (the design's, or `mm` where a bare number reads as millimetres).
|
||||
pub(crate) fn infer_unit_in(vals: &BTreeMap<String, Value>, e: &str, units: &str) -> String {
|
||||
let v = expr::eval_with(e, &|n| vals.get(n).copied().ok_or_else(|| DocError::Expr(format!("unknown parameter `{n}`"))));
|
||||
match v.ok().and_then(|v| v.kind()) {
|
||||
Some(Kind::Unitless) if !expr::references(e).is_empty() => String::new(),
|
||||
Some(Kind::Angle) => "deg".into(),
|
||||
_ => "mm".into(),
|
||||
_ => expr::length_unit_or_mm(units).to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,6 +897,18 @@ impl Document {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
// An equation curve's variable hides a parameter of its name: such a parameter is
|
||||
// not what its formulas refer to.
|
||||
for (variable, e) in sketch.equation_exprs_mut() {
|
||||
if variable == old {
|
||||
continue;
|
||||
}
|
||||
let r = expr::rename_reference(e, old, new);
|
||||
if r != *e {
|
||||
*e = r;
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
for e in sketch.text_word_exprs_mut() {
|
||||
let r = crate::text_params::rename_reference(e, old, new);
|
||||
if r != *e {
|
||||
@@ -1137,6 +1150,19 @@ mod design_length_tests {
|
||||
assert_eq!(written("", 5.0), w("mm", "5 mm"));
|
||||
}
|
||||
|
||||
/// A bare number typed as a formula (`=5`) means the design's units like `5` does.
|
||||
#[test]
|
||||
fn a_formula_that_is_a_bare_number_gets_the_design_unit() {
|
||||
let mut doc = Document::new("Units");
|
||||
doc.units = "in".into();
|
||||
let length = crate::expr::Kind::Length;
|
||||
assert_eq!(doc.with_design_unit("5", length), "5 in");
|
||||
assert_eq!(doc.with_design_unit("=5", length), "=5 in");
|
||||
assert_eq!(doc.with_design_unit("=5 mm", length), "=5 mm");
|
||||
let inches = doc.eval(&doc.with_design_unit("=5", length), length).unwrap();
|
||||
assert!((inches - 127.0).abs() < 1e-9, "{inches}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_written_value_reads_back_within_a_micrometre() {
|
||||
for units in ["mm", "cm", "m", "in", "ft"] {
|
||||
|
||||
@@ -152,6 +152,27 @@ pub enum NameError {
|
||||
},
|
||||
}
|
||||
|
||||
/// Whether `text` can be written into a name whole.
|
||||
///
|
||||
/// A curve's id goes into the name of the faces the curve makes (`F2:side:<id>`), and a
|
||||
/// name reads some characters as its own: `|` separates the faces of an edge, `,` the faces
|
||||
/// around a piece, `~` numbers the edges between two faces, `#` numbers a piece and `]`
|
||||
/// closes one. An id holding one of them splits every name it lands in: the id `c|1` gave
|
||||
/// the edges of an extrusion the names `F2:side:c|1#1|F2:side:c|1#2~1`, three separators
|
||||
/// where an edge names two faces and separates them once (#5858).
|
||||
///
|
||||
/// The test is the name's own round trip rather than a list of characters: the text is
|
||||
/// written into a name and read back, and it must read back as itself. A list would have
|
||||
/// to follow every change of the grammar (#5861), and would miss an id that reads back as
|
||||
/// something else (`s1.l4` reads as profile 1 of curve `l4`).
|
||||
pub fn text_fits_name(text: &str) -> bool {
|
||||
let name = format!("F0:side:{text}");
|
||||
match FaceName::parse(&name) {
|
||||
Ok(f) => f.to_string() == name && matches!(&f.base, Base::Made { role: Role::Side { profile: None, curve }, .. } if curve == text),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
impl FaceName {
|
||||
/// The feature that made the face: its base's, a copy's when it is one.
|
||||
pub fn feature(&self) -> Option<FeatureId> {
|
||||
|
||||
@@ -236,3 +236,15 @@ fn hostile_names_never_panic() {
|
||||
// A fillet on an open boundary's edge.
|
||||
assert!(matches!(face("F1:blend:F10:start").base, Base::Blend { rounds: Rounds::Edge(ref e), .. } if e.faces.len() == 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_text_that_cannot_be_written_into_a_name_whole_is_told() {
|
||||
// A curve's id goes into the name of the faces the curve makes, so it has to come
|
||||
// back out of the name as itself (#5858).
|
||||
for good in ["c1", "l4", "s01.l4", "c-1", "c_1", "a.b", "x"] {
|
||||
assert!(text_fits_name(good), "`{good}` fits a name");
|
||||
}
|
||||
for bad in ["c|1", "c,1", "c~1", "c]1", "c#1", "", "s1.l4"] {
|
||||
assert!(!text_fits_name(bad), "`{bad}` does not fit a name");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ fn same_geometry_inputs(a: &Document, b: &Document) -> bool {
|
||||
text_params,
|
||||
next_component_color_index,
|
||||
materials,
|
||||
print_faces,
|
||||
user_materials,
|
||||
appearances,
|
||||
body_components,
|
||||
@@ -162,6 +163,7 @@ fn same_geometry_inputs(a: &Document, b: &Document) -> bool {
|
||||
&& *text_params == b.text_params
|
||||
&& *next_component_color_index == b.next_component_color_index
|
||||
&& *materials == b.materials
|
||||
&& *print_faces == b.print_faces
|
||||
&& *user_materials == b.user_materials
|
||||
&& *appearances == b.appearances
|
||||
&& *body_components == b.body_components
|
||||
|
||||
@@ -11,6 +11,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use solidcraft_geom::Vec3;
|
||||
|
||||
use crate::canvas::{base64_decode, base64_encode};
|
||||
pub use crate::point_cloud_complex::{Column, Complex, Filter, Floats, Keep, MAX_COLUMNS, MAX_NAMES, Names};
|
||||
use crate::{DocError, IDENTITY, Mat, Result};
|
||||
|
||||
/// Most points one cloud may hold.
|
||||
@@ -19,6 +20,10 @@ pub const MAX_POINTS: usize = 20_000_000;
|
||||
pub const MAX_COORD: f64 = 1e9;
|
||||
/// Point sizes on screen (pixels).
|
||||
pub const POINT_SIZE: std::ops::RangeInclusive<f64> = 0.5..=16.0;
|
||||
/// Most filters on one cloud.
|
||||
pub const MAX_FILTERS: usize = 8;
|
||||
/// Properties every cloud has besides its file's: the coordinates in the design.
|
||||
pub const COORDINATES: [&str; 3] = ["x", "y", "z"];
|
||||
/// Length units a point cloud file may be in, and millimetres per unit.
|
||||
pub const UNITS: [(&str, f64); 5] = [("mm", 1.0), ("cm", 10.0), ("m", 1000.0), ("in", 25.4), ("ft", 304.8)];
|
||||
|
||||
@@ -65,6 +70,24 @@ pub struct PointCloud {
|
||||
pub height_range: Option<[f64; 2]>,
|
||||
#[serde(default = "yes")]
|
||||
pub visible: bool,
|
||||
/// The file's other properties of the points.
|
||||
#[serde(default, skip_serializing_if = "Complex::is_empty")]
|
||||
pub complex: Complex,
|
||||
/// The property `color_by: property` colours by.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub color_property: Option<String>,
|
||||
/// Only the points every filter keeps are shown.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub filters: Vec<Filter>,
|
||||
}
|
||||
|
||||
/// Where a property's values come from.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Source<'a> {
|
||||
/// A coordinate of each point in the design.
|
||||
Coordinate(usize),
|
||||
/// A column of the file: each point's.
|
||||
Column(&'a [f32]),
|
||||
}
|
||||
|
||||
/// How a cloud's points are coloured.
|
||||
@@ -78,6 +101,8 @@ pub enum ColorBy {
|
||||
Single,
|
||||
/// By height in the design: blue low, through cyan, green and yellow, to red high.
|
||||
Height,
|
||||
/// By `color_property`: the height ramp over its range or, for whole numbers, a palette.
|
||||
Property,
|
||||
}
|
||||
|
||||
impl ColorBy {
|
||||
@@ -90,6 +115,7 @@ impl ColorBy {
|
||||
"file" => Some(ColorBy::File),
|
||||
"single" => Some(ColorBy::Single),
|
||||
"height" => Some(ColorBy::Height),
|
||||
"property" => Some(ColorBy::Property),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -98,6 +124,7 @@ impl ColorBy {
|
||||
ColorBy::File => "file",
|
||||
ColorBy::Single => "single",
|
||||
ColorBy::Height => "height",
|
||||
ColorBy::Property => "property",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,6 +147,27 @@ pub fn height_ramp(t: f64) -> [u8; 3] {
|
||||
std::array::from_fn(|c| (a[c] * (1.0 - f) + b[c] * f).round().clamp(0.0, 255.0) as u8)
|
||||
}
|
||||
|
||||
/// Colours of whole-number labels, the label modulo their count; negative labels are grey.
|
||||
pub const PALETTE: [[u8; 3]; 10] = [
|
||||
[240, 140, 40],
|
||||
[245, 205, 65],
|
||||
[230, 65, 65],
|
||||
[165, 75, 190],
|
||||
[65, 190, 115],
|
||||
[75, 150, 220],
|
||||
[240, 120, 180],
|
||||
[140, 105, 75],
|
||||
[120, 215, 215],
|
||||
[190, 190, 80],
|
||||
];
|
||||
|
||||
pub fn label_color(v: f64) -> [u8; 3] {
|
||||
if !(v.is_finite() && v >= 0.0) {
|
||||
return PLAIN.map(byte);
|
||||
}
|
||||
PALETTE[(v.round() as usize) % PALETTE.len()]
|
||||
}
|
||||
|
||||
/// A colour channel (0..1) as a byte.
|
||||
pub fn byte(v: f32) -> u8 {
|
||||
(v.clamp(0.0, 1.0) * 255.0).round() as u8
|
||||
@@ -182,15 +230,57 @@ impl PointCloud {
|
||||
let (lo, hi) = (at(HEIGHT_TAIL)?, at(1.0 - HEIGHT_TAIL)?);
|
||||
Some(if hi - lo > 1e-9 { [lo, hi] } else { [lo - 0.5, lo + 0.5] })
|
||||
}
|
||||
/// The property colours come from: a column, or a coordinate (`z` for the height ramp).
|
||||
pub fn colored_property(&self) -> Option<&str> {
|
||||
match self.color_by {
|
||||
ColorBy::Height => Some("z"),
|
||||
ColorBy::Property => self.color_property.as_deref(),
|
||||
ColorBy::File | ColorBy::Single => None,
|
||||
}
|
||||
}
|
||||
/// Where the values of `name` are: a coordinate of each point or a column of the file.
|
||||
pub fn source(&self, name: &str) -> Option<Source<'_>> {
|
||||
if let Some(k) = COORDINATES.iter().position(|n| *n == name) {
|
||||
return Some(Source::Coordinate(k));
|
||||
}
|
||||
self.complex.column(name).map(|col| Source::Column(&col.values.0))
|
||||
}
|
||||
/// Every property the cloud can be coloured and filtered by: its coordinates, then its columns.
|
||||
pub fn property_names(&self) -> impl Iterator<Item = &str> {
|
||||
COORDINATES.into_iter().chain(self.complex.columns.iter().map(|c| c.name.as_str()))
|
||||
}
|
||||
/// The smallest and largest value of a property, the coordinates in the design.
|
||||
pub fn span(&self, property: &str) -> Option<[f64; 2]> {
|
||||
if let Some(span) = self.complex.span(property) {
|
||||
return Some(span);
|
||||
}
|
||||
let k = COORDINATES.iter().position(|n| *n == property)?;
|
||||
let v = self.world_corners()?.map(|p| [p.x, p.y, p.z][k]);
|
||||
Some([v.iter().copied().fold(f64::INFINITY, f64::min), v.iter().copied().fold(f64::NEG_INFINITY, f64::max)])
|
||||
}
|
||||
/// The ramp's range as far as it can be told without the elements: the one set, or else the
|
||||
/// coloured property's span within every range filtering it. The automatic range colouring
|
||||
/// by a property is exactly what the filters keep
|
||||
/// ([`crate::point_cloud_distribution::color_range`]), which this bounds.
|
||||
pub fn color_range(&self) -> Option<[f64; 2]> {
|
||||
if self.height_range.is_some() {
|
||||
return self.height_range;
|
||||
}
|
||||
let property = self.colored_property()?;
|
||||
let span = if self.color_by == ColorBy::Height { self.auto_height_range() } else { self.span(property) }?;
|
||||
let shown =
|
||||
self.filters.iter().filter(|f| f.property == property).filter_map(Filter::range).fold(span, |[lo, hi], [a, b]| [lo.max(a), hi.min(b)]);
|
||||
Some(if shown[0] <= shown[1] { crate::point_cloud_distribution::ramp_range(shown) } else { span })
|
||||
}
|
||||
/// The heights the height ramp runs between now: the cloud's own, else the automatic ones.
|
||||
pub fn height_range_now(&self) -> Option<[f64; 2]> {
|
||||
self.height_range.or_else(|| self.auto_height_range())
|
||||
}
|
||||
/// The colour of each point (by index) as the cloud is shown.
|
||||
pub fn shade(&self) -> impl Fn(usize) -> [u8; 3] + '_ {
|
||||
/// The colour of each point (by index) as the cloud is shown, the ramp over `range`.
|
||||
pub fn shade(&self, range: Option<[f64; 2]>) -> impl Fn(usize) -> [u8; 3] + '_ {
|
||||
let single = self.color.unwrap_or(PLAIN).map(byte);
|
||||
let plain = PLAIN.map(byte);
|
||||
let range = if self.color_by == ColorBy::Height { self.height_range_now() } else { None };
|
||||
let column = self.color_property.as_deref().and_then(|n| self.complex.column(n));
|
||||
move |i| match self.color_by {
|
||||
ColorBy::File => self.colors.get(i).unwrap_or(plain),
|
||||
ColorBy::Single => single,
|
||||
@@ -198,6 +288,14 @@ impl PointCloud {
|
||||
(Some([lo, hi]), Some(p)) => height_ramp((self.world_z(p) - lo) / (hi - lo)),
|
||||
_ => plain,
|
||||
},
|
||||
ColorBy::Property => match (column, column.and_then(|c| c.values.0.get(i))) {
|
||||
(Some(c), Some(v)) if c.integer => label_color(f64::from(*v)),
|
||||
(Some(_), Some(v)) => match range {
|
||||
Some([lo, hi]) if hi > lo => height_ramp((f64::from(*v) - lo) / (hi - lo)),
|
||||
_ => plain,
|
||||
},
|
||||
_ => plain,
|
||||
},
|
||||
}
|
||||
}
|
||||
/// The corners of the box around the points, placed in the design (mm).
|
||||
@@ -240,6 +338,18 @@ impl PointCloud {
|
||||
if !rigid(&self.transform) {
|
||||
return bad("its placement is not a rigid move");
|
||||
}
|
||||
self.complex.check(self.points.len())?;
|
||||
if self.filters.len() > MAX_FILTERS
|
||||
|| self.filters.iter().any(|f| match &f.keep {
|
||||
Keep::Range { range: [lo, hi] } => !(lo.is_finite() && hi.is_finite() && lo <= hi),
|
||||
Keep::Values { values } => values.len() > MAX_NAMES,
|
||||
})
|
||||
{
|
||||
return bad("its filters are not ranges, lowest first");
|
||||
}
|
||||
if self.color_by == ColorBy::Property && self.color_property.is_none() {
|
||||
return bad("it is coloured by a property without naming it");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -422,6 +532,9 @@ mod tests {
|
||||
color: None,
|
||||
height_range: None,
|
||||
visible: true,
|
||||
complex: Complex::default(),
|
||||
color_property: None,
|
||||
filters: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,6 +556,20 @@ mod tests {
|
||||
assert_eq!((unit_scale("M"), unit_scale("yd")), (Some(1000.0), None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_ramp_spans_what_is_shown_unless_set() {
|
||||
let mut c = cloud(vec![0.0; 9], Vec::new());
|
||||
c.complex.columns.push(Column { name: "t".into(), integer: false, values: Floats(vec![0.0, 10.0, 20.0].into()) });
|
||||
(c.color_by, c.color_property) = (ColorBy::Property, Some("t".into()));
|
||||
assert_eq!(c.color_range(), Some([0.0, 20.0]), "the whole span");
|
||||
c.filters = vec![Filter { property: "t".into(), keep: Keep::Range { range: [5.0, 50.0] } }];
|
||||
assert_eq!(c.color_range(), Some([5.0, 20.0]), "the span within the filter");
|
||||
c.filters.push(Filter { property: "layer".into(), keep: Keep::Range { range: [0.0, 1.0] } });
|
||||
assert_eq!(c.color_range(), Some([5.0, 20.0]), "another property's filter changes nothing");
|
||||
c.height_range = Some([1.0, 2.0]);
|
||||
assert_eq!(c.color_range(), Some([1.0, 2.0]), "a range set is kept");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn damaged_clouds_are_refused() {
|
||||
// Not whole points, not finite, not base64.
|
||||
@@ -474,26 +601,26 @@ mod tests {
|
||||
let colors: Vec<u8> = (0..102).flat_map(|i| [i as u8, 7, 9]).collect();
|
||||
let mut c = cloud(values, colors);
|
||||
c.origin = Vec3::ZERO;
|
||||
assert_eq!(c.shade()(3), [3, 7, 9], "the file's colours");
|
||||
assert_eq!(c.shade(c.color_range())(3), [3, 7, 9], "the file's colours");
|
||||
c.colors = Colors::default();
|
||||
assert_eq!(c.shade()(3), PLAIN.map(byte), "none: plain");
|
||||
assert_eq!(c.shade(c.color_range())(3), PLAIN.map(byte), "none: plain");
|
||||
c.color_by = ColorBy::Single;
|
||||
c.color = Some([1.0, 0.5, 0.0]);
|
||||
assert_eq!(c.shade()(50), [255, 128, 0]);
|
||||
assert_eq!(c.shade(c.color_range())(50), [255, 128, 0]);
|
||||
// The stray point doesn't stretch the automatic range.
|
||||
c.color_by = ColorBy::Height;
|
||||
// 102 points: the 2nd and the 99th (of 0…101) once sorted.
|
||||
assert_eq!(c.auto_height_range(), Some([2.0, 99.0]));
|
||||
{
|
||||
let shade = c.shade();
|
||||
let shade = c.shade(c.color_range());
|
||||
assert_eq!((shade(0), shade(100), shade(101)), (height_ramp(0.0), height_ramp(1.0), height_ramp(1.0)));
|
||||
assert_eq!(shade(50), height_ramp(48.0 / 97.0));
|
||||
}
|
||||
// A range of its own; moved up 100 mm, everything is above it.
|
||||
c.height_range = Some([0.0, 50.0]);
|
||||
assert_eq!(c.shade()(25), height_ramp(0.5));
|
||||
assert_eq!(c.shade(c.color_range())(25), height_ramp(0.5));
|
||||
c.transform[3][2] = 100.0;
|
||||
assert_eq!(c.shade()(0), height_ramp(1.0));
|
||||
assert_eq!(c.shade(c.color_range())(0), height_ramp(1.0));
|
||||
assert_eq!((height_ramp(0.0), height_ramp(1.0), height_ramp(f64::NAN)), ([40, 70, 200], [230, 70, 50], [40, 70, 200]));
|
||||
let back: PointCloud = serde_json::from_str(&serde_json::to_string(&c).unwrap()).unwrap();
|
||||
assert_eq!(back, c);
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
//! What a point cloud holds besides its points' places and colours: named numbers on its points
|
||||
//! (a PLY file's other vertex properties), to colour the cloud by and to filter it with. Whole
|
||||
//! numbers may have names (`role: 0 outer wall, 1 inner wall` in a PLY file's comments): they
|
||||
//! are labels, filtered by a set of values rather than a range.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::canvas::{base64_decode, base64_encode};
|
||||
use crate::point_cloud::MAX_POINTS;
|
||||
use crate::{DocError, Result};
|
||||
|
||||
/// Most named numbers per point.
|
||||
pub const MAX_COLUMNS: usize = 64;
|
||||
|
||||
/// One named number on every point.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Column {
|
||||
pub name: String,
|
||||
/// Whole numbers (labels, counts): coloured by a palette rather than a ramp.
|
||||
#[serde(default)]
|
||||
pub integer: bool,
|
||||
pub values: Floats,
|
||||
}
|
||||
|
||||
impl Column {
|
||||
/// The smallest and largest finite value.
|
||||
pub fn span(&self) -> Option<[f64; 2]> {
|
||||
let mut it = self.values.0.iter().filter(|v| v.is_finite()).map(|v| f64::from(*v));
|
||||
let first = it.next()?;
|
||||
Some(it.fold([first, first], |[lo, hi], v| [lo.min(v), hi.max(v)]))
|
||||
}
|
||||
}
|
||||
|
||||
/// The complex a cloud's points form: named numbers on the points, and the names of
|
||||
/// whole-numbered ones. Points alone are a complex of dimension 0.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Complex {
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub columns: Vec<Column>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub names: Vec<Names>,
|
||||
}
|
||||
|
||||
/// Most named values of one label.
|
||||
pub const MAX_NAMES: usize = 256;
|
||||
|
||||
/// The names of a label's values.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Names {
|
||||
pub property: String,
|
||||
pub values: Vec<(i32, String)>,
|
||||
}
|
||||
|
||||
impl Names {
|
||||
/// `property: 0 name, 1 another name, -1 none`, or `None` for any other text.
|
||||
pub fn parse(text: &str) -> Option<Names> {
|
||||
let (property, rest) = text.split_once(':')?;
|
||||
let property = property.trim();
|
||||
if property.is_empty() || property.contains(char::is_whitespace) {
|
||||
return None;
|
||||
}
|
||||
let values = rest
|
||||
.split(',')
|
||||
.map(|entry| {
|
||||
let (value, name) = entry.trim().split_once(' ')?;
|
||||
let name = name.trim();
|
||||
(!name.is_empty()).then(|| Some((value.parse::<i32>().ok()?, name.to_string()))).flatten()
|
||||
})
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
(!values.is_empty() && values.len() <= MAX_NAMES).then(|| Names { property: property.to_string(), values })
|
||||
}
|
||||
pub fn name(&self, value: i32) -> Option<&str> {
|
||||
self.values.iter().find(|(v, _)| *v == value).map(|(_, n)| n.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Complex {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.columns.is_empty() && self.names.is_empty()
|
||||
}
|
||||
/// The column named `name`.
|
||||
pub fn column(&self, name: &str) -> Option<&Column> {
|
||||
self.columns.iter().find(|c| c.name == name)
|
||||
}
|
||||
/// The smallest and largest value named `name`.
|
||||
pub fn span(&self, name: &str) -> Option<[f64; 2]> {
|
||||
self.column(name).and_then(Column::span)
|
||||
}
|
||||
/// The names of `property`'s values, when it is a label.
|
||||
pub fn names(&self, property: &str) -> Option<&Names> {
|
||||
self.names.iter().find(|n| n.property == property).filter(|_| self.integer(property))
|
||||
}
|
||||
/// Whether the values named `name` are whole numbers.
|
||||
pub fn integer(&self, name: &str) -> bool {
|
||||
self.column(name).is_some_and(|c| c.integer)
|
||||
}
|
||||
/// Every column has one number per point, the cloud having `points` points.
|
||||
pub fn check(&self, points: usize) -> Result<()> {
|
||||
let bad = |what: String| Err(DocError::Invalid(format!("point cloud properties: {what}")));
|
||||
if self.columns.len() > MAX_COLUMNS {
|
||||
return bad("too many properties".into());
|
||||
}
|
||||
for c in &self.columns {
|
||||
if c.values.0.len() != points {
|
||||
return bad(format!("property `{}` does not have one number per point", c.name));
|
||||
}
|
||||
}
|
||||
if self.names.len() > MAX_COLUMNS || self.names.iter().any(|n| n.values.is_empty() || n.values.len() > MAX_NAMES) {
|
||||
return bad("too many named values".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Which points are shown: those whose property lies in a range (both ends included), or, for a
|
||||
/// label, is one of a set of values.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Filter {
|
||||
pub property: String,
|
||||
#[serde(flatten)]
|
||||
pub keep: Keep,
|
||||
}
|
||||
|
||||
/// The values a filter keeps.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Keep {
|
||||
Range { range: [f64; 2] },
|
||||
Values { values: Vec<i32> },
|
||||
}
|
||||
|
||||
impl Filter {
|
||||
pub fn range(&self) -> Option<[f64; 2]> {
|
||||
match &self.keep {
|
||||
Keep::Range { range } => Some(*range),
|
||||
Keep::Values { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Numbers, shared between copies of the design.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Floats(pub Arc<[f32]>);
|
||||
|
||||
impl PartialEq for Floats {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.0, &other.0) || self.0.iter().map(|v| v.to_bits()).eq(other.0.iter().map(|v| v.to_bits()))
|
||||
}
|
||||
}
|
||||
|
||||
/// The largest base64 text of `n` four-byte words.
|
||||
fn base64_len(n: usize) -> usize {
|
||||
(n * 4).div_ceil(3) * 4 + 16
|
||||
}
|
||||
|
||||
fn words<'de, D: Deserializer<'de>>(d: D, max: usize) -> std::result::Result<Vec<[u8; 4]>, D::Error> {
|
||||
let s = String::deserialize(d)?;
|
||||
if s.len() > base64_len(max) {
|
||||
return Err(serde::de::Error::custom("too many numbers"));
|
||||
}
|
||||
let b = base64_decode(&s).ok_or_else(|| serde::de::Error::custom("numbers are not base64"))?;
|
||||
if !b.len().is_multiple_of(4) {
|
||||
return Err(serde::de::Error::custom("numbers are not whole four-byte words"));
|
||||
}
|
||||
Ok(b.as_chunks::<4>().0.to_vec())
|
||||
}
|
||||
|
||||
impl Serialize for Floats {
|
||||
fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
|
||||
s.serialize_str(&base64_encode(&self.0.iter().flat_map(|v| v.to_le_bytes()).collect::<Vec<u8>>()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Floats {
|
||||
fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
||||
Ok(Floats(words(d, MAX_POINTS)?.into_iter().map(f32::from_le_bytes).collect()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn properties_round_trip_and_are_checked_against_the_points() {
|
||||
let complex = Complex {
|
||||
columns: vec![
|
||||
Column { name: "t".into(), integer: false, values: Floats(vec![0.0, 0.5, 1.0].into()) },
|
||||
Column { name: "role".into(), integer: true, values: Floats(vec![0.0, 4.0, 4.0].into()) },
|
||||
],
|
||||
names: Vec::new(),
|
||||
};
|
||||
let back: Complex = serde_json::from_str(&serde_json::to_string(&complex).unwrap()).unwrap();
|
||||
assert_eq!(back, complex);
|
||||
complex.check(3).unwrap();
|
||||
assert!(complex.check(2).is_err(), "three numbers for two points");
|
||||
assert_eq!(complex.span("role"), Some([0.0, 4.0]));
|
||||
assert!(complex.integer("role") && !complex.integer("t") && !complex.integer("nope"));
|
||||
// Named values make a label, and a filter keeps a range or a set of them.
|
||||
let names = Names::parse("role: 0 outer wall, 4 bridge, -1 none").unwrap();
|
||||
assert_eq!((names.name(4), names.name(-1), names.name(2)), (Some("bridge"), Some("none"), None));
|
||||
for text in ["t: seconds since the start", "role 0 wall", ": 0 a", "role: x wall", "role: 0 "] {
|
||||
assert!(Names::parse(text).is_none(), "{text}");
|
||||
}
|
||||
let mut named = complex.clone();
|
||||
named.names = vec![names, Names::parse("t: 0 zero").unwrap()];
|
||||
assert!(named.names("role").is_some() && named.names("t").is_none(), "only whole numbers are labels");
|
||||
let set: Filter = serde_json::from_str(r#"{"property": "role", "values": [0, 4]}"#).unwrap();
|
||||
let range: Filter = serde_json::from_str(r#"{"property": "t", "range": [1, 3]}"#).unwrap();
|
||||
assert_eq!((set.range(), range.range()), (None, Some([1.0, 3.0])));
|
||||
assert_eq!(serde_json::to_value(&set).unwrap(), serde_json::json!({"property": "role", "values": [0, 4]}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
//! How much of a point cloud lies at each value of one of its properties, over what its filters
|
||||
//! keep: the histograms the Edit Point Cloud card draws in its range tracks, split into the
|
||||
//! colours the view draws, and the values where a label changes along a property, which the
|
||||
//! tracks snap to.
|
||||
//!
|
||||
//! Each point weighs the same, the cloud weighing 1. A range filter keeps the points between its
|
||||
//! ends, as the view does; a filter by values keeps those whose rounded value it holds; the
|
||||
//! colour sorts the points kept into the colours they are drawn in. The values the points kept
|
||||
//! take, from the least to the greatest, are the ramp's automatic range: the colours span exactly
|
||||
//! what is shown.
|
||||
|
||||
use crate::point_cloud::{ColorBy, Filter, Keep, PALETTE, PointCloud, Source};
|
||||
|
||||
/// Most bins of one histogram.
|
||||
pub const MAX_BINS: usize = 8192;
|
||||
|
||||
/// What the histograms need of a cloud's geometry, worked out once for its points.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Geometry {
|
||||
/// Each point in the design.
|
||||
world: Vec<[f64; 3]>,
|
||||
}
|
||||
|
||||
impl Geometry {
|
||||
pub fn of(c: &PointCloud) -> Geometry {
|
||||
Geometry { world: (0..c.len()).map(|i| c.world_point(i).map_or([0.0; 3], |p| [p.x, p.y, p.z])).collect() }
|
||||
}
|
||||
}
|
||||
|
||||
/// How a histogram is split by colour, into slots; the last slot holds what has no value to be
|
||||
/// coloured by.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Colour<'a> {
|
||||
/// One colour.
|
||||
One,
|
||||
/// The ramp over `range` of `property`, in `bands` equal bands; below and above the range
|
||||
/// count with the first and the last.
|
||||
Ramp { property: &'a str, range: [f64; 2], bands: usize },
|
||||
/// The palette of a whole-numbered `property`: a slot per colour of [`PALETTE`], then one
|
||||
/// for negative values.
|
||||
Palette { property: &'a str },
|
||||
}
|
||||
|
||||
impl Colour<'_> {
|
||||
/// How many slots the histogram has.
|
||||
pub fn slots(&self) -> usize {
|
||||
match self {
|
||||
Colour::One => 1,
|
||||
Colour::Ramp { bands, .. } => bands + 1,
|
||||
Colour::Palette { .. } => PALETTE.len() + 2,
|
||||
}
|
||||
}
|
||||
fn property(&self) -> Option<&str> {
|
||||
match self {
|
||||
Colour::One => None,
|
||||
Colour::Ramp { property, .. } | Colour::Palette { property } => Some(property),
|
||||
}
|
||||
}
|
||||
/// How a property's values are cut into bands, and the slot of each band.
|
||||
fn cut(&self) -> Option<Cut> {
|
||||
match *self {
|
||||
Colour::One => None,
|
||||
Colour::Ramp { range: [lo, hi], bands, .. } => Some(Cut::Grid { start: lo, step: (hi - lo) / bands as f64, count: bands + 1 }),
|
||||
Colour::Palette { .. } => Some(INTEGERS),
|
||||
}
|
||||
}
|
||||
fn slot(&self, band: usize) -> usize {
|
||||
match *self {
|
||||
Colour::One => 0,
|
||||
Colour::Ramp { bands, .. } => band.saturating_sub(1).min(bands.saturating_sub(1)),
|
||||
Colour::Palette { .. } => match integer(band) {
|
||||
Some(v) if v >= 0 => v as usize % PALETTE.len(),
|
||||
_ => PALETTE.len(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// How much lies in each bin, by colour slot.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Histogram {
|
||||
pub bins: usize,
|
||||
/// `slots[s][b]`: the measure of slot `s` in bin `b`.
|
||||
pub slots: Vec<Vec<f64>>,
|
||||
/// The least and the greatest value the points kept take, within the axis or not.
|
||||
pub extent: Option<[f64; 2]>,
|
||||
}
|
||||
|
||||
/// Where values are cut into bands, by increasing values.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum Cut {
|
||||
/// Below (band 0), within (1, both ends included) and above (2) a range.
|
||||
Range([f64; 2]),
|
||||
/// `count` values `start + k·step`: band 0 lies below the first, band `k` from the `k`th on.
|
||||
Grid { start: f64, step: f64, count: usize },
|
||||
}
|
||||
|
||||
/// The bands of whole numbers: band `k` holds the values rounding to `k - 2³¹`.
|
||||
const INTEGERS: Cut = Cut::Grid { start: 0.5 - 2_147_483_648.0, step: 1.0, count: u32::MAX as usize };
|
||||
|
||||
/// The whole number a band of [`INTEGERS`] holds.
|
||||
fn integer(band: usize) -> Option<i64> {
|
||||
i64::try_from(band).ok().map(|k| k - 2_147_483_648)
|
||||
}
|
||||
|
||||
impl Cut {
|
||||
fn band(&self, v: f64) -> usize {
|
||||
match *self {
|
||||
Cut::Range([a, b]) => usize::from(v >= a) + usize::from(v > b),
|
||||
Cut::Grid { start, step, count } => {
|
||||
if !(v >= start) {
|
||||
return 0;
|
||||
}
|
||||
(((v - start) / step).floor() as usize).saturating_add(1).min(count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A filter as a cut and the bands it keeps.
|
||||
struct Kept<'a> {
|
||||
cut: Cut,
|
||||
values: Option<&'a [i32]>,
|
||||
}
|
||||
|
||||
impl Kept<'_> {
|
||||
fn of(f: &Filter) -> Kept<'_> {
|
||||
match &f.keep {
|
||||
Keep::Range { range } => Kept { cut: Cut::Range(*range), values: None },
|
||||
Keep::Values { values } => Kept { cut: INTEGERS, values: Some(values) },
|
||||
}
|
||||
}
|
||||
fn keeps(&self, v: f64) -> bool {
|
||||
let band = self.cut.band(v);
|
||||
match self.values {
|
||||
None => band == 1,
|
||||
Some(values) => integer(band).is_some_and(|v| values.iter().any(|k| i64::from(*k) == v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The value of `s` at point `i`.
|
||||
fn value(s: Source, i: usize, world: &[[f64; 3]]) -> f64 {
|
||||
match s {
|
||||
Source::Coordinate(k) => world.get(i).and_then(|p| p.get(k)).copied().unwrap_or(f64::NAN),
|
||||
Source::Column(v) => v.get(i).map_or(f64::NAN, |x| f64::from(*x)),
|
||||
}
|
||||
}
|
||||
|
||||
/// How much of the cloud lies in each of `bins` bins over `axis` of `property`, by `colour`,
|
||||
/// within every one of `filters`; `None` for an axis or a number of bins it can't have.
|
||||
pub fn histogram(
|
||||
c: &PointCloud,
|
||||
g: &Geometry,
|
||||
property: &str,
|
||||
axis: [f64; 2],
|
||||
bins: usize,
|
||||
colour: &Colour,
|
||||
filters: &[Filter],
|
||||
) -> Option<Histogram> {
|
||||
if !(axis[0].is_finite() && axis[1].is_finite() && axis[1] > axis[0]) || bins == 0 || bins > MAX_BINS {
|
||||
return None;
|
||||
}
|
||||
if let Colour::Ramp { range: [lo, hi], bands, .. } = *colour
|
||||
&& !(hi > lo && bands > 0 && bands <= MAX_BINS)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let slots = colour.slots();
|
||||
let mut out = vec![vec![0.0; bins]; slots];
|
||||
let mut extent = None;
|
||||
let Some(p) = c.source(property) else { return Some(Histogram { bins, slots: out, extent }) };
|
||||
// A point is not filtered by a property the cloud doesn't have, as in the view.
|
||||
let kept: Vec<(Kept, Source)> = filters.iter().filter_map(|f| Some((Kept::of(f), c.source(&f.property)?))).collect();
|
||||
let coloured = colour.property().and_then(|n| c.source(n));
|
||||
let (colour_cut, plain) = (colour.cut(), slots - 1);
|
||||
let m = 1.0 / g.world.len().max(1) as f64;
|
||||
let width = (axis[1] - axis[0]) / bins as f64;
|
||||
for i in 0..g.world.len() {
|
||||
if !kept.iter().all(|(k, s)| k.keeps(value(*s, i, &g.world))) {
|
||||
continue;
|
||||
}
|
||||
let v = value(p, i, &g.world);
|
||||
if !v.is_finite() {
|
||||
continue;
|
||||
}
|
||||
extent = Some(extent.map_or([v, v], |[lo, hi]: [f64; 2]| [lo.min(v), hi.max(v)]));
|
||||
if !(v >= axis[0] && v <= axis[1]) {
|
||||
continue;
|
||||
}
|
||||
let slot = match (colour_cut, coloured) {
|
||||
(Some(cut), Some(s)) => colour.slot(cut.band(value(s, i, &g.world))),
|
||||
(Some(_), None) => plain,
|
||||
(None, _) => 0,
|
||||
};
|
||||
// The last bin holds the axis' upper end too.
|
||||
let bin = (((v - axis[0]) / width).floor() as usize).min(bins - 1);
|
||||
if let Some(b) = out.get_mut(slot).and_then(|s| s.get_mut(bin)) {
|
||||
*b += m;
|
||||
}
|
||||
}
|
||||
Some(Histogram { bins, slots: out, extent })
|
||||
}
|
||||
|
||||
/// A range for a ramp from the values it spans: a single value gets one unit around it.
|
||||
pub fn ramp_range([lo, hi]: [f64; 2]) -> [f64; 2] {
|
||||
if hi > lo { [lo, hi] } else { [lo - 0.5, lo + 0.5] }
|
||||
}
|
||||
|
||||
/// The ramp's range: the one set; else, coloured by a property, exactly the values it takes over
|
||||
/// what `filters` keep (the cloud's own bound, [`PointCloud::color_range`], when nothing is
|
||||
/// kept); coloured by height, the cloud's own (its points but the highest and lowest few).
|
||||
pub fn color_range(c: &PointCloud, g: &Geometry, filters: &[Filter]) -> Option<[f64; 2]> {
|
||||
color_range_by(c, |property, axis| histogram(c, g, property, axis, 1, &Colour::One, filters).and_then(|h| h.extent))
|
||||
}
|
||||
|
||||
/// [`color_range`], with the values the coloured property takes over what is kept given by
|
||||
/// `extent` (of the property and an axis over its span): worked out elsewhere, or not yet.
|
||||
pub fn color_range_by(c: &PointCloud, extent: impl FnOnce(&str, [f64; 2]) -> Option<[f64; 2]>) -> Option<[f64; 2]> {
|
||||
let property = c.colored_property()?;
|
||||
if c.height_range.is_some() || c.color_by != ColorBy::Property {
|
||||
return c.color_range();
|
||||
}
|
||||
let axis = ramp_range(c.span(property)?);
|
||||
extent(property, axis).map(ramp_range).or_else(|| c.color_range())
|
||||
}
|
||||
|
||||
/// The values of `property` where the whole-numbered `label` changes, point after point in order
|
||||
/// of `property`, lowest first.
|
||||
pub fn label_changes(c: &PointCloud, g: &Geometry, label: &str, property: &str) -> Vec<f64> {
|
||||
let (Some(p), Some(l)) = (c.source(property), c.source(label)) else { return Vec::new() };
|
||||
let mut at: Vec<(f64, i64)> = (0..g.world.len())
|
||||
.filter_map(|i| {
|
||||
let (v, l) = (value(p, i, &g.world), value(l, i, &g.world));
|
||||
v.is_finite().then(|| (v, if l.is_finite() { l.round() as i64 } else { i64::MIN }))
|
||||
})
|
||||
.collect();
|
||||
at.sort_by(|a, b| a.0.total_cmp(&b.0));
|
||||
let mut out: Vec<f64> = at.windows(2).filter(|w| w[0].1 != w[1].1).map(|w| w[1].0).collect();
|
||||
out.dedup();
|
||||
out
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "point_cloud_distribution_tests.rs"]
|
||||
mod tests;
|
||||
@@ -0,0 +1,125 @@
|
||||
use solidcraft_geom::Vec3;
|
||||
|
||||
use super::*;
|
||||
use crate::IDENTITY;
|
||||
use crate::point_cloud::{ColorBy, Colors, Column, Complex, Floats, Points};
|
||||
|
||||
/// A cloud of `points` with `columns` on them.
|
||||
fn cloud(points: &[[f32; 3]], columns: Vec<Column>) -> PointCloud {
|
||||
PointCloud {
|
||||
id: 1,
|
||||
name: "c".into(),
|
||||
file: String::new(),
|
||||
origin: Vec3::new(0.0, 0.0, 0.0),
|
||||
points: Points::new(points.iter().flatten().copied().collect::<Vec<f32>>().into()),
|
||||
colors: Colors::default(),
|
||||
source_points: points.len() as u64,
|
||||
units: "mm".into(),
|
||||
transform: IDENTITY,
|
||||
point_size: 2.0,
|
||||
color_by: ColorBy::File,
|
||||
color: None,
|
||||
height_range: None,
|
||||
visible: true,
|
||||
complex: Complex { columns, names: Vec::new() },
|
||||
color_property: None,
|
||||
filters: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn column(name: &str, integer: bool, values: &[f32]) -> Column {
|
||||
Column { name: name.into(), integer, values: Floats(values.to_vec().into()) }
|
||||
}
|
||||
|
||||
fn range(property: &str, range: [f64; 2]) -> Filter {
|
||||
Filter { property: property.into(), keep: Keep::Range { range } }
|
||||
}
|
||||
|
||||
fn close(a: &[f64], b: &[f64]) -> bool {
|
||||
a.len() == b.len() && a.iter().zip(b).all(|(x, y)| (x - y).abs() < 1e-9)
|
||||
}
|
||||
|
||||
/// Ten points along x, `t` the same as x.
|
||||
fn row() -> PointCloud {
|
||||
let points: Vec<[f32; 3]> = (0..10).map(|i| [i as f32 + 0.5, 0.0, 0.0]).collect();
|
||||
let t: Vec<f32> = points.iter().map(|p| p[0]).collect();
|
||||
cloud(&points, vec![column("t", false, &t)])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_point_weighs_alike_and_a_range_keeps_those_within_it() {
|
||||
let c = row();
|
||||
let g = Geometry::of(&c);
|
||||
let all = histogram(&c, &g, "t", [0.0, 10.0], 5, &Colour::One, &[]).unwrap();
|
||||
assert!(close(&all.slots[0], &[0.2; 5]));
|
||||
// Kept from t = 2 to 5: three points, ends included.
|
||||
let kept = histogram(&c, &g, "t", [0.0, 10.0], 5, &Colour::One, &[range("t", [2.0, 5.0])]).unwrap();
|
||||
assert!(close(&kept.slots[0], &[0.0, 0.2, 0.1, 0.0, 0.0]));
|
||||
// Filtered by another property: x from 0 to 4 keeps t from 0 to 4.
|
||||
let by_x = histogram(&c, &g, "t", [0.0, 10.0], 5, &Colour::One, &[range("x", [0.0, 4.0])]).unwrap();
|
||||
assert!(close(&by_x.slots[0], &[0.2, 0.2, 0.0, 0.0, 0.0]));
|
||||
// A filter on a property the cloud doesn't have keeps everything, as in the view.
|
||||
assert_eq!(histogram(&c, &g, "t", [0.0, 10.0], 5, &Colour::One, &[range("nope", [0.0, 1.0])]), Some(all));
|
||||
// An axis or a number of bins it can't have.
|
||||
for (axis, bins) in [([1.0, 1.0], 4), ([0.0, f64::NAN], 4), ([0.0, 1.0], 0), ([0.0, 1.0], MAX_BINS + 1)] {
|
||||
assert!(histogram(&c, &g, "t", axis, bins, &Colour::One, &[]).is_none());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn colours_split_what_is_kept() {
|
||||
// Four points, roles 0, 3, 3 and -1, t from 0 to 3.
|
||||
let c = cloud(
|
||||
&[[0.0; 3], [1.0, 0.0, 0.0], [2.0, 0.0, 0.0], [3.0, 0.0, 0.0]],
|
||||
vec![column("t", false, &[0.0, 1.0, 2.0, 3.0]), column("role", true, &[0.0, 3.0, 3.0, -1.0])],
|
||||
);
|
||||
let g = Geometry::of(&c);
|
||||
let colour = Colour::Palette { property: "role" };
|
||||
let h = histogram(&c, &g, "t", [0.0, 4.0], 4, &colour, &[]).unwrap();
|
||||
assert_eq!(h.slots.len(), colour.slots());
|
||||
assert!(close(&h.slots[0], &[0.25, 0.0, 0.0, 0.0]));
|
||||
assert!(close(&h.slots[3], &[0.0, 0.25, 0.25, 0.0]));
|
||||
assert!(close(&h.slots[PALETTE.len()], &[0.0, 0.0, 0.0, 0.25]), "a negative label");
|
||||
// A filter by values keeps role 3 only.
|
||||
let three = Filter { property: "role".into(), keep: Keep::Values { values: vec![3] } };
|
||||
let kept = histogram(&c, &g, "t", [0.0, 4.0], 4, &colour, &[three]).unwrap();
|
||||
let total: f64 = kept.slots.iter().flatten().sum();
|
||||
assert!((total - 0.5).abs() < 1e-9 && close(&kept.slots[3], &h.slots[3]));
|
||||
// A ramp over t in two bands, and coloured by a property the cloud doesn't have: plain.
|
||||
let ramp = Colour::Ramp { property: "t", range: [0.0, 4.0], bands: 2 };
|
||||
let r = histogram(&c, &g, "t", [0.0, 4.0], 4, &ramp, &[]).unwrap();
|
||||
assert!(close(&r.slots[0], &[0.25, 0.25, 0.0, 0.0]) && close(&r.slots[1], &[0.0, 0.0, 0.25, 0.25]));
|
||||
let none = histogram(&c, &g, "t", [0.0, 4.0], 4, &Colour::Palette { property: "nope" }, &[]).unwrap();
|
||||
assert!(close(&none.slots[PALETTE.len() + 1], &[0.25; 4]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn labels_change_where_the_next_point_has_another() {
|
||||
// Six points in order of t, layers 0 0 1 1 2 2.
|
||||
let points: Vec<[f32; 3]> = (0..6).map(|i| [i as f32, 0.0, 0.0]).collect();
|
||||
let c = cloud(&points, vec![column("t", false, &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0]), column("layer", true, &[0.0, 0.0, 1.0, 1.0, 2.0, 2.0])]);
|
||||
let g = Geometry::of(&c);
|
||||
assert_eq!(label_changes(&c, &g, "layer", "t"), vec![2.0, 4.0]);
|
||||
assert!(label_changes(&c, &g, "nope", "t").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_automatic_range_is_what_every_filter_keeps() {
|
||||
// Filtered by x from 2 to 4, coloured by t: the range is what is kept of t, though no filter
|
||||
// is on t (its span within filters on t would be all of it).
|
||||
let mut c = cloud(&[[0.0, 0.0, 0.0], [2.0, 0.0, 0.0], [4.0, 0.0, 0.0], [20.0, 0.0, 0.0]], vec![column("t", false, &[0.0, 3.0, 5.0, 7.0])]);
|
||||
c.color_by = ColorBy::Property;
|
||||
c.color_property = Some("t".into());
|
||||
let g = Geometry::of(&c);
|
||||
let x = [range("x", [2.0, 4.0])];
|
||||
assert_eq!(c.color_range(), Some([0.0, 7.0]));
|
||||
assert_eq!(color_range(&c, &g, &x), Some([3.0, 5.0]));
|
||||
// The point at x = 20 alone: one value, one unit wide.
|
||||
assert_eq!(color_range(&c, &g, &[range("x", [19.0, 21.0])]), Some([6.5, 7.5]));
|
||||
// Nothing kept: the cloud's own bound; a range set is kept as it is.
|
||||
assert_eq!(color_range(&c, &g, &[range("x", [50.0, 60.0])]), Some([0.0, 7.0]));
|
||||
c.height_range = Some([1.0, 2.0]);
|
||||
assert_eq!(color_range(&c, &g, &x), Some([1.0, 2.0]));
|
||||
let h = histogram(&c, &g, "t", [0.0, 1.0], 4, &Colour::One, &x).unwrap();
|
||||
assert_eq!(h.extent, Some([3.0, 5.0]), "the extent reaches past the axis");
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
//! The print face: the flat face of a body that a slicer export lays on the print bed (#8429).
|
||||
//! A body has at most one (`Document::print_faces`, by body name). It is held by the target a
|
||||
//! sketch on a face holds ([`Document::flat_face_target`]), so a rebuild that adds, removes or
|
||||
//! reorders faces finds the same face again, or says it is gone.
|
||||
|
||||
use solidcraft_geom::Vec3;
|
||||
|
||||
use crate::config::ConfigFaceTarget;
|
||||
use crate::{DocError, Document, ModelBody, ModelState, Result};
|
||||
|
||||
/// Where a print face is: a point on it and its outward unit normal, in the coordinates of the
|
||||
/// body it was found on.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct PrintFace {
|
||||
/// The face's index on the body (its first piece, when a change split it).
|
||||
pub index: usize,
|
||||
pub point: Vec3,
|
||||
pub normal: Vec3,
|
||||
}
|
||||
|
||||
impl Document {
|
||||
/// The target that marks flat face `index` of `body` as its print face.
|
||||
pub fn print_face_target(&self, body: &ModelBody, index: usize) -> Result<ConfigFaceTarget> {
|
||||
if body.body.is_mesh() {
|
||||
return Err(DocError::Invalid("not supported yet: a print face on a mesh body".into()));
|
||||
}
|
||||
if body.body.planar_face(index).is_none() {
|
||||
return Err(DocError::Invalid("only a flat face can be the print face".into()));
|
||||
}
|
||||
// The sketch-on-a-face wording ("choose a fixed plane") offers what a print face has not.
|
||||
self.flat_face_target(body, index).map_err(|_| {
|
||||
DocError::Invalid(
|
||||
"this face can't be the print face: the body's history no longer tells it apart from its other faces (as after a shell of a shell body); pick a face of another body, or edit the feature that reshaped it".into(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Where `body`'s print face is now. `None`: it has none. An error: the face can't be found
|
||||
/// any more, or is no longer flat.
|
||||
pub fn print_face(&self, state: &ModelState, body: &ModelBody) -> Option<Result<PrintFace>> {
|
||||
let target = self.print_faces.get(body.definition_name())?;
|
||||
Some(self.locate_print_face(state, body, target))
|
||||
}
|
||||
|
||||
/// The print face a copy of `source` gets (Move/Copy, Mirror): the face of `copy` named after
|
||||
/// `source`'s print face (a copy's faces carry their source's names, followed by the copy's
|
||||
/// instance, `F1:+x@F2.1`). `None`:
|
||||
/// `source` has no print face.
|
||||
pub fn copied_print_face(&self, state: &ModelState, source: &ModelBody, copy: &ModelBody) -> Option<Result<ConfigFaceTarget>> {
|
||||
let target = self.print_faces.get(source.definition_name())?;
|
||||
let found = || {
|
||||
let (indices, _) = self.anchored_face_indices(state, source, target)?;
|
||||
let first = indices.first().copied().ok_or_else(|| DocError::Unknown("the print face no longer exists".into()))?;
|
||||
let names = crate::naming::face_names(source);
|
||||
let name =
|
||||
names.get(first).map(|n| crate::naming::strip_piece(n)).ok_or_else(|| DocError::Unknown("the print face has no name".into()))?;
|
||||
let index = crate::naming::face_names(copy)
|
||||
.iter()
|
||||
.position(|n| crate::naming::strip_piece(without_last_instance(n)) == name)
|
||||
.ok_or_else(|| DocError::Unknown(format!("the copy has no face `{name}`")))?;
|
||||
self.print_face_target(copy, index)
|
||||
};
|
||||
Some(found())
|
||||
}
|
||||
|
||||
fn locate_print_face(&self, state: &ModelState, body: &ModelBody, target: &ConfigFaceTarget) -> Result<PrintFace> {
|
||||
if body.body.is_mesh() {
|
||||
return Err(DocError::Invalid("not supported yet: a print face on a mesh body".into()));
|
||||
}
|
||||
let (indices, _) = self.anchored_face_indices(state, body, target)?;
|
||||
let first = indices.first().copied().ok_or_else(|| DocError::Unknown("the print face no longer exists".into()))?;
|
||||
let plane = body.body.planar_face(first).ok_or_else(|| DocError::Invalid("the print face is no longer flat".into()))?;
|
||||
let scale = 1. + body.body.size();
|
||||
for index in indices.iter().skip(1) {
|
||||
let other = body.body.planar_face(*index).ok_or_else(|| DocError::Invalid("the print face is no longer flat".into()))?;
|
||||
if plane.normal().dot(other.normal()).abs() < 1. - 1e-8 || (other.origin - plane.origin).dot(plane.normal()).abs() > 1e-7 * scale {
|
||||
return Err(DocError::Invalid("the print face's pieces no longer lie on one plane".into()));
|
||||
}
|
||||
}
|
||||
// The surface's own orientation is how the kernel built it, so the side the material is
|
||||
// on is taken from the face's triangles, which point out of the body.
|
||||
let mesh = body.mesh();
|
||||
let mut area = Vec3::ZERO;
|
||||
for (t, f) in mesh.triangles.iter().zip(&mesh.tri_face) {
|
||||
if let (true, Some([a, b, c])) = (indices.contains(&(*f as usize)), mesh.tri(t)) {
|
||||
area += (b - a).cross(c - a);
|
||||
}
|
||||
}
|
||||
let normal = plane.normal().normalized().ok_or_else(|| DocError::Invalid("the print face's plane is degenerate".into()))?;
|
||||
let outward = area.dot(normal);
|
||||
if !(outward.abs() > 0.) {
|
||||
return Err(DocError::Invalid("the print face has no surface to lie on".into()));
|
||||
}
|
||||
Ok(PrintFace { index: first, point: plane.origin, normal: if outward < 0. { -normal } else { normal } })
|
||||
}
|
||||
}
|
||||
|
||||
/// A face name without the copy instance at its end (`F1:+x@F2.1` is `F1:+x`; a copy of a copy,
|
||||
/// `F1:+x@F2.1@F5.1`, is `F1:+x@F2.1`).
|
||||
fn without_last_instance(n: &str) -> &str {
|
||||
let Some(at) = n.rfind('@') else { return n };
|
||||
let instance = n.get(at + 1..).and_then(|t| t.strip_prefix('F')).and_then(|t| t.split_once('.'));
|
||||
let digits = |t: &str| !t.is_empty() && t.bytes().all(|b| b.is_ascii_digit());
|
||||
if instance.is_some_and(|(feature, k)| digits(feature) && digits(k)) { n.get(..at).unwrap_or(n) } else { n }
|
||||
}
|
||||
@@ -238,13 +238,14 @@ fn resolve_uncached(
|
||||
}
|
||||
LinkSource::Origin => vec![LinkGeom::Point(plane.to_local(Vec3::ZERO))],
|
||||
LinkSource::Axis { name } => {
|
||||
let d = match name.to_ascii_uppercase().as_str() {
|
||||
"X" => Vec3::X,
|
||||
"Y" => Vec3::Y,
|
||||
"Z" => Vec3::Z,
|
||||
_ => return Err(DocError::Unknown(format!("axis `{name}`"))),
|
||||
let (o, d) = match name.to_ascii_uppercase().as_str() {
|
||||
"X" => (Vec3::ZERO, Vec3::X),
|
||||
"Y" => (Vec3::ZERO, Vec3::Y),
|
||||
"Z" => (Vec3::ZERO, Vec3::Z),
|
||||
// A construction axis, by name (#9324), where the timeline so far puts it.
|
||||
_ => crate::eval::construction_axis_in(Some(doc), st, name, 0)?,
|
||||
};
|
||||
let o = plane.to_local(Vec3::ZERO);
|
||||
let o = plane.to_local(o);
|
||||
let d2 = Vec2::new(d.dot(plane.x), d.dot(plane.y));
|
||||
match d2.normalized() {
|
||||
Some(u) if d2.len() > 1e-9 => vec![LinkGeom::Line(o - u * AXIS_HALF, o + u * AXIS_HALF)],
|
||||
|
||||
@@ -39,6 +39,12 @@ pub struct RenderSetup {
|
||||
pub stage: solidcraft_render::stage::Stage,
|
||||
}
|
||||
|
||||
/// The CPU request a size check belongs to, so a refusal can name the profile that admits it.
|
||||
#[derive(Clone, Copy)]
|
||||
struct CpuSize {
|
||||
progressive: Option<solidcraft_render::job::CpuProgressiveOptions>,
|
||||
}
|
||||
|
||||
// Reuse Camera's representation and defaults, but reject misspelled saved fields. A remote
|
||||
// derive constructs Camera itself, so adding a Camera field requires updating this adapter.
|
||||
// Navigation/named-view deserialization keeps its existing compatibility policy.
|
||||
@@ -80,27 +86,29 @@ impl Default for RenderSetup {
|
||||
|
||||
impl RenderSetup {
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
let limits = match &self.job {
|
||||
Some(RenderJob::CpuRaytrace { options }) => options.budget.image_limits(options.progressive.is_some()),
|
||||
Some(RenderJob::GpuPath { .. }) => solidcraft_render::job::GPU_PATH_LIMITS,
|
||||
_ => RenderLimits::default(),
|
||||
let (limits, cpu) = match &self.job {
|
||||
Some(RenderJob::CpuRaytrace { options }) => {
|
||||
(options.budget.image_limits(options.progressive.is_some()), Some(CpuSize { progressive: options.progressive }))
|
||||
}
|
||||
Some(RenderJob::GpuPath { .. }) => (solidcraft_render::job::GPU_PATH_LIMITS, None),
|
||||
_ => (RenderLimits::default(), None),
|
||||
};
|
||||
self.validate_with_limits(limits)
|
||||
self.validate_with_limits(limits, cpu)
|
||||
}
|
||||
|
||||
/// Runtime CPU lowering has already moved typed options out of this setup.
|
||||
/// Saving still uses validate(), so a legacy setup cannot smuggle a large profile.
|
||||
pub fn validate_for_cpu(&self, budget: solidcraft_render::job::CpuBudget) -> Result<()> {
|
||||
budget.validate_image(self.width, self.height, None).map_err(|e| DocError::Invalid(e.to_string()))?;
|
||||
self.validate_with_limits(budget.image_limits(false))
|
||||
self.validate_with_limits(budget.image_limits(false), Some(CpuSize { progressive: None }))
|
||||
}
|
||||
|
||||
/// Typed GPU options have already been lowered; retain their dimension envelope.
|
||||
pub fn validate_for_gpu(&self) -> Result<()> {
|
||||
self.validate_with_limits(solidcraft_render::job::GPU_PATH_LIMITS)
|
||||
self.validate_with_limits(solidcraft_render::job::GPU_PATH_LIMITS, None)
|
||||
}
|
||||
|
||||
fn validate_with_limits(&self, limits: RenderLimits) -> Result<()> {
|
||||
fn validate_with_limits(&self, limits: RenderLimits, cpu: Option<CpuSize>) -> Result<()> {
|
||||
self.surfaces.validate()?;
|
||||
self.optics.validate()?;
|
||||
if !self.optics.is_empty() && !matches!(self.job, Some(RenderJob::GpuPath { .. })) {
|
||||
@@ -123,9 +131,14 @@ impl RenderSetup {
|
||||
if let Some((w, h)) = limits.fit(width, height, None)
|
||||
&& (w, h) != (width, height)
|
||||
{
|
||||
// A CPU refusal names the profile that can render the size (#8941). It is never
|
||||
// selected for the person: resolution and profile change only when they choose.
|
||||
let advice = cpu.map_or_else(String::new, |cpu| {
|
||||
format!("; {}", solidcraft_render::job::CpuBudget::size_advice(self.width, self.height, cpu.progressive))
|
||||
});
|
||||
return Err(DocError::Invalid(format!(
|
||||
"render output {width} × {height} exceeds the image limits ({} pixels per side, {} pixels in all); \
|
||||
the largest image at this aspect is {w} × {h}",
|
||||
the largest image at this aspect is {w} × {h}{advice}",
|
||||
limits.max_dimension, limits.max_pixels
|
||||
)));
|
||||
}
|
||||
@@ -538,9 +551,58 @@ mod tests {
|
||||
let setup = RenderSetup { width: 7680, height: 4320, ..Default::default() };
|
||||
let message = setup.validate().unwrap_err().to_string();
|
||||
assert!(message.contains("the largest image at this aspect is 27"), "{message}");
|
||||
assert!(!message.contains("CPU resource profile"), "a raster refusal names no CPU profile: {message}");
|
||||
assert!(RenderSetup { width: 2048, height: 2048, ..Default::default() }.validate().is_ok());
|
||||
}
|
||||
|
||||
/// #8941: 4K UHD under the default Compact profile names Studio, the profile that renders it;
|
||||
/// a 16K-wide image under Studio names Workstation; past Workstation no profile is named.
|
||||
/// The saved profile is never changed by the check, and GPU path tracing keeps its own limits.
|
||||
#[test]
|
||||
fn a_cpu_size_refusal_names_the_profile_that_can_render_it() {
|
||||
use solidcraft_render::job::CpuBudget;
|
||||
let cpu = |budget, width, height| RenderSetup {
|
||||
width,
|
||||
height,
|
||||
job: Some(RenderJob::CpuRaytrace { options: CpuJob { budget, ..Default::default() } }),
|
||||
..Default::default()
|
||||
};
|
||||
let compact = cpu(CpuBudget::Compact, 3840, 2160);
|
||||
let message = compact.validate().unwrap_err().to_string();
|
||||
assert!(message.contains("3840 × 2160 exceeds the image limits (4096 pixels per side, 4194304 pixels in all)"), "{message}");
|
||||
assert!(message.contains("the largest image at this aspect is 2730 × 1536"), "{message}");
|
||||
assert!(message.contains("choose the Studio CPU resource profile, or a smaller size"), "{message}");
|
||||
assert!(matches!(&compact.job, Some(RenderJob::CpuRaytrace { options }) if options.budget == CpuBudget::Compact));
|
||||
let message = compact.validate_for_cpu(CpuBudget::Compact).unwrap_err().to_string();
|
||||
assert!(message.contains("choose the Studio CPU resource profile"), "{message}");
|
||||
|
||||
cpu(CpuBudget::Studio, 3840, 2160).validate().unwrap();
|
||||
RenderSetup { width: 3840, height: 2160, ..Default::default() }.validate_for_cpu(CpuBudget::Studio).unwrap();
|
||||
|
||||
let message = cpu(CpuBudget::Studio, 15360, 4320).validate().unwrap_err().to_string();
|
||||
assert!(message.contains("choose the Workstation CPU resource profile"), "{message}");
|
||||
cpu(CpuBudget::Workstation, 15360, 4320).validate().unwrap();
|
||||
|
||||
let message = cpu(CpuBudget::Workstation, 16384, 16384).validate().unwrap_err().to_string();
|
||||
assert!(message.contains("no CPU resource profile accepts this size; choose a smaller size"), "{message}");
|
||||
for profile in ["Compact", "Studio", "Workstation"] {
|
||||
assert!(!message.contains(&format!("the {profile} CPU")), "{message}");
|
||||
}
|
||||
|
||||
// GPU path tracing: 4K renders, an over-limit size names no CPU profile.
|
||||
let gpu = |width, height| RenderSetup {
|
||||
width,
|
||||
height,
|
||||
job: Some(RenderJob::GpuPath { transparent_background: false, options: Default::default() }),
|
||||
..Default::default()
|
||||
};
|
||||
gpu(3840, 2160).validate().unwrap();
|
||||
gpu(3840, 2160).validate_for_gpu().unwrap();
|
||||
let message = gpu(8193, 8193).validate().unwrap_err().to_string();
|
||||
assert!(message.contains("(8192 pixels per side, 16777216 pixels in all)"), "{message}");
|
||||
assert!(!message.contains("CPU resource profile"), "{message}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn portable_jobs_preserve_complete_numerical_intent_and_legacy_omission() {
|
||||
use serde_json::json;
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
//! Equation curves (#8352): the points of a sketch curve worked out from its formulas over the
|
||||
//! design's parameters. The formulas are evaluated at evenly spaced values of the curve's
|
||||
//! variable; the sketch draws a cubic fit spline through those points. How many points: as many
|
||||
//! as it takes for the spline to stay within the curve's tolerance of the formulas, checked
|
||||
//! between the points, up to the most a spline takes. When the parameters change, the same
|
||||
//! number of points is placed again (`Document::apply_equation_values`), before every solve.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use solidcraft_geom::Vec2;
|
||||
use solidcraft_sketch::{EquationCurve, MAX_COORD, MAX_EQUATION_TEXT, MAX_SPLINE_POINTS, Sketch, fit_beziers_mode};
|
||||
|
||||
use crate::expr::{self, Defaults, Kind, Value};
|
||||
use crate::{DocError, Result};
|
||||
|
||||
/// The tolerance a new equation curve gets (mm).
|
||||
pub const DEFAULT_TOLERANCE: f64 = 0.01;
|
||||
/// The tightest and loosest tolerances (mm).
|
||||
pub const MIN_TOLERANCE: f64 = 1e-4;
|
||||
pub const MAX_TOLERANCE: f64 = 10.0;
|
||||
/// The fewest points a fit starts from.
|
||||
const FIRST_COUNT: usize = 9;
|
||||
/// The widest range of the variable.
|
||||
const MAX_RANGE: f64 = 1e6;
|
||||
/// How many times the point count is raised before the fit gives up.
|
||||
const MAX_ROUNDS: usize = 12;
|
||||
|
||||
/// An equation curve's points and how well the spline through them follows the formulas.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct EquationFit {
|
||||
/// The spline's points in order; a closed curve's last point is its first one again.
|
||||
pub points: Vec<Vec2>,
|
||||
/// The curve ends where it starts: the spline closes smoothly there.
|
||||
pub closed: bool,
|
||||
/// The largest distance (mm) found between the spline and the formulas.
|
||||
pub deviation: f64,
|
||||
}
|
||||
|
||||
/// How bare numbers read in the formulas: angles in radians (the variable is a plain number,
|
||||
/// `sin(t)` its sine), lengths in the design's unit.
|
||||
fn defaults(vals: &BTreeMap<String, Value>) -> Defaults {
|
||||
let len = vals.get(crate::eval::DESIGN_LEN).map(|v| v.v).filter(|v| v.is_finite() && *v > 0.0).unwrap_or(1.0);
|
||||
Defaults { len, ang: 1.0 }
|
||||
}
|
||||
|
||||
fn checked_text<'a>(what: &str, e: &'a str) -> Result<&'a str> {
|
||||
let e = e.trim();
|
||||
if e.is_empty() {
|
||||
return Err(DocError::Invalid(format!("{what} is empty")));
|
||||
}
|
||||
if e.chars().count() > MAX_EQUATION_TEXT {
|
||||
return Err(DocError::Invalid(format!("{what} is longer than {MAX_EQUATION_TEXT} characters")));
|
||||
}
|
||||
Ok(e)
|
||||
}
|
||||
|
||||
/// A formula's value (mm) where the variable is `at`. The variable hides a parameter of its name.
|
||||
fn formula(vals: &BTreeMap<String, Value>, e: &str, variable: &str, at: f64, d: Defaults) -> Result<f64> {
|
||||
let lookup = |n: &str| {
|
||||
if n == variable { Ok(Value::num(at)) } else { vals.get(n).copied().ok_or_else(|| DocError::Expr(format!("unknown parameter `{n}`"))) }
|
||||
};
|
||||
let v = expr::eval_with_defaults(e, &lookup, d)?.to_kind_in(Kind::Length, d)?;
|
||||
if v.is_finite() && v.abs() < MAX_COORD { Ok(v) } else { Err(DocError::Expr("the curve goes out of range".into())) }
|
||||
}
|
||||
|
||||
/// Where the variable starts or ends, as the plain number the formulas see: a number, an angle
|
||||
/// (in radians) or a length (in the design's unit).
|
||||
fn range_end(vals: &BTreeMap<String, Value>, e: &str, d: Defaults) -> Result<f64> {
|
||||
let v = expr::eval_with_defaults(e, &|n| vals.get(n).copied().ok_or_else(|| DocError::Expr(format!("unknown parameter `{n}`"))), d)?;
|
||||
let out = match v.kind() {
|
||||
Some(Kind::Unitless | Kind::Angle) => v.v,
|
||||
Some(Kind::Length) => v.v / d.len,
|
||||
None => return Err(DocError::Expr(format!("expected a number, an angle or a length, got {}", v.describe()))),
|
||||
};
|
||||
if out.is_finite() { Ok(out) } else { Err(DocError::Expr("not a finite number".into())) }
|
||||
}
|
||||
|
||||
/// The variable's range, checked.
|
||||
fn range(vals: &BTreeMap<String, Value>, eq: &EquationCurve, d: Defaults) -> Result<(f64, f64)> {
|
||||
let a = range_end(vals, checked_text("the start", &eq.start)?, d).map_err(|e| DocError::Expr(format!("start: {e}")))?;
|
||||
let b = range_end(vals, checked_text("the end", &eq.end)?, d).map_err(|e| DocError::Expr(format!("end: {e}")))?;
|
||||
if (b - a).abs() <= 1e-12 * a.abs().max(b.abs()).max(1.0) {
|
||||
return Err(DocError::Invalid("the start and the end of the range must differ".into()));
|
||||
}
|
||||
if (b - a).abs() > MAX_RANGE {
|
||||
return Err(DocError::Invalid(format!("the range is wider than {MAX_RANGE}")));
|
||||
}
|
||||
Ok((a, b))
|
||||
}
|
||||
|
||||
/// The curve's point where the variable is `at`.
|
||||
fn point_at(vals: &BTreeMap<String, Value>, eq: &EquationCurve, at: f64, d: Defaults) -> Result<Vec2> {
|
||||
let variable = eq.variable();
|
||||
let x = match &eq.x {
|
||||
Some(e) => formula(vals, e, variable, at, d).map_err(|e| DocError::Expr(format!("x: {e}")))?,
|
||||
// The explicit form: x is the variable, in the design's unit.
|
||||
None => {
|
||||
let x = at * d.len;
|
||||
if !(x.is_finite() && x.abs() < MAX_COORD) {
|
||||
return Err(DocError::Expr("the curve goes out of range".into()));
|
||||
}
|
||||
x
|
||||
}
|
||||
};
|
||||
let y = formula(vals, &eq.y, variable, at, d).map_err(|e| DocError::Expr(format!("y: {e}")))?;
|
||||
Ok(Vec2::new(x, y))
|
||||
}
|
||||
|
||||
/// The formulas' points at `count` evenly spaced values of the variable, from start to end.
|
||||
fn samples(vals: &BTreeMap<String, Value>, eq: &EquationCurve, (a, b): (f64, f64), count: usize, d: Defaults) -> Result<Vec<Vec2>> {
|
||||
let last = count.saturating_sub(1).max(1) as f64;
|
||||
(0..count)
|
||||
.map(|i| {
|
||||
let at = a + (b - a) * (i as f64 / last);
|
||||
point_at(vals, eq, at, d).map_err(|e| DocError::Expr(format!("at {} = {}: {e}", eq.variable(), short(at))))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A number short enough for a message.
|
||||
fn short(v: f64) -> String {
|
||||
let s = format!("{v:.6}");
|
||||
s.trim_end_matches('0').trim_end_matches('.').to_string()
|
||||
}
|
||||
|
||||
/// The size of the curve: the larger side of its box (for closing tolerances).
|
||||
fn extent(points: &[Vec2]) -> f64 {
|
||||
let (mut lo, mut hi) = (Vec2::new(f64::INFINITY, f64::INFINITY), Vec2::new(f64::NEG_INFINITY, f64::NEG_INFINITY));
|
||||
for p in points {
|
||||
lo = Vec2::new(lo.x.min(p.x), lo.y.min(p.y));
|
||||
hi = Vec2::new(hi.x.max(p.x), hi.y.max(p.y));
|
||||
}
|
||||
(hi.x - lo.x).max(hi.y - lo.y).max(0.0)
|
||||
}
|
||||
|
||||
/// Does a curve through these samples end where it starts?
|
||||
fn closes(points: &[Vec2]) -> bool {
|
||||
match (points.first(), points.last()) {
|
||||
(Some(a), Some(b)) => points.len() >= 4 && a.dist(*b) <= 1e-7 * extent(points).max(1.0),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Refuse samples a spline cannot pass through: two in a row on the same spot, or all of them.
|
||||
fn check_samples(points: &[Vec2], closed: bool) -> Result<()> {
|
||||
let size = extent(points);
|
||||
if size <= 1e-9 {
|
||||
return Err(DocError::Invalid("the formulas give the same point all along the range".into()));
|
||||
}
|
||||
let spans = if closed { points.len().saturating_sub(1) } else { points.len() };
|
||||
for w in points.windows(2).take(spans) {
|
||||
if let [p, q] = w
|
||||
&& p.dist(*q) <= 1e-9 * size.max(1.0)
|
||||
{
|
||||
return Err(DocError::Invalid("the curve stands still between two of its points: narrow the range or use fewer points".into()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Distance from `q` to the cubic Bézier `b`, sampled finely.
|
||||
fn bezier_distance(b: &[Vec2; 4], q: Vec2) -> f64 {
|
||||
const STEPS: usize = 32;
|
||||
let at = |t: f64| {
|
||||
let s = 1.0 - t;
|
||||
b[0] * (s * s * s) + b[1] * (3.0 * t * s * s) + b[2] * (3.0 * t * t * s) + b[3] * (t * t * t)
|
||||
};
|
||||
let mut best = f64::INFINITY;
|
||||
let mut prev = at(0.0);
|
||||
for i in 1..=STEPS {
|
||||
let next = at(i as f64 / STEPS as f64);
|
||||
let d = next - prev;
|
||||
let l2 = d.len2();
|
||||
let t = if l2 > 0.0 { ((q - prev).dot(d) / l2).clamp(0.0, 1.0) } else { 0.0 };
|
||||
best = best.min(q.dist(prev + d * t));
|
||||
prev = next;
|
||||
}
|
||||
best
|
||||
}
|
||||
|
||||
/// How far the spline through `points` strays from the formulas: the largest distance from the
|
||||
/// formulas' points a quarter, a half and three quarters of the way between two samples to the
|
||||
/// spline's piece between them.
|
||||
fn deviation(vals: &BTreeMap<String, Value>, eq: &EquationCurve, (a, b): (f64, f64), points: &[Vec2], closed: bool, d: Defaults) -> Result<f64> {
|
||||
let pieces = fit_beziers_mode(points, closed).map_err(|e| DocError::Invalid(e.to_string()))?;
|
||||
let step = (b - a) / points.len().saturating_sub(1).max(1) as f64;
|
||||
let mut worst: f64 = 0.0;
|
||||
for (i, piece) in pieces.iter().enumerate() {
|
||||
for k in [0.25, 0.5, 0.75] {
|
||||
let q = point_at(vals, eq, a + step * (i as f64 + k), d)?;
|
||||
worst = worst.max(bezier_distance(piece, q));
|
||||
}
|
||||
}
|
||||
Ok(worst)
|
||||
}
|
||||
|
||||
/// Check an equation's text and tolerance before any evaluation.
|
||||
pub fn check(eq: &EquationCurve) -> Result<()> {
|
||||
if let Some(x) = &eq.x {
|
||||
checked_text("x(t)", x)?;
|
||||
}
|
||||
checked_text(if eq.x.is_some() { "y(t)" } else { "y(x)" }, &eq.y)?;
|
||||
checked_text("the start", &eq.start)?;
|
||||
checked_text("the end", &eq.end)?;
|
||||
if !(eq.tolerance.is_finite() && (MIN_TOLERANCE..=MAX_TOLERANCE).contains(&eq.tolerance)) {
|
||||
return Err(DocError::Invalid(format!("the tolerance must be from {MIN_TOLERANCE} mm to {MAX_TOLERANCE} mm")));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The points of `count` samples (a closed curve's last one is its first), whether it closes,
|
||||
/// and how far the spline through them strays.
|
||||
pub fn sample(vals: &BTreeMap<String, Value>, eq: &EquationCurve, count: usize, closed: Option<bool>) -> Result<EquationFit> {
|
||||
check(eq)?;
|
||||
if !(2..=MAX_SPLINE_POINTS).contains(&count) {
|
||||
return Err(DocError::Invalid(format!("an equation curve takes 2 to {MAX_SPLINE_POINTS} points")));
|
||||
}
|
||||
let d = defaults(vals);
|
||||
let span = range(vals, eq, d)?;
|
||||
let mut points = samples(vals, eq, span, count, d)?;
|
||||
let closed = closed.unwrap_or_else(|| closes(&points)) && count >= 4;
|
||||
if closed
|
||||
&& let Some(first) = points.first().copied()
|
||||
&& let Some(last) = points.last_mut()
|
||||
{
|
||||
*last = first;
|
||||
}
|
||||
check_samples(&points, closed)?;
|
||||
let deviation = deviation(vals, eq, span, &points, closed, d)?;
|
||||
Ok(EquationFit { points, closed, deviation })
|
||||
}
|
||||
|
||||
/// The points of an equation curve, as few as keep the spline within its tolerance of the
|
||||
/// formulas. Refused when even the most points a spline takes are not close enough.
|
||||
pub fn fit(vals: &BTreeMap<String, Value>, eq: &EquationCurve) -> Result<EquationFit> {
|
||||
let mut count = FIRST_COUNT;
|
||||
for _ in 0..MAX_ROUNDS {
|
||||
let fit = sample(vals, eq, count, None)?;
|
||||
if fit.deviation <= eq.tolerance {
|
||||
return Ok(fit);
|
||||
}
|
||||
if count >= MAX_SPLINE_POINTS {
|
||||
return Err(DocError::Invalid(format!(
|
||||
"even {MAX_SPLINE_POINTS} points stray {} mm from the formulas, more than the tolerance of {} mm: raise the tolerance or narrow the range",
|
||||
short(fit.deviation),
|
||||
short(eq.tolerance)
|
||||
)));
|
||||
}
|
||||
// A cubic fit's error falls with the fourth power of the spacing: aim a little past
|
||||
// what that asks for, at least half as many points again.
|
||||
let ratio = (fit.deviation / eq.tolerance).powf(0.25) * 1.2;
|
||||
let next = (count as f64 * ratio.max(1.5)).ceil();
|
||||
count = if next.is_finite() && next < MAX_SPLINE_POINTS as f64 { next as usize } else { MAX_SPLINE_POINTS };
|
||||
}
|
||||
Err(DocError::Invalid("the equation curve's points could not be fitted".into()))
|
||||
}
|
||||
|
||||
impl crate::Document {
|
||||
/// Place the points of the sketch's equation curves where their formulas put them now (in
|
||||
/// place), with the number of points each has. Their points are fixed, so the solve keeps
|
||||
/// them there. A curve that is gone or is no longer a fit point spline is left as it is.
|
||||
pub fn apply_equation_values(&self, vals: &BTreeMap<String, Value>, sk: &mut Sketch) -> Result<()> {
|
||||
for k in 0..sk.equations.len() {
|
||||
let Some(eq) = sk.equations.get(k).cloned() else { continue };
|
||||
let Some(ci) = sk.curve_index(&eq.curve) else { continue };
|
||||
let Some(solidcraft_sketch::CurveKind::Spline { pts, control: false, periodic, .. }) = sk.curves.get(ci).map(|c| &c.kind) else {
|
||||
continue;
|
||||
};
|
||||
let (count, closed) = (pts.len(), *periodic);
|
||||
let fit = sample(vals, &eq, count, Some(closed)).map_err(|e| DocError::Expr(format!("equation curve {}: {e}", eq.curve)))?;
|
||||
sk.place_equation_points(ci, &fit.points)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn eq(x: Option<&str>, y: &str, start: &str, end: &str) -> EquationCurve {
|
||||
EquationCurve {
|
||||
curve: String::new(),
|
||||
x: x.map(str::to_string),
|
||||
y: y.into(),
|
||||
start: start.into(),
|
||||
end: end.into(),
|
||||
tolerance: DEFAULT_TOLERANCE,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_circle_closes_and_stays_within_the_tolerance() {
|
||||
let vals = BTreeMap::new();
|
||||
let fit = fit(&vals, &eq(Some("10 * cos(t)"), "10 * sin(t)", "0", "2 * pi")).unwrap();
|
||||
assert!(fit.closed);
|
||||
assert!(fit.deviation <= DEFAULT_TOLERANCE, "{}", fit.deviation);
|
||||
for p in &fit.points {
|
||||
assert!((p.len() - 10.0).abs() < 1e-9, "{p:?}");
|
||||
}
|
||||
assert_eq!(fit.points.first(), fit.points.last());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_variable_hides_a_parameter_and_parameters_drive_the_curve() {
|
||||
let mut vals = BTreeMap::new();
|
||||
vals.insert("t".to_string(), Value::length(1000.0));
|
||||
vals.insert("amp".to_string(), Value::length(5.0));
|
||||
let fit = fit(&vals, &eq(None, "amp * sin(x / 10)", "0 mm", "100 mm")).unwrap();
|
||||
assert!(!fit.closed);
|
||||
let (first, last) = (fit.points[0], *fit.points.last().unwrap());
|
||||
assert!((first - Vec2::new(0.0, 0.0)).len() < 1e-9, "{first:?}");
|
||||
assert!((last.x - 100.0).abs() < 1e-9 && (last.y - 5.0 * 10f64.sin()).abs() < 1e-9, "{last:?}");
|
||||
assert!(fit.points.iter().all(|p| p.y.abs() <= 5.0 + 1e-9));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_design_in_inches_reads_bare_numbers_in_inches() {
|
||||
let mut vals = BTreeMap::new();
|
||||
vals.insert(crate::eval::DESIGN_LEN.to_string(), Value::num(25.4));
|
||||
let fit = fit(&vals, &eq(Some("t"), "2", "0", "1")).unwrap();
|
||||
let last = *fit.points.last().unwrap();
|
||||
assert!((last - Vec2::new(25.4, 50.8)).len() < 1e-9, "{last:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn more_points_where_the_tolerance_is_tighter() {
|
||||
let vals = BTreeMap::new();
|
||||
let mut e = eq(Some("t * cos(t)"), "t * sin(t)", "0", "6 * pi");
|
||||
e.tolerance = 0.1;
|
||||
let loose = fit(&vals, &e).unwrap();
|
||||
e.tolerance = 0.005;
|
||||
let tight = fit(&vals, &e).unwrap();
|
||||
assert!(tight.points.len() > loose.points.len(), "{} vs {}", tight.points.len(), loose.points.len());
|
||||
assert!(tight.deviation <= 0.005 && loose.deviation <= 0.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hostile_formulas_and_ranges_are_refused() {
|
||||
let vals = BTreeMap::new();
|
||||
for (x, y, a, b, tol) in [
|
||||
(Some("t"), "sqrt(t)", "-1", "1", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "1 / t", "-1", "1", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "t", "0", "0", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "t", "0", "1e300", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "t", "0", "nan", DEFAULT_TOLERANCE),
|
||||
(Some("t * 1 deg"), "t", "0", "1", DEFAULT_TOLERANCE),
|
||||
(Some("1e300 * t"), "t", "0", "1", DEFAULT_TOLERANCE),
|
||||
(Some("5"), "5", "0", "1", DEFAULT_TOLERANCE),
|
||||
(Some(""), "t", "0", "1", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "t", "0", "1", f64::NAN),
|
||||
(Some("t"), "t", "0", "1", 0.0),
|
||||
(Some("t"), "unknown_name * t", "0", "1", DEFAULT_TOLERANCE),
|
||||
(Some("t"), "sin(1e5 * t)", "0", "1000", 1e-4),
|
||||
] {
|
||||
let mut e = eq(x, y, a, b);
|
||||
e.tolerance = tol;
|
||||
assert!(fit(&vals, &e).is_err(), "{x:?} {y} {a}..{b} {tol}");
|
||||
}
|
||||
let long = "t + ".repeat(400) + "t";
|
||||
assert!(fit(&vals, &eq(Some(&long), "t", "0", "1")).is_err());
|
||||
}
|
||||
}
|
||||
@@ -486,6 +486,8 @@ fn hostile_expressions_never_panic() {
|
||||
"deg",
|
||||
"x",
|
||||
"sqrt",
|
||||
"cosh",
|
||||
"atanh",
|
||||
"pow",
|
||||
"min",
|
||||
"max",
|
||||
@@ -715,3 +717,156 @@ fn timeline_group_legacy_json_omits_empty_joint_membership() {
|
||||
assert!(value["timeline_groups"][0].get("joints").is_none());
|
||||
assert_eq!(Document::from_json(&saved).unwrap().to_json(), saved);
|
||||
}
|
||||
|
||||
/// A sketch whose touching curves are cut into more pieces than the profile search looks at
|
||||
/// says that some profiles may be missing, instead of leaving them out silently (#6896); an
|
||||
/// ordinary sketch says nothing.
|
||||
#[test]
|
||||
fn a_sketch_too_large_to_search_whole_says_profiles_may_be_missing() {
|
||||
let mut doc = Document::new("large");
|
||||
let mut sk = Sketch::new();
|
||||
// Concentric ellipses 100 m across, each sampled into thousands of pieces, all one island.
|
||||
let c = sk.add_point(Vec2::ZERO, None).unwrap();
|
||||
for k in 0..5 {
|
||||
let m = sk.add_point(Vec2::new(1e5 - k as f64 * 1e3, 0.0), None).unwrap();
|
||||
sk.add_curve(solidcraft_sketch::CurveKind::Ellipse { c, m, r: 6e4 - k as f64 * 1e3 }, None).unwrap();
|
||||
}
|
||||
let large = doc.add_feature(FeatureKind::Sketch { plane: PlaneRef::Origin { name: "XY".into() }, sketch: sk }, None).unwrap();
|
||||
let (plate, plate_sketch) = plate_doc();
|
||||
let mut m = Model::new();
|
||||
m.evaluate(&doc);
|
||||
let warning = m.result(large).and_then(|r| r.warning.clone()).unwrap_or_default();
|
||||
assert!(warning.contains("some profiles may be missing"), "{warning}");
|
||||
let mut m = Model::new();
|
||||
m.evaluate(&plate);
|
||||
assert!(m.result(plate_sketch).and_then(|r| r.warning.as_deref()).is_none());
|
||||
}
|
||||
|
||||
fn browser_group(id: u64, component: u64, folder: &str, parent: Option<u64>, items: &[BrowserEntry]) -> BrowserGroup {
|
||||
BrowserGroup { id, name: format!("G{id}"), component, folder: folder.into(), parent, items: items.to_vec() }
|
||||
}
|
||||
|
||||
fn item(key: &str) -> BrowserEntry {
|
||||
BrowserEntry::item(key)
|
||||
}
|
||||
|
||||
fn group(id: u64) -> BrowserEntry {
|
||||
BrowserEntry::Group(id)
|
||||
}
|
||||
|
||||
/// The design with what `browser_pruned` drops gone (the design itself when nothing is).
|
||||
fn pruned(doc: &Document) -> Document {
|
||||
let mut out = doc.clone();
|
||||
if let Some((groups, order)) = doc.browser_pruned() {
|
||||
(out.browser_groups, out.browser_order) = (groups, order);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Pruning keeps every group but cuts a parent that loops, is the group itself, is past the
|
||||
/// nesting limit, or is in another component or folder, to the top level; and it drops entries
|
||||
/// for deleted sketches and placements, repeats, and the lists of a missing component. Body names
|
||||
/// are never judged.
|
||||
#[test]
|
||||
fn browser_pruning_cuts_bad_parents_and_drops_stale_and_repeated_entries() {
|
||||
let mut doc = Document::new("prune");
|
||||
let sketch = doc.add_feature(FeatureKind::Sketch { plane: PlaneRef::Origin { name: "XY".into() }, sketch: Sketch::new() }, None).unwrap();
|
||||
let key = sketch.to_string();
|
||||
doc.components.push(Component { id: 7, name: "Part".into(), ..Default::default() });
|
||||
doc.occurrences.push(Occurrence { id: 20, component: 7, parent: 0, name: "Part".into(), transform: IDENTITY, grounded: false });
|
||||
let deep = MAX_GROUP_NESTING as u64 + 2;
|
||||
doc.browser_groups = vec![
|
||||
browser_group(1, 0, "bodies", Some(2), &[]),
|
||||
browser_group(2, 0, "bodies", Some(1), &[]),
|
||||
browser_group(3, 0, "bodies", Some(3), &[]),
|
||||
browser_group(4, 7, "bodies", Some(5), &[]),
|
||||
browser_group(5, 0, "bodies", None, &[item("a"), group(7), group(7), item("a")]),
|
||||
browser_group(6, 0, "sketches", Some(5), &[item(&key), item("999")]),
|
||||
browser_group(7, 0, "bodies", Some(5), &[]),
|
||||
browser_group(8, 0, "bodies", None, &[item("a"), item("b")]),
|
||||
];
|
||||
doc.browser_groups.extend((0..deep).map(|i| browser_group(100 + i, 0, "construction", i.checked_sub(1).map(|p| 100 + p), &[])));
|
||||
doc.browser_order.insert("0/bodies".into(), vec![item("Lid"), item("Ghost"), item("Lid"), group(5), group(5)]);
|
||||
doc.browser_order.insert("0/components".into(), vec![item("21"), item("20")]);
|
||||
doc.browser_order.insert("99/bodies".into(), vec![item("x")]);
|
||||
let after = pruned(&doc);
|
||||
let parent = |id| after.browser_group(id).unwrap().parent;
|
||||
assert_eq!(after.browser_groups.len(), doc.browser_groups.len(), "no group is dropped");
|
||||
assert_eq!([1, 2, 3, 4, 6].map(parent), [None; 5], "a loop, itself, another component, another folder");
|
||||
assert_eq!(parent(7), Some(5));
|
||||
for i in 0..deep {
|
||||
assert_eq!(parent(100 + i), (1..MAX_GROUP_NESTING as u64).contains(&i).then(|| 99 + i), "level {} of a chain {deep} deep", i + 1);
|
||||
}
|
||||
assert_eq!(after.browser_group(5).unwrap().items, [item("a"), group(7)]);
|
||||
assert_eq!(after.browser_group(8).unwrap().items, [item("b")], "an item stays in the first group that has it");
|
||||
assert_eq!(after.browser_group(6).unwrap().items, [item(&key)], "the deleted sketch goes");
|
||||
assert_eq!(after.browser_order["0/bodies"], [item("Lid"), item("Ghost"), group(5)], "body names stay; repeats go");
|
||||
assert_eq!(after.browser_order["0/components"], [item("20")], "the deleted placement goes");
|
||||
assert!(!after.browser_order.contains_key("99/bodies"));
|
||||
assert!(Document::new("clean").browser_pruned().is_none(), "nothing to prune is not a change");
|
||||
}
|
||||
|
||||
/// Levels and ancestry follow the parents. Groups a list does not name go after the last one it
|
||||
/// names, in creation order, or first when it names none: above the items, as a design saved
|
||||
/// before groups could be ordered has always shown them.
|
||||
#[test]
|
||||
fn group_levels_and_the_order_of_groups_a_list_does_not_name() {
|
||||
let mut doc = Document::new("order");
|
||||
doc.browser_groups = vec![
|
||||
browser_group(1, 0, "bodies", None, &[item("x")]),
|
||||
browser_group(2, 0, "bodies", None, &[]),
|
||||
browser_group(3, 0, "bodies", None, &[]),
|
||||
browser_group(4, 0, "bodies", Some(1), &[]),
|
||||
browser_group(5, 0, "bodies", Some(4), &[]),
|
||||
];
|
||||
assert_eq!([1, 2, 4, 5].map(|id| doc.group_level(id)), [1, 1, 2, 3]);
|
||||
assert!(doc.group_within(5, 1) && doc.group_within(5, 5) && !doc.group_within(1, 5) && !doc.group_within(2, 5));
|
||||
assert_eq!(doc.group_height(1), 3);
|
||||
let top = |doc: &Document| doc.ordered_entries(0, "bodies", None);
|
||||
assert_eq!(top(&doc), [group(1), group(2), group(3)], "no list: creation order");
|
||||
doc.browser_order.insert("0/bodies".into(), vec![item("a")]);
|
||||
assert_eq!(top(&doc), [group(1), group(2), group(3), item("a")], "a list of items only: groups above them");
|
||||
doc.browser_order.insert("0/bodies".into(), vec![item("a"), group(2), item("b"), group(2), group(9)]);
|
||||
assert_eq!(top(&doc), [item("a"), group(2), group(1), group(3), item("b")], "after the last listed; repeats and unknown ignored");
|
||||
assert_eq!(doc.ordered_entries(0, "bodies", Some(1)), [group(4), item("x")], "inside a group too");
|
||||
}
|
||||
|
||||
/// Nested groups and a `components` order survive a save and a load, saved as numbers (groups) and
|
||||
/// strings (items). A design from before groups could nest reads with the browser it always had:
|
||||
/// no parents, groups in creation order above the items in their saved order, saved back as read.
|
||||
#[test]
|
||||
fn browser_data_survives_a_save_and_old_designs_read_unchanged() {
|
||||
let mut doc = Document::new("nested");
|
||||
doc.components.push(Component { id: 7, name: "Part".into(), ..Default::default() });
|
||||
for id in [20, 21] {
|
||||
doc.occurrences.push(Occurrence { id, component: 7, parent: 0, name: format!("P{id}"), transform: IDENTITY, grounded: false });
|
||||
}
|
||||
doc.browser_groups = vec![browser_group(2, 0, "bodies", None, &[item("Lid"), group(3)]), browser_group(3, 0, "bodies", Some(2), &[item("Base")])];
|
||||
doc.browser_order.insert("0/bodies".into(), vec![item("Cap"), group(2)]);
|
||||
doc.browser_order.insert("0/components".into(), vec![item("21"), item("20")]);
|
||||
let saved = doc.to_json();
|
||||
let value: serde_json::Value = serde_json::from_str(&saved).unwrap();
|
||||
assert_eq!(value["browser_order"]["0/bodies"], serde_json::json!(["Cap", 2]));
|
||||
assert_eq!((&value["browser_groups"][1]["parent"], value["browser_groups"][0].get("parent")), (&serde_json::json!(2), None));
|
||||
let loaded = Document::from_json(&saved).unwrap();
|
||||
assert_eq!((&loaded.browser_groups, &loaded.browser_order), (&doc.browser_groups, &doc.browser_order));
|
||||
let resaved: serde_json::Value = serde_json::from_str(&loaded.to_json()).unwrap();
|
||||
assert_eq!((&resaved["browser_groups"], &resaved["browser_order"]), (&value["browser_groups"], &value["browser_order"]));
|
||||
|
||||
let groups = serde_json::json!([
|
||||
{"id": 3, "name": "Fasteners", "component": 0, "folder": "bodies", "items": ["Bolt", "Nut"]},
|
||||
{"id": 4, "name": "Plates", "component": 0, "folder": "bodies", "items": ["Plate"]},
|
||||
]);
|
||||
for (order, top) in [
|
||||
(serde_json::json!({}), vec![group(3), group(4)]),
|
||||
(serde_json::json!({"0/bodies": ["Washer", "Bolt", "Cap"]}), vec![group(3), group(4), item("Washer"), item("Bolt"), item("Cap")]),
|
||||
] {
|
||||
let mut old: serde_json::Value = serde_json::from_str(&Document::new("old").to_json()).unwrap();
|
||||
(old["browser_groups"], old["browser_order"]) = (groups.clone(), order.clone());
|
||||
let loaded = Document::from_json(&old.to_string()).unwrap();
|
||||
assert!(loaded.browser_groups.iter().all(|g| g.parent.is_none()), "{order}");
|
||||
assert_eq!(loaded.ordered_entries(0, "bodies", None), top, "{order}");
|
||||
let resaved: serde_json::Value = serde_json::from_str(&loaded.to_json()).unwrap();
|
||||
assert_eq!(resaved["browser_groups"], groups, "{order}");
|
||||
}
|
||||
}
|
||||
|
||||