mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 10:35:58 +00:00
Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0537623a75 | |||
| 2a0096fe4a | |||
| cc9d76cd86 | |||
| c61ffb54a8 | |||
| ab889a8fff | |||
| fcc3753a4c | |||
| 2c9d0a2847 | |||
| 99fd05afeb | |||
| a8051760f7 | |||
| c795a3f581 | |||
| 2cab9dc142 | |||
| 6d8d53aac8 | |||
| 4e6939b5cf | |||
| f6ff2ff139 | |||
| 048c1ae8a8 | |||
| b00a1e87f4 | |||
| 8cbde001ef | |||
| ad8b2f91bb | |||
| 9919825ea3 | |||
| 97e0ff9050 | |||
| c48c1a09d3 | |||
| ee3d41210d | |||
| be685d064f | |||
| 32e613aa8c | |||
| 58a9d33f02 | |||
| a8e6154c0d | |||
| d61dff69a6 | |||
| 8c853fff3e | |||
| daec1091f4 | |||
| 0520910bfd | |||
| 46f24f2394 | |||
| 1236863b17 | |||
| 4f4b1fc2d2 | |||
| d5a79a77e6 | |||
| 5d47946e4d | |||
| 69cfd89ae8 | |||
| 9e6e0b8df1 | |||
| b7b25f9e2b | |||
| 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 |
+10
-1
@@ -42,7 +42,6 @@ filter = "binary(action_matrix) & test(=action_matrix_sample)"
|
||||
threads-required = 12
|
||||
priority = 100
|
||||
|
||||
|
||||
# The slowest tests start first, so a shard does not end with one of them running alone on a
|
||||
# core while the others sit idle (seed_81 alone takes about 20 minutes under CI load). Medians
|
||||
# from the CI test timings (the junit artifacts), slowest first; a test over ~100 s belongs here.
|
||||
@@ -70,6 +69,16 @@ filter = """
|
||||
"""
|
||||
priority = 100
|
||||
|
||||
# Each nextest test has its own process/device. Concurrent cold lavapipe path
|
||||
# compiles contend for CPU and can exhaust the 600 s pipeline setup budget.
|
||||
# Serialize this module per CI shard; other tests retain their normal parallelism.
|
||||
[test-groups.gpu-path]
|
||||
max-threads = 1
|
||||
|
||||
[[profile.ci.overrides]]
|
||||
filter = "package(=solidcraft-gpu) & test(/^path::/)"
|
||||
test-group = "gpu-path"
|
||||
|
||||
# Full local validation opts into its own scheduling policy. Keep GitHub CI's
|
||||
# worker reservation and slow-test priorities above independent of this runner.
|
||||
[profile.local-ci]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Preserve canonical source receipts and the runtime icon-discovery snapshot.
|
||||
.gitattributes text eol=lf
|
||||
/assets/icons/ui/design/requested_icons.txt text eol=lf
|
||||
+475
@@ -14,9 +14,33 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| assets/render/catalog/capabilities.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/capabilities.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| assets/render/catalog/environments.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/environments.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| assets/render/catalog/lighting.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/lighting.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| assets/render/catalog/materials.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/materials.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| assets/render/catalog/quality-presets.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/quality-presets.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| assets/render/catalog/scene-presets.json | SolidCraft contributors | Byte-identical runtime export of docs/render-materials/scene-presets.json; generated and checked by tools/render-library/generate.py | MIT OR Apache-2.0 |
|
||||
| examples/chebyshev-motion-trace.json | SolidCraft contributors | Original parametric Chebyshev lambda mechanism and associative-trace demo, constructed from analytic circle intersections; classical link proportions documented at https://doi.org/10.1002/rcs.70095; no external CAD geometry or artwork | MIT OR Apache-2.0 |
|
||||
| examples/material-card.json | SolidCraft contributors | original analytic box and explicitly synthetic engineering card; invented illustrative constants, no external material dataset | MIT OR Apache-2.0 |
|
||||
| examples/studio/author_sweep.py | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/author_scene.py | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/materials.json | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-exploded-sweep.json | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-exploded-render.json | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-exploded.json | SolidCraft contributors | original editable CAD scene and authoring metadata; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/stage1-sweep.json | SolidCraft contributors | original tangent circular-arc CAD cyclorama; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/stage1.json | SolidCraft contributors | original editable CAD studio scene; no imported geometry or external image assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/stage1-render.json | SolidCraft contributors | original studio camera and lighting parameters | MIT OR Apache-2.0 |
|
||||
| examples/render-studio.json | SolidCraft contributors | original procedural box/cylinder enclosure script for the integrated Render workspace | MIT OR Apache-2.0 |
|
||||
| examples/render-opaque-studio.json | SolidCraft contributors | original procedural sphere study varying opaque metal fraction and roughness independently; no external assets or engineering data | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/path/denoise.wgsl | SolidCraft contributors | original bounded edge-aware a-trous spatial filter; GPU2 donor d710e31, no external shader source | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/path/denoise_guides.wgsl | SolidCraft contributors | original deterministic centre-ray material and geometry guide pass; GPU2 donor d710e31, no external shader source | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/path/shadows.wgsl | SolidCraft contributors | original bounded area, sun and environment visibility transport; GPU2 donor d710e31, no external shader source | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/path/textures.wgsl | SolidCraft contributors | original planar colour and normal map sampling; GPU2 donor d710e31, no external shader source | MIT OR Apache-2.0 |
|
||||
| assets/appearances/starter_pack.rs | SolidCraft contributors | original illustrative optical recipes, authored scalar values and future procedural resource descriptors; no measured or external material dataset | MIT OR Apache-2.0 |
|
||||
| examples/material-finishes.json | SolidCraft contributors | original procedural sphere study of six illustrative opaque finishes with generic material densities; no external assets or measured optical data | MIT OR Apache-2.0 |
|
||||
| examples/render-path-studio.json | SolidCraft contributors | original procedural opaque enclosure, teal insert and metal fasteners for progressive rendering; no imported models | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/path/path.wgsl | SolidCraft contributors | original software BVH traversal and path integration using the existing SolidCraft surface/studio equations; no external shader source | MIT OR Apache-2.0 |
|
||||
| crates/gpu/src/pbr.rs | SolidCraft contributors | original WGSL translation of SolidCraft's opaque surface and fixed studio reference, embedded as Rust source; no external shader code | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/macos/source/SolidCraft.icon/icon.json | SolidCraft contributors | approved Icon Composer composition and appearance settings for the original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/macos/source/SolidCraft.icon/Assets/02-grid.svg | SolidCraft contributors | original perspective grid with elliptical radial alpha, exported from VectorCraft | MIT OR Apache-2.0 |
|
||||
@@ -98,6 +122,7 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| tests/oracle/63-hinge-knuckle/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/63-hinge-knuckle/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 |
|
||||
| tests/oracle/65-sketch-gear-tooth/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/65-sketch-gear-tooth/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 |
|
||||
| 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/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 |
|
||||
@@ -564,3 +589,453 @@ A frame whose meshes the GPU refuses to stage (device lost or out of memory) is
|
||||
skipped with a warning instead of panicking (#1469).
|
||||
Paint callbacks are prepared only after a drawable is acquired, so a skipped
|
||||
surface frame cannot strand cached meshes without their GPU initialization.
|
||||
|
||||
## Runtime studio lighting mathematics
|
||||
|
||||
`crates/gpu/src/path/path.wgsl` implements the power-heuristic estimator from the
|
||||
mathematical description in [PBRT fourth edition, section 13.4](https://pbr-book.org/4ed/Light_Transport_I_Surface_Reflection/A_Better_Path_Tracer).
|
||||
No PBRT code or assets were copied. `crates/render/src/job/lighting.rs` evaluates
|
||||
[Krzysztof Narkowicz's published 2016 ACES rational fit](https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/)
|
||||
using its published coefficients (author licenses the fit under CC0/MIT).
|
||||
These original implementations are under SolidCraft's MIT OR Apache-2.0 licence.
|
||||
|
||||
## Original coffee framing variant
|
||||
|
||||
| File | Author | Provenance | Licence |
|
||||
|---|---|---|---|
|
||||
| examples/studio/author_coffee_framing.py | SolidCraft contributors | original editable composition, camera and documentation; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-framing.json | SolidCraft contributors | original editable composition, camera and documentation; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-framing-sweep.json | SolidCraft contributors | original editable composition, camera and documentation; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-framing-render.json | SolidCraft contributors | original editable composition, camera and documentation; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-framing.md | SolidCraft contributors | original editable composition, camera and documentation; no external assets | MIT OR Apache-2.0 |
|
||||
|
||||
## Original cylindrical coffee housing variant
|
||||
|
||||
| File | Author | Provenance | Licence |
|
||||
|---|---|---|---|
|
||||
| examples/studio/author_coffee_cylinder.py | SolidCraft contributors | original parametric cylindrical CAD construction and editable command recipes; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-cylinder.json | SolidCraft contributors | original cylindrical housing on the original exploded coffee composition; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-cylinder-sweep.json | SolidCraft contributors | original cylindrical housing and continuous CAD cyclorama; no external assets | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-cylinder-render.json | SolidCraft contributors | original camera, studio lighting and optical settings retained from the framing variant | MIT OR Apache-2.0 |
|
||||
| examples/studio/coffee-cylinder.md | SolidCraft contributors | original dimensional recipe, provenance and validation limitations | MIT OR Apache-2.0 |
|
||||
|
||||
## Runtime environment sampling
|
||||
|
||||
`crates/render/src/lighting/environment.rs` and the environment/sun portions of
|
||||
`crates/gpu/src/path/path.wgsl` are original SolidCraft implementations of
|
||||
solid-angle importance sampling and MIS, informed by the mathematical description
|
||||
in [PBRT fourth edition, sections 12.5](https://pbr-book.org/4ed/Light_Sources/Infinite_Area_Lights)
|
||||
and [13.4](https://pbr-book.org/4ed/Light_Transport_I_Surface_Reflection/A_Better_Path_Tracer).
|
||||
The procedural gradient and inline RGBE test fixtures are original mathematical
|
||||
colours, not downloaded imagery. No third-party environment images or shader code
|
||||
are included. Licence: MIT OR Apache-2.0.
|
||||
|
||||
## Original tumbler showcase assets
|
||||
|
||||
The CAD room, tumblers, window opening, wood/weave patterns and RGBE sky below
|
||||
are original SolidCraft contributor work. No third-party scene, photograph, HDRI,
|
||||
texture, or AI-generated artwork was used. Python authoring sources are included.
|
||||
All listed files use the repository MIT OR Apache-2.0 licence.
|
||||
|
||||
| File | Source / author | Use | License |
|
||||
| --- | --- | --- | --- |
|
||||
| examples/studio/author_showcase.py | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/author_tumblers.py | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/textures/ATTRIBUTION.md | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/textures/author_textures.py | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/textures/environment-manifest.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/textures/manifest.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-hdr-textures-blocked-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-hdr-textures-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-materials.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-sun-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-sun-textures-blocked-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-sun-textures-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-sun.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-textures-blocked-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers-textures-render.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
| examples/studio/tumblers.json | Original SolidCraft contributors | Editable scene / runtime resource / reproducible authoring metadata | MIT OR Apache-2.0 |
|
||||
|
||||
The original studio generators produce local ignored PNG maps and an RGBE gradient.
|
||||
Generated image bytes are not source assets; their authorship, licences and expected
|
||||
hashes are documented under `examples/studio/textures`. Rendered evidence belongs
|
||||
on the results branch. No photographs, scans or external image assets are included.
|
||||
|
||||
## Additional render and showcase resources
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| assets/render/starter/tools/check_all.py | SolidCraft contributors | original read-only authored/native resource validation orchestration and evidence receipts | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/test_check_all.py | SolidCraft contributors | original validation-runner regression fixtures and subprocess tests | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/requirements.txt | SolidCraft contributors | pinned offline authoring tool requirements; no application dependency changes | MIT OR Apache-2.0 |
|
||||
| crates/render/examples/validate_starter.rs | SolidCraft contributors | original native resource conformance checker using public SolidCraft decoding, normalization, sampling and mip APIs | MIT OR Apache-2.0 |
|
||||
| .gitattributes | SolidCraft contributors | original canonical line-ending policy for the existing runtime icon-discovery manifest; no artwork or icon-assignment changes | MIT OR Apache-2.0 |
|
||||
| assets/render/.gitattributes | SolidCraft contributors | original canonical line-ending policy for SHA-256-pinned renderer authoring resources | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/.gitattributes | SolidCraft contributors | original canonical line-ending policy for SHA-256-pinned renderer authoring resources | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/assembly-bench-soft.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/automotive-turntable.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/black-metal-strips.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/cnc-overhead.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/esd-bench-neutral.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/fdm-neutral-inspection.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/garage-door.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/hangar-skylight.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/home-workbench.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/makerspace-worklights.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/mechanical-bay.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/neutral-comparison.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/neutral-side-softbox.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/paint-inspection-bands.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/printed-part-photo.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/rework-offset-strips.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/robot-led-editorial.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/showroom-ribbons.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/spacecraft-clean-bay.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/sun-free-overcast.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/vacuum-black.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/warm-table-window.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/white-enveloping-studio.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/exports/woodshop-window.hdr | SolidCraft contributors | original analytic relative-radiance HDR export; recipe, linear-sRGB primaries and SHA-256 in assets/render/starter/environments/manifest.json; not measured photometry | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/manifest.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/environments/source/recipes.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/lighting/exports/rigs.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/lighting/recipe.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-001/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-001/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-001/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-001/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-001/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-002/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-002/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-002/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-002/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-002/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-003/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-003/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-003/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-003/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-003/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-004/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-004/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-004/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-004/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-004/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-005/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-005/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-005/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-005/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-005/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-006/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-006/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-006/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-006/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-006/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-007/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-007/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-007/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-007/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-007/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-008/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-008/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-008/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-008/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-008/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-009/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-009/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-009/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-009/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-009/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-010/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-010/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-010/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-010/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-010/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-011/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-011/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-011/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-011/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-011/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-012/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-012/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-012/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-012/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-012/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-013/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-013/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-013/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-013/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-013/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-014/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-014/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-014/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-014/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-014/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-015/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-015/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-015/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-015/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-015/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-016/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-016/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-016/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-016/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-016/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-017/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-017/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-017/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-017/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-017/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-018/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-018/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-018/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-018/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-018/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-019/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-019/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-019/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-019/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-019/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-020/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-020/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-020/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-020/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-020/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-021/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-021/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-021/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-021/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-021/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-022/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-022/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-022/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-022/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-022/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-023/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-023/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-023/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-023/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-023/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-024/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-024/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-024/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-024/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-024/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-025/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-025/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-025/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-025/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-025/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-026/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-026/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-026/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-026/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-026/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-027/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-027/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-027/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-027/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-027/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-028/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-028/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-028/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-028/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-028/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-029/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-029/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-029/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-029/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-029/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-030/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-030/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-030/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-030/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-030/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-031/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-031/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-031/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-031/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-031/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-032/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-032/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-032/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-032/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-032/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-033/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-033/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-033/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-033/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-033/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-034/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-034/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-034/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-034/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-034/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-035/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-035/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-035/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-035/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-035/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-036/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-036/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-036/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-036/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-036/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-037/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-037/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-037/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-037/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-037/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-038/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-038/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-038/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-038/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-038/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-039/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-039/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-039/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-039/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-039/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-040/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-040/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-040/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-040/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-040/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-041/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-041/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-041/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-041/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-041/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-042/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-042/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-042/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-042/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-042/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-043/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-043/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-043/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-043/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-043/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-044/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-044/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-044/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-044/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-044/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-045/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-045/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-045/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-045/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-045/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-046/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-046/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-046/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-046/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-046/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-047/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-047/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-047/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-047/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-047/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-048/base_color.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-048/height.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-048/metallic.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-048/normal_open_gl.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/exports/SURF-048/roughness.png | SolidCraft contributors | original deterministic periodic PBR map export; recipe, role, scale and SHA-256 in assets/render/starter/materials/manifest.json; not measured material data | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/manifest.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/materials/source/recipes.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/pack.json | SolidCraft contributors | original clean-room renderer resource recipe or manifest; authored/unbound scope and source receipts in assets/render/starter/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/environments.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/lighting.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/materials.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/test_environments.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/test_lighting.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/test_materials.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/starter/tools/validate_pack.py | SolidCraft contributors | original clean-room offline resource authoring, numerical verification or validation tool; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/licenses/UFL.txt | Canonical Ltd. | exact Ubuntu Font Licence 1.0 notice retained from https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/UFL.txt for the modelled Ubuntu Light lettering | Ubuntu Font Licence 1.0 |
|
||||
| assets/render/selene/materials/appearance-pack.json | SolidCraft contributors | original clean-room English appearance authoring data: 48 illustrative opaque PBR projections with separate advanced target specifications; no measured dataset or external assets | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/materials/appearance-swatches.json | SolidCraft contributors | original analytic command script for 48 opaque box swatches and a support base, derived only from the adjacent original appearance pack; no external artwork or engineering properties | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/models/SELENE-functional.solidcraft | SolidCraft contributors (native enhancements); 0xlillith (original rover); SychPL / Mateusz Sych (supplied showcase assembly); Canonical Ltd. (lettering outlines) | native-command derivative of the unchanged author-supplied source, with original bearing, suspension, gripper, electronics and presentation work; source and final hashes in assets/render/selene/SOURCE.md and VALIDATION.md | Model and showcase contributions: MIT OR Apache-2.0 (explicit SychPL grant https://github.com/tangency-labs/solidcraft/pull/5494#issuecomment-6375788360); lettering: Ubuntu Font Licence 1.0, notice retained in assets/render/selene/licenses/UFL.txt |
|
||||
| assets/render/selene/motion/interference-pairs.json | SolidCraft contributors | original authored exact-body pair selection for bounded native clearance checks on the functional SELENE derivative; not a generated collision result | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/motion/mechanism-acceptance.json | SolidCraft contributors | original kinematic acceptance criteria, inspected source-container bindings and analytic planning checks from cited public SolidCraft documentation and the admitted native source; derivative runtime acceptance is recorded separately | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/motion/preflight-commands.json | SolidCraft contributors | original read-only inventory script using existing project commands; no source-model selectors or state mutations | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/motion/sample-sequence.json | SolidCraft contributors | original future lunar sampling and sealed-vial dynamics state specification; no simulation or physical calibration result | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/scenes/roles.json | SolidCraft contributors | original semantic role and candidate-material authoring specification for the prepared SELENE demo; no native geometry or external assets bundled | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/scenes/shots.json | SolidCraft contributors | original shot, framing and staged-sequence authoring specification for the prepared SELENE demo; no render or simulation result claimed | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/scenes/stages.json | SolidCraft contributors | original stage composition and light-ownership authoring specification derived from the project render catalog; scientific context linked in scenes/README.md | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/source-lock.json | SolidCraft contributors | original source-admission metadata and public-reference inventory pinning the supplied improved SELENE native file; original-model and font notices preserved in SOURCE.md | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/source/SELENE-showcase.solidcraft | 0xlillith (original rover); SychPL / Mateusz Sych (showcase assembly and helpers); SolidCraft contributors (emblem); Canonical Ltd. (lettering outlines) | unchanged author-published native file from https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft; source hash and license evidence in assets/render/selene/SOURCE.md | Model and showcase contributions: MIT OR Apache-2.0 (explicit SychPL grant https://github.com/tangency-labs/solidcraft/pull/5494#issuecomment-6375788360); lettering: Ubuntu Font Licence 1.0, notice retained in assets/render/selene/licenses/UFL.txt |
|
||||
| assets/render/selene/tools/bearings.py | SolidCraft contributors | original native-command authoring of grooved bearings, rolling-element kinematics, clamp hubs and arm/head clearances; analytic geometry, no copied CAD source | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/build.py | SolidCraft contributors | original Python development tool for pinned-source native command replay, staged checkpoints, command-trace and geometry health checks; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/electronics.py | SolidCraft contributors | original native-command Raspberry Pi 5 visual reconstruction using public manufacturer mechanical dimensions; original package envelopes and connector internals, no manufacturer CAD or artwork copied | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/export_views.py | SolidCraft contributors | original native MCP preview export tool for three reusable showcase views; changes only transient visibility and cameras and verifies the source master hash | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/finishes.py | SolidCraft contributors | original native physical-material proxy and opaque PBR assignment generator preserving the supplied rover palette | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/mechanisms.py | SolidCraft contributors | original native-command gripper sleeves, pads, wheel ownership, joint limits and inspection studies with independent analytic suspension relation | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/prepare.py | SolidCraft contributors | original Python development tool for bounded native-container inspection and reviewed opaque body-assignment preparation; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/presentation.py | SolidCraft contributors | original native-command browser organization, camera/render setups and closed sample-vial glass preparation | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/suspension.py | SolidCraft contributors | original native-command trailing-arm suspension, telescoping coilover loops, plain bushings, carrier gussets and local motion clearances derived from the admitted rover geometry; independent analytic pin-distance relation, no copied external CAD | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/validate_native.py | SolidCraft contributors | original bounded native MCP verification tool for sampled SELENE kinematics, independent analytic follower and world-coordinate checks, optional exact-name interference pairs and unchanged input hashes; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/validate_prepared.py | SolidCraft contributors | original Python development validator for prepared SELENE resources, source status, references, hashes and command projections; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/tools/yaw_supports.py | SolidCraft contributors | original native-command plain yaw journals, flanged brass thrust bushings, recessed axial retaining pins and mounting-head clearances derived from the admitted rover geometry; no copied external CAD | MIT OR Apache-2.0 |
|
||||
| assets/render/selene/ui/demo-flow.json | SolidCraft contributors | original progressive-disclosure UI integration specification for the existing Render workspace; no copied UI artwork or runtime registration | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/baseline-setup-commands.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/capabilities.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/environment-presets.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/environments.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/lighting.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/lunar-physics-fixtures.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/materials.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/provenance.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/quality-presets.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/roadmap.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/scene-presets.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/selene-bindings.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/simulation-requirements.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/studio-presets.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/ui-integration.json | SolidCraft contributors | original English UI integration specification and exact source-revision mappings from SolidCraft's own implemented shell, UI kit and accepted icons; no copied artwork or runtime registration | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/ux.json | SolidCraft contributors | original clean-room English catalog, preset or analytic planning data; external references documented in docs/render-materials/SOURCES.md; no external assets bundled | MIT OR Apache-2.0 |
|
||||
| docs/render-materials/validate_catalog.py | SolidCraft contributors | original Python development validator for catalog references, preset composition and analytic specification fixtures; no application runtime dependency | MIT OR Apache-2.0 |
|
||||
|
||||
### Built-in render resource adapters (personal integration batch, 2026-10-22)
|
||||
|
||||
The original adapters in `crates/engine/src/cmd/render/library.rs`, the generated lookup `library_data.rs` and its generator `tools/render-library/generate.py` project the already attributed starter and SELENE resources without replacing their bytes or authoring manifests. The added scalar texture channels, explicit color/V conventions and immutable-source/GPU-payload sharing are original contributor work under MIT OR Apache-2.0. No external code, commercial CAD data or new third-party imagery was imported. Source metadata and the original authoring attribution remain authoritative; pending runtime acceptance is not a photometric or engineering qualification.
|
||||
|
||||
## Physical reference resource additions
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| assets/render/physical/bindings.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/exports/coverage.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/exports/native-cards.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/profiles.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/quantities.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/sources.json | SolidCraft contributors | original physical-reference curation, associations or derived schema-1 export; per-fact public sources retained without relicensing their publications | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/tools/check_physical.py | SolidCraft contributors | original offline physical-reference validation and projection tool | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/tools/physical.py | SolidCraft contributors | original offline physical-reference validation and projection tool | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/tools/test_physical.py | SolidCraft contributors | original offline physical-reference validation and projection tool | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/tools/export_library.py | SolidCraft contributors | original explicit reference-library planner and native no-loss export verifier; no external code | MIT OR Apache-2.0 |
|
||||
| assets/render/physical/tools/test_export_library.py | SolidCraft contributors | original regressions for native capability refusal, source identity and physical-card preservation | MIT OR Apache-2.0 |
|
||||
|
||||
| tools/render-library/selene_studio.py | SolidCraft contributors | original bounded native MCP studio orchestration with pinned editable master, explicit GPU policy and request/export receipts; no generated model or image substitutes | MIT OR Apache-2.0 |
|
||||
|
||||
| tools/render-library/selene_recipe.py | SolidCraft contributors | original full-detail SELENE material/light composition and analytic camera fit; unchanged pinned native master, no external imagery or measured optical dataset | MIT OR Apache-2.0 |
|
||||
| tools/render-library/test_selene_recipe.py | SolidCraft contributors | original independent projection, scaling, nonmutation and input-refusal fixtures for the SELENE studio recipe | MIT OR Apache-2.0 |
|
||||
|
||||
| assets/render/selene/scenes/studio-hero.json | SolidCraft contributors | original executable render intent and verified provenance for the selected native SELENE studio showcase; authored RGB appearance and relative light units, not measured optics or simulation results | MIT OR Apache-2.0 |
|
||||
| tools/render-library/publish_selene.py | SolidCraft contributors | original bounded native-frame publication checks for explicit visual review, source identity, resource hashes, PNG CRCs and scanline limits; copies completed native bytes without image synthesis or resampling | MIT OR Apache-2.0 |
|
||||
| tools/render-library/test_publish_selene.py | SolidCraft contributors | original tiny analytic PNG fixtures for source-size, CRC, expansion, dimensions and explicit-publication-consent regressions | MIT OR Apache-2.0 |
|
||||
|
||||
| tools/render-library/package_selene.py | SolidCraft contributors | original byte-preserving packaging of the reviewed native SELENE PNG, public provenance and checksums; bounded resource/PNG verification, no fonts, executables or new render execution | MIT OR Apache-2.0 |
|
||||
| .github/workflows/selene-showcase.yml | SolidCraft contributors | original read-only artifact-delivery workflow for the reviewed native SELENE export; existing pinned repository actions, no compilation, package installation, secret use or renderer claims | MIT OR Apache-2.0 |
|
||||
|
||||
| tools/render-library/verify_linear_master.py | SolidCraft contributors | original independent validation driver for native linear EXR output using the official OpenEXR Python reader as an external test oracle; no codec implementation copied or production dependency added | MIT OR Apache-2.0 |
|
||||
|
||||
## Aging, effects and backgrounds showcase, 2026-10-23
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| tools/render-showcase/instrument.py | SolidCraft contributors | original native-scene authoring, checksum-verified editorial assembly or bounded delivery tool; no third-party source or font binary copied | MIT OR Apache-2.0 |
|
||||
| tools/render-showcase/compose.py | SolidCraft contributors | original native-scene authoring, checksum-verified editorial assembly or bounded delivery tool; no third-party source or font binary copied | MIT OR Apache-2.0 |
|
||||
| tools/render-showcase/package.py | SolidCraft contributors | original native-scene authoring, checksum-verified editorial assembly or bounded delivery tool; no third-party source or font binary copied | MIT OR Apache-2.0 |
|
||||
|
||||
| distribution/SolidCraft-Render-Showcase.zip | SolidCraft contributors and the explicitly credited original model/UI/resource authors | byte-verified selected collaborator package of reviewed native media, editable sample, recipes and public provenance; contained attribution and existing SELENE lettering notices retained; no fonts or executable binaries | MIT OR Apache-2.0 for new contributions; referenced original notices retained |
|
||||
| distribution/SolidCraft-Render-Showcase.json | SolidCraft contributors | original verified delivery archive manifest with exact SHA-256, member count and bounded scope | MIT OR Apache-2.0 |
|
||||
|
||||
+8
-2
@@ -186,8 +186,14 @@ no LTO, and debug assertions off (truck has debug-only assertions that reject va
|
||||
builds several times faster than `--release`. If a test fails only in a plain debug build, say so
|
||||
in the PR. `cargo xtask test` builds the tests with it and then runs every test binary at once
|
||||
(`cargo test` runs them one after another); arguments after `--` go to each binary, e.g.
|
||||
`cargo xtask test -- shell`. Tests run beside each other on a busy machine, so a test must not
|
||||
depend on wall-clock timing.
|
||||
`cargo xtask test -- shell`. Set `SOLIDCRAFT_TEST_JOBS` to a positive integer to opt into a
|
||||
shared bound on top-level test/side commands for `cargo xtask test` and `cargo xtask ci`.
|
||||
For example, `SOLIDCRAFT_TEST_JOBS=2` allows two commands at once; the sequential wasm/doc
|
||||
worker consumes one of those slots. Every binary and side check still runs after failures.
|
||||
Without the variable the existing concurrency is unchanged. `RUST_TEST_THREADS`,
|
||||
`ACTION_MATRIX_JOBS` and Cargo's build-job setting remain independent caller overrides;
|
||||
this limit does not choose their values or change test filters, timeouts or baselines.
|
||||
Tests run beside each other on a busy machine, so a test must not depend on wall-clock timing.
|
||||
|
||||
**Ready pull requests test what they touch.** CI maps changed files to workspace packages and
|
||||
runs Clippy, the test build and tests for those and their dependents. The
|
||||
|
||||
Generated
+20
-17
@@ -4208,7 +4208,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"block2 0.6.2",
|
||||
"eframe",
|
||||
@@ -4240,11 +4240,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-3dx-client"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-cli"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4256,7 +4256,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-derive"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4265,7 +4265,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-doc"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -4282,7 +4282,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-engine"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"schemars",
|
||||
@@ -4301,7 +4301,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-geom"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4310,15 +4310,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-gpu"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
"naga",
|
||||
"pollster 0.4.0",
|
||||
"robust",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"solidcraft-engine",
|
||||
"solidcraft-geom",
|
||||
"solidcraft-io",
|
||||
"solidcraft-kernel",
|
||||
"solidcraft-render",
|
||||
"thiserror 2.0.21",
|
||||
@@ -4327,7 +4330,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-io"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"cadmpeg-core",
|
||||
"cadmpeg-ir",
|
||||
@@ -4350,7 +4353,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-kernel"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"proptest",
|
||||
@@ -4370,7 +4373,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-mcp"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"solidcraft-engine",
|
||||
@@ -4379,7 +4382,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-render"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"moxcms",
|
||||
@@ -4393,7 +4396,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-sketch"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4404,14 +4407,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-space-mouse"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-ui-egui"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
@@ -4440,7 +4443,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-web"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
@@ -5976,7 +5979,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"serde_json",
|
||||
|
||||
+2
-1
@@ -5,7 +5,7 @@ members = ["crates/*", "apps/*", "xtask"]
|
||||
exclude = ["vendor"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
rust-version = "1.95"
|
||||
@@ -13,6 +13,7 @@ authors = ["SolidCraft contributors"]
|
||||
repository = "https://github.com/bherbruck/solidcraft"
|
||||
|
||||
[workspace.dependencies]
|
||||
robust = "1.2"
|
||||
# internal
|
||||
solidcraft-geom = { path = "crates/geom" }
|
||||
solidcraft-sketch = { path = "crates/sketch" }
|
||||
|
||||
+8
-2
@@ -55,10 +55,10 @@ PCB / Package, Render, Animation, Simulation, Manufacture/CAM, Drawings.
|
||||
| M3 | General fillets and chamfers (curved edges, chains, vertex blends); saddle rolling-ball surfaces now use continuous seam sections and arc-length fitting with shared contact boundaries and bounded accuracy checks; tiny rim edges remain selected instead of nearby wall seams when filleting (#2498) | in progress | 30 |
|
||||
| M4 | Files: STEP import (done — [docs/step-import.md](docs/step-import.md)), FreeCAD/Rhino solids through cadmpeg (done, desktop, browser and CLI), 3MF export and 3MF/STL import as mesh bodies (done), 3MF with B-rep face tags ([docs/formats/3mf-face-tags.md](docs/formats/3mf-face-tags.md), done), constant-section parametric mesh reconstruction, DXF sketches, OBJ import | in progress | 6 |
|
||||
| M5 | Persistent naming of faces and edges (docs/book/src/dev/naming.md): faces named from their exact kernel-reported history (sketch curve sides, caps, revolve sections, primitive sides, blends, shell inner walls, pattern/mirror copies; split pieces told apart by the faces around them, lumps of a cut body named after their faces), edges by their faces; fillets/chamfers, sketches on faces, shell/draft/offset/replace faces, hole placements, joint origins and face appearances resolve by name first and warn when the entity split or vanished: done. sheet metal edges by base sketch line and flange side, shell inner faces, sweep and loft roles: done. kernel-reported face history: done (merged faces answer to every name; operations without history yet fall back to geometric names, flagged unverified; format 14 keeps older designs' geometric names). Left: history through sheet metal, plastic, surface and emboss features; FaceSource certificates through history | in progress | 20 |
|
||||
| M6 | UI depth: selection feedback and origin (done), timeline editing (done: hover and selection highlight modifier faces, including fillets and chamfers; edit feature, history marker drag, dependency-checked single and multi-item reorder, suppress, rename, delete with dependents, re-resolved references; redefining selections refreshes persistent edge/face references while retaining feature identity and dimension names; responsive feature history with width-driven icons/names/title, snapping width resize, bottom/left/browser-stack docking, shared-column collapse, rollback bar, multi-selection and persistent folders), right-docked dialogs (done), live previews for every feature dialog (done), keyboard-first commands with on-canvas value boxes and sketch inline dimensions (done), drag manipulators with automatic join/cut (done: extrude incl. two sides, fillet, shell, hole depth, move, pattern spacing, revolve rotator, extrude taper), dark theme (done), right-click menu with Repeat (done), measure tool (done), section analysis (done), selection filter (done), drag-solve of sketch points (done); appearance controls now preserve body/face/component targeting, named transparent looks, reuse/search and override removal; preferences | in progress | 6 |
|
||||
| M6 | UI depth: selection feedback and origin (done), timeline editing (done: hover and selection highlight modifier faces, including fillets and chamfers; edit feature, history marker drag, dependency-checked single and multi-item reorder, suppress, rename, delete with dependents, re-resolved references; redefining selections refreshes persistent edge/face references while retaining feature identity and dimension names; responsive feature history with width-driven icons/names/title, snapping width resize, bottom/left/browser-stack docking, shared-column collapse, rollback bar, multi-selection and persistent folders), right-docked dialogs (done), live previews for every feature dialog (done), keyboard-first commands with on-canvas value boxes and sketch inline dimensions (done), drag manipulators with automatic join/cut (done: extrude incl. two sides, fillet, shell, hole depth, move, pattern spacing, revolve rotator, extrude taper), dark theme (done), right-click menu with Repeat (done), measure tool (done), section analysis (done), selection filter (done), drag-solve of sketch points (done); appearance controls now preserve body/face/component targeting, named transparent looks, reuse/search and override removal; Browser Expand All / Collapse All (`browser.expand_all`, `browser.collapse_all`) on the design and component menus; preferences | in progress | 6 |
|
||||
| M7 | Thin extrude (walls along open or closed curves: centre, inside, outside or two sides; mitred corners, crossing walls joined; #721), sweep, loft (incl. to a point), rib and web (to next / depth), emboss (planar faces and exact radial emboss/deboss of bounded orthogonal profiles on complete exterior cylinders/sleeves), thread (cosmetic, and modelled M3–M20 outside and inside: the ISO profile screwed in as a faceted cut), coil (smooth B-spline helical walls), pipe, pattern on path, patterns of bodies and components, replace face (parallel), align, remove, feature copy/paste: done. Unique eligible cylindrical targets are inferred for new Emboss features. Left: general curved-face emboss and exact (unfaceted) modelled threads | in progress | 12 |
|
||||
| M8 | Surface workspace (#772). Done: Patch (sketch regions; edge loops filled G0, plus `crown`), Stitch, Thicken (planes and cylinders), Extend (straight edges of planar surfaces), Trim (by a plane, a face or sketch curves swept onto the surface, keeping a side or the picked regions; mutual trim of two surfaces, extended to meet and stitched, #767), Delete Face (healing), Boundary Fill, zebra/draft/curvature-map analysis, Surface Extrude/Revolve/Sweep/Loft from open and closed curves, Offset, Unstitch and Reverse Normal; the continuity-driven core (`kernel/src/bridge.rs`, G0–G3 Hermite rows) with **Blend** (`surface.blend`, #764: edge chains along one or several faces, closed rims paired seam to seam or from picked seams, a dialog), **Match** (`surface.match`), **Boundary** (`surface.boundary`, #763 — two sketch curves exact with G0–G3, three or four as the flat patch of their loop, and curve networks: Coons and Gordon surfaces through sketch, 3D-sketch or edge curves, a point for a three-sided side, G1/G2 against the faces along one direction's edges, joined into their body on request; G1/G2 on two sides that meet at a corner waits for the Gregory-type corner), **Fair** (`surface.fair`, CV fairing), **continuity analysis** (`inspect.continuity`, #770; a toolbar tool with edge markers and a legend, and curvature combs along face isocurves) and a multi-section **loft** with per-end continuity and crown, and guide rails on solid and surface lofts (one or two, scaling or stretching the sections between; #201). Also in the Class-A pass: G1…G4 blend curves in the sketch, chord and variable-radius fillets on curved edges (with honest refusals where the fit cannot hold), and a G2 corner patch where filleted edges meet (kernel; the command refuses until the patch's sections can be sewn to the blends' contacts). Left: bias/form-factor fillet sections (design recorded), a Gregory-type corner, surface Fillet between separate surface bodies (#769), Ruled (#762), Untrim (#761), curved-face Extend (#760), and every remaining #757–#772 item | deferred | — |
|
||||
| M9 | Components and assemblies: New Component / Create Components from Bodies, active component, per-component origin/bodies/sketches/timeline entries, occurrences with transforms, Copy/Paste vs Paste New, nested Browser tree with visibility and isolate; Ground, Move/Copy of occurrences, joints (rigid, revolute, slider, cylindrical, pin-slot, planar, ball) by joint origins with limits and Drive Joints, closed kinematic loops (four-bar, slider-crank: the loop's other joints follow the driven one on its branch, and driving stops where a loop can no longer close), cams (`joint.cam`: a revolute cam drives a slider or revolute follower along a closed sketch profile or the cam's edges, knife, roller or flat followers, worked out again when the profile changes; drives, studies, closed loops, contact sets), As-built Joint, Rigid Group, Contact Sets (driving and motion studies stop where bodies in a set would pass through each other), Motion Study (joint values keyed along a timeline, playback, export of occurrence positions as JSON/CSV), motion analysis (joint values and a point's path charted over a study as value, velocity and acceleration; the parts that collide along a study, with the steps where they do), Exploded views (automatic or by hand, shown without changing placements); interference, per-component physical properties; STEP with assembly structure; URDF export for robot simulators (links with meshes, mass and inertia; joint chains whose values match Drive Joints; docs/urdf.md). Physical properties now measure material-aware component/occurrence placements, descendants and repeated instances, including pending moves and body reassignment offsets; contact geometry and automatic exploded centres respect those offsets. Groundwork done: component tree, occurrences with transforms (instances, Paste New), world placement, active component as authoring frame, ground, Capture/Revert Position, moving bodies and sketches. UI: ASSEMBLE panel dialogs for New Component, Joint (snaps on faces, edges, circles and vertices; animated motion preview; offsets, flip, limits), As-built Joint, Joint Origin, Rigid Group, Drive Joints (live slider), Motion Link, Cam and Interference (overlaps shown red); joints in the timeline and the Browser | in progress | 32 |
|
||||
| M9 | Components and assemblies: New Component / Create Components from Bodies, active component, per-component origin/bodies/sketches/timeline entries, occurrences with transforms, Copy/Paste vs Paste New, nested Browser tree with visibility and isolate; Ground, Move/Copy of occurrences, joints (rigid, revolute, slider, cylindrical, pin-slot, planar, ball) by joint origins with limits and Drive Joints, closed kinematic loops (four-bar, slider-crank: the loop's other joints follow the driven one on its branch, and driving stops where a loop can no longer close), cams (`joint.cam`: a revolute cam drives a slider or revolute follower along a closed sketch profile or the cam's edges, knife, roller or flat followers, worked out again when the profile changes; drives, studies, closed loops, contact sets), As-built Joint, Rigid Group, Contact Sets (driving and motion studies stop where bodies in a set would pass through each other), Motion Study (joint values keyed along a timeline, playback, export of occurrence positions as JSON/CSV), motion analysis (joint values and a point's path charted over a study as value, velocity and acceleration; the parts that collide along a study, with the steps where they do), Exploded views (automatic or by hand, shown without changing placements, and exported as an animation coming apart and back together); interference, per-component physical properties; STEP with assembly structure; URDF export for robot simulators (links with meshes, mass and inertia; joint chains whose values match Drive Joints; docs/urdf.md). Physical properties now measure material-aware component/occurrence placements, descendants and repeated instances, including pending moves and body reassignment offsets; contact geometry and automatic exploded centres respect those offsets. Groundwork done: component tree, occurrences with transforms (instances, Paste New), world placement, active component as authoring frame, ground, Capture/Revert Position, moving bodies and sketches. UI: ASSEMBLE panel dialogs for New Component, Joint (snaps on faces, edges, circles and vertices; animated motion preview; offsets, flip, limits), As-built Joint, Joint Origin, Rigid Group, Drive Joints (live slider), Motion Link, Cam and Interference (overlaps shown red); joints in the timeline and the Browser | in progress | 32 |
|
||||
| M10 | Sheet metal: flange (base, edge, contour), hem, unfold/refold, convert, flat pattern + DXF, rules: done. PLASTIC enclosure subset: Boss, Rib, Web, Lip/Groove, Snap Fit, Rest, Plastic Rules (library, edit, assign; rule draft and clearance as feature defaults): done, tested against hand-computed geometry. UI: SHEET METAL and PLASTIC tabs with dialogs (live preview, Edit Feature, pre-selection) for Flange, Hem, Unfold/Refold, Convert, Sheet Metal Rules, Create Flat Pattern (flat view with bend lines, bend table CSV/JSON and DXF export with exact circle/arc/line cutouts), Boss, Lip/Groove, Snap Fit, Rest, Manage and Assign Plastic Rules; Fold (bend along a sketch line); flanges meeting at a corner closed at any angle with the rule's gap; edge flanges with their own angle and height per edge in one feature; corner reliefs (notch, round, rectangular, tear) chosen by the rule; Convert to Sheet Metal from a solid or shelled body by its bend edges (flat faces, sharp bends) | in progress | 36 |
|
||||
| M11 | 2D drawings | deferred | — |
|
||||
| M12 | Release: cross-platform packages, verification and deliberate publication implemented; original current-UI demo refreshed. Trusted distribution signing and broader performance work remain | in progress | 16 |
|
||||
@@ -143,6 +143,12 @@ completed drawings publish atomically. The browser still exports synchronously.
|
||||
|
||||
## Render foundation
|
||||
|
||||
- Original starter appearances (#1722): 34 opaque recipes through existing commands, with six explicitly unavailable glass recipes and preserved legacy looks; see [the contract](docs/render-starter-appearances.md).
|
||||
|
||||
- Bounded linear film accumulation (#1696) supplies caller-admitted mean/variance storage and complete-pass views; actual progressive consumers remain separate. See [the film contract](docs/render-film.md).
|
||||
|
||||
- Definition-local visual mapping (#1214) supplies a bounded numerical frame, physical repeat coordinates and a deterministic one-time grain-axis suggestion. It adds no saved record or texture consumer; see [the mapping contract](docs/render-visual-mapping.md).
|
||||
|
||||
- Explicit texture normalization (#1218) produces completed float RGBA with
|
||||
role-aware linear color/data semantics, bounded matrix/TRC ICC conversion and
|
||||
opt-in EXIF orientation. It retains high-precision raw samples and records lossy
|
||||
|
||||
@@ -19,6 +19,11 @@ path = "src/main.rs"
|
||||
name = "solvecraft-cli"
|
||||
path = "src/alias.rs"
|
||||
|
||||
[features]
|
||||
default = ["raytrace-cpu"]
|
||||
bundled-render-library = ["solidcraft-engine/bundled-render-library"]
|
||||
raytrace-cpu = ["solidcraft-engine/raytrace-cpu"]
|
||||
|
||||
[dependencies]
|
||||
solidcraft-engine = { workspace = true }
|
||||
solidcraft-gpu = { workspace = true }
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
//! Reproducible evidence through the production command/job interfaces.
|
||||
//! Usage: studio_evidence RECIPE.json RENDER-PARAMS.json OUTPUT.png
|
||||
//! Writes the editable design, command timings and actual adapter/job metadata beside PNG.
|
||||
//! Accepts runtime requests as well as inline or named saved render jobs.
|
||||
use serde_json::{Value, json};
|
||||
use solidcraft_engine::{
|
||||
Session,
|
||||
doc::render_settings::{RenderJob, RenderSetup},
|
||||
render::job::{CpuHost, ErrorCode, JobId, Phase},
|
||||
};
|
||||
use std::{
|
||||
io::Read,
|
||||
path::Path,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
fn read_json(path: &str) -> Result<Value, String> {
|
||||
let mut bytes = Vec::new();
|
||||
std::fs::File::open(path).map_err(|e| format!("{path}: {e}"))?.take(16_777_217).read_to_end(&mut bytes).map_err(|e| e.to_string())?;
|
||||
if bytes.len() > 16_777_216 {
|
||||
return Err("evidence input exceeds 16 MiB".into());
|
||||
}
|
||||
serde_json::from_slice(&bytes).map_err(|e| format!("{path}: {e}"))
|
||||
}
|
||||
|
||||
// Only decide which optional host must be installed. The production command
|
||||
// still validates and resolves the actual request without a second wire format.
|
||||
fn needs_gpu(session: &Session, params: &Value) -> Result<bool, String> {
|
||||
let inline = params.get("settings").filter(|value| !value.is_null());
|
||||
let named = params.get("setup").filter(|value| !value.is_null());
|
||||
if inline.is_some() && named.is_some() {
|
||||
return Err("choose either setup or settings".into());
|
||||
}
|
||||
let inline_setup = inline
|
||||
.filter(|value| value.get("job").is_some_and(|job| !job.is_null()))
|
||||
.map(|value| serde_json::from_value::<RenderSetup>(value.clone()).map_err(|e| e.to_string()))
|
||||
.transpose()?;
|
||||
let setup = if let Some(name) = named.and_then(Value::as_str) {
|
||||
Some(session.doc.render.setups.get(name).ok_or("no saved render setup with that name")?)
|
||||
} else {
|
||||
inline_setup.as_ref()
|
||||
};
|
||||
if let Some(setup) = setup
|
||||
&& let Some(job) = &setup.job
|
||||
{
|
||||
if params.as_object().is_some_and(|object| object.keys().any(|key| !matches!(key.as_str(), "setup" | "settings" | "replace"))) {
|
||||
return Err("saved render jobs cannot be mixed with runtime controls".into());
|
||||
}
|
||||
setup.validate().map_err(|e| e.to_string())?;
|
||||
return Ok(matches!(job, RenderJob::GpuPath { .. }));
|
||||
}
|
||||
Ok(params.get("progressive").and_then(Value::as_bool) == Some(true))
|
||||
}
|
||||
|
||||
fn run() -> Result<(), String> {
|
||||
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||
let [recipe_path, params_path, output_path] = args.as_slice() else {
|
||||
return Err("usage: studio_evidence RECIPE.json RENDER-PARAMS.json OUTPUT.png".into());
|
||||
};
|
||||
let output = Path::new(output_path);
|
||||
if !output.extension().is_some_and(|e| e.eq_ignore_ascii_case("png")) {
|
||||
return Err("output must have a .png extension".into());
|
||||
}
|
||||
let recipe = read_json(recipe_path)?;
|
||||
let params = read_json(params_path)?;
|
||||
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 generation_seconds = generation_start.elapsed().as_secs_f64();
|
||||
let design_path = output.with_extension("solidcraft");
|
||||
session.execute("file.save_as", &json!({"path":design_path})).map_err(|e| e.to_string())?;
|
||||
let scene = solidcraft_engine::product_scene::extract(&session).map_err(|e| e.to_string())?;
|
||||
let bodies: Vec<Value> = scene
|
||||
.meshes
|
||||
.iter()
|
||||
.map(|mesh| json!({"name":mesh.name,"vertices":mesh.mesh.positions.len(),"triangles":mesh.mesh.triangles.len()}))
|
||||
.collect();
|
||||
drop(scene);
|
||||
|
||||
let cpu_host_start = Instant::now();
|
||||
session.set_render_job_host(Some(CpuHost::for_platform().map_err(|e| e.to_string())?)).map_err(|e| e.to_string())?;
|
||||
let cpu_host_seconds = cpu_host_start.elapsed().as_secs_f64();
|
||||
// Match runtime and saved-job dispatch. CPU evidence must not require a
|
||||
// Vulkan device, parse GPU policy or initialize a GPU host.
|
||||
let (adapter_report, gpu_host_seconds) = if needs_gpu(&session, ¶ms)? {
|
||||
let gpu_host_start = Instant::now();
|
||||
let policy = solidcraft_gpu::select::Policy::from_env().map_err(|e| e.to_string())?;
|
||||
let (adapter, report) =
|
||||
solidcraft_gpu::select::pick_vulkan(policy, |_| true).ok_or("no Vulkan adapter satisfies the requested GPU policy")?;
|
||||
session.register_render_job_host(solidcraft_gpu::path::host_on_adapter(&adapter).map_err(|e| e.to_string())?).map_err(|e| e.to_string())?;
|
||||
(Some(report), Some(gpu_host_start.elapsed().as_secs_f64()))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let preflight = session.execute("render.preflight", ¶ms).map_err(|e| e.to_string())?;
|
||||
let start = Instant::now();
|
||||
let started = session.execute("render.start", ¶ms).map_err(|e| e.to_string())?;
|
||||
let executor = started
|
||||
.get("resolved")
|
||||
.and_then(|resolved| resolved.get("executor"))
|
||||
.and_then(Value::as_str)
|
||||
.ok_or("started job did not report the resolved image executor")?
|
||||
.to_owned();
|
||||
let id: JobId = serde_json::from_value(started.get("job").cloned().ok_or("missing job id")?).map_err(|e| e.to_string())?;
|
||||
let handle = session.render_job_handle(id).map_err(|e| e.to_string())?;
|
||||
eprintln!("Rendering through production {executor} executor");
|
||||
if let Some(adapter) = &adapter_report {
|
||||
eprintln!("GPU adapter: {adapter:?}");
|
||||
}
|
||||
let status = loop {
|
||||
match handle.wait_timeout(Duration::from_secs(10)) {
|
||||
Ok(status) => break status,
|
||||
Err(error) if error.code == ErrorCode::TimedOut && start.elapsed() < Duration::from_secs(3600) => {
|
||||
let status = handle.status().map_err(|e| e.to_string())?;
|
||||
eprintln!(
|
||||
"Render progress: {:?} {}/{} after {:.1}s",
|
||||
status.progress.phase,
|
||||
status.progress.done,
|
||||
status.progress.total,
|
||||
start.elapsed().as_secs_f64()
|
||||
);
|
||||
}
|
||||
Err(error) => {
|
||||
let _ = handle.cancel();
|
||||
return Err(error.to_string());
|
||||
}
|
||||
}
|
||||
};
|
||||
let render_and_encode_seconds = start.elapsed().as_secs_f64();
|
||||
if status.progress.phase != Phase::Completed {
|
||||
return Err(status.error.map_or_else(|| "render did not complete".into(), |e| e.to_string()));
|
||||
}
|
||||
let exported = session.execute("render.export", &json!({"job":id,"path":output_path,"overwrite":true})).map_err(|e| e.to_string())?;
|
||||
let report = json!({
|
||||
"recipe":recipe_path,"render_params":params,"executor":executor,"adapter":adapter_report,
|
||||
"environment":{"SOLIDCRAFT_GPU":std::env::var("SOLIDCRAFT_GPU").ok(),"WGPU_BACKEND":std::env::var("WGPU_BACKEND").ok()},
|
||||
"cad_generation_seconds":generation_seconds,"cpu_host_setup_seconds":cpu_host_seconds,"gpu_host_setup_seconds":gpu_host_seconds,
|
||||
"render_and_encode_seconds":render_and_encode_seconds,
|
||||
"timing_scope":"wall time from render.start through completed PNG encoding; includes job preparation and readback, excludes CAD generation, preflight and initial CPU/GPU host setup; GPU setup timing includes adapter selection and pipelines when requested",
|
||||
"bodies":bodies,"commands":commands,"command_timings":command_timings,
|
||||
"preflight":preflight,"export":exported,"editable_design":design_path
|
||||
});
|
||||
std::fs::write(output.with_extension("json"), serde_json::to_vec_pretty(&report).map_err(|e| e.to_string())?).map_err(|e| e.to_string())?;
|
||||
println!("{}", serde_json::to_string_pretty(&report).map_err(|e| e.to_string())?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
run()
|
||||
}
|
||||
@@ -69,6 +69,7 @@ impl Control {
|
||||
return Err("--connect requires a loopback address and a nonzero port (the app listens on 127.0.0.1)".into());
|
||||
}
|
||||
let token = solidcraft_engine::control_auth::client_token(addr.port(), token)
|
||||
.map(|t| t.token)
|
||||
.ok_or("no control token: pass --token, set SOLIDCRAFT_CONTROL_TOKEN, or run on the app's computer (its token file)")?;
|
||||
if token.len() > 4096 {
|
||||
return Err("the control token is longer than 4096 bytes".into());
|
||||
|
||||
@@ -69,7 +69,7 @@ const USAGE_BENCH_ASSISTANT: &str = " solidcraft-cli bench-assistant --connect
|
||||
/// `snapshot`'s lines in the usage.
|
||||
const USAGE_SNAPSHOT: &str = " solidcraft-cli snapshot <script|design> [--in design.solidcraft|part.step] --out shot.png [--width W] [--height H] [--view NAME | --camera JSON] [--no-grid] [--no-axes]\n [--body NAME:opacity=0.3,color=#rrggbb]... [--tool NAME]... [--section z=27]\n solidcraft-cli snapshot --in <design.solidcraft|part.step> --out shot.png ...\n (as with run, --in starts from a design and the script runs on top of it; an option snapshot doesn't take is an error;\n --view: iso, front, back, top, bottom, left, right, or the name of a view saved in the design with view.save;\n --camera: {target: [x,y,z], yaw, pitch, distance, fov?} in mm and radians, as the MCP screenshot takes it (docs/mcp.md);\n --no-grid and --no-axes leave the ground grid (on Z 0) and the origin's axes out of the picture;\n --body: how one body is drawn, as appearance.assign takes it: opacity 0-1 (below 1 is see-through, so what is inside\n it shows) and color #rrggbb, either or both, once per body;\n --tool: draw this body solid in the tool colour and every other body see-through, so a cut's or a join's tool body\n is visible inside the material it meets; a later --body overrides it;\n --section: cut the model as inspect.section does, so the inside shows: z=27 (the plane through that world\n coordinate, keeping the smaller side), add ,flip to keep the other side, or XY, XZ, YZ, or its own JSON)\n";
|
||||
/// `render`'s lines in the usage.
|
||||
const USAGE_RENDER: &str = " solidcraft-cli render <script|design> --out image.png [--setup NAME] [--width W] [--height H] [--transparent] [--overwrite] [--timeout SECONDS]\n";
|
||||
const USAGE_RENDER: &str = " solidcraft-cli render <script|design> --out image.png [--setup NAME] [--width W] [--height H] [--transparent] [--overwrite] [--timeout SECONDS]\n [--progressive] [--samples N] [--max-depth N] [--seed N] [--exposure EV] [--lighting FILE.json] [--environment FILE.json] [--tone-map reinhard|aces_fitted]\n";
|
||||
/// `exec`'s lines in the usage.
|
||||
const USAGE_EXEC: &str = " solidcraft-cli exec <command> [json-params]\n";
|
||||
/// `commands`'s lines in the usage.
|
||||
@@ -82,7 +82,7 @@ const USAGE_ORACLE: &str = " solidcraft-cli oracle <case-dir>... [--json]\n";
|
||||
const USAGE_FUZZ: &str =
|
||||
" solidcraft-cli fuzz [--from N] [--count N] [--jobs J] [--timeout S] [--steps N] [--minimise] [--out DIR] [--report FILE]\n";
|
||||
/// `mcp`'s lines in the usage.
|
||||
const USAGE_MCP: &str = " solidcraft-cli mcp [--headless] [--in design.solidcraft|script.json] [--connect 127.0.0.1:PORT [--token T]] [--allow-path DIR]... [--allow-any-path]\n [--param-check off|warn|strict]\n";
|
||||
const USAGE_MCP: &str = " solidcraft-cli mcp [--headless] [--in design.solidcraft|script.json] [--connect 127.0.0.1:PORT [--token T]] [--allow-path DIR]... [--allow-any-path]\n [--param-check off|warn|strict] [--render-gpu]\n";
|
||||
/// `crashes`'s lines in the usage.
|
||||
const USAGE_CRASHES: &str = " solidcraft-cli crashes [list [--json] | show <id> | replay <id> | dir | clear [<id>]]\n";
|
||||
/// `licences`'s lines in the usage.
|
||||
@@ -629,6 +629,10 @@ fn cmd_exec(args: &[String]) -> Result<(), String> {
|
||||
/// a running app's control port. stdout carries only protocol messages. Files the agent's tool
|
||||
/// calls reach are confined to `solidcraft_mcp::agent_scope` unless `--allow-any-path` is given.
|
||||
fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
let render_gpu = args.iter().any(|arg| arg == "--render-gpu");
|
||||
if render_gpu && flag(args, "--connect").is_some() {
|
||||
return Err("mcp: --render-gpu installs a headless image host; a connected application owns its own device".into());
|
||||
}
|
||||
install_renderer();
|
||||
let scope = (!args.iter().any(|a| a == "--allow-any-path"))
|
||||
.then(|| solidcraft_mcp::agent_scope(flags(args, "--allow-path").into_iter().map(std::path::PathBuf::from)));
|
||||
@@ -672,9 +676,13 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
}
|
||||
Box::new(remote)
|
||||
}
|
||||
(None, Some(path)) => Box::new(solidcraft_mcp::Headless::new(load_checked(path, param_check)?)),
|
||||
// No arguments: the running desktop app, found through the discovery file it wrote
|
||||
// (docs/control-protocol.md); none running (or `--headless`): a session of its own.
|
||||
(None, Some(path)) => {
|
||||
let mut headless = solidcraft_mcp::Headless::new(load_checked(path, param_check)?);
|
||||
if render_gpu {
|
||||
headless.session.register_render_job_host(solidcraft_gpu::path::host().map_err(|e| e.to_string())?).map_err(|e| e.to_string())?;
|
||||
}
|
||||
Box::new(headless)
|
||||
}
|
||||
(None, None) => {
|
||||
if !args.iter().any(|a| a == "--headless")
|
||||
&& let Some(port) = discover_app()
|
||||
@@ -684,6 +692,9 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
|
||||
}
|
||||
let mut headless = solidcraft_mcp::Headless::default();
|
||||
headless.session.param_check = param_check;
|
||||
if render_gpu {
|
||||
headless.session.register_render_job_host(solidcraft_gpu::path::host().map_err(|e| e.to_string())?).map_err(|e| e.to_string())?;
|
||||
}
|
||||
Box::new(headless)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,25 +1,89 @@
|
||||
//! Complete headless image-job workflow through the same engine commands as the UI/MCP.
|
||||
use serde_json::json;
|
||||
use serde_json::{Value, json};
|
||||
use solidcraft_engine::{
|
||||
doc::render_settings::RenderSetup,
|
||||
render::job::{CpuHost, JobId, Phase},
|
||||
Session,
|
||||
doc::render_settings::{RenderJob, RenderSetup},
|
||||
render::job::{CpuHost, JobId, Phase, ToneMap},
|
||||
};
|
||||
|
||||
/// Only explicit runtime CLI flags are stored here. A typed setup owns these
|
||||
/// values even when a supplied flag happens to match the saved value.
|
||||
#[derive(Default)]
|
||||
struct RuntimeOptions {
|
||||
progressive: bool,
|
||||
transparent: bool,
|
||||
samples: Option<u32>,
|
||||
max_depth: Option<u32>,
|
||||
seed: Option<u32>,
|
||||
lighting: Option<String>,
|
||||
tone_map: Option<ToneMap>,
|
||||
environment: Option<String>,
|
||||
}
|
||||
|
||||
impl RuntimeOptions {
|
||||
fn explicit_flag(&self) -> Option<&'static str> {
|
||||
[
|
||||
(self.progressive, "--progressive"),
|
||||
(self.transparent, "--transparent"),
|
||||
(self.samples.is_some(), "--samples"),
|
||||
(self.max_depth.is_some(), "--max-depth"),
|
||||
(self.seed.is_some(), "--seed"),
|
||||
(self.lighting.is_some(), "--lighting"),
|
||||
(self.tone_map.is_some(), "--tone-map"),
|
||||
(self.environment.is_some(), "--environment"),
|
||||
]
|
||||
.into_iter()
|
||||
.find_map(|(present, flag)| present.then_some(flag))
|
||||
}
|
||||
|
||||
fn request(&self, session: &Session, settings: RenderSetup) -> Result<(Value, bool), String> {
|
||||
if let Some(job) = &settings.job {
|
||||
if let Some(flag) = self.explicit_flag() {
|
||||
return Err(format!("{flag} cannot accompany a typed saved render setup; change the saved job options instead"));
|
||||
}
|
||||
settings.validate().map_err(|e| e.to_string())?;
|
||||
session.doc.render.validate_resources(&settings).map_err(|e| e.to_string())?;
|
||||
let needs_gpu = matches!(job, RenderJob::GpuPath { .. });
|
||||
return Ok((json!({"settings":settings}), needs_gpu));
|
||||
}
|
||||
// Legacy setups and unnamed requests retain their runtime wire contract.
|
||||
settings.validate().map_err(|e| e.to_string())?;
|
||||
let mut params = json!({"settings":settings,"transparent_background":self.transparent,
|
||||
"progressive":self.progressive,"samples":self.samples,"max_depth":self.max_depth,"seed":self.seed});
|
||||
if let Some(path) = &self.lighting {
|
||||
let text = solidcraft_engine::io::vfs::read_to_string(path, 65536).map_err(|e| format!("could not read lighting: {e}"))?;
|
||||
let lighting: solidcraft_engine::render::job::StudioLighting = serde_json::from_str(&text).map_err(|e| e.to_string())?;
|
||||
params["lighting"] = json!(lighting);
|
||||
}
|
||||
if let Some(tone_map) = self.tone_map {
|
||||
params["tone_map"] = json!(tone_map);
|
||||
}
|
||||
if let Some(path) = &self.environment {
|
||||
let text = solidcraft_engine::io::vfs::read_to_string(path, 65536).map_err(|e| format!("could not read environment: {e}"))?;
|
||||
params["environment"] = serde_json::from_str(&text).map_err(|e| e.to_string())?;
|
||||
}
|
||||
Ok((params, self.progressive))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(args: &[String]) -> Result<(), String> {
|
||||
let input = args.first().filter(|p| !p.starts_with('-')).ok_or("render requires an input design or script")?;
|
||||
let mut out = None;
|
||||
let mut setup = None;
|
||||
let mut width = None;
|
||||
let mut height = None;
|
||||
let mut transparent = false;
|
||||
let mut exposure = None;
|
||||
let mut runtime = RuntimeOptions::default();
|
||||
let mut overwrite = false;
|
||||
let mut timeout = 120u64;
|
||||
let mut i = 1;
|
||||
while let Some(arg) = args.get(i) {
|
||||
match arg.as_str() {
|
||||
"--transparent" => transparent = true,
|
||||
"--progressive" => runtime.progressive = true,
|
||||
"--transparent" => runtime.transparent = true,
|
||||
"--overwrite" => overwrite = true,
|
||||
"--out" | "--setup" | "--width" | "--height" | "--timeout" => {
|
||||
"--out" | "--setup" | "--width" | "--height" | "--timeout" | "--samples" | "--max-depth" | "--seed" | "--exposure" | "--lighting"
|
||||
| "--tone-map" | "--environment" => {
|
||||
i += 1;
|
||||
let value = args.get(i).ok_or_else(|| format!("missing value for {arg}"))?;
|
||||
match arg.as_str() {
|
||||
@@ -27,6 +91,20 @@ pub fn run(args: &[String]) -> Result<(), String> {
|
||||
"--setup" => setup = Some(value.clone()),
|
||||
"--width" => width = Some(value.parse::<u32>().map_err(|_| "invalid width")?),
|
||||
"--height" => height = Some(value.parse::<u32>().map_err(|_| "invalid height")?),
|
||||
"--samples" => runtime.samples = Some(value.parse::<u32>().map_err(|_| "invalid samples")?),
|
||||
"--max-depth" => runtime.max_depth = Some(value.parse::<u32>().map_err(|_| "invalid depth")?),
|
||||
"--seed" => runtime.seed = Some(value.parse::<u32>().map_err(|_| "invalid seed")?),
|
||||
"--exposure" => exposure = Some(value.parse::<f64>().map_err(|_| "invalid exposure")?),
|
||||
// Defer file reads until a saved job has rejected conflicting controls.
|
||||
"--environment" => runtime.environment = Some(value.clone()),
|
||||
"--lighting" => runtime.lighting = Some(value.clone()),
|
||||
"--tone-map" => {
|
||||
runtime.tone_map = Some(match value.as_str() {
|
||||
"reinhard" => ToneMap::Reinhard,
|
||||
"aces_fitted" => ToneMap::AcesFitted,
|
||||
_ => return Err("tone-map must be reinhard or aces_fitted".into()),
|
||||
})
|
||||
}
|
||||
_ => timeout = value.parse::<u64>().map_err(|_| "invalid timeout")?,
|
||||
}
|
||||
}
|
||||
@@ -39,18 +117,10 @@ pub fn run(args: &[String]) -> Result<(), String> {
|
||||
}
|
||||
let out = out.ok_or("render requires --out FILE.png")?;
|
||||
let mut session = crate::load(input)?;
|
||||
session.set_render_job_host(Some(CpuHost::for_platform().map_err(|e| e.to_string())?)).map_err(|e| e.to_string())?;
|
||||
session.execute("render.scene", &json!({})).map_err(|e| e.to_string())?;
|
||||
let mut settings = if let Some(name) = setup {
|
||||
session.doc.render.setups.get(&name).cloned().ok_or("no saved render setup with that name")?
|
||||
let mut settings = if let Some(name) = setup.as_deref() {
|
||||
session.doc.render.setups.get(name).cloned().ok_or("no saved render setup with that name")?
|
||||
} else {
|
||||
let mut settings = RenderSetup::default();
|
||||
if let Some(camera) = session.camera {
|
||||
settings.camera = camera;
|
||||
} else {
|
||||
settings.camera.fit(&solidcraft_engine::product_scene::extract(&session).map_err(|e| e.to_string())?.bounds);
|
||||
}
|
||||
settings
|
||||
RenderSetup::default()
|
||||
};
|
||||
if let Some(width) = width {
|
||||
settings.width = width;
|
||||
@@ -58,7 +128,27 @@ pub fn run(args: &[String]) -> Result<(), String> {
|
||||
if let Some(height) = height {
|
||||
settings.height = height;
|
||||
}
|
||||
let params = json!({"settings":settings,"transparent_background":transparent});
|
||||
if let Some(exposure) = exposure {
|
||||
settings.exposure_ev = exposure;
|
||||
}
|
||||
// Resolve saved intent before opening a GPU or explicitly settling geometry.
|
||||
// Width/height/exposure only change this validated inline settings clone.
|
||||
let (mut params, needs_gpu) = runtime.request(&session, settings)?;
|
||||
session.set_render_job_host(Some(CpuHost::for_platform().map_err(|e| e.to_string())?)).map_err(|e| e.to_string())?;
|
||||
if needs_gpu {
|
||||
session.register_render_job_host(solidcraft_gpu::path::host().map_err(|e| e.to_string())?).map_err(|e| e.to_string())?;
|
||||
}
|
||||
session.execute("render.scene", &json!({})).map_err(|e| e.to_string())?;
|
||||
if setup.is_none() {
|
||||
let camera = if let Some(camera) = session.camera {
|
||||
camera
|
||||
} else {
|
||||
let mut camera = RenderSetup::default().camera;
|
||||
camera.fit(&solidcraft_engine::product_scene::extract(&session).map_err(|e| e.to_string())?.bounds);
|
||||
camera
|
||||
};
|
||||
params["settings"]["camera"] = json!(camera);
|
||||
}
|
||||
let preflight = session.execute("render.preflight", ¶ms).map_err(|e| e.to_string())?;
|
||||
let started = session.execute("render.start", ¶ms).map_err(|e| e.to_string())?;
|
||||
let id: JobId = serde_json::from_value(started["job"].clone()).map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -144,3 +144,16 @@ fn fuzz_refuses_an_argument_it_does_not_take() {
|
||||
assert!(stderr.contains(arg), "`fuzz {arg}`: {stderr}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_help_keeps_the_registered_gpu_request_controls() {
|
||||
for args in [vec!["--help"], vec!["render", "--help"]] {
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_solidcraft-cli")).args(&args).output().unwrap();
|
||||
assert!(output.status.success(), "{args:?}: {}", String::from_utf8_lossy(&output.stderr));
|
||||
assert!(output.stderr.is_empty());
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
for flag in ["--progressive", "--samples", "--max-depth", "--seed", "--exposure", "--lighting", "--environment", "--tone-map"] {
|
||||
assert!(stdout.contains(flag), "{args:?} lost {flag}: {stdout}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//! Explicit native GPU registration must not change bridged MCP ownership.
|
||||
use std::process::Command;
|
||||
#[test]
|
||||
fn connected_application_rejects_headless_gpu_installation_before_connecting() {
|
||||
let result = Command::new(env!("CARGO_BIN_EXE_solidcraft-cli")).args(["mcp", "--render-gpu", "--connect", "127.0.0.1:1"]).output().unwrap();
|
||||
assert!(!result.status.success());
|
||||
let message = String::from_utf8_lossy(&result.stderr);
|
||||
assert!(message.contains("connected application owns its own device"), "{message}");
|
||||
}
|
||||
@@ -59,6 +59,84 @@ fn cli_loads_both_design_encodings_by_contents() {
|
||||
}
|
||||
}
|
||||
|
||||
/// #1369: a pending concept that did not land in the numbered release must not be silently
|
||||
/// dropped on open/resave, in either encoding or before replacing an existing destination.
|
||||
#[test]
|
||||
fn unknown_pending_concepts_preserve_the_open_design_and_output_files() {
|
||||
use solidcraft_engine::{Session, doc, io};
|
||||
|
||||
let dir = Scratch::new();
|
||||
for version in [33, doc::format::FORMAT] {
|
||||
let mut experimental = doc::Document::new("Experimental");
|
||||
experimental.format = doc::format::format_string(version);
|
||||
experimental.format_pending.push("experimental-card".into());
|
||||
for (extension, bytes) in [("json", io::write_design(&experimental)), ("solidcraft", io::write_design_container(&experimental).unwrap())] {
|
||||
let source = dir.0.join(format!("experimental-{version}.{extension}"));
|
||||
std::fs::write(&source, &bytes).unwrap();
|
||||
let mut session = Session::default();
|
||||
session.execute("solid.box", &json!({"length": 2, "width": 3, "height": 4})).unwrap();
|
||||
let original = session.doc.clone();
|
||||
let original_path = session.path.clone();
|
||||
let undo = session.undo.len();
|
||||
let dirty = session.is_dirty();
|
||||
let err = session.execute("doc.open", &json!({"path": source})).unwrap_err().to_string();
|
||||
assert!(err.contains("experimental-card") && err.contains("update SolidCraft"), "{err}");
|
||||
assert_eq!(session.doc, original);
|
||||
assert_eq!(session.path, original_path);
|
||||
assert_eq!(session.undo.len(), undo);
|
||||
assert_eq!(session.is_dirty(), dirty);
|
||||
|
||||
for existing in [false, true] {
|
||||
let destination = dir.0.join(format!("output-{version}-{extension}-{existing}.{extension}"));
|
||||
let backup = io::backup_path(&destination);
|
||||
if existing {
|
||||
std::fs::write(&destination, b"existing design").unwrap();
|
||||
std::fs::write(&backup, b"existing backup").unwrap();
|
||||
}
|
||||
let output = cli().args(["run", "--in"]).arg(&source).arg("--save").arg(&destination).output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
let error = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(error.contains("experimental-card") && error.contains("update SolidCraft"), "{error}");
|
||||
if existing {
|
||||
assert_eq!(std::fs::read(&destination).unwrap(), b"existing design");
|
||||
assert_eq!(std::fs::read(&backup).unwrap(), b"existing backup");
|
||||
} else {
|
||||
assert!(!destination.exists() && !backup.exists());
|
||||
}
|
||||
assert_eq!(std::fs::read(&source).unwrap(), bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn known_pending_concepts_and_released_files_round_trip_with_inert_metadata() {
|
||||
use solidcraft_engine::{doc, io};
|
||||
|
||||
let dir = Scratch::new();
|
||||
let current = doc::Document::new("Supported");
|
||||
let mut released = current.clone();
|
||||
released.format = doc::format::format_string(33);
|
||||
released.format_pending.clear();
|
||||
let mut experimental = released.clone();
|
||||
experimental.format_pending.push("reserved-body-names".into());
|
||||
for (index, mut document) in [current, released, experimental].into_iter().enumerate() {
|
||||
document.metadata.0.insert("com.example.tool".into(), json!({"format_pending": ["experimental-card"], "physical_card": {"density": 700}}));
|
||||
for (extension, bytes) in [("json", io::write_design(&document)), ("solidcraft", io::write_design_container(&document).unwrap())] {
|
||||
let source = dir.0.join(format!("supported-{index}.{extension}"));
|
||||
let destination = dir.0.join(format!("resaved-{index}.{extension}"));
|
||||
std::fs::write(&source, &bytes).unwrap();
|
||||
let output = cli().args(["run", "--in"]).arg(&source).arg("--save").arg(&destination).output().unwrap();
|
||||
assert!(output.status.success(), "{}", String::from_utf8_lossy(&output.stderr));
|
||||
let reopened = io::read_design(&std::fs::read(&destination).unwrap()).unwrap();
|
||||
assert_eq!(reopened.metadata, document.metadata);
|
||||
assert_eq!(reopened.name, document.name);
|
||||
assert_eq!(reopened.features, document.features);
|
||||
assert_eq!(std::fs::read(&source).unwrap(), bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn results_still_save_and_export_the_script_once() {
|
||||
let dir = Scratch::new();
|
||||
@@ -209,3 +287,175 @@ fn timings_and_profile_report_each_command() {
|
||||
assert!(!output.status.success());
|
||||
assert!(String::from_utf8_lossy(&output.stderr).contains("--timings needs a script"));
|
||||
}
|
||||
|
||||
fn render_setup_script(dir: &Scratch, job: Value) -> PathBuf {
|
||||
let path = dir.0.join("render.json");
|
||||
std::fs::write(
|
||||
&path,
|
||||
json!({"commands":[
|
||||
{"command":"solid.box","params":{"length":10,"width":10,"height":10}},
|
||||
{"command":"render.settings.set","params":{"name":"Portable setup","set":{"width":16,"height":16,"job":job}}}
|
||||
]})
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
path
|
||||
}
|
||||
|
||||
#[cfg(feature = "raytrace-cpu")]
|
||||
#[test]
|
||||
fn render_uses_typed_cpu_setups_from_scripts_and_saved_designs() {
|
||||
for options in [json!({}), json!({"progressive":{"samples_per_pixel":3,"seed":81},"lights":[]})] {
|
||||
let dir = Scratch::new();
|
||||
let script = render_setup_script(&dir, json!({"method":"cpu_raytrace","options":options}));
|
||||
let image = dir.0.join("script.png");
|
||||
let result = json_output(
|
||||
cli()
|
||||
.arg("render")
|
||||
.arg(&script)
|
||||
.args(["--setup", "Portable setup", "--out"])
|
||||
.arg(&image)
|
||||
.env("SOLIDCRAFT_GPU", "must-not-be-read-for-cpu")
|
||||
.output()
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(result["preflight"]["resolved"]["executor"], "cpu-raytrace");
|
||||
assert_eq!(result["export"]["frame"]["executor"], "cpu-raytrace");
|
||||
assert_eq!(result["preflight"]["request"]["integrator"], "raytrace");
|
||||
assert_eq!(result["preflight"]["request"]["raytrace"].get("progressive"), options.get("progressive"));
|
||||
let png = image::load_from_memory(&std::fs::read(&image).unwrap()).unwrap();
|
||||
assert_eq!((png.width(), png.height()), (16, 16));
|
||||
|
||||
let saved = dir.0.join("portable.solidcraft");
|
||||
json_output(cli().arg("run").arg(&script).arg("--save").arg(&saved).output().unwrap());
|
||||
let original = std::fs::read(&saved).unwrap();
|
||||
let overridden = dir.0.join("overridden.png");
|
||||
let result = json_output(
|
||||
cli()
|
||||
.arg("render")
|
||||
.arg(&saved)
|
||||
.args(["--setup", "Portable setup", "--out"])
|
||||
.arg(&overridden)
|
||||
.args(["--width", "12", "--height", "8", "--exposure", "1.25"])
|
||||
.env("SOLIDCRAFT_GPU", "must-not-be-read-for-cpu")
|
||||
.output()
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(result["preflight"]["request"]["width"], 12);
|
||||
assert_eq!(result["preflight"]["request"]["height"], 8);
|
||||
assert_eq!(result["preflight"]["request"]["raytrace"]["exposure_ev"], 1.25);
|
||||
assert_eq!(result["export"]["frame"]["executor"], "cpu-raytrace");
|
||||
assert_eq!(result["preflight"]["request"]["raytrace"].get("progressive"), options.get("progressive"));
|
||||
let png = image::load_from_memory(&std::fs::read(overridden).unwrap()).unwrap();
|
||||
assert_eq!((png.width(), png.height()), (12, 8));
|
||||
assert_eq!(std::fs::read(saved).unwrap(), original, "CLI overrides must not rewrite saved intent");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_preserves_typed_raster_and_legacy_runtime_controls() {
|
||||
for job in [Value::Null, json!({"method":"raster","transparent_background":true})] {
|
||||
let dir = Scratch::new();
|
||||
let script = render_setup_script(&dir, job.clone());
|
||||
let out = dir.0.join("raster.png");
|
||||
let mut command = cli();
|
||||
command
|
||||
.arg("render")
|
||||
.arg(&script)
|
||||
.args(["--setup", "Portable setup", "--out"])
|
||||
.arg(&out)
|
||||
.env("SOLIDCRAFT_GPU", "must-not-be-read-for-raster");
|
||||
if job.is_null() {
|
||||
command.arg("--transparent");
|
||||
}
|
||||
let result = json_output(command.output().unwrap());
|
||||
assert_eq!(result["preflight"]["resolved"]["executor"], "cpu-product");
|
||||
assert_eq!(result["export"]["frame"]["executor"], "cpu-product");
|
||||
assert_eq!(result["preflight"]["request"]["transparent_background"], true);
|
||||
assert!(std::fs::read(out).unwrap().starts_with(b"\x89PNG\r\n\x1a\n"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_render_rejects_explicit_runtime_flags_before_gpu_or_option_file_reads() {
|
||||
let dir = Scratch::new();
|
||||
let script = render_setup_script(&dir, json!({"method":"gpu_path","options":{"samples":64,"seed":0}}));
|
||||
let out = dir.0.join("existing.png");
|
||||
std::fs::write(&out, b"previous completed image").unwrap();
|
||||
for flags in [
|
||||
&["--progressive"][..],
|
||||
&["--transparent"][..],
|
||||
&["--samples", "64"][..],
|
||||
&["--max-depth", "8"][..],
|
||||
&["--seed", "0"][..],
|
||||
&["--lighting", "deliberately-missing-lighting.json"][..],
|
||||
&["--tone-map", "reinhard"][..],
|
||||
&["--environment", "deliberately-missing-environment.json"][..],
|
||||
] {
|
||||
let output = cli()
|
||||
.arg("render")
|
||||
.arg(&script)
|
||||
.args(["--setup", "Portable setup", "--out"])
|
||||
.arg(&out)
|
||||
.arg("--overwrite")
|
||||
.args(flags)
|
||||
.env("SOLIDCRAFT_GPU", "must-not-be-read-for-conflicts")
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
let error = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(error.contains(&format!("{} cannot accompany a typed saved render setup", flags[0])), "{error}");
|
||||
assert!(output.stdout.is_empty());
|
||||
assert_eq!(std::fs::read(&out).unwrap(), b"previous completed image");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_gpu_render_selects_its_host_without_a_progressive_runtime_flag() {
|
||||
// A deliberately invalid policy proves that dispatch reached the GPU host
|
||||
// without depending on an adapter or accepting a CPU fallback. The legacy
|
||||
// --progressive path must still reach that same host-selection boundary.
|
||||
for job in [json!({"method":"gpu_path","options":{"samples":2}}), Value::Null] {
|
||||
let dir = Scratch::new();
|
||||
let script = render_setup_script(&dir, job.clone());
|
||||
let out = dir.0.join("gpu.png");
|
||||
let mut command = cli();
|
||||
command.arg("render").arg(&script).args(["--setup", "Portable setup", "--out"]).arg(&out).env("SOLIDCRAFT_GPU", "not-a-gpu-policy");
|
||||
if job.is_null() {
|
||||
command.arg("--progressive");
|
||||
}
|
||||
let output = command.output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
let error = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(error.contains("SOLIDCRAFT_GPU must be auto, hardware, software or cpu"), "{error}");
|
||||
assert!(!out.exists());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_setup_overrides_obey_shared_validation_before_host_initialization() {
|
||||
let dir = Scratch::new();
|
||||
let script = render_setup_script(&dir, json!({"method":"cpu_raytrace","options":{"progressive":{"samples_per_pixel":64}}}));
|
||||
let out = dir.0.join("invalid.png");
|
||||
// 1024 * 1024 * 64 exceeds the unchanged default Compact camera-sample
|
||||
// budget. Admission must name that envelope before initializing any host.
|
||||
for (flags, message) in [
|
||||
(&["--width", "1024", "--height", "1024"][..], "CPU Compact exceeds its 16777216 camera-sample admission"),
|
||||
(&["--width", "0"][..], "render output must be at least"),
|
||||
(&["--exposure", "NaN"][..], "render exposure must be finite"),
|
||||
] {
|
||||
let output = cli()
|
||||
.arg("render")
|
||||
.arg(&script)
|
||||
.args(["--setup", "Portable setup", "--out"])
|
||||
.arg(&out)
|
||||
.args(flags)
|
||||
.env("SOLIDCRAFT_GPU", "must-not-be-read-for-invalid-settings")
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
let error = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(error.contains(message), "{error}");
|
||||
assert!(!out.exists());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ workspace = true
|
||||
name = "solidcraft-web"
|
||||
path = "src/main.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
bundled-render-library = ["solidcraft-engine/bundled-render-library"]
|
||||
|
||||
[dependencies]
|
||||
solidcraft-engine = { workspace = true }
|
||||
solidcraft-ui-egui = { workspace = true }
|
||||
|
||||
@@ -7,6 +7,11 @@ license.workspace = true
|
||||
publish = false
|
||||
default-run = "solidcraft"
|
||||
|
||||
[features]
|
||||
default = ["raytrace-cpu", "bundled-render-library"]
|
||||
bundled-render-library = ["solidcraft-engine/bundled-render-library"]
|
||||
raytrace-cpu = ["solidcraft-engine/raytrace-cpu"]
|
||||
|
||||
# The workspace lints, except unsafe_code: denied, not forbidden, so that src/open_documents.rs
|
||||
# (macOS file-open events), src/native_crash.rs (Windows exception filter) and src/native_frame.rs
|
||||
# (Windows resize border) can allow it: none has a safe API. Keep the rest in sync with [workspace.lints].
|
||||
|
||||
@@ -35,7 +35,7 @@ fn new_token() -> Option<String> {
|
||||
pub fn remove_token_file() {
|
||||
if let Ok(files) = TOKEN_FILES.lock() {
|
||||
for p in files.iter() {
|
||||
let _ = std::fs::remove_file(p);
|
||||
control_auth::remove_token_file(p);
|
||||
}
|
||||
}
|
||||
if let Some(port) = APP_PORT.lock().ok().and_then(|p| *p) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
//! A `.step`/`.stp` file opens as a new design holding the file's bodies (an Import feature); a
|
||||
//! `.3mf`/`.stl`/`.obj`/`.glb`/`.gltf` file as a new design holding mesh bodies.
|
||||
//!
|
||||
//! `SOLIDCRAFT_SETTINGS_DIR` selects an explicit absolute settings directory without legacy adoption.
|
||||
//! `--control <port>` (or `SOLIDCRAFT_CONTROL_PORT`) starts a localhost JSON-lines control
|
||||
//! server: `{"id":1,"method":"engine.execute","params":{"command":"solid.box","params":{…}}}`.
|
||||
//! Without them the channel still opens, on the default port, unless Preferences turns it off.
|
||||
@@ -459,14 +460,15 @@ fn http_call(url: &str, timeout: std::time::Duration) -> Result<ureq::http::Resp
|
||||
}
|
||||
|
||||
/// The per-user settings folder: eframe's storage (`app.ron`) and the anti-aliasing preference.
|
||||
fn settings_dir() -> Option<std::path::PathBuf> {
|
||||
eframe::storage_dir("SolidCraft")
|
||||
fn settings_dir() -> Result<Option<std::path::PathBuf>, String> {
|
||||
let selected = std::env::var_os("SOLIDCRAFT_SETTINGS_DIR");
|
||||
startup::settings_directory(selected.as_deref(), eframe::storage_dir("SolidCraft"))
|
||||
}
|
||||
|
||||
/// The anti-aliasing preference, kept next to eframe's storage (it is needed before the
|
||||
/// window opens).
|
||||
fn graphics_path() -> Option<std::path::PathBuf> {
|
||||
settings_dir().map(|d| d.join("graphics.json"))
|
||||
settings_dir().ok().flatten().map(|d| d.join("graphics.json"))
|
||||
}
|
||||
|
||||
/// Compatibility shim (docs/compatibility.md): on the first launch after the rename, copy the
|
||||
@@ -476,7 +478,7 @@ fn graphics_path() -> Option<std::path::PathBuf> {
|
||||
/// old app id's `~/.var/app` folder; that copy comes first, as it is the newest. The old folders
|
||||
/// are never changed.
|
||||
fn adopt_legacy_settings() {
|
||||
let (Some(current), Some(legacy)) = (settings_dir(), eframe::storage_dir("SolveCraft")) else { return };
|
||||
let (Some(current), Some(legacy)) = (settings_dir().ok().flatten(), eframe::storage_dir("SolveCraft")) else { return };
|
||||
let legacy_eframe = eframe::storage_dir(solidcraft_engine::io::LEGACY_APP_ID);
|
||||
let old_flatpak = solidcraft_engine::io::legacy_flatpak_path(¤t);
|
||||
if let Err(e) = adopt_settings(¤t, old_flatpak.as_deref(), &legacy, legacy_eframe.as_deref()) {
|
||||
@@ -576,7 +578,11 @@ fn main() -> eframe::Result {
|
||||
#[cfg(target_os = "macos")]
|
||||
objc2_foundation::NSProcessInfo::processInfo().setProcessName(objc2_foundation::ns_string!("SolidCraft"));
|
||||
mark("main");
|
||||
adopt_legacy_settings();
|
||||
// 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() {
|
||||
adopt_legacy_settings();
|
||||
}
|
||||
let mut safe_mode = startup::env_on(std::env::var(startup::SAFE_MODE_ENV).ok().as_deref());
|
||||
let mut control_port: Option<u16> = solidcraft_engine::geom::env::var("CONTROL_PORT").and_then(|p| p.parse().ok());
|
||||
let mut files = Vec::new();
|
||||
@@ -613,7 +619,6 @@ fn main() -> eframe::Result {
|
||||
}
|
||||
// Settings that don't read are moved aside; launches that never got a window are counted,
|
||||
// and after a few in a row this one starts in safe mode (docs/book/src/guide/troubleshooting.md).
|
||||
let settings = settings_dir();
|
||||
let mut notes: Vec<String> = Vec::new();
|
||||
let mut failed_starts = 0;
|
||||
if let Some(dir) = &settings {
|
||||
|
||||
@@ -241,6 +241,7 @@ struct Reading {
|
||||
device: Option<Source>,
|
||||
/// A source that is connected but has not yet shown a device behind it (spacenavd's socket answers
|
||||
/// with no mouse plugged in; its protocol has no enumeration, so the first record is the evidence).
|
||||
#[cfg(target_os = "linux")]
|
||||
awaiting: Option<Source>,
|
||||
axes: Axes,
|
||||
/// When each of X, Y, Z, Rx, Ry and Rz last arrived. Each ages on its own: a device may send
|
||||
@@ -287,6 +288,7 @@ impl Reading {
|
||||
}
|
||||
|
||||
/// A record arrived from the source being waited on: there is a device.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn heard(&mut self) {
|
||||
if self.device.is_none() {
|
||||
self.device = self.awaiting.take();
|
||||
@@ -296,6 +298,7 @@ impl Reading {
|
||||
fn new(now: Instant) -> Self {
|
||||
Self {
|
||||
device: None,
|
||||
#[cfg(target_os = "linux")]
|
||||
awaiting: None,
|
||||
axes: Axes::default(),
|
||||
at: [now; 6],
|
||||
@@ -460,12 +463,20 @@ fn connected(ctx: &Context, shared: &Mutex<Reading>, source: Source) {
|
||||
let now = Instant::now();
|
||||
let stale = now.checked_sub(STALE_AFTER).unwrap_or(now);
|
||||
// A daemon is not yet a device: it counts once a record comes from it.
|
||||
let (device, awaiting) = if needs_evidence(source) { (None, Some(source)) } else { (Some(source), None) };
|
||||
let waiting = needs_evidence(source);
|
||||
// A HID device reports the state of its buttons, so the first state seen is a baseline; the daemon
|
||||
// and the driver send presses and releases, which start from nothing down.
|
||||
let buttons_known = !matches!(source, Source::Hid(_));
|
||||
let generation = CONNECTIONS.fetch_add(1, Ordering::Relaxed).wrapping_add(1);
|
||||
*reading = Reading { device, awaiting, at: [stale; 6], buttons_known, generation, ..Reading::new(now) };
|
||||
*reading = Reading {
|
||||
device: (!waiting).then_some(source),
|
||||
#[cfg(target_os = "linux")]
|
||||
awaiting: waiting.then_some(source),
|
||||
at: [stale; 6],
|
||||
buttons_known,
|
||||
generation,
|
||||
..Reading::new(now)
|
||||
};
|
||||
}
|
||||
ctx.request_repaint();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,25 @@ pub const RENDERER_ENV: &str = "SOLIDCRAFT_RENDERER";
|
||||
pub const FAILED_STARTS_FOR_SAFE_MODE: u32 = 2;
|
||||
const MARKER: &str = "starting";
|
||||
|
||||
/// Explicit application-settings isolation for side-by-side builds and native UI
|
||||
/// acceptance. A supplied invalid path refuses startup rather than falling back
|
||||
/// to the user's ordinary settings. No directory is read or created here.
|
||||
pub fn settings_directory(override_path: Option<&std::ffi::OsStr>, default: Option<PathBuf>) -> Result<Option<PathBuf>, String> {
|
||||
match override_path {
|
||||
None => Ok(default),
|
||||
Some(raw) => {
|
||||
let path = PathBuf::from(raw);
|
||||
if raw.is_empty() || !path.is_absolute() {
|
||||
return Err("SOLIDCRAFT_SETTINGS_DIR must be a nonempty absolute directory path".into());
|
||||
}
|
||||
if path.exists() && !path.is_dir() {
|
||||
return Err("SOLIDCRAFT_SETTINGS_DIR names a file, not a directory".into());
|
||||
}
|
||||
Ok(Some(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether an environment value switches something on.
|
||||
pub fn env_on(v: Option<&str>) -> bool {
|
||||
v.map(str::trim).is_some_and(|v| !v.is_empty() && v != "0" && !v.eq_ignore_ascii_case("false"))
|
||||
@@ -214,6 +233,19 @@ mod tests {
|
||||
d
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn isolated_settings_are_explicit_absolute_and_never_fall_back() {
|
||||
let default = std::env::temp_dir().join("ordinary-settings");
|
||||
assert_eq!(settings_directory(None, Some(default.clone())).unwrap(), Some(default.clone()));
|
||||
let selected = std::env::temp_dir().join("solidcraft-isolated-settings-fixture");
|
||||
assert_eq!(settings_directory(Some(selected.as_os_str()), Some(default.clone())).unwrap(), Some(selected));
|
||||
for raw in ["", "relative/settings", "../ordinary"] {
|
||||
assert!(settings_directory(Some(std::ffi::OsStr::new(raw)), Some(default.clone())).is_err());
|
||||
}
|
||||
let file = std::env::current_exe().unwrap();
|
||||
assert!(settings_directory(Some(file.as_os_str()), Some(default)).is_err());
|
||||
}
|
||||
|
||||
#[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,11 @@
|
||||
//! Original illustrative opaque finishes; not measured optical or engineering data.
|
||||
//! (name, sRGB color, metal fraction, perceptual roughness). IOR is an illustrative 1.5.
|
||||
//! Separate names preserve the scalar library's appearance and saved assignments.
|
||||
pub const OPAQUE_FINISHES: [(&str, [u8; 3], f64, f64); 6] = [
|
||||
("Steel - Satin PBR", [158, 164, 172], 1.0, 0.4),
|
||||
("Aluminum - Satin PBR", [204, 208, 214], 1.0, 0.3),
|
||||
("Copper - Clean PBR", [204, 122, 80], 1.0, 0.25),
|
||||
("ABS - Molded PBR", [222, 222, 216], 0.0, 0.4),
|
||||
("PLA - Smooth PBR", [110, 160, 222], 0.0, 0.35),
|
||||
("Wood - Oak Uniform PBR Preview", [190, 146, 92], 0.0, 0.65),
|
||||
];
|
||||
@@ -0,0 +1,292 @@
|
||||
//! Original starter visual data, MIT OR Apache-2.0. No external material library.
|
||||
use crate::appearance_pack::{Category, GlassBoundary, GlassRecipe, OpaqueRecipe, TextureAxis, TextureRecipe, VisualPreset};
|
||||
|
||||
const WOOD: &str = "Uniform opaque preview only; grain resources/mapping are not applied";
|
||||
const SOLAR: &str = "Uniform opaque preview only; no cell grid, busbars, electricity or efficiency claim";
|
||||
const REGOLITH: &str = "Uniform opaque preview only; no granular displacement or measured lunar optical data";
|
||||
const OPAQUE: &str = "Illustrative opaque isotropic PBR; no measured alloy, polymer or engineering properties";
|
||||
|
||||
const fn look(color: [u8; 3], metallic: f64, roughness: f64, dielectric_ior: f64) -> OpaqueRecipe {
|
||||
OpaqueRecipe { color, metallic, roughness, dielectric_ior }
|
||||
}
|
||||
const fn maps(id: &'static str, repeat_mm: [f64; 2], grain: bool) -> Option<TextureRecipe> {
|
||||
Some(TextureRecipe { id, repeat_mm, grain_axis: if grain { Some(TextureAxis::V) } else { None } })
|
||||
}
|
||||
const fn glass(transmission_linear_rgb: [f64; 3], ior: f64, reference_path_mm: f64, boundary: GlassBoundary) -> GlassRecipe {
|
||||
GlassRecipe { transmission_linear_rgb, dielectric_ior: ior, reference_path_mm, boundary }
|
||||
}
|
||||
|
||||
pub const STARTER_PACK: [VisualPreset; 40] = [
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.oak-honey",
|
||||
"Wood - Honey Oak Uniform Preview",
|
||||
Category::Wood,
|
||||
look([190, 145, 88], 0.0, 0.64, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.oak-honey.maps-v1", [120.0, 240.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.oak-smoked",
|
||||
"Wood - Smoked Oak Uniform Preview",
|
||||
Category::Wood,
|
||||
look([91, 72, 55], 0.0, 0.68, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.oak-smoked.maps-v1", [120.0, 240.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.walnut-dark",
|
||||
"Wood - Dark Walnut Uniform Preview",
|
||||
Category::Wood,
|
||||
look([99, 66, 43], 0.0, 0.60, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.walnut-dark.maps-v1", [100.0, 220.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.maple-light",
|
||||
"Wood - Light Maple Uniform Preview",
|
||||
Category::Wood,
|
||||
look([221, 192, 141], 0.0, 0.57, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.maple-light.maps-v1", [100.0, 200.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.cherry-warm",
|
||||
"Wood - Warm Cherry Uniform Preview",
|
||||
Category::Wood,
|
||||
look([164, 99, 65], 0.0, 0.58, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.cherry-warm.maps-v1", [110.0, 220.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.ash-pale",
|
||||
"Wood - Pale Ash Uniform Preview",
|
||||
Category::Wood,
|
||||
look([209, 186, 146], 0.0, 0.70, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.ash-pale.maps-v1", [120.0, 260.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.birch-cream",
|
||||
"Wood - Cream Birch Uniform Preview",
|
||||
Category::Wood,
|
||||
look([228, 206, 163], 0.0, 0.63, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.birch-cream.maps-v1", [100.0, 200.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.wood.teak-golden",
|
||||
"Wood - Golden Teak Uniform Preview",
|
||||
Category::Wood,
|
||||
look([167, 122, 66], 0.0, 0.61, 1.5),
|
||||
WOOD,
|
||||
maps("starter.wood.teak-golden.maps-v1", [110.0, 250.0], true),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.carbon-steel-polished",
|
||||
"Metal - Polished Carbon Steel",
|
||||
Category::Metal,
|
||||
look([161, 166, 173], 1.0, 0.16, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.stainless-soft-satin",
|
||||
"Metal - Soft Satin Stainless",
|
||||
Category::Metal,
|
||||
look([187, 193, 201], 1.0, 0.36, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.aluminum-bead-blast",
|
||||
"Metal - Bead Blast Aluminum",
|
||||
Category::Metal,
|
||||
look([195, 201, 210], 1.0, 0.58, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.aluminum-silver-polish",
|
||||
"Metal - Silver Polish Aluminum",
|
||||
Category::Metal,
|
||||
look([218, 224, 232], 1.0, 0.13, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.copper-aged-warm",
|
||||
"Metal - Warm Aged Copper",
|
||||
Category::Metal,
|
||||
look([171, 95, 57], 1.0, 0.48, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.brass-champagne",
|
||||
"Metal - Champagne Satin Brass",
|
||||
Category::Metal,
|
||||
look([205, 173, 102], 1.0, 0.32, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.bronze-dark-cast",
|
||||
"Metal - Dark Cast Bronze",
|
||||
Category::Metal,
|
||||
look([133, 95, 58], 1.0, 0.66, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.titanium-matte",
|
||||
"Metal - Matte Gray Titanium",
|
||||
Category::Metal,
|
||||
look([147, 149, 157], 1.0, 0.53, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.gold-warm",
|
||||
"Metal - Warm Reflective Gold",
|
||||
Category::Metal,
|
||||
look([235, 190, 82], 1.0, 0.18, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.metal.silver-cool",
|
||||
"Metal - Cool Reflective Silver",
|
||||
Category::Metal,
|
||||
look([225, 230, 237], 1.0, 0.12, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.abs-charcoal",
|
||||
"Plastic - Charcoal ABS",
|
||||
Category::Plastic,
|
||||
look([43, 45, 48], 0.0, 0.44, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.abs-warm-white",
|
||||
"Plastic - Warm White ABS",
|
||||
Category::Plastic,
|
||||
look([232, 229, 220], 0.0, 0.40, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque("starter.plastic.pla-coral", "Plastic - Coral PLA", Category::Plastic, look([218, 99, 83], 0.0, 0.43, 1.5), OPAQUE, None),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.petg-cyan-opaque",
|
||||
"Plastic - Opaque Cyan PETG",
|
||||
Category::Plastic,
|
||||
look([36, 148, 167], 0.0, 0.29, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.nylon-ivory",
|
||||
"Plastic - Ivory Nylon",
|
||||
Category::Plastic,
|
||||
look([220, 213, 190], 0.0, 0.62, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.pc-graphite-opaque",
|
||||
"Plastic - Opaque Graphite PC",
|
||||
Category::Plastic,
|
||||
look([70, 76, 84], 0.0, 0.27, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.hdpe-natural-opaque",
|
||||
"Plastic - Opaque Natural HDPE",
|
||||
Category::Plastic,
|
||||
look([221, 222, 207], 0.0, 0.48, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque("starter.plastic.pom-black", "Plastic - Black POM", Category::Plastic, look([29, 31, 35], 0.0, 0.32, 1.5), OPAQUE, None),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.tpu-matte-black",
|
||||
"Plastic - Matte Black TPU",
|
||||
Category::Plastic,
|
||||
look([31, 30, 32], 0.0, 0.83, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.plastic.peek-amber-opaque",
|
||||
"Plastic - Opaque Amber PEEK",
|
||||
Category::Plastic,
|
||||
look([157, 119, 62], 0.0, 0.51, 1.5),
|
||||
OPAQUE,
|
||||
None,
|
||||
),
|
||||
VisualPreset::glass(
|
||||
"starter.glass.clear-soda-lime",
|
||||
"Glass Recipe - Clear Soda Lime",
|
||||
glass([0.92, 0.98, 0.96], 1.52, 3.0, GlassBoundary::Closed),
|
||||
),
|
||||
VisualPreset::glass("starter.glass.low-iron-clear", "Glass Recipe - Low Iron Clear", glass([0.98, 0.99, 1.0], 1.50, 4.0, GlassBoundary::Closed)),
|
||||
VisualPreset::glass("starter.glass.smoky-neutral", "Glass Recipe - Smoky Neutral", glass([0.35, 0.38, 0.42], 1.52, 3.0, GlassBoundary::Closed)),
|
||||
VisualPreset::glass("starter.glass.amber-tint", "Glass Recipe - Amber Tint", glass([0.84, 0.38, 0.08], 1.51, 3.0, GlassBoundary::Closed)),
|
||||
VisualPreset::glass("starter.glass.cobalt-blue", "Glass Recipe - Cobalt Blue", glass([0.06, 0.14, 0.76], 1.53, 3.0, GlassBoundary::Closed)),
|
||||
VisualPreset::glass(
|
||||
"starter.glass.thin-clear",
|
||||
"Glass Recipe - Thin Clear Sheet",
|
||||
glass([0.95, 0.98, 0.99], 1.50, 2.0, GlassBoundary::Thin { thickness_mm: 2.0 }),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.solar.mono-blue",
|
||||
"Solar Panel - Mono Blue Uniform Preview",
|
||||
Category::Solar,
|
||||
look([20, 41, 85], 0.0, 0.20, 1.5),
|
||||
SOLAR,
|
||||
maps("starter.solar.mono-blue.maps-v1", [160.0, 160.0], false),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.solar.thin-film-dark",
|
||||
"Solar Panel - Dark Thin Film Uniform Preview",
|
||||
Category::Solar,
|
||||
look([28, 33, 42], 0.0, 0.28, 1.5),
|
||||
SOLAR,
|
||||
maps("starter.solar.thin-film-dark.maps-v1", [100.0, 200.0], false),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.regolith.mare-charcoal",
|
||||
"Regolith - Mare Charcoal Uniform Preview",
|
||||
Category::Regolith,
|
||||
look([56, 56, 55], 0.0, 0.97, 1.5),
|
||||
REGOLITH,
|
||||
maps("starter.regolith.mare-charcoal.maps-v1", [200.0, 200.0], false),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.regolith.highland-pale",
|
||||
"Regolith - Highland Pale Uniform Preview",
|
||||
Category::Regolith,
|
||||
look([116, 113, 106], 0.0, 0.93, 1.5),
|
||||
REGOLITH,
|
||||
maps("starter.regolith.highland-pale.maps-v1", [200.0, 200.0], false),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.regolith.dust-neutral",
|
||||
"Regolith - Neutral Dust Uniform Preview",
|
||||
Category::Regolith,
|
||||
look([86, 85, 81], 0.0, 1.0, 1.5),
|
||||
REGOLITH,
|
||||
maps("starter.regolith.dust-neutral.maps-v1", [150.0, 150.0], false),
|
||||
),
|
||||
VisualPreset::opaque(
|
||||
"starter.regolith.agglutinate-dark",
|
||||
"Regolith - Dark Agglutinate Uniform Preview",
|
||||
Category::Regolith,
|
||||
look([66, 63, 60], 0.0, 0.89, 1.5),
|
||||
REGOLITH,
|
||||
maps("starter.regolith.agglutinate-dark.maps-v1", [200.0, 200.0], false),
|
||||
),
|
||||
];
|
||||
@@ -108,8 +108,8 @@ pub(crate) fn glyph_icon(name: &str) -> Option<&'static str> {
|
||||
}
|
||||
pub(crate) fn glyph_letter(name: &str) -> &'static str {
|
||||
match name {
|
||||
"Horizontal" => "H",
|
||||
"Vertical" => "V",
|
||||
"Horizontal" => "-",
|
||||
"Vertical" => "|",
|
||||
_ => "?",
|
||||
}
|
||||
}
|
||||
|
||||
+165
-1
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Vybrat…",
|
||||
"Circular": "Kruhově",
|
||||
"Circumference": "Obvod",
|
||||
"Clockwise": "Ve směru hodinových ručiček",
|
||||
"Close draft": "Zavřít koncept",
|
||||
"Collisions": "Kolize",
|
||||
"Colour": "Barva",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Hledat příkazy",
|
||||
"Search this library": "Prohledat tuto knihovnu",
|
||||
"Section": "Řez",
|
||||
"Section position": "Poloha průřezu",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Vybrat jiné: podržte levé tlačítko na modelu (nebo pravé tlačítko › Vybrat jiné…) a zobrazí se vše pod kurzorem; dalším kliknutím na stejné místo vyberete další prvek. Dvojklikem prostředním tlačítkem přejdete na výchozí pohled (Předvolby › Navigace).",
|
||||
"Select bodies (a face picks its body)": "Vyberte tělesa (plocha vybere své těleso)",
|
||||
"Select bodies or faces instead": "Vyberte místo toho tělesa nebo plochy",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft se zavřel dříve, než se tyto návrhy uložily. Lze otevřít jejich poslední automatické uložení.",
|
||||
"Specialise": "Specializovat",
|
||||
"Speed": "Rychlost",
|
||||
"Square": "Čtverec",
|
||||
"Stand it up": "Postavit",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Postavit: otočení o čtvrt otáčky kolem osy X jako jeden prvek Posunutí, který lze vrátit.",
|
||||
"Stand this part up?": "Postavit tento díl?",
|
||||
"Start angle": "Počáteční úhel",
|
||||
"Start bulge": "Vypouklost začátku",
|
||||
"Start continuity": "Návaznost začátku",
|
||||
"Step": "Krok",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "úhel, výška",
|
||||
"appearance.dielectric_ior": "Index lomu dielektrika",
|
||||
"appearance.metallic": "Kovovost",
|
||||
"appearance.only_available": "Pouze dostupné vzhledy",
|
||||
"appearance.pbr_help": "Tento povrch zobrazíte v renderu nebo v produktovém PNG. Bez lomu a průchodu světla.",
|
||||
"appearance.pbr_opaque": "Neprůhledné PBR",
|
||||
"appearance.roughness": "Drsnost",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Nový fyzický materiál",
|
||||
"cmd.material_delete": "Smazat fyzický materiál",
|
||||
"cmd.material_edit": "Upravit fyzický materiál",
|
||||
"cmd.material_inspect": "Zkontrolovat fyzický materiál",
|
||||
"cmd.material_list": "Seznam materiálů",
|
||||
"cmd.material_properties_directional": "Směrový modul pružnosti",
|
||||
"cmd.material_properties_validate": "Ověřit data fyzického materiálu",
|
||||
@@ -619,6 +625,8 @@
|
||||
"cmd.plastic_rules": "Seznam pravidel pro plasty",
|
||||
"cmd.plastic_snap_fit": "Zacvakávací spoj",
|
||||
"cmd.render_backends": "Renderovací jádra",
|
||||
"cmd.render_camera_fit": "Zarámovat objekt renderu",
|
||||
"cmd.render_camera_get": "Prohlédnout kameru renderu",
|
||||
"cmd.render_cancel": "Zrušit render",
|
||||
"cmd.render_export": "Exportovat obrázek renderu",
|
||||
"cmd.render_preflight": "Zkontrolovat požadavek na render",
|
||||
@@ -626,6 +634,7 @@
|
||||
"cmd.render_settings_apply": "Použít kameru renderu",
|
||||
"cmd.render_settings_get": "Nastavení renderu",
|
||||
"cmd.render_settings_set": "Uložit nastavení renderu",
|
||||
"cmd.render_stage_backdrop": "Uložit fyzické pozadí renderu",
|
||||
"cmd.render_start": "Renderovat obrázek",
|
||||
"cmd.render_status": "Průběh renderu",
|
||||
"cmd.select_clear": "Zrušit výběr",
|
||||
@@ -1001,20 +1010,51 @@
|
||||
"recovery.min_ago": "před {count} min",
|
||||
"recovery.never_saved": "nikdy neuloženo",
|
||||
"render.background": "Pozadí scény",
|
||||
"render.bloom_enable": "Záře ve výstupu",
|
||||
"render.bloom_help": "Kreativní záře z lineárních jasů se třemi normalizovanými průchody. Poloměr v pixelech výstupu, přičtení před sRGB. Nejde o simulaci čočky, objemu ani zlepšení konvergence. Surové EXR se nemění.",
|
||||
"render.bloom_opaque": "Záře vyžaduje neprůhledný výstup. Průhledné PNG se odmítne, neprovede se skryté sloučení.",
|
||||
"render.bloom_radius": "Poloměr záře",
|
||||
"render.bloom_strength": "Síla záře",
|
||||
"render.bloom_threshold": "Lineární práh jasů",
|
||||
"render.cpu_aa_help": "Prostorové vzorky: více vzorků zlepší hrany a prodlouží vykreslení.",
|
||||
"render.cpu_key_rim": "Hlavní a obrysové",
|
||||
"render.cpu_lighting": "Předvolba osvětlení",
|
||||
"render.cpu_neutral": "Neutrální",
|
||||
"render.cpu_opaque_required": "CPU trasování vyžaduje neprůhledné pozadí. Vypněte průhledné pozadí.",
|
||||
"render.cpu_options_pending": "Panel podporuje vzorky hran, předvolby světel, stíny a expozici. Další volby jsou v API.",
|
||||
"render.cpu_primary_samples": "Vzorky hran na pixel",
|
||||
"render.cpu_shadows": "Vrhat stíny",
|
||||
"render.cpu_summary": "Neprůhledný CPU PNG · světla · stíny · bez skla a textur",
|
||||
"render.cpu_warm_cool": "Teplé a studené",
|
||||
"render.exr_pending": "GPU může uchovat surové lineární EXR. Komprese, vícevrstvé obrazy a pomocné průchody zatím nejsou dostupné.",
|
||||
"render.fit": "Přizpůsobit produktu",
|
||||
"render.gpu_depth": "Maximální hloubka cesty",
|
||||
"render.gpu_options_help": "Tyto volby platí pro tuto úlohu. Expozice vychází z uloženého nastavení.",
|
||||
"render.gpu_path_failed": "Trasování cest GPU není dostupné",
|
||||
"render.gpu_path_first_setup": "První příprava na této GPU může trvat několik minut; SolidCraft lze mezitím používat. Při dalších spuštěních se použijí zkompilované shadery, pokud je ovladač uchová.",
|
||||
"render.gpu_path_preparing": "Trasování cest GPU: kompilace shaderů…",
|
||||
"render.gpu_seed": "Náhodné semeno",
|
||||
"render.gpu_unavailable": "Trasování cest GPU není na tomto zařízení připraveno.",
|
||||
"render.image_advanced": "Pokročilé nastavení GPU",
|
||||
"render.image_cancelled": "Render zrušen",
|
||||
"render.image_cancelling": "Rušení",
|
||||
"render.image_completed": "Obrázek připraven k exportu",
|
||||
"render.image_encoding": "Kódování PNG",
|
||||
"render.image_export": "Exportovat PNG",
|
||||
"render.image_export": "Exportovat hotový obrázek",
|
||||
"render.image_exposure": "Expozice",
|
||||
"render.image_failed": "Render selhal",
|
||||
"render.image_height": "Výška",
|
||||
"render.image_help": "Náhledový obrázek z CPU · PNG · přibližná průhlednost",
|
||||
"render.image_host_missing": "Není dostupný vykreslovací hostitel.",
|
||||
"render.image_method": "Metoda obrazu",
|
||||
"render.image_overwrite": "Nahradit existující soubor",
|
||||
"render.image_preparing": "Příprava obrázku",
|
||||
"render.image_progressive": "Progresivní render",
|
||||
"render.image_queued": "Čeká na render",
|
||||
"render.image_reduce": "Zkuste menší obrázek nebo jednodušší scénu.",
|
||||
"render.image_running": "Renderování obrázku",
|
||||
"render.image_samples": "Vzorků na pixel",
|
||||
"render.image_scene_stale": "Před kontrolou nebo spuštěním dokončete modelování nebo obnovte scénu.",
|
||||
"render.image_stale": "Tento obrázek používá scénu zachycenou před pozdějšími změnami.",
|
||||
"render.image_start": "Spustit render",
|
||||
"render.image_supported": "Požadavek na render je podporován; fronta a paměť se znovu ověří při spuštění.",
|
||||
@@ -1024,17 +1064,135 @@
|
||||
"render.image_unknown": "Stav renderu není k dispozici",
|
||||
"render.image_use_largest": "Použít největší velikost v tomto poměru stran:",
|
||||
"render.image_width": "Šířka",
|
||||
"render.material_absorption": "Absorpce R · G · B (na mm)",
|
||||
"render.material_add": "Přidat nebo upravit těleso",
|
||||
"render.material_assignments": "Přiřazení těles",
|
||||
"render.material_binding_enable": "Zahrnout úpravy tohoto tělesa",
|
||||
"render.material_box": "Osově zarovnaný kvádr",
|
||||
"render.material_browse": "Vybrat obrázek…",
|
||||
"render.material_certification": "Uzavřené sklo používá geometrickou vzdálenost. GPU příprava ověřuje topologii, orientaci, překryvy a optická rozhraní; kontrola jen přijímá požadavek.",
|
||||
"render.material_choose_body": "Vybrat těleso scény",
|
||||
"render.material_closed": "Uzavřená objemová síť",
|
||||
"render.material_coat": "Čirý povlak na základním materiálu",
|
||||
"render.material_coat_enable": "Zapnout čirý povlak",
|
||||
"render.material_coat_help": "Ilustrativní dielektrický povlak na stávajícím neprůhledném vzhledu. Nulová váha ponechá základ beze změny.",
|
||||
"render.material_color_map": "Obraz základní barvy (sRGB)",
|
||||
"render.material_custom": "Vlastní ilustrativní optika",
|
||||
"render.material_enable": "Použít tyto úpravy materiálů GPU",
|
||||
"render.material_filter": "Filtrovat tělesa scény…",
|
||||
"render.material_filter_help": "Zobrazuje se nejvýše 128 shod. U velkých scén zpřesněte filtr.",
|
||||
"render.material_glass": "Sklo a optická absorpce",
|
||||
"render.material_glass_enable": "Použít fyzikální sklo na těleso",
|
||||
"render.material_glass_exclusive": "Tento renderer nepodporuje sklo s povlakem nebo mapami na témže tělese.",
|
||||
"render.material_glass_help": "Původní ilustrativní recepty. Vzorky ukazují propustnost, ne render. Absorpce je −ln(lineární propustnosti) / referenční vzdálenost; alfa se nemění.",
|
||||
"render.material_gpu_required": "Aktivní úpravy vyžadují GPU tracing. Před kontrolou nebo spuštěním vyberte GPU nebo úpravy vypněte.",
|
||||
"render.material_ior": "Index lomu (IOR)",
|
||||
"render.material_limits": "Nejvýše 128 nastavení těles, 32 oddělených skel, 64 povlaků a 128 vazeb textur. Shodné mapy sdílejí paměť; limity zařízení a celkové paměti zůstávají aktivní.",
|
||||
"render.material_map_invalid": "Cesty map musí být omezené místní cesty; síla normál musí být konečná mezi 0 a 1.",
|
||||
"render.material_map_required": "Před použitím map vyberte obraz barvy nebo normál.",
|
||||
"render.material_maps": "Rovinné mapy barvy a normál",
|
||||
"render.material_maps_enable": "Zapnout mapy neprůhledného tělesa",
|
||||
"render.material_maps_help": "PNG/JPEG do 1024×1024; celkem 16 MiB kódovaných dat. U a V jsou kolmé vektory opakování ve světových mm (nejvýše 128 opakování). Barva je sRGB, normály OpenGL +Y. Soubory se zachytí při kontrole/spuštění.",
|
||||
"render.material_normal_map": "Obraz normál (OpenGL, +Y)",
|
||||
"render.material_normal_strength": "Síla normál (0–1)",
|
||||
"render.material_origin": "Počátek mapování X · Y · Z (mm)",
|
||||
"render.material_refresh": "Obnovit tělesa scény",
|
||||
"render.material_refresh_needed": "Scéna se změnila. Před přidáním cíle obnovte seznam.",
|
||||
"render.material_remove": "Odstranit přiřazení",
|
||||
"render.material_repeat_u": "Jedno opakování U X · Y · Z (mm)",
|
||||
"render.material_repeat_v": "Jedno opakování V X · Y · Z (mm)",
|
||||
"render.material_revalidate": "Znovu ověřit těleso",
|
||||
"render.material_revalidate_needed": "Přiřazení patří ke starší revizi scény. Před renderem znovu ověřte přesnou identitu tělesa.",
|
||||
"render.material_roughness": "Drsnost povlaku (0,045–1)",
|
||||
"render.material_shadow": "Propouštět přímé stínové paprsky",
|
||||
"render.material_target_missing": "Pořadí a název tělesa již nesouhlasí. Odstraňte přiřazení a znovu výslovně vyberte těleso.",
|
||||
"render.material_thickness": "Tloušťka vrstvy (mm)",
|
||||
"render.material_thin": "Tenká vrstva",
|
||||
"render.material_title": "Materiály GPU obrazu",
|
||||
"render.material_transient": "Dočasné optické úpravy pro tuto kartu. Neukládají se do návrhu, nastavení renderu ani knihovny materiálů.",
|
||||
"render.material_weight": "Váha povlaku (0–1)",
|
||||
"render.method_cpu": "Trasování paprsků CPU",
|
||||
"render.method_gpu": "Trasování cest GPU",
|
||||
"render.method_raster": "CPU rastr",
|
||||
"render.navigation_help": "Kamera se ovládá stejně jako v návrhu (Předvolby › Navigace). Uložit nastavení zaznamená aktuální kameru.",
|
||||
"render.opaque_image_summary": "Náhledové PNG · neprůhledné PBR · smíšená průhlednost",
|
||||
"render.opaque_preview_help": "Neprůhledné PBR a jednoduché barvy; smíšená průhlednost. Lom světla, HDRI a finální render zatím nejsou k dispozici.",
|
||||
"render.output_format_status": "PNG je přesný dokončený obraz. Volitelné GPU EXR uchovává lineární FLOAT32 radianci před filtry. Export nikdy nenahrazuje výsledek náhledem nebo jinou úlohou.",
|
||||
"render.perspective": "Perspektivní kamera",
|
||||
"render.preview": "Integrovaný náhled",
|
||||
"render.preview_help": "Rastrové stínování a smíšená průhlednost. Lom světla, HDRI a finální render zatím nejsou k dispozici.",
|
||||
"render.progressive_image_summary": "Náhledové PNG · neprůhledné PBR · postupné vzorkování",
|
||||
"render.reload_settings": "Znovu načíst uložené nastavení",
|
||||
"render.restore_camera": "Obnovit uloženou kameru",
|
||||
"render.result_actual_help": "Jeden pixel obrázku na jeden pixel obrazovky.",
|
||||
"render.result_capture": "Zachycená revize",
|
||||
"render.result_current": "Zachycená revize modelu je aktuální.",
|
||||
"render.result_empty": "Zatím není hotový obrázek. Zkontrolujte nastavení a spusťte vykreslování.",
|
||||
"render.result_fit": "Přizpůsobit obrázek",
|
||||
"render.result_job": "Úloha",
|
||||
"render.result_navigation": "Posun a přiblížení používají nastavení navigace. Mezerník + tažení posouvá.",
|
||||
"render.result_open": "Otevřít hotový obrázek na hlavním plátně.",
|
||||
"render.result_preview": "Živý náhled",
|
||||
"render.result_retained": "Zobrazuje se poslední hotový obrázek; novější vykreslení jej zatím nenahradilo.",
|
||||
"render.result_title": "Výsledek vykreslení",
|
||||
"render.return_design": "Zpět k návrhu",
|
||||
"render.ribbon_backgrounds": "Pozadí",
|
||||
"render.ribbon_check": "Kontrola",
|
||||
"render.ribbon_check_help": "Ověřit přesný aktuální návrh renderu. Bez skrytého přepnutí vykreslovače, zmenšení nebo nahrazení zdrojů.",
|
||||
"render.ribbon_edit_lights": "Upravit světla",
|
||||
"render.ribbon_environment_help": "HDR osvětlení, pozadí kamery a fyzické plochy jsou samostatné ovládací prvky s potvrzením nahrazení.",
|
||||
"render.ribbon_finish_dialog": "Nejprve dokončete dialog souboru nebo potvrzení.",
|
||||
"render.ribbon_frame": "Zarámovat",
|
||||
"render.ribbon_hdr_library": "Knihovna HDR",
|
||||
"render.ribbon_job_active": "Render již běží; před spuštěním dalšího jej výslovně zrušte.",
|
||||
"render.ribbon_light_rigs": "Sestavy světel",
|
||||
"render.ribbon_lights_help": "Zkontrolovat světelné sestavy nebo upravit podporovaná světla; aktuální nastavení nahradí až výslovné použití.",
|
||||
"render.ribbon_materials": "Materiály",
|
||||
"render.ribbon_materials_help": "Otevřít inspektor vzhledu a původní povrchy. Optické úpravy nemění skrytě technické vlastnosti.",
|
||||
"render.ribbon_no_active_job": "Není aktivní render ke zrušení.",
|
||||
"render.ribbon_no_result": "Před exportem dokončete render.",
|
||||
"render.ribbon_no_saved_camera": "Před obnovením kamery uložte záběr.",
|
||||
"render.ribbon_saved_camera": "Uložená kamera",
|
||||
"render.ribbon_shots": "Záběry",
|
||||
"render.ribbon_studios": "Studia",
|
||||
"render.ribbon_studios_help": "Procházejte dostupná studia a před použitím zkontrolujte nahrazované prvky. Koncepty zůstávají označené.",
|
||||
"render.ribbon_surface_maps": "Mapy povrchu",
|
||||
"render.save_setup": "Uložit nastavení",
|
||||
"render.setup_name": "Název nastavení",
|
||||
"render.studio_add_area": "Přidat plošné světlo",
|
||||
"render.studio_ambient": "Konstantní zář prostředí",
|
||||
"render.studio_aperture": "Poloměr clony",
|
||||
"render.studio_area": "Plošné světlo",
|
||||
"render.studio_area_help": "Nejvýše čtyři jednostranné obdélníky. Kolmé poloviční hrany U a V určují velikost; U × V míří na osvětlenou stranu. Souřadnice jsou světové milimetry.",
|
||||
"render.studio_center": "Střed X, Y, Z (mm)",
|
||||
"render.studio_denoise": "Potlačit šum v hotovém obrazu",
|
||||
"render.studio_denoise_help": "Závěrečný filtr respektuje hrany; může změkčit detaily. Sklo a ostré zrcadlové povrchy se nefiltrují.",
|
||||
"render.studio_direction": "Směr ke slunci (X, Y, Z)",
|
||||
"render.studio_environment": "Prostředí",
|
||||
"render.studio_environment_bounds": "Intenzita prostředí musí být 0–100 a otočení −360° až 360°.",
|
||||
"render.studio_environment_none": "Bez mapy prostředí",
|
||||
"render.studio_focus": "Osová zaostřovací vzdálenost",
|
||||
"render.studio_half_u": "Poloviční hrana U (mm)",
|
||||
"render.studio_half_v": "Poloviční hrana V (mm)",
|
||||
"render.studio_hdr": "Soubor Radiance HDR",
|
||||
"render.studio_hdr_browse": "Vybrat HDR…",
|
||||
"render.studio_hdr_help": "Radiance .hdr, panorama 2:1, nejvýše 2048 × 1024. EXR není dostupné. Předpoklad barev platí jen při neurčených primárních barvách.",
|
||||
"render.studio_hdr_required": "Vyberte místní soubor .hdr.",
|
||||
"render.studio_hdr_srgb": "Neurčené primární barvy chápat jako lineární sRGB",
|
||||
"render.studio_intensity": "Intenzita prostředí",
|
||||
"render.studio_lens": "Hloubka ostrosti",
|
||||
"render.studio_lens_perspective": "Hloubka ostrosti vyžaduje perspektivní kameru.",
|
||||
"render.studio_lighting": "Studiové osvětlení",
|
||||
"render.studio_lighting_enable": "Použít vlastní studiové osvětlení",
|
||||
"render.studio_radiance": "Lineární RGB zář",
|
||||
"render.studio_remove_area": "Odebrat plošné světlo",
|
||||
"render.studio_rotation": "Otočení prostředí",
|
||||
"render.studio_runtime_help": "Optické úpravy těles jsou v Materiálech GPU obrazu. Ovládání studia a materiálů je dočasné a nemění uložené vzhledy.",
|
||||
"render.studio_sky": "Umělecká obloha",
|
||||
"render.studio_sky_help": "Původní přechod oblohy pro osvětlení; nejde o kalibrovaný model atmosféry.",
|
||||
"render.studio_sun": "Slunce",
|
||||
"render.studio_sun_radius": "Úhlový poloměr",
|
||||
"render.studio_tone_map": "Mapování tónů",
|
||||
"render.unavailable_preview": "Toto nastavení vyžaduje nedostupný profil náhledu.",
|
||||
"render.unsaved": "Neuložené změny náhledu",
|
||||
"render.use_preview": "Použít integrovaný náhled",
|
||||
@@ -1120,6 +1278,10 @@
|
||||
"toolbar.customize_note": "Karta {tab}. Zaškrtnutím příkazu přidáte jeho tlačítko na panel nástrojů. Můžete také přetáhnout řádek z rozbalovací nabídky panelu na panel nástrojů, odstranit tlačítko přetažením mimo panel nástrojů nebo použít připínáček na řádku rozbalovací nabídky.",
|
||||
"toolbar.image": "OBRÁZEK",
|
||||
"toolbar.render": "RENDER",
|
||||
"toolbar.render_appearance": "VZHLED",
|
||||
"toolbar.render_camera": "KAMERA",
|
||||
"toolbar.render_environment": "PROSTŘEDÍ",
|
||||
"toolbar.render_lighting": "OSVĚTLENÍ",
|
||||
"toolbar.render_scene": "SCÉNA",
|
||||
"trace.points": "Bodů podél cesty: {count}",
|
||||
"trace.stopped_by_contact": "Končí ve vzorku {sample}: {a} by prošlo skrz {b}",
|
||||
@@ -1681,6 +1843,8 @@
|
||||
"ui.hideOrigin": "Skrýt počátek",
|
||||
"ui.hidePlanes": "Skrýt roviny",
|
||||
"ui.hideProfile": "Skrýt profil",
|
||||
"ui.hide_origin_by_default": "Ve výchozím stavu skrýt počátek",
|
||||
"ui.hide_origin_note": "Nové návrhy začínají se skrytou složkou Počátek. Návrh si ponechá vlastní nastavení počátku, jakmile ho zobrazíte nebo skryjete.",
|
||||
"ui.history_back": "O krok zpět",
|
||||
"ui.history_below_browser": "Pod prohlížečem",
|
||||
"ui.history_first": "Přejít na začátek",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Vælg…",
|
||||
"Circular": "Cirkulær",
|
||||
"Circumference": "Omkreds",
|
||||
"Clockwise": "Med uret",
|
||||
"Close draft": "Luk kladde",
|
||||
"Collisions": "Kollisioner",
|
||||
"Colour": "Farve",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Søg efter kommandoer",
|
||||
"Search this library": "Søg i dette bibliotek",
|
||||
"Section": "Snit",
|
||||
"Section position": "Profilets placering",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Vælg andet: Hold venstre museknap nede uden at flytte markøren på modellen (eller højreklik › Vælg andet…) for at vise alt under markøren. Klik igen samme sted for at vælge næste objekt. Dobbeltklik på den midterste museknap for at gå til Hjem (Indstillinger › Navigation).",
|
||||
"Select bodies (a face picks its body)": "Vælg emner (en flade vælger sit emne)",
|
||||
"Select bodies or faces instead": "Vælg emner eller flader i stedet",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft lukkede, før disse designs blev gemt. Den seneste automatiske lagring kan åbnes.",
|
||||
"Specialise": "Specialisér",
|
||||
"Speed": "Hastighed",
|
||||
"Square": "Kvadrat",
|
||||
"Stand it up": "Stil op",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Stil op: En kvart omdrejning om X som én flyttefeature, der kan fortrydes.",
|
||||
"Stand this part up?": "Stil dette emne op?",
|
||||
"Start angle": "Startvinkel",
|
||||
"Start bulge": "Udbuling ved starten",
|
||||
"Start continuity": "Overgang ved starten",
|
||||
"Step": "Trin",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "vinkel, højde",
|
||||
"appearance.dielectric_ior": "Dielektrisk brydningsindeks",
|
||||
"appearance.metallic": "Metallisk",
|
||||
"appearance.only_available": "Kun tilgængelige udseender",
|
||||
"appearance.pbr_help": "Se denne overflade i Rendering eller i en billedfil. Lyset brydes ikke og passerer ikke gennem overfladen.",
|
||||
"appearance.pbr_opaque": "Uigennemsigtig PBR",
|
||||
"appearance.roughness": "Ruhed",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Nyt fysisk materiale",
|
||||
"cmd.material_delete": "Slet fysisk materiale",
|
||||
"cmd.material_edit": "Redigér fysisk materiale",
|
||||
"cmd.material_inspect": "Inspicér fysisk materiale",
|
||||
"cmd.material_list": "Vis materialer",
|
||||
"cmd.material_properties_directional": "Retningsafhængigt elasticitetsmodul",
|
||||
"cmd.material_properties_validate": "Validér fysiske materialedata",
|
||||
|
||||
+135
-1
@@ -85,6 +85,7 @@
|
||||
"Choose…": "Auswählen…",
|
||||
"Circular": "Kreisförmig",
|
||||
"Circumference": "Umfang",
|
||||
"Clockwise": "Im Uhrzeigersinn",
|
||||
"Close draft": "Entwurf schließen",
|
||||
"Collapse": "Einklappen",
|
||||
"Collisions": "Kollisionen",
|
||||
@@ -404,6 +405,7 @@
|
||||
"Search this library": "Diese Bibliothek durchsuchen",
|
||||
"Second plane": "Zweite Ebene",
|
||||
"Section": "Schnitt",
|
||||
"Section position": "Lage des Querschnitts",
|
||||
"Sections (one sketch each)": "Querschnitte (je eine Skizze)",
|
||||
"Select Other": "Andere auswählen",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Anderes auswählen: Halten Sie die linke Taste ruhig auf dem Modell gedrückt (oder Rechtsklick › Anderes auswählen…), um alles unter dem Cursor aufzulisten; klicken Sie erneut an dieselbe Stelle, um das nächste Element dort auszuwählen. Doppelklick mit der mittleren Taste wechselt zur Startansicht (Einstellungen › Navigation).",
|
||||
@@ -432,9 +434,11 @@
|
||||
"Specialise": "Spezialisieren",
|
||||
"Speed": "Geschwindigkeit",
|
||||
"Splitting tool": "Trennwerkzeug",
|
||||
"Square": "Quadrat",
|
||||
"Stand it up": "Aufrichten",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Aufrichten: eine Vierteldrehung um X, als ein Verschieben-Merkmal, das sich rückgängig machen lässt.",
|
||||
"Stand this part up?": "Dieses Teil aufrichten?",
|
||||
"Start angle": "Startwinkel",
|
||||
"Start bulge": "Startausbauchung",
|
||||
"Start continuity": "Startstetigkeit",
|
||||
"Step": "Schritt",
|
||||
@@ -520,6 +524,7 @@
|
||||
"angle, height": "Winkel, Höhe",
|
||||
"appearance.dielectric_ior": "Brechungsindex des Dielektrikums",
|
||||
"appearance.metallic": "Metallanteil",
|
||||
"appearance.only_available": "Nur verfügbare Erscheinungsbilder",
|
||||
"appearance.pbr_help": "Diese Oberfläche in Render oder einem Produkt-PNG ansehen. Keine Brechung oder Transmission.",
|
||||
"appearance.pbr_opaque": "Opakes PBR",
|
||||
"appearance.roughness": "Rauheit",
|
||||
@@ -684,6 +689,7 @@
|
||||
"cmd.material_create": "Neues physikalisches Material",
|
||||
"cmd.material_delete": "Physisches Material löschen",
|
||||
"cmd.material_edit": "Physisches Material bearbeiten",
|
||||
"cmd.material_inspect": "Physikalisches Material prüfen",
|
||||
"cmd.material_list": "Materialien auflisten",
|
||||
"cmd.material_properties_directional": "Richtungsabhängiger Elastizitätsmodul",
|
||||
"cmd.material_properties_validate": "Physikalische Materialdaten prüfen",
|
||||
@@ -730,13 +736,32 @@
|
||||
"cmd.plastic_rules": "Kunststoffregeln auflisten",
|
||||
"cmd.plastic_snap_fit": "Rastverbindung",
|
||||
"cmd.render_backends": "Render-Backends",
|
||||
"cmd.render_camera_fit": "Renderobjekt einpassen",
|
||||
"cmd.render_camera_get": "Renderkamera prüfen",
|
||||
"cmd.render_cancel": "Rendering abbrechen",
|
||||
"cmd.render_export": "PNG exportieren",
|
||||
"cmd.render_hdr_inspect": "HDR-Quelle untersuchen",
|
||||
"cmd.render_library_appearance_apply": "Opakes Bibliotheksaussehen anwenden",
|
||||
"cmd.render_library_describe": "Render-Ressource untersuchen",
|
||||
"cmd.render_library_environment_apply": "Integrierte HDR-Umgebung anwenden",
|
||||
"cmd.render_library_list": "Render-Bibliothek durchsuchen",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_studio_apply": "Erstellte Studiolichter anwenden",
|
||||
"cmd.render_library_studio_prepare": "Erstellte Studiolichter vorbereiten",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "Erstellte Oberflächenmaps vorbereiten",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "Ziele für Render-Ressourcen suchen",
|
||||
"cmd.render_preflight": "Renderanfrage prüfen",
|
||||
"cmd.render_result_pin": "Angezeigtes Render-Ergebnis behalten",
|
||||
"cmd.render_scene": "Renderszene prüfen",
|
||||
"cmd.render_settings_apply": "Renderkamera anwenden",
|
||||
"cmd.render_settings_capture_hdr": "Render-Einstellungen mit HDR speichern",
|
||||
"cmd.render_settings_get": "Rendereinstellungen",
|
||||
"cmd.render_settings_set": "Rendereinstellungen speichern",
|
||||
"cmd.render_stage_backdrop": "Physischen Renderhintergrund speichern",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
"cmd.render_start": "Bild rendern",
|
||||
"cmd.render_status": "Renderfortschritt",
|
||||
"cmd.select_clear": "Auswahl aufheben",
|
||||
@@ -1058,6 +1083,8 @@
|
||||
"manage.material_hint": "Wählen Sie Körper und deren physikalisches Material aus.",
|
||||
"manage.parameters_hint": "Bearbeiten Sie Ausdrücke und Einheiten. Änderungen werden mit der Eingabetaste oder beim Verlassen eines Feldes übernommen.",
|
||||
"manage.rules_hint": "Wählen Sie eine Regel zum Bearbeiten oder erstellen Sie eine neue. Bestätigen Sie, um die Regel zu speichern.",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"measure.at": "Bei",
|
||||
"measure.item": "Element {number}",
|
||||
"messages.ago_h": "vor {n} Std.",
|
||||
@@ -1121,13 +1148,35 @@
|
||||
"recovery.just_now": "gerade eben",
|
||||
"recovery.min_ago": "vor {count} Min.",
|
||||
"recovery.never_saved": "nie gespeichert",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.background": "Szenenhintergrund",
|
||||
"render.bloom_enable": "Darstellungs-Bloom",
|
||||
"render.bloom_help": "Kreativer Ausgabeglanz aus linearen Glanzlichtern mit drei normierten Durchläufen. Radius in Ausgabepixeln; Addition vor sRGB. Keine Linsen-, Volumen- oder Konvergenzsimulation. Das rohe EXR bleibt unverändert.",
|
||||
"render.bloom_opaque": "Bloom benötigt eine deckende Ausgabe. Transparentes PNG wird abgelehnt, nicht still abgeflacht.",
|
||||
"render.bloom_radius": "Bloom-Radius",
|
||||
"render.bloom_strength": "Bloom-Stärke",
|
||||
"render.bloom_threshold": "Linearer Glanzlichtschwellwert",
|
||||
"render.camera_pitch": "Kameraneigung",
|
||||
"render.camera_set": "Render-Kamera einstellen",
|
||||
"render.clear_stage": "Remove saved stage",
|
||||
"render.cpu_budget": "CPU-Ressourcenprofil",
|
||||
"render.cpu_budget_bodies": "Körperobergrenze",
|
||||
"render.cpu_budget_compact": "Kompakt (bisherige Grenzen)",
|
||||
"render.cpu_budget_details": "Ressourcengrenzen",
|
||||
"render.cpu_budget_help": "Größere Grenzen ausdrücklich wählen. Auflösung und Samples werden nie automatisch reduziert.",
|
||||
"render.cpu_budget_memory": "Speicherobergrenze pro Auftrag",
|
||||
"render.cpu_budget_not_guarantee": "Dies sind Zulassungsgrenzen, keine RAM-Reservierung oder Geschwindigkeitsgarantie. Geometrie, Film und Vorschauen teilen das Speicherbudget. Das Rendern bleibt abbrechbar.",
|
||||
"render.cpu_budget_resize": "Der Entwurf überschreitet das CPU-Profil oder sein Kamera-Sample-Budget. Kleinere Abmessungen ausdrücklich bestätigen oder ein größeres Profil wählen.",
|
||||
"render.cpu_budget_studio": "Studio (große Bilder)",
|
||||
"render.cpu_budget_triangles": "Dreiecksobergrenze",
|
||||
"render.cpu_budget_workstation": "Workstation (komplexe Szenen)",
|
||||
"render.exr_pending": "Die GPU kann rohe lineare EXR-Dateien behalten. Kompression, mehrschichtige Bilder und zusätzliche Renderpässe bleiben nicht verfügbar.",
|
||||
"render.fit": "Produkt einpassen",
|
||||
"render.image_cancelled": "Rendering abgebrochen",
|
||||
"render.image_cancelling": "Wird abgebrochen",
|
||||
"render.image_completed": "Bild bereit zum Export",
|
||||
"render.image_encoding": "PNG wird kodiert",
|
||||
"render.image_export": "PNG exportieren",
|
||||
"render.image_export": "Fertiges Bild exportieren",
|
||||
"render.image_failed": "Rendering fehlgeschlagen",
|
||||
"render.image_height": "Höhe",
|
||||
"render.image_help": "CPU-Vorschaubild · PNG · angenäherte Transparenz",
|
||||
@@ -1145,17 +1194,98 @@
|
||||
"render.image_unknown": "Renderstatus nicht verfügbar",
|
||||
"render.image_use_largest": "Größte Größe mit diesem Seitenverhältnis verwenden:",
|
||||
"render.image_width": "Breite",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.library_applied": "Ressourcenvariante angewendet. Vollständigen Renderauftrag vor dem Start prüfen.",
|
||||
"render.library_apply_hdr": "Mit dieser HDR-Umgebung speichern",
|
||||
"render.library_apply_maps": "Erstellte GPU-Oberflächenmaps verwenden",
|
||||
"render.library_apply_studio": "Erstellte Studiovariante speichern",
|
||||
"render.library_apply_uniform": "Einheitliches opakes Aussehen anwenden",
|
||||
"render.library_authored_help": "Original erstellte Ressourcen dienen der Darstellung, nicht als gemessene technische Daten. Jede Aktion wendet nur ihre angegebene Variante an.",
|
||||
"render.library_blocked": "Diese Ressource benötigt noch Kalibrierung oder eine externe Sonne und kann noch nicht angewendet werden.",
|
||||
"render.library_center": "Mittelpunkt des Lichtaufbaus",
|
||||
"render.library_emitters_only_ack": "Nur Strahler verwenden; dokumentierte passive Karten auslassen",
|
||||
"render.library_environment_concepts": "Umgebungskonzepte",
|
||||
"render.library_extent": "Objektausdehnung",
|
||||
"render.library_hdr": "Integrierte HDR-Umgebungen",
|
||||
"render.library_hdr_help": "Bettet das originale HDR in die gespeicherte Einstellung ein. Der Längengradursprung wird ausdrücklich umgerechnet; nach dem Speichern ist keine externe Datei nötig.",
|
||||
"render.library_light_concepts": "Beleuchtungskonzepte",
|
||||
"render.library_maps_help": "Built-in maps can be saved with pinned sources and local occurrence mapping. Temporary optical overrides remain a separate mode.",
|
||||
"render.library_material_concepts": "Materialkonzepte",
|
||||
"render.library_next": "Nächste Seite",
|
||||
"render.library_physical_profiles": "Physical reference profiles",
|
||||
"render.library_previous": "Vorherige Seite",
|
||||
"render.library_quality_concepts": "Qualitätsspezifikationen",
|
||||
"render.library_replace_environment": "Vorhandene Umgebung ausdrücklich ersetzen",
|
||||
"render.library_replace_studio": "Replace saved lighting, environment and stage",
|
||||
"render.library_results": "Passende Ressourcen",
|
||||
"render.library_rig_help": "Fit once at an explicit center and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_rigs": "Erstellte Lichtaufbauten",
|
||||
"render.library_save_maps": "Save maps to this setup",
|
||||
"render.library_scene_bounds": "Erfasste Szenengrenzen verwenden",
|
||||
"render.library_scenes": "Szenenspezifikationen",
|
||||
"render.library_search": "Bibliothek durchsuchen",
|
||||
"render.library_selene": "SELENE: opake Oberflächen",
|
||||
"render.library_specification_only": "Nur Spezifikation: keine vollständig ausführbare Voreinstellung. Erforderliche Effekte, Ressourcen und Objektrollen müssen noch implementiert und gebunden werden.",
|
||||
"render.library_surfaces": "Erstellte PBR-Oberflächen",
|
||||
"render.library_target": "Zielkörper",
|
||||
"render.library_title": "Render-Ressourcenbibliothek",
|
||||
"render.library_uniform_ack": "Einheitliche Näherung ohne räumliche oder erweiterte Effekte verwenden",
|
||||
"render.material_color_replace": "Basismap ersetzt Körperfarbe",
|
||||
"render.material_limits": "Höchstens 128 Körperüberschreibungen, 32 getrennte Glaskörper, 64 Beschichtungen und 128 Texturbindungen. Identische Maps teilen Speicher; Geräte- und Gesamtspeichergrenzen bleiben aktiv.",
|
||||
"render.material_metallic_map": "Metallanteil-Map (linear)",
|
||||
"render.material_roughness_map": "Rauheitsmap (linear)",
|
||||
"render.material_v_up": "Textur-V zeigt im Bild nach oben",
|
||||
"render.navigation_help": "Die Kamera bewegt sich wie im Konstruieren (Einstellungen › Navigation). Setup speichern übernimmt die aktuelle Kamera.",
|
||||
"render.opaque_image_summary": "Vorschau-PNG · opakes PBR · Transparenz durch Blending",
|
||||
"render.opaque_preview_help": "Opakes PBR und einfache Farben; Transparenz durch Blending. Brechung, HDRI und finales Rendering sind noch nicht verfügbar.",
|
||||
"render.output_format_status": "PNG enthält das exakte fertige Anzeigebild. Optionales GPU-EXR bewahrt rohe lineare FLOAT32-Strahldichte vor Filtern. Export ersetzt nie durch Vorschaucache oder anderen Auftrag.",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "Perspektivische Kamera",
|
||||
"render.physical_acknowledge": "I understand this partial reference needs grade, condition and source review",
|
||||
"render.physical_associations": "Physical candidates and roles",
|
||||
"render.physical_copy_plan": "Copy plan with sources and omissions",
|
||||
"render.physical_material_name": "Proposed reference material name",
|
||||
"render.physical_omissions": "Properties not representable in the native card",
|
||||
"render.physical_plan_only": "Read-only plan prepared. No material was created or assigned. Keep its extended profile and omissions when reviewing the native card.",
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.preview": "Integrierte Vorschau",
|
||||
"render.preview_help": "Rasterdarstellung mit gemischter Transparenz. Brechung, HDRI und finales Rendering sind noch nicht verfügbar.",
|
||||
"render.reload_settings": "Gespeicherte Einstellungen laden",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "Gespeicherte Kamera laden",
|
||||
"render.result_reduced_display": "Anzeigevorschau auf die Geräte-/Cachegrenze reduziert. PNG und Export behalten die volle Auflösung; native 100%-Ansicht ist hier nicht verfügbar.",
|
||||
"render.return_design": "Zurück zu Design",
|
||||
"render.ribbon_backgrounds": "Hintergründe",
|
||||
"render.ribbon_check": "Prüfen",
|
||||
"render.ribbon_check_help": "Genau den aktuellen Renderentwurf prüfen. Kein stiller Rendererwechsel, keine Verkleinerung oder Ersetzung.",
|
||||
"render.ribbon_edit_lights": "Licht ändern",
|
||||
"render.ribbon_environment_help": "HDR-Beleuchtung, Kamerahintergründe und physische Bühnen sind getrennte Einstellungen mit ausdrücklicher Ersetzungsbestätigung.",
|
||||
"render.ribbon_finish_dialog": "Zuerst den Datei- oder Bestätigungsdialog abschließen.",
|
||||
"render.ribbon_frame": "Einpassen",
|
||||
"render.ribbon_hdr_library": "HDR-Bibliothek",
|
||||
"render.ribbon_job_active": "Ein Render läuft bereits; vor einem neuen Auftrag ausdrücklich abbrechen.",
|
||||
"render.ribbon_light_rigs": "Lichtaufbauten",
|
||||
"render.ribbon_lights_help": "Lichtaufbauten prüfen oder unterstützte Lichter bearbeiten; erst ausdrücklich Anwenden ersetzt die Einrichtung.",
|
||||
"render.ribbon_materials": "Materialien",
|
||||
"render.ribbon_materials_help": "Gemeinsamen Erscheinungsinspektor und Originaloberflächen öffnen. Optik ändert keine technischen Eigenschaften stillschweigend.",
|
||||
"render.ribbon_no_active_job": "Kein aktiver Render zum Abbrechen.",
|
||||
"render.ribbon_no_result": "Vor dem Export muss ein Render abgeschlossen sein.",
|
||||
"render.ribbon_no_saved_camera": "Vor dem Wiederherstellen eine Aufnahme speichern.",
|
||||
"render.ribbon_saved_camera": "Gespeicherte Kamera",
|
||||
"render.ribbon_shots": "Aufnahmen",
|
||||
"render.ribbon_studios": "Studios",
|
||||
"render.ribbon_studios_help": "Implementierte Studios durchsuchen und Ersetzungen vor dem Anwenden prüfen. Konzepte bleiben gekennzeichnet.",
|
||||
"render.ribbon_surface_maps": "Oberflächen",
|
||||
"render.save_setup": "Setup speichern",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.setup_name": "Name des Setups",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.unavailable_preview": "Dieses Setup verlangt ein nicht verfügbares Vorschauprofil.",
|
||||
"render.unsaved": "Ungespeicherte Vorschauänderungen",
|
||||
"render.use_preview": "Integrierte Vorschau verwenden",
|
||||
@@ -1243,6 +1373,10 @@
|
||||
"toolbar.customize_note": "Registerkarte {tab}. Markieren Sie einen Befehl, um ihm eine Schaltfläche in der Werkzeugleiste zu geben. Sie können auch eine Zeile aus dem Aufklappmenü eines Panels auf die Werkzeugleiste ziehen, eine Schaltfläche zum Entfernen aus der Werkzeugleiste ziehen oder die Stecknadel einer Menüzeile verwenden.",
|
||||
"toolbar.image": "BILD",
|
||||
"toolbar.render": "RENDERN",
|
||||
"toolbar.render_appearance": "ERSCHEINUNG",
|
||||
"toolbar.render_camera": "KAMERA",
|
||||
"toolbar.render_environment": "UMGEBUNG",
|
||||
"toolbar.render_lighting": "BELEUCHTUNG",
|
||||
"toolbar.render_scene": "SZENE",
|
||||
"trace.points": "{count} Punkte entlang der Bahn",
|
||||
"trace.stopped_by_contact": "Endet bei Probe {sample}: {a} würde {b} durchdringen",
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
"Modeled": "Modelled",
|
||||
"cmd.construct_point_center": "Point At Centre Of Circle/Sphere/Torus",
|
||||
"cmd.inspect_center_of_mass": "Centre of Mass",
|
||||
"cmd.render_aging_describe": "Layered Surface Aging",
|
||||
"cmd.render_effects_describe": "Lens and Creative Effects",
|
||||
"cmd.sketch_arc_center_point": "Centre Point Arc",
|
||||
"cmd.sketch_circle_center": "Centre Diameter Circle",
|
||||
"cmd.sketch_rectangle_center": "Centre Rectangle",
|
||||
@@ -14,7 +16,81 @@
|
||||
"cmd.sketch_slot_center_point": "Centre Point Slot",
|
||||
"cmd.sketch_slot_center_to_center": "Centre to Centre Slot",
|
||||
"pattern.alignment_hint": "Counts include the original. Centre balances copies; Flip chooses the extra side for even totals.",
|
||||
"render.aging_add": "Add aging layer",
|
||||
"render.aging_airborne": "Airborne dust / participating medium",
|
||||
"render.aging_airborne_help": "Airborne dust is a separate finite homogeneous scattering volume. It changes transport and raw EXR, not the surface-aging stack. Existing volume/glass/denoising restrictions remain explicit; no atmosphere is added automatically.",
|
||||
"render.aging_all_bodies": "All eligible opaque bodies",
|
||||
"render.aging_chips": "Chipped paint",
|
||||
"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_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_metallic": "Layer metallic fraction",
|
||||
"render.aging_origin": "Field origin · world mm",
|
||||
"render.aging_patina": "Copper-green patina",
|
||||
"render.aging_refresh_targets": "Inspect current bodies",
|
||||
"render.aging_roughness": "Layer roughness",
|
||||
"render.aging_rust": "Oxidized iron / rust",
|
||||
"render.aging_scale": "Pattern scale",
|
||||
"render.aging_scratches": "Fine scratches",
|
||||
"render.aging_target": "Target & coordinates",
|
||||
"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.backdrop_x": "Centre X",
|
||||
"render.backdrop_y": "Centre Y",
|
||||
"render.background_camera_section": "Camera background · PNG presentation",
|
||||
"render.background_completed_frozen": "The displayed result is a frozen completed image. Editing a background does not repaint that result automatically. Use Regrade for camera-only changes, or Render for a new physical stage.",
|
||||
"render.background_hdr_separate": "The current HDR resources illuminate and reflect on surfaces; they are not automatically displayed as a panorama behind the subject. Changing a gradient does not rotate or recolour the lighting.",
|
||||
"render.background_lighting_section": "HDR illumination · separate from camera background",
|
||||
"render.background_no_alpha_override": "A camera background is not added to transparent output silently. Raw-master regrading uses captured coverage and does not reapply denoising; the source EXR remains unchanged.",
|
||||
"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.chromatic_offset": "Chromatic edge offset",
|
||||
"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.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.layer_down": "Move down",
|
||||
"render.layer_enabled": "Layer enabled",
|
||||
"render.layer_remove": "Remove layer",
|
||||
"render.layer_strength": "Layer strength",
|
||||
"render.layer_up": "Move up",
|
||||
"render.lens_effects_help": "Flare uses up to four separated bright sources in the actual linear image. Ghosts, halo, streaks, chromatic offsets and radial distortion are artistic image-space approximations. Spatial effects need opaque output; outside samples extend the image edge. Grain is deterministic. No physics, EXR or geometry is altered.",
|
||||
"render.lens_effects_title": "Lens-inspired & photographic",
|
||||
"render.look_add": "Add colour look",
|
||||
"render.look_bleach": "Bleach-bypass-inspired",
|
||||
"render.look_cool": "Cool",
|
||||
"render.look_cyanotype": "Cyanotype-inspired",
|
||||
"render.look_faded": "Faded print",
|
||||
"render.look_mono": "Monochrome",
|
||||
"render.look_sepia": "Sepia",
|
||||
"render.look_strength": "Look strength",
|
||||
"render.look_teal_orange": "Teal / orange",
|
||||
"render.look_title": "Creative look stack",
|
||||
"render.look_warm": "Warm",
|
||||
"render.opaque_preview_help": "Opaque PBR and simple colours; blended transparency. Refraction, HDRI and final rendering are not available yet.",
|
||||
"render.page_aging": "Aging & contamination",
|
||||
"render.page_background": "Backgrounds",
|
||||
"render.page_effects": "Lens & finishing effects",
|
||||
"render.radial_distortion": "Radial distortion",
|
||||
"render.ribbon_aging": "Aging",
|
||||
"render.ribbon_effects": "Effects",
|
||||
"render.sharpening": "Detail sharpening",
|
||||
"render.soft_focus": "Soft focus",
|
||||
"sketch_text.align_center": "Centre",
|
||||
"ui.3d_mouse_step_pull": "Pull the cap towards you, hold it, then let go.",
|
||||
"ui.center": "Centre",
|
||||
|
||||
+667
-1
@@ -97,6 +97,7 @@
|
||||
"Circle center": "Circle center",
|
||||
"Circular": "Circular",
|
||||
"Circumference": "Circumference",
|
||||
"Clockwise": "Clockwise",
|
||||
"Close draft": "Close draft",
|
||||
"Collapse": "Collapse",
|
||||
"Collisions": "Collisions",
|
||||
@@ -116,6 +117,7 @@
|
||||
"Continue on GitHub": "Continue on GitHub",
|
||||
"Continuity": "Continuity",
|
||||
"Control Radius": "Control Radius",
|
||||
"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",
|
||||
@@ -240,6 +242,7 @@
|
||||
"Horiz./Vert.": "Horiz./Vert.",
|
||||
"I-Beam": "I-Beam",
|
||||
"IMAGES": "IMAGES",
|
||||
"Import material into design": "Import material into design",
|
||||
"Import…": "Import…",
|
||||
"In This Design": "In This Design",
|
||||
"In place (surfaces)": "In place (surfaces)",
|
||||
@@ -290,6 +293,7 @@
|
||||
"Mass Center": "Mass Center",
|
||||
"Matched restrictions check the final values.": "Matched restrictions check the final values.",
|
||||
"Material": "Material",
|
||||
"Material copied. Existing body assignments are unchanged.": "Material copied. Existing body assignments are unchanged.",
|
||||
"Max": "Max",
|
||||
"Maximum": "Maximum",
|
||||
"Mesh body": "Mesh body",
|
||||
@@ -313,6 +317,7 @@
|
||||
"Move later": "Move later",
|
||||
"Move up": "Move up",
|
||||
"Name": "Name",
|
||||
"Name on import": "Name on import",
|
||||
"Nearest": "Nearest",
|
||||
"New": "New",
|
||||
"New Comp.": "New Comp.",
|
||||
@@ -322,6 +327,7 @@
|
||||
"No crash reports.": "No crash reports.",
|
||||
"No matching appearance presets.": "No matching appearance presets.",
|
||||
"No matching appearances": "No matching appearances",
|
||||
"No matching physical materials.": "No matching physical materials.",
|
||||
"No visible bodies or sketches to export.": "No visible bodies or sketches to export.",
|
||||
"Nominal diameter": "Nominal diameter",
|
||||
"None": "None",
|
||||
@@ -351,6 +357,7 @@
|
||||
"Path": "Path",
|
||||
"Pattern": "Pattern",
|
||||
"Per Edge": "Per Edge",
|
||||
"Physical material definitions": "Physical material definitions",
|
||||
"Pick the tool bodies": "Pick the tool bodies",
|
||||
"Picked": "Picked",
|
||||
"Picked point": "Picked point",
|
||||
@@ -450,6 +457,7 @@
|
||||
"Second plane": "Second plane",
|
||||
"Section": "Section",
|
||||
"Section (optional)": "Section (optional)",
|
||||
"Section position": "Section position",
|
||||
"Sections (one sketch each)": "Sections (one sketch each)",
|
||||
"Select Other": "Select Other",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).",
|
||||
@@ -479,9 +487,11 @@
|
||||
"Specialise": "Specialise",
|
||||
"Speed": "Speed",
|
||||
"Splitting tool": "Splitting tool",
|
||||
"Square": "Square",
|
||||
"Stand it up": "Stand it up",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Stand it up: a quarter turn about X, as one Move feature you can undo.",
|
||||
"Stand this part up?": "Stand this part up?",
|
||||
"Start angle": "Start angle",
|
||||
"Start bulge": "Start bulge",
|
||||
"Start continuity": "Start continuity",
|
||||
"Step": "Step",
|
||||
@@ -606,6 +616,7 @@
|
||||
"angle, height": "angle, height",
|
||||
"appearance.dielectric_ior": "Dielectric IOR",
|
||||
"appearance.metallic": "Metallic",
|
||||
"appearance.only_available": "Available appearances only",
|
||||
"appearance.pbr_help": "View this surface in Render or a product PNG. No refraction or transmission.",
|
||||
"appearance.pbr_opaque": "Opaque PBR",
|
||||
"appearance.roughness": "Roughness",
|
||||
@@ -634,6 +645,8 @@
|
||||
"cmd.appearance_list": "List Appearances",
|
||||
"cmd.assembly_bom": "Bill of Materials",
|
||||
"cmd.body_rename": "Rename Body",
|
||||
"cmd.browser_collapse_all": "Collapse All",
|
||||
"cmd.browser_expand_all": "Expand All",
|
||||
"cmd.browser_group": "New Group",
|
||||
"cmd.browser_move": "Move Browser Items",
|
||||
"cmd.browser_order": "Order Browser Items",
|
||||
@@ -770,6 +783,7 @@
|
||||
"cmd.material_create": "New Physical Material",
|
||||
"cmd.material_delete": "Delete Physical Material",
|
||||
"cmd.material_edit": "Edit Physical Material",
|
||||
"cmd.material_inspect": "Inspect Physical Material",
|
||||
"cmd.material_list": "List Materials",
|
||||
"cmd.material_properties_directional": "Directional Elastic Modulus",
|
||||
"cmd.material_properties_validate": "Validate Physical Material Data",
|
||||
@@ -817,14 +831,45 @@
|
||||
"cmd.plastic_rest": "Rest",
|
||||
"cmd.plastic_rules": "List Plastic Rules",
|
||||
"cmd.plastic_snap_fit": "Snap Fit",
|
||||
"cmd.render_aging_describe": "Layered Surface Aging",
|
||||
"cmd.render_backends": "Render Backends",
|
||||
"cmd.render_camera_fit": "Frame Render Subject",
|
||||
"cmd.render_camera_get": "Inspect Render Camera",
|
||||
"cmd.render_cancel": "Cancel Render",
|
||||
"cmd.render_effects_describe": "Lens and Creative Effects",
|
||||
"cmd.render_export": "Export Render Image",
|
||||
"cmd.render_hdr_inspect": "Inspect HDR Source",
|
||||
"cmd.render_library_appearance_apply": "Apply Library Opaque Appearance",
|
||||
"cmd.render_library_describe": "Inspect Render Library Resource",
|
||||
"cmd.render_library_environment_apply": "Apply Built-in HDR Environment",
|
||||
"cmd.render_library_list": "Browse Render Library",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_preview": "Inspect Original Surface Map",
|
||||
"cmd.render_library_studio_apply": "Apply Authored Studio Lights",
|
||||
"cmd.render_library_studio_prepare": "Prepare Authored Studio Lights",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "Prepare Authored Surface Maps",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "Find Render Library Targets",
|
||||
"cmd.render_optics_bind": "Save Optical Binding",
|
||||
"cmd.render_optics_unbind": "Remove Optical Binding",
|
||||
"cmd.render_preflight": "Check Render Request",
|
||||
"cmd.render_preset_apply": "Apply Native Studio",
|
||||
"cmd.render_preset_resolve": "Review Native Studio",
|
||||
"cmd.render_quality_prepare": "Review Fixed Sampling Budget",
|
||||
"cmd.render_result_pin": "Retain Displayed Render Result",
|
||||
"cmd.render_result_regrade": "Regrade Linear Master",
|
||||
"cmd.render_scene": "Inspect Render Scene",
|
||||
"cmd.render_settings_apply": "Apply Render Camera",
|
||||
"cmd.render_settings_capture_hdr": "Save Render Settings with HDR",
|
||||
"cmd.render_settings_get": "Render Settings",
|
||||
"cmd.render_settings_set": "Save Render Settings",
|
||||
"cmd.render_shot_duplicate": "Duplicate Render Shot",
|
||||
"cmd.render_shot_remove": "Remove Render Shot",
|
||||
"cmd.render_shot_rename": "Rename Render Shot",
|
||||
"cmd.render_stage_backdrop": "Save Physical Render Background",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
"cmd.render_start": "Render Image",
|
||||
"cmd.render_status": "Render Progress",
|
||||
"cmd.select_clear": "Clear Selection",
|
||||
@@ -959,13 +1004,20 @@
|
||||
"cmd.timeline_suppress": "Suppress Feature",
|
||||
"cmd.view_ambient_occlusion": "Ambient Occlusion",
|
||||
"cmd.view_apply": "Restore Named View",
|
||||
"cmd.view_back": "Back View",
|
||||
"cmd.view_bottom": "Bottom View",
|
||||
"cmd.view_delete": "Delete Named View",
|
||||
"cmd.view_front": "Front View",
|
||||
"cmd.view_graphics_preset": "Graphics Preset",
|
||||
"cmd.view_isometric": "Isometric View",
|
||||
"cmd.view_left": "Left View",
|
||||
"cmd.view_list": "List Named Views",
|
||||
"cmd.view_navigate": "Navigate View",
|
||||
"cmd.view_normal_to": "Normal to Selection",
|
||||
"cmd.view_rename": "Rename Named View",
|
||||
"cmd.view_right": "Right View",
|
||||
"cmd.view_save": "New Named View",
|
||||
"cmd.view_top": "Top View",
|
||||
"color.copy": "Click to copy color values",
|
||||
"color.edit": "Click to edit color",
|
||||
"color.gamma": "Showing color values in 0-255 gamma space",
|
||||
@@ -1154,6 +1206,49 @@
|
||||
"manage.material_hint": "Select bodies and choose their physical material.",
|
||||
"manage.parameters_hint": "Edit expressions and units. Changes apply on Enter or when leaving a field.",
|
||||
"manage.rules_hint": "Choose a rule to edit, or create a new rule. Confirm to save the rule.",
|
||||
"material.editor.add_property": "Add property",
|
||||
"material.editor.add_source": "Add source",
|
||||
"material.editor.assigned_density": "Assigned density",
|
||||
"material.editor.axes": "Material axes",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"material.editor.copy_name": "Copy of {name}",
|
||||
"material.editor.density_range": "Assigned density must be above 0 and at most 1000 g/cm³.",
|
||||
"material.editor.designation": "Designation",
|
||||
"material.editor.duplicate": "Duplicate",
|
||||
"material.editor.engineering_card": "Engineering property card",
|
||||
"material.editor.family": "Material family",
|
||||
"material.editor.glass": "Glass",
|
||||
"material.editor.illustrative": "Illustrative",
|
||||
"material.editor.invalid_property": "Unsupported property type.",
|
||||
"material.editor.isotropic": "Isotropic",
|
||||
"material.editor.measurement": "Measurement",
|
||||
"material.editor.metal": "Metal",
|
||||
"material.editor.moisture": "Moisture, dry basis",
|
||||
"material.editor.name_required": "Enter a name with 1–128 characters.",
|
||||
"material.editor.no_draft": "No material draft is open.",
|
||||
"material.editor.number_required": "Enter a finite numeric value.",
|
||||
"material.editor.orthotropic": "Orthotropic",
|
||||
"material.editor.other": "Other",
|
||||
"material.editor.polymer": "Polymer",
|
||||
"material.editor.preserved_appearance": "Preserved appearance",
|
||||
"material.editor.public_reference": "Public reference",
|
||||
"material.editor.reference": "Reference",
|
||||
"material.editor.save_or_discard": "Save or discard the material draft before assigning a material.",
|
||||
"material.editor.saved": "Material saved. Body assignments are unchanged.",
|
||||
"material.editor.scope": "Save stores this material without assigning it to bodies. Blank properties and conditions remain unknown. Card density does not change assigned density or mass.",
|
||||
"material.editor.source_id": "Source ID",
|
||||
"material.editor.source_kind": "Source type",
|
||||
"material.editor.source_title": "Source title",
|
||||
"material.editor.sources": "Sources",
|
||||
"material.editor.stale": "This material changed while the draft was open. Discard and reopen it before saving.",
|
||||
"material.editor.state": "Material state",
|
||||
"material.editor.strain_rate": "Strain rate",
|
||||
"material.editor.symmetry": "Elastic symmetry",
|
||||
"material.editor.temperature": "Temperature",
|
||||
"material.editor.unknown_card": "Engineering properties are unknown. Save may keep only the assigned density and existing appearance.",
|
||||
"material.editor.user_supplied": "User supplied",
|
||||
"material.editor.wood": "Wood",
|
||||
"measure.at": "At",
|
||||
"measure.item": "Item {number}",
|
||||
"messages.ago_h": "{n} h ago",
|
||||
@@ -1339,21 +1434,248 @@
|
||||
"recovery.just_now": "just now",
|
||||
"recovery.min_ago": "{count} min ago",
|
||||
"recovery.never_saved": "never saved",
|
||||
"render.adaptive_absolute": "Absolute RGB error floor",
|
||||
"render.adaptive_coverage": "Coverage error target",
|
||||
"render.adaptive_enable": "Allocate samples with independent pilots",
|
||||
"render.adaptive_help": "GPU only. Independent pilot samples are discarded, then allocate 16 or more production samples per pixel up to Samples per pixel. RGB and coverage variance guide allocation; rare paths may be missed and capped pixels may remain noisy. The final report counts actual work. No certified noise or time guarantee.",
|
||||
"render.adaptive_minimum": "Minimum production samples",
|
||||
"render.adaptive_pending": "GPU independent-pilot adaptive allocation and conditional Fresnel strata are available. Certified convergence, rare-event guarantees and CPU adaptive transport remain unavailable.",
|
||||
"render.adaptive_pilots": "Pilot samples per pixel",
|
||||
"render.adaptive_relative": "Relative RGB error target",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.advanced_material_scope": "One finite homogeneous GPU medium is available under explicit limits. Density grids, nested glass/volume combinations, subsurface surfaces, displacement, spectral transport and unbound advanced material concepts remain unavailable.",
|
||||
"render.aging_add": "Add aging layer",
|
||||
"render.aging_airborne": "Airborne dust / participating medium",
|
||||
"render.aging_airborne_help": "Airborne dust is a separate finite homogeneous scattering volume. It changes transport and raw EXR, not the surface-aging stack. Existing volume/glass/denoising restrictions remain explicit; no atmosphere is added automatically.",
|
||||
"render.aging_all_bodies": "All eligible opaque bodies",
|
||||
"render.aging_chips": "Chipped paint",
|
||||
"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_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_metallic": "Layer metallic fraction",
|
||||
"render.aging_origin": "Field origin · world mm",
|
||||
"render.aging_patina": "Copper-green patina",
|
||||
"render.aging_refresh_targets": "Inspect current bodies",
|
||||
"render.aging_roughness": "Layer roughness",
|
||||
"render.aging_rust": "Oxidized iron / rust",
|
||||
"render.aging_scale": "Pattern scale",
|
||||
"render.aging_scratches": "Fine scratches",
|
||||
"render.aging_target": "Target & coordinates",
|
||||
"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.all_controls_help": "Dense inspection of all current controls. Section pages provide focused editing without changing the underlying request.",
|
||||
"render.appearance_physics_separate": "Visual appearance does not assign density, thermal data or other engineering properties.",
|
||||
"render.availability_native": "Native composition; review before applying",
|
||||
"render.availability_projection": "Supported projection; see scope and omissions",
|
||||
"render.availability_reference": "Reference data; not an automatic assignment",
|
||||
"render.backdrop_alpha_conflict": "Choose this backdrop or transparent PNG output; the renderer will not silently ignore either setting.",
|
||||
"render.backdrop_enable": "Use camera-only gradient backdrop",
|
||||
"render.backdrop_first": "Start / center color",
|
||||
"render.backdrop_help": "This screen-space backdrop does not illuminate, cast shadows, reflect or represent terrain. It is excluded from raw EXR. Geometry, lights and the HDR environment stay independent.",
|
||||
"render.backdrop_horizontal": "Horizontal gradient",
|
||||
"render.backdrop_radial": "Radial gradient",
|
||||
"render.backdrop_radius": "Radius",
|
||||
"render.backdrop_second": "End / edge color",
|
||||
"render.backdrop_vertical": "Vertical gradient",
|
||||
"render.backdrop_x": "Center X",
|
||||
"render.backdrop_y": "Center Y",
|
||||
"render.background": "Scene background",
|
||||
"render.background_camera_section": "Camera background · PNG presentation",
|
||||
"render.background_completed_frozen": "The displayed result is a frozen completed image. Editing a background does not repaint that result automatically. Use Regrade for camera-only changes, or Render for a new physical stage.",
|
||||
"render.background_hdr_separate": "The current HDR resources illuminate and reflect on surfaces; they are not automatically displayed as a panorama behind the subject. Changing a gradient does not rotate or recolour the lighting.",
|
||||
"render.background_lighting_section": "HDR illumination · separate from camera background",
|
||||
"render.background_no_alpha_override": "A camera background is not added to transparent output silently. Raw-master regrading uses captured coverage and does not reapply denoising; the source EXR remains unchanged.",
|
||||
"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.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.",
|
||||
"render.base_color": "Base color · sRGB",
|
||||
"render.base_metallic": "Metallic fraction",
|
||||
"render.base_opaque_only": "This editor preserves opaque body semantics. Use the explicit glass controls for optical transmission.",
|
||||
"render.bloom_enable": "Display bloom",
|
||||
"render.bloom_help": "Creative output-only glow from positive linear highlights, spread with three normalized 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.bloom_opaque": "Bloom requires opaque output. Transparent PNG is refused, not silently flattened.",
|
||||
"render.bloom_radius": "Bloom radius",
|
||||
"render.bloom_strength": "Bloom strength",
|
||||
"render.bloom_threshold": "Linear highlight threshold",
|
||||
"render.browse_capabilities": "Inspect complete capability catalog",
|
||||
"render.browse_environments": "Browse original HDR environments",
|
||||
"render.browse_native_scenes": "Browse native studios",
|
||||
"render.browse_physical": "Inspect physical references",
|
||||
"render.browse_quality": "Inspect quality specifications",
|
||||
"render.browse_rigs": "Browse authored light rigs",
|
||||
"render.browse_scene_specs": "Browse advanced scene specifications",
|
||||
"render.browse_surfaces": "Browse authored surfaces",
|
||||
"render.browser_library": "Library",
|
||||
"render.browser_model": "Model",
|
||||
"render.camera_distance": "Eye-to-target distance",
|
||||
"render.camera_exact_help": "World millimeters; angles are displayed in degrees and saved as radians. Navigation uses the same camera as the viewport.",
|
||||
"render.camera_fov": "Vertical field of view",
|
||||
"render.camera_pitch": "Camera pitch",
|
||||
"render.camera_roll": "Roll",
|
||||
"render.camera_set": "Set Render Camera",
|
||||
"render.camera_target": "Target position · mm",
|
||||
"render.camera_yaw": "Yaw",
|
||||
"render.chromatic_offset": "Chromatic edge offset",
|
||||
"render.clear_stage": "Remove saved stage",
|
||||
"render.copy_request": "Copy JSON",
|
||||
"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_full_u": "Full U side · mm",
|
||||
"render.cpu_area_full_v": "Full V side · mm",
|
||||
"render.cpu_area_samples": "Area-light samples",
|
||||
"render.cpu_binding_confirm": "Confirm this body",
|
||||
"render.cpu_binding_stale": "The scene changed. Confirm this reflection target again before rendering.",
|
||||
"render.cpu_body_choose": "Choose a body",
|
||||
"render.cpu_body_filter": "Filter bodies by name",
|
||||
"render.cpu_body_filter_more": "Refine the filter to see more bodies.",
|
||||
"render.cpu_body_missing": "A reflection target is missing, hidden, ambiguous or has a name longer than 128 bytes. Choose it again.",
|
||||
"render.cpu_budget": "CPU resource profile",
|
||||
"render.cpu_budget_bodies": "Body ceiling",
|
||||
"render.cpu_budget_compact": "Compact (legacy limits)",
|
||||
"render.cpu_budget_details": "Resource limits",
|
||||
"render.cpu_budget_help": "Choose larger limits explicitly. Resolution and samples are never reduced automatically.",
|
||||
"render.cpu_budget_memory": "Job memory ceiling",
|
||||
"render.cpu_budget_not_guarantee": "These are admission ceilings, not a RAM reservation or a speed guarantee. Geometry, film and retained previews share the memory budget; rendering remains cancellable.",
|
||||
"render.cpu_budget_resize": "The draft exceeds this CPU profile or its camera-sample budget. Accept smaller dimensions explicitly or select a larger profile.",
|
||||
"render.cpu_budget_studio": "Studio (large images)",
|
||||
"render.cpu_budget_triangles": "Triangle ceiling",
|
||||
"render.cpu_budget_workstation": "Workstation (heavy scenes)",
|
||||
"render.cpu_captured_hdr": "HDR captured for this image",
|
||||
"render.cpu_check_capture_help": "Check and Start verify the same file digest or use the embedded HDR. Each image keeps its captured source.",
|
||||
"render.cpu_check_changed": "The controls or model changed after this check. Check again before rendering.",
|
||||
"render.cpu_constant_help": "Constant radiance is visible to reflected or transmitted rays. It does not provide direct diffuse lighting.",
|
||||
"render.cpu_custom_directions": "Replace preset with custom directional lights",
|
||||
"render.cpu_direction": "Direction toward light (X, Y, Z)",
|
||||
"render.cpu_directional": "Directional light",
|
||||
"render.cpu_directional_add": "Add directional light",
|
||||
"render.cpu_environment": "CPU environment",
|
||||
"render.cpu_environment_background": "The image background stays separate from environment lighting.",
|
||||
"render.cpu_environment_bounds": "CPU intensity must be 0–64, HDR rotation finite within ±1,000,000 radians, and HDR samples 1, 4, 16 or 64.",
|
||||
"render.cpu_environment_constant": "Constant secondary-ray environment",
|
||||
"render.cpu_environment_none": "No CPU environment",
|
||||
"render.cpu_environment_samples": "HDR lighting samples",
|
||||
"render.cpu_exposure_help": "CPU exposure must be between −16 and 16 EV. A GPU exposure outside that range is retained until you change it.",
|
||||
"render.cpu_fixed": "Single image",
|
||||
"render.cpu_hdr_help": "Radiance .hdr, 2:1 panorama, up to 2048 × 1024 and 16 MiB. CPU requires explicit sRGB/D65 primaries in the file; unspecified primaries and EXR are refused.",
|
||||
"render.cpu_hdr_reflection_help": "HDR rough reflections require fully metallic body and face surfaces. Check reports unsupported combinations.",
|
||||
"render.cpu_key_rim": "Key and rim",
|
||||
"render.cpu_last_check": "Last CPU check",
|
||||
"render.cpu_light_help": "Up to eight directional lights. An empty custom list turns them off; selecting a preset restores its lights. Colors are linear RGB and intensity is relative, not watts.",
|
||||
"render.cpu_light_intensity": "Relative intensity (0–64)",
|
||||
"render.cpu_light_minimum": "Minimum distance for attenuation",
|
||||
"render.cpu_light_position": "World position (X, Y, Z)",
|
||||
"render.cpu_light_reference": "Reference distance for intensity",
|
||||
"render.cpu_light_remove": "Remove light",
|
||||
"render.cpu_lighting": "Lighting preset",
|
||||
"render.cpu_lights": "CPU lights",
|
||||
"render.cpu_linear_color": "Linear color (R, G, B)",
|
||||
"render.cpu_neutral": "Neutral",
|
||||
"render.cpu_opaque_required": "CPU ray tracing needs an opaque background. Clear Transparent background to continue.",
|
||||
"render.cpu_options_pending": "This CPU panel cannot edit emission, surface effects, glass or anisotropy yet. Clear those API options before using it.",
|
||||
"render.cpu_point": "Point light",
|
||||
"render.cpu_point_add": "Add point light",
|
||||
"render.cpu_point_help": "Up to eight point lights, added to the selected directional lighting. Distances are in mm; the minimum must not exceed the reference distance.",
|
||||
"render.cpu_primary_samples": "Edge samples per pixel",
|
||||
"render.cpu_progressive": "CPU progressive",
|
||||
"render.cpu_progressive_help": "Accumulate the existing CPU integrator in passes of one primary sample. Selected reflections require one sample; area lights, dielectrics and anisotropy require Single image.",
|
||||
"render.cpu_progressive_limits": "At most 1,048,576 pixels and 16,777,216 pixel × sample evaluations. Changing samples never resizes the image automatically.",
|
||||
"render.cpu_progressive_seed": "CPU sampling seed",
|
||||
"render.cpu_progressive_spp": "samples per pixel",
|
||||
"render.cpu_reflection_add": "Add rough reflection",
|
||||
"render.cpu_reflection_depth": "Reflection depth (1–8)",
|
||||
"render.cpu_reflection_empty": "No bodies selected: scene reflections are off.",
|
||||
"render.cpu_reflection_help": "Choose bodies and set Off, Mirror or Rough. Rough uses the assigned surface roughness. More samples and bounces increase time; this is bounded specular transport, not global illumination.",
|
||||
"render.cpu_reflection_limit": "Up to 64 reflected bodies are supported.",
|
||||
"render.cpu_reflection_mirror": "Mirror",
|
||||
"render.cpu_reflection_off": "Off",
|
||||
"render.cpu_reflection_rough": "Rough",
|
||||
"render.cpu_reflection_samples": "Reflection samples (1–64)",
|
||||
"render.cpu_reflections": "CPU reflections",
|
||||
"render.cpu_runtime_help": "Numeric light and environment settings are saved with the setup. Body reflections and HDR files remain temporary. Existing area-light and spot-cone values are retained.",
|
||||
"render.cpu_sampling_mode": "CPU sampling mode",
|
||||
"render.cpu_shadows": "Cast shadows",
|
||||
"render.cpu_summary": "CPU ray tracing · reflections · HDR · directional and point lights",
|
||||
"render.cpu_warm_cool": "Warm and cool",
|
||||
"render.diag_bodies": "Visible bodies",
|
||||
"render.diag_job_details": "Captured job details",
|
||||
"render.diag_last_check": "Last preflight",
|
||||
"render.diag_memory": "Logical admission estimate",
|
||||
"render.diag_not_implemented": "Explicit capability boundaries",
|
||||
"render.diag_preflight_details": "Preflight details",
|
||||
"render.diag_request": "Exact current request",
|
||||
"render.diag_triangles": "Triangles",
|
||||
"render.discard_continue": "Discard draft and continue",
|
||||
"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_reset_lens": "Reset lens effects",
|
||||
"render.effects_seed": "Pattern seed",
|
||||
"render.export_display": "Export: display PNG",
|
||||
"render.export_linear": "Export: raw linear EXR",
|
||||
"render.exr_pending": "GPU can retain raw linear EXR. Compression, multilayer images and auxiliary render passes remain unavailable.",
|
||||
"render.film_grain": "Photographic grain",
|
||||
"render.fit": "Fit Product",
|
||||
"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.gpu_depth": "Maximum path depth",
|
||||
"render.gpu_options_help": "Samples, depth, seed and exposure are saved with this setup. Only the active image method is saved.",
|
||||
"render.gpu_path_failed": "GPU path tracer unavailable",
|
||||
"render.gpu_path_first_setup": "The first setup on this GPU can take several minutes; SolidCraft stays usable meanwhile. Later starts reuse the compiled shaders where the driver keeps them.",
|
||||
"render.gpu_path_preparing": "GPU path tracer: compiling shaders…",
|
||||
"render.gpu_seed": "Random seed",
|
||||
"render.gpu_unavailable": "GPU path tracing is not ready on this device.",
|
||||
"render.ground_apply": "Fit and save ground",
|
||||
"render.ground_gap": "Explicit clearance gap",
|
||||
"render.ground_linear_rgb": "Diffuse reflectance · linear RGB",
|
||||
"render.ground_margin": "Ground extent margin",
|
||||
"render.hdr_details": "HDR source details",
|
||||
"render.hdr_embedded": "HDR saved inside this design",
|
||||
"render.hdr_embedded_help": "Rendering uses the bytes included in the design; the original file is no longer needed.",
|
||||
"render.hdr_file_captured": "HDR file checked. Save will embed these bytes; if the file changes, check it again explicitly.",
|
||||
"render.hdr_inspect": "Check HDR file",
|
||||
"render.hdr_inspect_required": "Select and check an HDR file before saving or rendering.",
|
||||
"render.hdr_primaries_declared": "The source declares its color primaries.",
|
||||
"render.hdr_primaries_srgb": "Color primaries: sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "The source does not declare primaries; review the renderer color requirements.",
|
||||
"render.hdr_resource_missing": "This design is missing the saved HDR resource.",
|
||||
"render.image_advanced": "Advanced GPU controls",
|
||||
"render.image_cancelled": "Render cancelled",
|
||||
"render.image_cancelling": "Cancelling",
|
||||
"render.image_completed": "Image ready to export",
|
||||
"render.image_encoding": "Encoding PNG",
|
||||
"render.image_export": "Export PNG",
|
||||
"render.image_export": "Export completed image",
|
||||
"render.image_exposure": "Exposure",
|
||||
"render.image_failed": "Render failed",
|
||||
"render.image_height": "Height",
|
||||
"render.image_help": "CPU preview image · PNG · approximate transparency",
|
||||
"render.image_host_missing": "No image host is installed.",
|
||||
"render.image_method": "Image method",
|
||||
"render.image_overwrite": "Replace existing file",
|
||||
"render.image_preparing": "Preparing image",
|
||||
"render.image_progressive": "Progressive rendering",
|
||||
"render.image_queued": "Waiting to render",
|
||||
"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_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.",
|
||||
@@ -1363,20 +1685,347 @@
|
||||
"render.image_unknown": "Render status unavailable",
|
||||
"render.image_use_largest": "Use the largest size at this aspect:",
|
||||
"render.image_width": "Width",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspect_scene": "Refresh captured scene summary",
|
||||
"render.keep_editing": "Keep editing",
|
||||
"render.layer_down": "Move down",
|
||||
"render.layer_enabled": "Layer enabled",
|
||||
"render.layer_remove": "Remove layer",
|
||||
"render.layer_strength": "Layer strength",
|
||||
"render.layer_up": "Move up",
|
||||
"render.lens_effects_help": "Flare uses up to four separated bright sources in the actual linear image. Ghosts, halo, streaks, chromatic offsets and radial distortion are artistic image-space approximations. Spatial effects need opaque output; outside samples extend the image edge. Grain is deterministic. No physics, EXR or geometry is altered.",
|
||||
"render.lens_effects_title": "Lens-inspired & photographic",
|
||||
"render.library_all": "Catalog",
|
||||
"render.library_all_states": "All availability states",
|
||||
"render.library_applied": "Resource projection applied. Check the complete render request before starting.",
|
||||
"render.library_apply_hdr": "Save with this HDR environment",
|
||||
"render.library_apply_maps": "Use authored GPU surface maps",
|
||||
"render.library_apply_studio": "Save authored studio projection",
|
||||
"render.library_apply_uniform": "Apply uniform opaque appearance",
|
||||
"render.library_authored_help": "Original authored resources are illustrative, not measured engineering data. Each action applies only its stated projection.",
|
||||
"render.library_blocked": "Blocked / requires calibration",
|
||||
"render.library_capabilities": "Capability specifications",
|
||||
"render.library_center": "Rig center",
|
||||
"render.library_clear_search": "Clear",
|
||||
"render.library_details": "Specification and provenance",
|
||||
"render.library_emitters_only_ack": "Use emitters only; omit the documented passive cards",
|
||||
"render.library_empty": "No matching resources. Try a different query or availability filter.",
|
||||
"render.library_environment_concepts": "Environment concepts",
|
||||
"render.library_extent": "Subject extent",
|
||||
"render.library_favorite": "Add favorite",
|
||||
"render.library_favorites": "Favorites",
|
||||
"render.library_hdr": "Built-in HDR environments",
|
||||
"render.library_hdr_help": "Embeds the original HDR in the saved setup. The authored longitude origin is converted explicitly; no external file is needed after saving.",
|
||||
"render.library_inspect_only": "Select to inspect; nothing is applied automatically. Favorites and recent history belong to this open document session.",
|
||||
"render.library_light_concepts": "Lighting concepts",
|
||||
"render.library_maps_help": "Built-in maps can be saved with pinned sources and local occurrence mapping. Temporary optical overrides remain a separate mode.",
|
||||
"render.library_material_concepts": "Material concepts",
|
||||
"render.library_native_scenes": "Native studios",
|
||||
"render.library_next": "Next page",
|
||||
"render.library_omitted": "Not included",
|
||||
"render.library_physical_profiles": "Physical reference profiles",
|
||||
"render.library_previous": "Previous page",
|
||||
"render.library_quality_concepts": "Quality specifications",
|
||||
"render.library_recent": "Recent",
|
||||
"render.library_replace_environment": "Replace the existing environment explicitly",
|
||||
"render.library_replace_studio": "Replace saved lighting, environment and stage",
|
||||
"render.library_results": "Matching resources",
|
||||
"render.library_rig_help": "Fit once at an explicit center and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_rigs": "Authored lighting rigs",
|
||||
"render.library_save_maps": "Save maps to this setup",
|
||||
"render.library_scene_bounds": "Use captured scene bounds",
|
||||
"render.library_scenes": "Scene specifications",
|
||||
"render.library_search": "Search library",
|
||||
"render.library_select_hint": "Choose a resource in the Library to inspect its supported actions and limitations.",
|
||||
"render.library_selene": "SELENE opaque appearances",
|
||||
"render.library_selene_shots": "SELENE shot specifications",
|
||||
"render.library_short_blocked": "Unavailable",
|
||||
"render.library_short_native": "Native composition",
|
||||
"render.library_short_projection": "Supported projection",
|
||||
"render.library_short_reference": "Reference only",
|
||||
"render.library_short_specification": "Specification only",
|
||||
"render.library_source_preview": "Load source-map preview",
|
||||
"render.library_source_preview_help": "Authored base-color source map. This is not a rendered or measured material preview.",
|
||||
"render.library_specification_only": "Specification only: not a complete executable preset. Required effects, resources and subject roles still need explicit implementation and binding.",
|
||||
"render.library_specs": "Specifications only",
|
||||
"render.library_status": "Availability",
|
||||
"render.library_surfaces": "Authored PBR surfaces",
|
||||
"render.library_target": "Target body",
|
||||
"render.library_title": "Render resource library",
|
||||
"render.library_unfavorite": "Remove favorite",
|
||||
"render.library_uniform_ack": "Use the uniform approximation without spatial or advanced effects",
|
||||
"render.library_usable": "Executable projections",
|
||||
"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_bleach": "Bleach-bypass-inspired",
|
||||
"render.look_cool": "Cool",
|
||||
"render.look_cyanotype": "Cyanotype-inspired",
|
||||
"render.look_faded": "Faded print",
|
||||
"render.look_mono": "Monochrome",
|
||||
"render.look_sepia": "Sepia",
|
||||
"render.look_strength": "Look strength",
|
||||
"render.look_teal_orange": "Teal / orange",
|
||||
"render.look_title": "Creative look stack",
|
||||
"render.look_warm": "Warm",
|
||||
"render.mapping_scale": "Physical repeat multiplier",
|
||||
"render.material_absorption": "Absorption R · G · B (per mm)",
|
||||
"render.material_add": "Add or edit this body",
|
||||
"render.material_assignments": "Body assignments",
|
||||
"render.material_binding_enable": "Include this body override",
|
||||
"render.material_box": "Axis-aligned box",
|
||||
"render.material_browse": "Choose image…",
|
||||
"render.material_certification": "Closed glass uses geometric distance. Topology, orientation, overlap and optical boundaries are checked during GPU preparation; Check only admits the request.",
|
||||
"render.material_choose_body": "Choose a scene body",
|
||||
"render.material_closed": "Closed solid mesh",
|
||||
"render.material_coat": "Clear coat over the base material",
|
||||
"render.material_coat_enable": "Enable clear coat",
|
||||
"render.material_coat_help": "Illustrative dielectric coating over the existing opaque appearance. Zero weight leaves the base unchanged.",
|
||||
"render.material_color_map": "Base color image (sRGB)",
|
||||
"render.material_color_replace": "Base map replaces body color",
|
||||
"render.material_custom": "Custom illustrative optics",
|
||||
"render.material_enable": "Use these GPU material overrides",
|
||||
"render.material_filter": "Filter scene bodies…",
|
||||
"render.material_filter_help": "Up to 128 matching bodies are shown. Refine the filter for large scenes.",
|
||||
"render.material_glass": "Glass and optical absorption",
|
||||
"render.material_glass_enable": "Use physical glass on this body",
|
||||
"render.material_glass_exclusive": "Glass cannot share a body with clear coat or runtime maps in this renderer.",
|
||||
"render.material_glass_help": "Original illustrative recipes. Swatches show transmittance, not a rendered preview. Absorption is −ln(linear transmittance) / reference distance; alpha is unchanged.",
|
||||
"render.material_gpu_required": "These active material overrides require GPU path tracing. Select GPU or disable the overrides before Check or Start.",
|
||||
"render.material_ior": "Index of refraction (IOR)",
|
||||
"render.material_limits": "At most 128 body overrides, 32 disjoint glass bodies, 64 coats and 128 texture bindings. Identical maps share storage; actual device and total memory limits still apply.",
|
||||
"render.material_map_invalid": "Map paths must be bounded local paths; normal strength must be finite and between 0 and 1.",
|
||||
"render.material_map_required": "Choose a color image or a normal image before using maps.",
|
||||
"render.material_maps": "Planar color and normal maps",
|
||||
"render.material_maps_enable": "Enable maps for this opaque body",
|
||||
"render.material_maps_help": "PNG/JPEG up to 1024×1024; 16 MiB encoded total. U and V are orthogonal world-mm repeat vectors (maximum 128 repeats). Color is sRGB; normal data uses OpenGL +Y. Files are captured at Check/Start.",
|
||||
"render.material_metallic_map": "Metallic map (linear)",
|
||||
"render.material_normal_map": "Normal image (OpenGL, +Y)",
|
||||
"render.material_normal_strength": "Normal strength (0–1)",
|
||||
"render.material_origin": "Mapping origin X · Y · Z (mm)",
|
||||
"render.material_refresh": "Refresh scene bodies",
|
||||
"render.material_refresh_needed": "Scene changed. Refresh the body list before adding a target.",
|
||||
"render.material_remove": "Remove this assignment",
|
||||
"render.material_repeat_u": "One U repeat X · Y · Z (mm)",
|
||||
"render.material_repeat_v": "One V repeat X · Y · Z (mm)",
|
||||
"render.material_revalidate": "Revalidate this body",
|
||||
"render.material_revalidate_needed": "This assignment belongs to an earlier scene revision. Revalidate its exact body identity before rendering.",
|
||||
"render.material_roughness": "Coat roughness (0.045–1)",
|
||||
"render.material_roughness_map": "Roughness map (linear)",
|
||||
"render.material_shadow": "Transmit straight shadow rays",
|
||||
"render.material_target_missing": "The body ordinal and name no longer match. Remove this assignment and explicitly choose the intended body again.",
|
||||
"render.material_thickness": "Thin-sheet thickness (mm)",
|
||||
"render.material_thin": "Thin sheet",
|
||||
"render.material_title": "GPU image materials",
|
||||
"render.material_transient": "Temporary optical overrides for this document tab. They are not saved in the design, render setup or material library.",
|
||||
"render.material_v_up": "Texture V points upward in the image",
|
||||
"render.material_weight": "Coat weight (0–1)",
|
||||
"render.method_cpu": "CPU ray tracing",
|
||||
"render.method_gpu": "GPU path tracing",
|
||||
"render.method_limit_raster": "Raster uses the fixed opaque studio preview. Select an explicit raytracing method for supported optical controls.",
|
||||
"render.method_raster": "CPU raster",
|
||||
"render.navigation_help": "The camera moves as in Design (Preferences › Navigation). Save Setup records the current camera.",
|
||||
"render.nested_enable": "Certified nested dielectrics",
|
||||
"render.nested_help": "Up to 16 containing layers; every parent must be convex and every child strictly inside it. Intersections, touching surfaces, thin sheets and straight-shadow transmission refuse. Camera-inside state follows the certified hierarchy. Does not create a liquid surface or merge touching CAD boundaries.",
|
||||
"render.opaque_image_summary": "Preview PNG · opaque PBR · blended transparency",
|
||||
"render.opaque_preview_help": "Opaque PBR and simple colors; blended transparency. Refraction, HDRI and final rendering are not available yet.",
|
||||
"render.optics_remove": "Remove saved optics",
|
||||
"render.optics_replace": "Replace this target’s saved optics explicitly",
|
||||
"render.optics_save": "Save these optics to the setup",
|
||||
"render.optics_saved": "Saved optical targets",
|
||||
"render.optics_saved_help": "Exact definition, feature and occurrence identity survives offline reopen. Missing/replaced/hidden targets refuse; engineering materials are unchanged. Save or discard numeric edits before removing a saved target.",
|
||||
"render.output_format_status": "PNG is the exact completed display image. Optional GPU EXR retains raw scene-linear FLOAT32 radiance before display filters. Export never substitutes the preview cache or a different job.",
|
||||
"render.output_lock_ratio": "Lock aspect ratio",
|
||||
"render.output_over_budget": "The requested image exceeds the selected resource envelope. Choose a compatible size or profile explicitly; no automatic downgrade occurs.",
|
||||
"render.output_ratio_refused": "The linked dimension exceeds this method’s size limit. The previous size is retained; unlock the ratio or choose a smaller value.",
|
||||
"render.output_swap_orientation": "Swap width and height",
|
||||
"render.page_aging": "Aging & contamination",
|
||||
"render.page_all": "All controls",
|
||||
"render.page_appearance": "Appearance",
|
||||
"render.page_background": "Backgrounds",
|
||||
"render.page_camera": "Camera",
|
||||
"render.page_diagnostics": "Diagnostics",
|
||||
"render.page_effects": "Lens & finishing effects",
|
||||
"render.page_environment": "Environment",
|
||||
"render.page_lighting": "Lighting",
|
||||
"render.page_output": "Output",
|
||||
"render.page_scene": "Scene",
|
||||
"render.passive_stage": "Ground and passive stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "Perspective camera",
|
||||
"render.physical_acknowledge": "I understand this partial reference needs grade, condition and source review",
|
||||
"render.physical_associations": "Physical candidates and roles",
|
||||
"render.physical_background_help": "Real passive floor and wall, separate from the camera backdrop. Cyclorama uses 24 polygonal strips; it is not an infinite or analytically smooth surface. Replaces the saved stage only with your consent.",
|
||||
"render.physical_copy_plan": "Copy plan with sources and omissions",
|
||||
"render.physical_cyclorama": "Fit polygonal cyclorama",
|
||||
"render.physical_floor_wall": "Fit physical floor and wall",
|
||||
"render.physical_material_name": "Proposed reference material name",
|
||||
"render.physical_omissions": "Properties not representable in the native card",
|
||||
"render.physical_plan_only": "Read-only plan prepared. No material was created or assigned. Keep its extended profile and omissions when reviewing the native card.",
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.post_contrast": "Contrast",
|
||||
"render.post_gain_b": "Blue gain",
|
||||
"render.post_gain_g": "Green gain",
|
||||
"render.post_gain_r": "Red gain",
|
||||
"render.post_help": "Creative presentation only. RGB gains precede tone mapping; contrast, saturation and vignette follow in display-linear light. Start Render creates new transport samples. Regrade uses the selected retained raw master without denoising or new rays.",
|
||||
"render.post_reset": "Reset presentation filters",
|
||||
"render.post_saturation": "Saturation",
|
||||
"render.post_title": "Presentation filters",
|
||||
"render.post_vignette": "Vignette",
|
||||
"render.preview": "Integrated preview",
|
||||
"render.preview_help": "Raster shading and blended transparency. Refraction, HDRI and final rendering are not available yet.",
|
||||
"render.preview_image_settings_help": "Live Preview keeps fixed studio lighting. Exposure and image lighting apply to the image job when you Check or Start.",
|
||||
"render.preview_retry": "Retry live preview",
|
||||
"render.preview_unavailable_help": "The live preview is unavailable. Saved setups and image-job controls remain accessible. Change the scene or explicitly retry; a refused scene is not rebuilt on every frame.",
|
||||
"render.preview_upload": "Live-preview vertex payload",
|
||||
"render.preview_upload_help": "Exact preview vertex bytes, not total GPU or process memory. Geometry is not simplified. Image jobs use their own admission and lighting.",
|
||||
"render.progressive_image_summary": "Preview PNG · PBR and glass · progressive samples",
|
||||
"render.quality_ack": "Acknowledge the fixed-budget projection and omissions",
|
||||
"render.quality_apply": "Use this fixed sampling budget",
|
||||
"render.quality_projection_help": "Q presets include future requirements. This action projects only a supported fixed-sample PNG budget and explicitly omits adaptive stopping, raw linear output and independent transmission limits.",
|
||||
"render.quality_review": "Review sampling budget",
|
||||
"render.queue_pending": "There is no automatic production queue or animation renderer in this UI. Completed still images remain separately exportable.",
|
||||
"render.radial_distortion": "Radial distortion",
|
||||
"render.regrade_action": "Regrade raw master (no denoising)",
|
||||
"render.regrade_help": "Creates a separate PNG from the selected completed raw master, using these presentation controls. Does not trace rays, change the captured size/camera/lights, or overwrite the EXR. Denoising is not reapplied: raw masters do not retain its guides. The derivative remains exportable through the same job controls.",
|
||||
"render.reload_settings": "Reload Saved Settings",
|
||||
"render.replace_ground": "Confirm replacement of existing stage",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "Restore Saved Camera",
|
||||
"render.result_actual_help": "One image pixel per display pixel.",
|
||||
"render.result_capture": "Captured revision",
|
||||
"render.result_current": "The captured model revision is current.",
|
||||
"render.result_empty": "No completed image yet. Check the settings, then start a render.",
|
||||
"render.result_fit": "Fit Image",
|
||||
"render.result_job": "Job",
|
||||
"render.result_navigation": "Pan and zoom use Navigation preferences. Space + drag pans.",
|
||||
"render.result_open": "Open the completed image in the main canvas.",
|
||||
"render.result_preview": "Live Preview",
|
||||
"render.result_provisional": "Provisional CPU image",
|
||||
"render.result_provisional_help": "This checkpoint is not exportable. Export keeps the last completed result; cancellation returns to that result.",
|
||||
"render.result_reduced_display": "Display preview reduced to the viewport device/cache limit. The retained PNG and export keep full resolution; native 100% inspection is unavailable for this reduced view.",
|
||||
"render.result_retained": "Showing the last completed image; a newer render has not replaced it.",
|
||||
"render.result_sequence": "Checkpoint",
|
||||
"render.result_title": "Render Result",
|
||||
"render.return_design": "Return to Design",
|
||||
"render.review_stale": "This review is stale. Resolve or check again before applying.",
|
||||
"render.ribbon_aging": "Aging",
|
||||
"render.ribbon_backgrounds": "Backgrounds",
|
||||
"render.ribbon_check": "Check",
|
||||
"render.ribbon_check_help": "Validate the exact current draft that Render will submit. No renderer fallback, silent resize or resource replacement.",
|
||||
"render.ribbon_edit_lights": "Edit Lights",
|
||||
"render.ribbon_effects": "Effects",
|
||||
"render.ribbon_environment_help": "HDR illumination, camera-only backgrounds and physical stage surfaces are separate controls with explicit replacement consent.",
|
||||
"render.ribbon_finish_dialog": "Finish the current file or confirmation dialog first.",
|
||||
"render.ribbon_frame": "Frame",
|
||||
"render.ribbon_hdr_library": "HDR Library",
|
||||
"render.ribbon_job_active": "A render is already running; cancel it explicitly before starting another.",
|
||||
"render.ribbon_light_rigs": "Light Rigs",
|
||||
"render.ribbon_lights_help": "Inspect authored rigs or edit supported lights without replacing the current setup until you explicitly apply the change.",
|
||||
"render.ribbon_materials": "Materials",
|
||||
"render.ribbon_materials_help": "Open the shared appearance inspector and original surface library. Optical edits never silently change engineering properties.",
|
||||
"render.ribbon_no_active_job": "There is no active render to cancel.",
|
||||
"render.ribbon_no_result": "Complete a render before exporting its exact image.",
|
||||
"render.ribbon_no_saved_camera": "Save a shot before restoring its camera.",
|
||||
"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_surface_maps": "Surface Maps",
|
||||
"render.sampling_title": "Adaptive and transmission sampling",
|
||||
"render.save_continue": "Save and continue",
|
||||
"render.save_setup": "Save Setup",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.scene_apply": "Apply reviewed studio",
|
||||
"render.scene_consent": "Confirm lighting, environment, exposure and stage replacement",
|
||||
"render.scene_preserved_fields": "Camera, sampling, dimensions, optical bindings, CAD geometry and engineering materials are preserved.",
|
||||
"render.scene_preserves_design": "Compose lighting and a passive stage for the visible subject. Geometry, engineering materials and the camera remain separate.",
|
||||
"render.scene_replaces": "Replaces",
|
||||
"render.scene_review": "Resolve and review",
|
||||
"render.scene_review_help": "Review the complete native composition before applying. Unbound advanced SCENE specifications are not substituted.",
|
||||
"render.scene_scope_details": "Composition scope",
|
||||
"render.setup_legacy_environment": "This older setup uses legacy environment rotation or intensity. Those values are retained; convert them explicitly before saving a full image job.",
|
||||
"render.setup_name": "Setup name",
|
||||
"render.setup_numeric_help": "Save records the active image method and all its numeric settings. Reload or choosing another setup replaces this draft; restore the camera separately.",
|
||||
"render.setup_offline_help": "You can edit and save this method without its renderer. Check and Start require an available host.",
|
||||
"render.setup_runtime_unsupported": "This full job cannot be saved yet: it contains maps or scene-body bindings. Remove those temporary inputs before saving a portable setup.",
|
||||
"render.setup_save_missing": "The saved render configuration could not be found after the command completed.",
|
||||
"render.sharpening": "Detail sharpening",
|
||||
"render.shot_duplicate": "Duplicate saved shot",
|
||||
"render.shot_manager": "Saved shots",
|
||||
"render.shot_new_name": "New shot name",
|
||||
"render.shot_remove": "Remove saved shot",
|
||||
"render.shot_remove_help": "Remove only this saved setup. Source geometry and completed images are preserved; the action can be undone.",
|
||||
"render.shot_remove_title": "Remove saved shot?",
|
||||
"render.shot_rename": "Rename saved shot",
|
||||
"render.shot_saved_only": "Save the current draft first. Duplicate and rename preserve exact saved options and resource references.",
|
||||
"render.sky_ground": "Ground · linear RGB",
|
||||
"render.sky_horizon": "Horizon · linear RGB",
|
||||
"render.sky_zenith": "Zenith · linear RGB",
|
||||
"render.soft_focus": "Soft focus",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.studio_add_area": "Add area light",
|
||||
"render.studio_ambient": "Constant environment radiance",
|
||||
"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_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.",
|
||||
"render.studio_direction": "Direction toward sun (X, Y, Z)",
|
||||
"render.studio_environment": "Environment",
|
||||
"render.studio_environment_bounds": "Environment rotation must be finite within ±1,000,000 radians and intensity between 0 and 100.",
|
||||
"render.studio_environment_none": "No environment map",
|
||||
"render.studio_focus": "Axial focus distance",
|
||||
"render.studio_half_u": "Half-edge U (mm)",
|
||||
"render.studio_half_v": "Half-edge V (mm)",
|
||||
"render.studio_hdr": "Radiance HDR file",
|
||||
"render.studio_hdr_browse": "Choose HDR…",
|
||||
"render.studio_hdr_help": "Radiance .hdr, 2:1 panorama, up to 2048 × 1024. EXR is unavailable. The color assumption applies only when primaries are unspecified.",
|
||||
"render.studio_hdr_required": "Choose a local .hdr file.",
|
||||
"render.studio_hdr_srgb": "Interpret unspecified primaries as linear sRGB",
|
||||
"render.studio_intensity": "Environment intensity",
|
||||
"render.studio_lens": "Depth of field",
|
||||
"render.studio_lens_perspective": "Depth of field requires a perspective camera.",
|
||||
"render.studio_lighting": "Studio lighting",
|
||||
"render.studio_lighting_enable": "Use custom studio lighting",
|
||||
"render.studio_needs_review": "Review method and settings",
|
||||
"render.studio_radiance": "Linear RGB radiance",
|
||||
"render.studio_ready": "Ready to check",
|
||||
"render.studio_remove_area": "Remove area light",
|
||||
"render.studio_rotation": "Environment rotation",
|
||||
"render.studio_runtime_help": "Numeric studio settings and checked HDR sources can be saved with the setup. Body optical/material overrides remain temporary and do not change saved appearances.",
|
||||
"render.studio_saved": "Saved setup / current camera",
|
||||
"render.studio_sky": "Artistic sky",
|
||||
"render.studio_sky_help": "Original sky gradient for lighting; not a calibrated atmospheric model.",
|
||||
"render.studio_sun": "Sun",
|
||||
"render.studio_sun_radius": "Angular radius",
|
||||
"render.studio_title": "Render studio",
|
||||
"render.studio_tone_map": "Tone mapping",
|
||||
"render.subsurface_enable": "Interior scattering random walk",
|
||||
"render.subsurface_help": "Closed dielectric only. Scattering and RGB absorption are separate per-mm coefficients. Paths scatter inside actual geometry, then refract or reflect at the boundary. Disable straight shadow transmission, surface denoising and exterior volume; use one Fresnel stratum. Not a diffusion shader, density grid or measured material. Dense media may need more samples and path depth.",
|
||||
"render.subsurface_rate": "Scattering collision rate",
|
||||
"render.transmission_scope": "GPU glass supports certified disjoint media. Unrestricted nested media and a noise-free transmission estimator are not provided.",
|
||||
"render.transmission_strata": "Conditional Fresnel strata",
|
||||
"render.transmission_strata_help": "1 preserves the original stream. 2 or 4 subpaths stratify the first glass reflection/transmission choice with unchanged Snell and absorption laws. More paths cost more work; this is not denoising, nested-media support or a promise of faster rendering.",
|
||||
"render.unavailable_preview": "This setup requests an unavailable preview profile.",
|
||||
"render.unsaved": "Unsaved preview changes",
|
||||
"render.use_preview": "Use Integrated Preview",
|
||||
"render.volume_albedo": "Scattering albedo · linear RGB",
|
||||
"render.volume_anisotropy": "Phase mean cosine",
|
||||
"render.volume_enable": "Enable participating medium",
|
||||
"render.volume_extinction": "Extinction coefficient",
|
||||
"render.volume_help": "GPU transport inside one finite box, with Beer attenuation and HG scattering on camera and indirect paths. Uses explicit studio/HDR/sky lighting, including shadow attenuation. Positive phase cosine scatters forward. Glass boundaries and surface denoising must be disabled explicitly. Zero extinction leaves transport unchanged. Not a physical lunar atmosphere, density grid, volume emission, spectral transport or certified material property.",
|
||||
"render.volume_max": "Maximum bounds · world mm",
|
||||
"render.volume_min": "Minimum bounds · world mm",
|
||||
"render.volume_title": "Bounded homogeneous volume",
|
||||
"sample.bracket.about": "Base flange with edge flanges and a hem on a 2 mm rule",
|
||||
"sample.bracket.name": "Sheet Metal Bracket",
|
||||
"sample.enclosure.about": "Shelled box with a lip, screw bosses, a rest and a snap fit",
|
||||
@@ -1469,6 +2118,10 @@
|
||||
"toolbar.customize_note": "{tab} tab. Tick a command to give it a toolbar button. You can also drag a row of a panel's drop-down onto the toolbar, drag a button off the toolbar to remove it, or use the pin on a drop-down row.",
|
||||
"toolbar.image": "IMAGE",
|
||||
"toolbar.render": "RENDER",
|
||||
"toolbar.render_appearance": "APPEARANCE",
|
||||
"toolbar.render_camera": "CAMERA",
|
||||
"toolbar.render_environment": "ENVIRONMENT",
|
||||
"toolbar.render_lighting": "LIGHTING",
|
||||
"toolbar.render_scene": "SCENE",
|
||||
"trace.points": "{count} points along the path",
|
||||
"trace.stopped_by_contact": "Ends at sample {sample}: {a} would pass through {b}",
|
||||
@@ -1587,6 +2240,8 @@
|
||||
"ui.agent_chat_allowed": "Allowed",
|
||||
"ui.agent_chat_answered": "Answer: {option}",
|
||||
"ui.agent_chat_approval": "Allow the agent to do this?",
|
||||
"ui.agent_chat_attach_selection": "Attach selection",
|
||||
"ui.agent_chat_attach_selection_tip": "Send what is selected in the model (faces, edges, features, bodies) with the message, so the agent knows what you mean",
|
||||
"ui.agent_chat_attach_view": "Attach view",
|
||||
"ui.agent_chat_attach_view_tip": "Send a picture of the current view with the message",
|
||||
"ui.agent_chat_attachable": "Pictures, PDFs, text and CAD files",
|
||||
@@ -1604,6 +2259,11 @@
|
||||
"ui.agent_chat_command": "Agent command",
|
||||
"ui.agent_chat_connect": "Connect",
|
||||
"ui.agent_chat_copy": "Copy",
|
||||
"ui.agent_chat_ctx_bodies": "Bodies",
|
||||
"ui.agent_chat_ctx_elements": "Elements",
|
||||
"ui.agent_chat_ctx_features": "Features",
|
||||
"ui.agent_chat_ctx_more": "+{n} more",
|
||||
"ui.agent_chat_ctx_other": "Other",
|
||||
"ui.agent_chat_custom_hint": "Any program that speaks the Agent Client Protocol on stdin and stdout. No shell runs it.",
|
||||
"ui.agent_chat_denied": "Denied",
|
||||
"ui.agent_chat_deny": "Deny",
|
||||
@@ -1662,6 +2322,8 @@
|
||||
"ui.agent_chat_paste_picture": "Paste a picture",
|
||||
"ui.agent_chat_permission": "The agent asks to run: {title}",
|
||||
"ui.agent_chat_pick": "Agent",
|
||||
"ui.agent_chat_pick_context": "Pick context",
|
||||
"ui.agent_chat_pick_context_tip": "Choose faces, edges, features and bodies in the model for the agent to look at, then press OK",
|
||||
"ui.agent_chat_placeholder": "Ask the agent to change the design…",
|
||||
"ui.agent_chat_placeholder_busy": "Queue a message for when the agent is done (Ctrl+Enter: send now)",
|
||||
"ui.agent_chat_pop_out": "Open in its own window, which you can move to another screen",
|
||||
@@ -2043,6 +2705,8 @@
|
||||
"ui.hideOrigin": "Hide Origin",
|
||||
"ui.hidePlanes": "Hide Planes",
|
||||
"ui.hideProfile": "Hide Profile",
|
||||
"ui.hide_origin_by_default": "Hide origin by default",
|
||||
"ui.hide_origin_note": "New designs start with the Origin folder hidden. A design keeps its own Origin setting once you show or hide it.",
|
||||
"ui.history_back": "Go back one step",
|
||||
"ui.history_below_browser": "Below browser",
|
||||
"ui.history_edge_hint": "double-click the edge",
|
||||
@@ -2061,6 +2725,7 @@
|
||||
"ui.hole_type": "Hole Type",
|
||||
"ui.home": "Home",
|
||||
"ui.homeView": "Home View",
|
||||
"ui.horizontal_constraint": "Horizontal Constraint",
|
||||
"ui.horizontal_vertical": "Horizontal/Vertical",
|
||||
"ui.import_ellipsis": "Import…",
|
||||
"ui.infinite": "Infinite",
|
||||
@@ -2341,6 +3006,7 @@
|
||||
"ui.untitled": "Untitled",
|
||||
"ui.up_axis_note": "Which axis points up in the views (axis view, Home, Look At). Designs are unchanged.",
|
||||
"ui.updateToCurrentView": "Update to Current View",
|
||||
"ui.vertical_constraint": "Vertical Constraint",
|
||||
"ui.view_centre": "View centre",
|
||||
"ui.visual_shaded_hidden_edges": "Shaded with hidden edges",
|
||||
"ui.visual_shaded_with_edges": "Shaded with edges",
|
||||
|
||||
+645
-1
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Elegir…",
|
||||
"Circular": "Circular",
|
||||
"Circumference": "Circunferencia",
|
||||
"Clockwise": "Horario",
|
||||
"Close draft": "Cerrar borrador",
|
||||
"Collisions": "Colisiones",
|
||||
"Colour": "Color",
|
||||
@@ -84,6 +85,7 @@
|
||||
"Contact Sets": "Conjuntos de contacto",
|
||||
"Contact sets": "Conjuntos de contacto",
|
||||
"Continuity": "Continuidad",
|
||||
"Copies the definition only. Assign it from Physical Material when ready.": "Copia solo la definición. Asígnala desde Material físico cuando esté lista.",
|
||||
"Copy Error Message": "Copiar mensaje de error",
|
||||
"Copy Warning Message": "Copiar mensaje de advertencia",
|
||||
"Copy all licences": "Copiar todas las licencias",
|
||||
@@ -173,6 +175,7 @@
|
||||
"Home view": "Vista de inicio",
|
||||
"Horiz./Vert.": "Horiz./Vert.",
|
||||
"IMAGES": "IMÁGENES",
|
||||
"Import material into design": "Importar material al diseño",
|
||||
"Import…": "Importar…",
|
||||
"In This Design": "En este diseño",
|
||||
"In place (surfaces)": "En su posición (superficies)",
|
||||
@@ -208,6 +211,7 @@
|
||||
"Mass Center": "Centro de masas",
|
||||
"Matched restrictions check the final values.": "Las restricciones que se cumplen comprueban los valores finales.",
|
||||
"Material": "Material",
|
||||
"Material copied. Existing body assignments are unchanged.": "Material copiado. Se conservan las asignaciones actuales de los cuerpos.",
|
||||
"Max": "Máx.",
|
||||
"Mid Radius": "Radio intermedio",
|
||||
"Middle double-click": "Doble clic central",
|
||||
@@ -224,6 +228,7 @@
|
||||
"Move later": "Mover después",
|
||||
"Move up": "Mover arriba",
|
||||
"Name": "Nombre",
|
||||
"Name on import": "Nombre al importar",
|
||||
"Nearest": "Más cercano",
|
||||
"New": "Nuevo",
|
||||
"New Comp.": "Nuevo comp.",
|
||||
@@ -233,6 +238,7 @@
|
||||
"No crash reports.": "No hay informes de fallos.",
|
||||
"No matching appearance presets.": "No hay preajustes de apariencia coincidentes.",
|
||||
"No matching appearances": "No hay apariencias coincidentes",
|
||||
"No matching physical materials.": "No hay materiales físicos coincidentes.",
|
||||
"No visible bodies or sketches to export.": "No hay cuerpos ni bocetos visibles para exportar.",
|
||||
"None": "Ninguno",
|
||||
"Not available yet": "Todavía no disponible",
|
||||
@@ -254,6 +260,7 @@
|
||||
"Path": "Trayectoria",
|
||||
"Pattern": "Patrón",
|
||||
"Per Edge": "Por arista",
|
||||
"Physical material definitions": "Definiciones de materiales físicos",
|
||||
"Pick the tool bodies": "Selecciona los cuerpos herramienta",
|
||||
"Picked": "Seleccionado",
|
||||
"Picked point": "Punto seleccionado",
|
||||
@@ -322,6 +329,7 @@
|
||||
"Search commands": "Buscar comandos",
|
||||
"Search this library": "Buscar en esta biblioteca",
|
||||
"Section": "Sección",
|
||||
"Section position": "Posición de la sección",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Seleccionar otro: mantén pulsado el botón izquierdo sobre el modelo (o haz clic derecho › Seleccionar otro…) para ver todo lo que hay bajo el cursor; vuelve a pulsar en el mismo lugar para seleccionar el siguiente elemento. Haz doble clic con el botón central para volver a Inicio (Preferencias › Navegación).",
|
||||
"Select bodies (a face picks its body)": "Selecciona cuerpos (al seleccionar una cara se selecciona su cuerpo)",
|
||||
"Select bodies or faces instead": "Selecciona cuerpos o caras en su lugar",
|
||||
@@ -345,9 +353,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft se cerró antes de guardar estos diseños. Puedes abrir su último guardado automático.",
|
||||
"Specialise": "Especializar",
|
||||
"Speed": "Velocidad",
|
||||
"Square": "Cuadrado",
|
||||
"Stand it up": "Poner en vertical",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Poner en vertical: un cuarto de vuelta alrededor del eje X, como una única operación Mover que puedes deshacer.",
|
||||
"Stand this part up?": "¿Poner esta pieza en vertical?",
|
||||
"Start angle": "Ángulo inicial",
|
||||
"Start bulge": "Abombamiento inicial",
|
||||
"Start continuity": "Continuidad inicial",
|
||||
"Step": "Paso",
|
||||
@@ -412,6 +422,7 @@
|
||||
"angle, height": "ángulo, altura",
|
||||
"appearance.dielectric_ior": "Índice de refracción dieléctrico",
|
||||
"appearance.metallic": "Metalicidad",
|
||||
"appearance.only_available": "Solo apariencias disponibles",
|
||||
"appearance.pbr_help": "Visualiza esta superficie en Renderizado o en un PNG del producto. Sin refracción ni transmisión.",
|
||||
"appearance.pbr_opaque": "PBR opaco",
|
||||
"appearance.roughness": "Rugosidad",
|
||||
@@ -573,6 +584,7 @@
|
||||
"cmd.material_create": "Nuevo material físico",
|
||||
"cmd.material_delete": "Eliminar material físico",
|
||||
"cmd.material_edit": "Editar material físico",
|
||||
"cmd.material_inspect": "Inspeccionar material físico",
|
||||
"cmd.material_list": "Listar materiales",
|
||||
"cmd.material_properties_directional": "Módulo elástico direccional",
|
||||
"cmd.material_properties_validate": "Validar datos del material físico",
|
||||
@@ -618,14 +630,45 @@
|
||||
"cmd.plastic_rest": "Apoyo",
|
||||
"cmd.plastic_rules": "Listar reglas de plástico",
|
||||
"cmd.plastic_snap_fit": "Encaje a presión",
|
||||
"cmd.render_aging_describe": "Envejecimiento por capas",
|
||||
"cmd.render_backends": "Motores de renderizado",
|
||||
"cmd.render_camera_fit": "Encuadrar sujeto de render",
|
||||
"cmd.render_camera_get": "Inspeccionar cámara de render",
|
||||
"cmd.render_cancel": "Cancelar renderizado",
|
||||
"cmd.render_effects_describe": "Efectos de lente y creativos",
|
||||
"cmd.render_export": "Exportar imagen renderizada",
|
||||
"cmd.render_hdr_inspect": "Inspeccionar fuente HDR",
|
||||
"cmd.render_library_appearance_apply": "Aplicar aspecto opaco de la biblioteca",
|
||||
"cmd.render_library_describe": "Inspeccionar recurso de renderizado",
|
||||
"cmd.render_library_environment_apply": "Aplicar entorno HDR incluido",
|
||||
"cmd.render_library_list": "Explorar la biblioteca de renderizado",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_preview": "Inspect Original Surface Map",
|
||||
"cmd.render_library_studio_apply": "Aplicar iluminación de estudio",
|
||||
"cmd.render_library_studio_prepare": "Preparar iluminación de estudio",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "Preparar mapas de superficie",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "Buscar destinos de recursos de renderizado",
|
||||
"cmd.render_optics_bind": "Guardar asignación óptica",
|
||||
"cmd.render_optics_unbind": "Quitar asignación óptica",
|
||||
"cmd.render_preflight": "Comprobar solicitud de renderizado",
|
||||
"cmd.render_preset_apply": "Apply Native Studio",
|
||||
"cmd.render_preset_resolve": "Review Native Studio",
|
||||
"cmd.render_quality_prepare": "Review Fixed Sampling Budget",
|
||||
"cmd.render_result_pin": "Conservar el resultado mostrado",
|
||||
"cmd.render_result_regrade": "Reeditar máster lineal",
|
||||
"cmd.render_scene": "Inspeccionar escena de renderizado",
|
||||
"cmd.render_settings_apply": "Aplicar cámara de renderizado",
|
||||
"cmd.render_settings_capture_hdr": "Guardar configuración de renderizado con HDR",
|
||||
"cmd.render_settings_get": "Ajustes de renderizado",
|
||||
"cmd.render_settings_set": "Guardar ajustes de renderizado",
|
||||
"cmd.render_shot_duplicate": "Duplicate Render Shot",
|
||||
"cmd.render_shot_remove": "Remove Render Shot",
|
||||
"cmd.render_shot_rename": "Rename Render Shot",
|
||||
"cmd.render_stage_backdrop": "Guardar fondo físico de render",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
"cmd.render_start": "Renderizar imagen",
|
||||
"cmd.render_status": "Progreso del renderizado",
|
||||
"cmd.select_clear": "Borrar selección",
|
||||
@@ -952,6 +995,49 @@
|
||||
"manage.material_hint": "Seleccione cuerpos y elija su material físico.",
|
||||
"manage.parameters_hint": "Edite expresiones y unidades. Los cambios se aplican al pulsar Intro o salir de un campo.",
|
||||
"manage.rules_hint": "Elija una regla para editarla o cree una nueva. Confirme para guardar la regla.",
|
||||
"material.editor.add_property": "Añadir propiedad",
|
||||
"material.editor.add_source": "Añadir fuente",
|
||||
"material.editor.assigned_density": "Densidad asignada",
|
||||
"material.editor.axes": "Ejes del material",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"material.editor.copy_name": "Copia de {name}",
|
||||
"material.editor.density_range": "La densidad asignada debe ser mayor que 0 y no superar 1000 g/cm³.",
|
||||
"material.editor.designation": "Designación",
|
||||
"material.editor.duplicate": "Duplicar",
|
||||
"material.editor.engineering_card": "Ficha de propiedades físicas",
|
||||
"material.editor.family": "Familia del material",
|
||||
"material.editor.glass": "Vidrio",
|
||||
"material.editor.illustrative": "Ilustrativa",
|
||||
"material.editor.invalid_property": "Tipo de propiedad no admitido.",
|
||||
"material.editor.isotropic": "Isótropo",
|
||||
"material.editor.measurement": "Medición",
|
||||
"material.editor.metal": "Metal",
|
||||
"material.editor.moisture": "Humedad en base seca",
|
||||
"material.editor.name_required": "Introduce un nombre de 1 a 128 caracteres.",
|
||||
"material.editor.no_draft": "No hay ningún borrador de material abierto.",
|
||||
"material.editor.number_required": "Introduce un valor numérico finito.",
|
||||
"material.editor.orthotropic": "Ortótropo",
|
||||
"material.editor.other": "Otra",
|
||||
"material.editor.polymer": "Polímero",
|
||||
"material.editor.preserved_appearance": "Apariencia conservada",
|
||||
"material.editor.public_reference": "Referencia pública",
|
||||
"material.editor.reference": "Referencia",
|
||||
"material.editor.save_or_discard": "Guarda o descarta el borrador antes de asignar un material.",
|
||||
"material.editor.saved": "Material guardado. Las asignaciones a cuerpos no han cambiado.",
|
||||
"material.editor.scope": "Guardar almacena este material sin asignarlo a cuerpos. Las propiedades y condiciones vacías siguen siendo desconocidas. La densidad de la ficha no cambia la densidad asignada ni la masa.",
|
||||
"material.editor.source_id": "ID de la fuente",
|
||||
"material.editor.source_kind": "Tipo de fuente",
|
||||
"material.editor.source_title": "Título de la fuente",
|
||||
"material.editor.sources": "Fuentes",
|
||||
"material.editor.stale": "Este material cambió mientras el borrador estaba abierto. Descártalo y vuelve a abrirlo antes de guardar.",
|
||||
"material.editor.state": "Estado del material",
|
||||
"material.editor.strain_rate": "Velocidad de deformación",
|
||||
"material.editor.symmetry": "Simetría elástica",
|
||||
"material.editor.temperature": "Temperatura",
|
||||
"material.editor.unknown_card": "Las propiedades físicas son desconocidas. Puedes guardar solo la densidad asignada y la apariencia existente.",
|
||||
"material.editor.user_supplied": "Aportada por la usuaria",
|
||||
"material.editor.wood": "Madera",
|
||||
"measure.at": "En",
|
||||
"measure.item": "Elemento {number}",
|
||||
"messages.ago_h": "hace {n} h",
|
||||
@@ -1006,21 +1092,248 @@
|
||||
"recovery.just_now": "justo ahora",
|
||||
"recovery.min_ago": "hace {count} min",
|
||||
"recovery.never_saved": "nunca guardado",
|
||||
"render.adaptive_absolute": "Umbral de error RGB absoluto",
|
||||
"render.adaptive_coverage": "Objetivo de error de cobertura",
|
||||
"render.adaptive_enable": "Asignar muestras con diagnóstico independiente",
|
||||
"render.adaptive_help": "Solo GPU. Se descartan las muestras de diagnóstico independientes y se asignan al menos 16 muestras finales por píxel, hasta el límite Muestras por píxel. La varianza RGB y de cobertura orienta la asignación; pueden omitirse trayectorias raras y quedar ruido al alcanzar el límite. El informe cuenta el trabajo real, sin garantía de ruido ni tiempo.",
|
||||
"render.adaptive_minimum": "Mínimo de muestras finales",
|
||||
"render.adaptive_pending": "Disponibles en GPU la asignación adaptativa con diagnóstico independiente y los estratos de Fresnel. Siguen pendientes la convergencia certificada, las garantías de eventos raros y el transporte adaptativo CPU.",
|
||||
"render.adaptive_pilots": "Muestras de diagnóstico por píxel",
|
||||
"render.adaptive_relative": "Objetivo de error RGB relativo",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.advanced_material_scope": "Disponible un medio homogéneo GPU finito con límites explícitos. Siguen pendientes las rejillas de densidad, vidrio y volumen combinados, superficies subsuperficiales, desplazamiento, transporte espectral y conceptos avanzados sin implementar.",
|
||||
"render.aging_add": "Añadir capa de envejecimiento",
|
||||
"render.aging_airborne": "Polvo en suspensión / medio participante",
|
||||
"render.aging_airborne_help": "El polvo suspendido es un volumen homogéneo finito e independiente. Cambia el transporte y el EXR, no la pila de superficies. Se mantienen las restricciones de volumen, vidrio y reducción de ruido; nunca se añade una atmósfera automáticamente.",
|
||||
"render.aging_all_bodies": "Todos los cuerpos opacos aptos",
|
||||
"render.aging_chips": "Pintura desconchada",
|
||||
"render.aging_class_any": "Todas las clases opacas",
|
||||
"render.aging_class_dielectric": "Solo superficies no metálicas",
|
||||
"render.aging_class_metal": "Solo superficies metálicas",
|
||||
"render.aging_color": "Color de capa · sRGB",
|
||||
"render.aging_coverage": "Cobertura",
|
||||
"render.aging_dust": "Polvo depositado",
|
||||
"render.aging_empty": "Sin capas: se conservan las superficies originales.",
|
||||
"render.aging_fading": "Recubrimiento descolorido",
|
||||
"render.aging_grime": "Suciedad y manchas",
|
||||
"render.aging_help": "Combina hasta ocho capas ópticas, en orden. Óxido y pátina son apariencias, no simulaciones de edad o corrosión. La escala usa milímetros globales. No cambian geometría, masa ni propiedades de ingeniería; vidrio y escenario quedan excluidos.",
|
||||
"render.aging_metallic": "Fracción metálica de capa",
|
||||
"render.aging_origin": "Origen del campo · mm globales",
|
||||
"render.aging_patina": "Pátina verde de cobre",
|
||||
"render.aging_refresh_targets": "Inspeccionar cuerpos actuales",
|
||||
"render.aging_roughness": "Rugosidad de capa",
|
||||
"render.aging_rust": "Óxido de hierro",
|
||||
"render.aging_scale": "Escala del patrón",
|
||||
"render.aging_scratches": "Arañazos finos",
|
||||
"render.aging_target": "Destino y coordenadas",
|
||||
"render.aging_target_help": "El destino debe conservar el índice y nombre capturados. Las máscaras se anclan al mundo, no siguen piezas móviles. No detectan cavidades ni desgaste geométrico de aristas. Filtra la lista para encontrar otros cuerpos.",
|
||||
"render.aging_target_search": "Filtrar nombres de cuerpos",
|
||||
"render.aging_upward": "Depósito en caras superiores",
|
||||
"render.all_controls_help": "Inspección de todos los controles. Las secciones permiten editar por contexto sin cambiar la petición subyacente.",
|
||||
"render.appearance_physics_separate": "El aspecto visual no asigna densidad, propiedades térmicas ni otros datos de ingeniería.",
|
||||
"render.availability_native": "Composición nativa; revisar antes de aplicar",
|
||||
"render.availability_projection": "Proyección compatible; consulta alcance y omisiones",
|
||||
"render.availability_reference": "Datos de referencia; no es una asignación automática",
|
||||
"render.backdrop_alpha_conflict": "Elige el fondo o la salida PNG transparente; el renderizador no ignorará ninguna opción.",
|
||||
"render.backdrop_enable": "Usar fondo degradado solo para la cámara",
|
||||
"render.backdrop_first": "Color inicial / central",
|
||||
"render.backdrop_help": "Este fondo de pantalla no ilumina, proyecta sombras, refleja ni representa terreno. Se excluye del EXR sin procesar. Geometría, luces y entorno HDR son independientes.",
|
||||
"render.backdrop_horizontal": "Degradado horizontal",
|
||||
"render.backdrop_radial": "Degradado radial",
|
||||
"render.backdrop_radius": "Radio",
|
||||
"render.backdrop_second": "Color final / del borde",
|
||||
"render.backdrop_vertical": "Degradado vertical",
|
||||
"render.backdrop_x": "Centro X",
|
||||
"render.backdrop_y": "Centro Y",
|
||||
"render.background": "Fondo de la escena",
|
||||
"render.background_camera_section": "Fondo de cámara · presentación PNG",
|
||||
"render.background_completed_frozen": "El resultado mostrado es una imagen terminada e inmutable. Editar el fondo no repinta automáticamente ese resultado. Usa Reeditar para cambios de cámara o Renderizar para un escenario físico nuevo.",
|
||||
"render.background_hdr_separate": "Los HDR actuales iluminan y se reflejan en las superficies; no se muestran automáticamente como una panorámica detrás del objeto. Cambiar el degradado no gira ni recolorea la iluminación.",
|
||||
"render.background_lighting_section": "Iluminación HDR · independiente del fondo de cámara",
|
||||
"render.background_no_alpha_override": "El fondo de cámara no se añade silenciosamente a una salida transparente. La reedición usa la cobertura capturada y no vuelve a reducir ruido; el EXR original se conserva.",
|
||||
"render.background_not_light": "El color de fondo es presentación, no una fuente de luz adicional.",
|
||||
"render.background_regrade": "Aplicar al máster bruto retenido",
|
||||
"render.background_stage_occlusion": "Esta toma incluye geometría de escenario. Un suelo o pared grandes pueden llenar el encuadre y ocultar el fondo de cámara. Elimina o ajusta el escenario de forma explícita, o cambia su reflectancia. Reeditar no elimina geometría capturada.",
|
||||
"render.background_workflow": "Elige el tipo de fondo: color/degradado solo para la cámara, escenario físico que recibe luz o iluminación HDR. Son independientes. Vista previa es una vista de modelado; renderiza o reedita un máster retenido para ver el acabado de cámara.",
|
||||
"render.base_appearance": "Aspecto editable del cuerpo",
|
||||
"render.base_apply": "Aplicar aspecto al cuerpo",
|
||||
"render.base_apply_help": "Asignación visual deshacible al cuerpo exacto revisado. Los aspectos por cara y materiales físicos permanecen separados.",
|
||||
"render.base_color": "Color base · sRGB",
|
||||
"render.base_metallic": "Fracción metálica",
|
||||
"render.base_opaque_only": "Este editor conserva la semántica opaca. Utiliza los controles de vidrio para transmisión óptica.",
|
||||
"render.bloom_enable": "Resplandor de presentación",
|
||||
"render.bloom_help": "Resplandor creativo del resultado a partir de altas luces lineales, extendido con tres pasadas normalizadas. Radio en píxeles de salida. Se añade en luz lineal de pantalla antes de sRGB; no simula lentes ni volúmenes ni mejora la convergencia. El EXR original no cambia.",
|
||||
"render.bloom_opaque": "El resplandor requiere salida opaca. Se rechaza el PNG transparente, sin aplanarlo silenciosamente.",
|
||||
"render.bloom_radius": "Radio del resplandor",
|
||||
"render.bloom_strength": "Intensidad del resplandor",
|
||||
"render.bloom_threshold": "Umbral lineal de altas luces",
|
||||
"render.browse_capabilities": "Consultar catálogo completo de capacidades",
|
||||
"render.browse_environments": "Explorar entornos HDR originales",
|
||||
"render.browse_native_scenes": "Explorar estudios nativos",
|
||||
"render.browse_physical": "Consultar referencias físicas",
|
||||
"render.browse_quality": "Consultar especificaciones de calidad",
|
||||
"render.browse_rigs": "Explorar conjuntos de luces",
|
||||
"render.browse_scene_specs": "Explorar especificaciones de escenas avanzadas",
|
||||
"render.browse_surfaces": "Explorar superficies originales",
|
||||
"render.browser_library": "Biblioteca",
|
||||
"render.browser_model": "Modelo",
|
||||
"render.camera_distance": "Distancia de la cámara al objetivo",
|
||||
"render.camera_exact_help": "Milímetros del mundo; ángulos mostrados en grados y guardados en radianes. La navegación utiliza la misma cámara que el visor.",
|
||||
"render.camera_fov": "Campo de visión vertical",
|
||||
"render.camera_pitch": "Inclinación de cámara",
|
||||
"render.camera_roll": "Giro",
|
||||
"render.camera_set": "Establecer cámara de render",
|
||||
"render.camera_target": "Posición del objetivo · mm",
|
||||
"render.camera_yaw": "Azimut",
|
||||
"render.chromatic_offset": "Separación cromática",
|
||||
"render.clear_stage": "Remove saved stage",
|
||||
"render.copy_request": "Copiar JSON",
|
||||
"render.cpu_aa_help": "Más muestras suavizan los bordes y aumentan el tiempo de renderizado.",
|
||||
"render.cpu_area_add": "Añadir luz rectangular CPU",
|
||||
"render.cpu_area_editor": "Luces rectangulares CPU",
|
||||
"render.cpu_area_editor_help": "Vectores de lado completos en milímetros; U por V señala la cara emisora. No son los semilados de las luces GPU.",
|
||||
"render.cpu_area_full_u": "Lado U completo · mm",
|
||||
"render.cpu_area_full_v": "Lado V completo · mm",
|
||||
"render.cpu_area_samples": "Muestras por luz de área",
|
||||
"render.cpu_binding_confirm": "Confirmar este cuerpo",
|
||||
"render.cpu_binding_stale": "La escena ha cambiado. Confirma de nuevo este cuerpo de los reflejos antes de renderizar.",
|
||||
"render.cpu_body_choose": "Elegir un cuerpo",
|
||||
"render.cpu_body_filter": "Filtrar cuerpos por nombre",
|
||||
"render.cpu_body_filter_more": "Afina el filtro para ver más cuerpos.",
|
||||
"render.cpu_body_missing": "Un cuerpo de los reflejos falta, está oculto, es ambiguo o su nombre supera 128 bytes. Vuelve a elegirlo.",
|
||||
"render.cpu_budget": "Perfil de recursos de CPU",
|
||||
"render.cpu_budget_bodies": "Máximo de cuerpos",
|
||||
"render.cpu_budget_compact": "Compacto (límites anteriores)",
|
||||
"render.cpu_budget_details": "Límites de recursos",
|
||||
"render.cpu_budget_help": "Selecciona límites mayores de forma explícita. La resolución y las muestras nunca se reducen automáticamente.",
|
||||
"render.cpu_budget_memory": "Memoria máxima del trabajo",
|
||||
"render.cpu_budget_not_guarantee": "Son límites de admisión, no una reserva de RAM ni una garantía de velocidad. Geometría, acumulación y vistas previas comparten el presupuesto de memoria; el renderizado se puede cancelar.",
|
||||
"render.cpu_budget_resize": "La configuración supera este perfil de CPU o su presupuesto de muestras. Acepta unas dimensiones menores de forma explícita o selecciona un perfil superior.",
|
||||
"render.cpu_budget_studio": "Estudio (imágenes grandes)",
|
||||
"render.cpu_budget_triangles": "Máximo de triángulos",
|
||||
"render.cpu_budget_workstation": "Estación de trabajo (escenas pesadas)",
|
||||
"render.cpu_captured_hdr": "HDR capturado para esta imagen",
|
||||
"render.cpu_check_capture_help": "Comprobar e Iniciar verifican la misma huella del archivo o usan el HDR del diseño. Cada imagen conserva su fuente capturada.",
|
||||
"render.cpu_check_changed": "Los controles o el modelo han cambiado desde esta comprobación. Comprueba de nuevo antes de renderizar.",
|
||||
"render.cpu_constant_help": "La radiancia constante llega a los rayos reflejados o transmitidos. No aporta iluminación difusa directa.",
|
||||
"render.cpu_custom_directions": "Sustituir el preajuste por luces direccionales",
|
||||
"render.cpu_direction": "Dirección hacia la luz (X, Y, Z)",
|
||||
"render.cpu_directional": "Luz direccional",
|
||||
"render.cpu_directional_add": "Añadir luz direccional",
|
||||
"render.cpu_environment": "Entorno CPU",
|
||||
"render.cpu_environment_background": "El fondo de la imagen se mantiene separado de la iluminación del entorno.",
|
||||
"render.cpu_environment_bounds": "La intensidad CPU debe ser 0–64, el giro HDR finito dentro de ±1 000 000 radianes y las muestras HDR 1, 4, 16 o 64.",
|
||||
"render.cpu_environment_constant": "Entorno constante para rayos secundarios",
|
||||
"render.cpu_environment_none": "Sin entorno CPU",
|
||||
"render.cpu_environment_samples": "Muestras de iluminación HDR",
|
||||
"render.cpu_exposure_help": "La exposición CPU debe estar entre −16 y 16 EV. Una exposición GPU fuera de ese rango se conserva hasta que la cambies.",
|
||||
"render.cpu_fixed": "Imagen fija",
|
||||
"render.cpu_hdr_help": "Radiance .hdr, panorama 2:1, hasta 2048 × 1024 y 16 MiB. La CPU exige primarias sRGB/D65 explícitas en el archivo; rechaza primarias sin definir y EXR.",
|
||||
"render.cpu_hdr_reflection_help": "Los reflejos rugosos con HDR requieren superficies totalmente metálicas en el cuerpo y sus caras. Comprobar indica las combinaciones no admitidas.",
|
||||
"render.cpu_key_rim": "Principal y contorno",
|
||||
"render.cpu_last_check": "Última comprobación CPU",
|
||||
"render.cpu_light_help": "Hasta ocho luces direccionales. Una lista personalizada vacía las apaga; elegir un preajuste restaura sus luces. El color es RGB lineal y la intensidad es relativa, no vatios.",
|
||||
"render.cpu_light_intensity": "Intensidad relativa (0–64)",
|
||||
"render.cpu_light_minimum": "Distancia mínima de atenuación",
|
||||
"render.cpu_light_position": "Posición en el mundo (X, Y, Z)",
|
||||
"render.cpu_light_reference": "Distancia de referencia de la intensidad",
|
||||
"render.cpu_light_remove": "Quitar luz",
|
||||
"render.cpu_lighting": "Preajuste de iluminación",
|
||||
"render.cpu_lights": "Luces CPU",
|
||||
"render.cpu_linear_color": "Color lineal (R, G, B)",
|
||||
"render.cpu_neutral": "Neutro",
|
||||
"render.cpu_opaque_required": "El trazado CPU requiere un fondo opaco. Desactiva Fondo transparente para continuar.",
|
||||
"render.cpu_options_pending": "Este panel CPU todavía no puede editar emisión, efectos de superficie, vidrio ni anisotropía. Borra esas opciones de la API antes de usarlo.",
|
||||
"render.cpu_point": "Luz puntual",
|
||||
"render.cpu_point_add": "Añadir luz puntual",
|
||||
"render.cpu_point_help": "Hasta ocho luces puntuales, añadidas a la iluminación direccional elegida. Las distancias están en mm; la mínima no puede superar la de referencia.",
|
||||
"render.cpu_primary_samples": "Muestras de borde por píxel",
|
||||
"render.cpu_progressive": "CPU progresivo",
|
||||
"render.cpu_progressive_help": "Acumula el integrador CPU actual en pasadas de una muestra primaria. Los reflejos seleccionados requieren una muestra; luces de área, dieléctricos y anisotropía requieren Imagen fija.",
|
||||
"render.cpu_progressive_limits": "Máximo de 1.048.576 píxeles y 16.777.216 evaluaciones de píxel × muestra. Cambiar las muestras nunca redimensiona la imagen automáticamente.",
|
||||
"render.cpu_progressive_seed": "Semilla de muestreo CPU",
|
||||
"render.cpu_progressive_spp": "muestras por píxel",
|
||||
"render.cpu_reflection_add": "Añadir reflejo rugoso",
|
||||
"render.cpu_reflection_depth": "Profundidad de reflejos (1–8)",
|
||||
"render.cpu_reflection_empty": "Sin cuerpos seleccionados: los reflejos de la escena están desactivados.",
|
||||
"render.cpu_reflection_help": "Elige cuerpos y selecciona Desactivado, Espejo o Rugoso. Rugoso usa la rugosidad asignada al material. Más muestras y rebotes aumentan el tiempo; el transporte especular es acotado y no calcula iluminación global.",
|
||||
"render.cpu_reflection_limit": "Se admiten hasta 64 cuerpos con reflejos.",
|
||||
"render.cpu_reflection_mirror": "Espejo",
|
||||
"render.cpu_reflection_off": "Desactivado",
|
||||
"render.cpu_reflection_rough": "Rugoso",
|
||||
"render.cpu_reflection_samples": "Muestras de reflejos (1–64)",
|
||||
"render.cpu_reflections": "Reflejos CPU",
|
||||
"render.cpu_runtime_help": "Los ajustes numéricos de luces y entorno se guardan con la configuración. Los reflejos por cuerpo y los archivos HDR siguen siendo temporales. Se conservan los valores existentes de luces de área y conos de foco.",
|
||||
"render.cpu_sampling_mode": "Modo de muestreo CPU",
|
||||
"render.cpu_shadows": "Proyectar sombras",
|
||||
"render.cpu_summary": "Trazado CPU · reflejos · HDR · luces direccionales y puntuales",
|
||||
"render.cpu_warm_cool": "Cálido y frío",
|
||||
"render.diag_bodies": "Cuerpos visibles",
|
||||
"render.diag_job_details": "Detalles del trabajo capturado",
|
||||
"render.diag_last_check": "Última comprobación",
|
||||
"render.diag_memory": "Estimación lógica de memoria",
|
||||
"render.diag_not_implemented": "Límites explícitos de capacidades",
|
||||
"render.diag_preflight_details": "Detalles de la comprobación",
|
||||
"render.diag_request": "Petición actual exacta",
|
||||
"render.diag_triangles": "Triángulos",
|
||||
"render.discard_continue": "Descartar borrador y continuar",
|
||||
"render.draft_confirm_help": "El borrador contiene cambios pendientes. Guárdalos antes de cambiar, descártalos explícitamente o sigue editando.",
|
||||
"render.draft_confirm_title": "Conservar los ajustes editados",
|
||||
"render.effects_gpu_only": "Estos efectos requieren trazado GPU. Cambiar de pestaña no cambia automáticamente el motor.",
|
||||
"render.effects_help": "Combina filtros de color ordenados y efectos de lente en imagen. Render y reedición del máster usan los mismos ajustes guardados. El EXR bruto no cambia. Son controles artísticos originales, no emulaciones calibradas de lentes o películas comerciales.",
|
||||
"render.effects_reset_lens": "Restablecer efectos de lente",
|
||||
"render.effects_seed": "Semilla del patrón",
|
||||
"render.export_display": "Exportar: PNG de visualización",
|
||||
"render.export_linear": "Exportar: EXR lineal",
|
||||
"render.exr_pending": "La GPU puede conservar EXR lineal original. La compresión, las imágenes multicapa y los pases auxiliares siguen sin estar disponibles.",
|
||||
"render.film_grain": "Grano fotográfico",
|
||||
"render.fit": "Ajustar producto",
|
||||
"render.flare_ghosts": "Anillos por fuente",
|
||||
"render.flare_halo": "Halo de flare",
|
||||
"render.flare_streak": "Estela estilo anamórfico",
|
||||
"render.flare_strength": "Intensidad del flare",
|
||||
"render.flare_threshold": "Umbral lineal del flare",
|
||||
"render.gpu_depth": "Profundidad máxima del trazado",
|
||||
"render.gpu_options_help": "Las muestras, la profundidad, la semilla y la exposición se guardan con esta configuración. Solo se guarda el método de imagen activo.",
|
||||
"render.gpu_path_failed": "Trazado GPU no disponible",
|
||||
"render.gpu_path_first_setup": "La primera preparación en esta GPU puede tardar varios minutos; puedes seguir usando SolidCraft. Los siguientes inicios reutilizan los sombreadores compilados cuando el controlador los conserva.",
|
||||
"render.gpu_path_preparing": "Trazado GPU: compilando sombreadores…",
|
||||
"render.gpu_seed": "Semilla aleatoria",
|
||||
"render.gpu_unavailable": "El trazado GPU aún no está disponible en este dispositivo.",
|
||||
"render.ground_apply": "Ajustar y guardar suelo",
|
||||
"render.ground_gap": "Separación geométrica explícita",
|
||||
"render.ground_linear_rgb": "Reflectancia difusa · RGB lineal",
|
||||
"render.ground_margin": "Margen de extensión del suelo",
|
||||
"render.hdr_details": "Detalles de la fuente HDR",
|
||||
"render.hdr_embedded": "HDR guardado dentro del diseño",
|
||||
"render.hdr_embedded_help": "El renderizado usa los bytes incluidos en el diseño; el archivo original ya no es necesario.",
|
||||
"render.hdr_file_captured": "Archivo HDR comprobado. Guardar incluirá estos bytes; si el archivo cambia, compruébalo de nuevo explícitamente.",
|
||||
"render.hdr_inspect": "Comprobar archivo HDR",
|
||||
"render.hdr_inspect_required": "Selecciona y comprueba un archivo HDR antes de guardar o renderizar.",
|
||||
"render.hdr_primaries_declared": "La fuente declara sus primarias de color.",
|
||||
"render.hdr_primaries_srgb": "Primarias de color: sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "La fuente no declara primarias; revisa los requisitos de color del motor.",
|
||||
"render.hdr_resource_missing": "El recurso HDR guardado no existe en este diseño.",
|
||||
"render.image_advanced": "Opciones avanzadas de GPU",
|
||||
"render.image_cancelled": "Renderizado cancelado",
|
||||
"render.image_cancelling": "Cancelando",
|
||||
"render.image_completed": "Imagen lista para exportar",
|
||||
"render.image_encoding": "Codificando PNG",
|
||||
"render.image_export": "Exportar PNG",
|
||||
"render.image_export": "Exportar imagen terminada",
|
||||
"render.image_exposure": "Exposición",
|
||||
"render.image_failed": "Error de renderizado",
|
||||
"render.image_height": "Altura",
|
||||
"render.image_help": "Imagen de vista previa por CPU · PNG · transparencia aproximada",
|
||||
"render.image_host_missing": "No hay un motor de imagen instalado.",
|
||||
"render.image_method": "Método de imagen",
|
||||
"render.image_overwrite": "Sustituir archivo existente",
|
||||
"render.image_preparing": "Preparando imagen",
|
||||
"render.image_progressive": "Renderizado progresivo",
|
||||
"render.image_queued": "Esperando para renderizar",
|
||||
"render.image_reduce": "Prueba con una imagen más pequeña o una escena más sencilla.",
|
||||
"render.image_running": "Renderizando imagen",
|
||||
"render.image_samples": "Muestras por píxel",
|
||||
"render.image_scene_stale": "Termina la operación de modelado o actualiza la escena antes de comprobar o iniciar una imagen.",
|
||||
"render.image_stale": "Esta imagen utiliza la escena capturada antes de los cambios posteriores.",
|
||||
"render.image_start": "Iniciar renderizado",
|
||||
"render.image_supported": "La solicitud de renderizado es compatible; la cola y la memoria disponible se comprobarán de nuevo al iniciar.",
|
||||
@@ -1030,20 +1343,347 @@
|
||||
"render.image_unknown": "Estado del renderizado no disponible",
|
||||
"render.image_use_largest": "Usar el tamaño máximo para esta proporción:",
|
||||
"render.image_width": "Anchura",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspect_scene": "Actualizar resumen de la escena",
|
||||
"render.keep_editing": "Seguir editando",
|
||||
"render.layer_down": "Bajar",
|
||||
"render.layer_enabled": "Capa activada",
|
||||
"render.layer_remove": "Eliminar capa",
|
||||
"render.layer_strength": "Intensidad de capa",
|
||||
"render.layer_up": "Subir",
|
||||
"render.lens_effects_help": "El flare usa hasta cuatro altas luces separadas de la imagen lineal real. Anillos, halo, estelas, separación cromática y distorsión son aproximaciones artísticas en imagen. Los efectos espaciales requieren salida opaca; las muestras exteriores extienden el borde. El grano es determinista. No cambian física, EXR ni geometría.",
|
||||
"render.lens_effects_title": "Lente y fotografía",
|
||||
"render.library_all": "Catálogo",
|
||||
"render.library_all_states": "Todos los estados",
|
||||
"render.library_applied": "Variante del recurso aplicada. Comprueba la solicitud completa antes de renderizar.",
|
||||
"render.library_apply_hdr": "Guardar con este entorno HDR",
|
||||
"render.library_apply_maps": "Usar mapas de superficie GPU",
|
||||
"render.library_apply_studio": "Guardar la variante de iluminación",
|
||||
"render.library_apply_uniform": "Aplicar aspecto opaco uniforme",
|
||||
"render.library_authored_help": "Los recursos originales son ilustrativos, no datos de ingeniería medidos. Cada acción aplica únicamente la variante indicada.",
|
||||
"render.library_blocked": "Bloqueado / requiere calibración",
|
||||
"render.library_capabilities": "Especificaciones de capacidades",
|
||||
"render.library_center": "Centro de la iluminación",
|
||||
"render.library_clear_search": "Limpiar",
|
||||
"render.library_details": "Especificación y procedencia",
|
||||
"render.library_emitters_only_ack": "Usar solo emisores; omitir las tarjetas pasivas indicadas",
|
||||
"render.library_empty": "No hay recursos coincidentes. Prueba otra búsqueda o filtro.",
|
||||
"render.library_environment_concepts": "Conceptos de entornos",
|
||||
"render.library_extent": "Extensión del objeto",
|
||||
"render.library_favorite": "Añadir favorito",
|
||||
"render.library_favorites": "Favoritos",
|
||||
"render.library_hdr": "Entornos HDR incluidos",
|
||||
"render.library_hdr_help": "Incorpora el HDR original a la configuración guardada. Convierte explícitamente el origen azimutal; tras guardar no se necesita ningún archivo externo.",
|
||||
"render.library_inspect_only": "Selecciona para inspeccionar; no se aplica nada automáticamente. Favoritos e historial pertenecen a la sesión de este documento.",
|
||||
"render.library_light_concepts": "Conceptos de iluminación",
|
||||
"render.library_maps_help": "Built-in maps can be saved with pinned sources and local occurrence mapping. Temporary optical overrides remain a separate mode.",
|
||||
"render.library_material_concepts": "Conceptos de materiales",
|
||||
"render.library_native_scenes": "Estudios nativos",
|
||||
"render.library_next": "Página siguiente",
|
||||
"render.library_omitted": "No incluido",
|
||||
"render.library_physical_profiles": "Physical reference profiles",
|
||||
"render.library_previous": "Página anterior",
|
||||
"render.library_quality_concepts": "Especificaciones de calidad",
|
||||
"render.library_recent": "Recientes",
|
||||
"render.library_replace_environment": "Sustituir explícitamente el entorno existente",
|
||||
"render.library_replace_studio": "Replace saved lighting, environment and stage",
|
||||
"render.library_results": "Recursos encontrados",
|
||||
"render.library_rig_help": "Fit once at an explicit center and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_rigs": "Configuraciones de iluminación creadas",
|
||||
"render.library_save_maps": "Save maps to this setup",
|
||||
"render.library_scene_bounds": "Usar los límites de la escena capturada",
|
||||
"render.library_scenes": "Especificaciones de escenas",
|
||||
"render.library_search": "Buscar en la biblioteca",
|
||||
"render.library_select_hint": "Elige un recurso en la Biblioteca para ver sus acciones disponibles y sus límites.",
|
||||
"render.library_selene": "Aspectos opacos de SELENE",
|
||||
"render.library_selene_shots": "Especificaciones de tomas de SELENE",
|
||||
"render.library_short_blocked": "No disponible",
|
||||
"render.library_short_native": "Composición nativa",
|
||||
"render.library_short_projection": "Proyección compatible",
|
||||
"render.library_short_reference": "Solo referencia",
|
||||
"render.library_short_specification": "Solo especificación",
|
||||
"render.library_source_preview": "Cargar vista del mapa original",
|
||||
"render.library_source_preview_help": "Mapa de color base original. No es una vista renderizada ni una medición del material.",
|
||||
"render.library_specification_only": "Solo especificación: no es un preajuste ejecutable completo. Los efectos, recursos y roles del objeto requieren implementación y asociación explícitas.",
|
||||
"render.library_specs": "Solo especificaciones",
|
||||
"render.library_status": "Disponibilidad",
|
||||
"render.library_surfaces": "Superficies PBR creadas",
|
||||
"render.library_target": "Cuerpo de destino",
|
||||
"render.library_title": "Biblioteca de recursos de renderizado",
|
||||
"render.library_unfavorite": "Quitar favorito",
|
||||
"render.library_uniform_ack": "Usar la aproximación uniforme sin efectos espaciales ni avanzados",
|
||||
"render.library_usable": "Proyecciones ejecutables",
|
||||
"render.linear_help": "Conserva un máster RGBA de 32 bits en coma flotante antes de la reducción de ruido, exposición, mapeo tonal, filtros y fondo. sRGB lineal/D65, premultiplicado por cobertura. Requiere memoria adicional. Sin compresión ni pases extra.",
|
||||
"render.linear_retain": "Conservar EXR lineal sin procesar",
|
||||
"render.linear_unavailable": "La imagen terminada seleccionada no conserva EXR. Activa la opción antes de renderizar; no se puede recuperar la radiancia original de un PNG.",
|
||||
"render.look_add": "Añadir filtro de color",
|
||||
"render.look_bleach": "Inspirado en bleach bypass",
|
||||
"render.look_cool": "Frío",
|
||||
"render.look_cyanotype": "Inspirado en cianotipia",
|
||||
"render.look_faded": "Copia desvanecida",
|
||||
"render.look_mono": "Monocromo",
|
||||
"render.look_sepia": "Sepia",
|
||||
"render.look_strength": "Intensidad del filtro",
|
||||
"render.look_teal_orange": "Verde azulado / naranja",
|
||||
"render.look_title": "Pila de filtros creativos",
|
||||
"render.look_warm": "Cálido",
|
||||
"render.mapping_scale": "Multiplicador de repetición física",
|
||||
"render.material_absorption": "Absorción R · G · B (por mm)",
|
||||
"render.material_add": "Añadir o editar este cuerpo",
|
||||
"render.material_assignments": "Asignaciones por cuerpo",
|
||||
"render.material_binding_enable": "Incluir los ajustes de este cuerpo",
|
||||
"render.material_box": "Caja alineada con los ejes",
|
||||
"render.material_browse": "Elegir imagen…",
|
||||
"render.material_certification": "El vidrio cerrado usa la distancia geométrica. La preparación GPU valida topología, orientación, solapamientos y límites ópticos; Comprobar solo admite la petición.",
|
||||
"render.material_choose_body": "Elegir un cuerpo de la escena",
|
||||
"render.material_closed": "Malla sólida cerrada",
|
||||
"render.material_coat": "Recubrimiento sobre el material base",
|
||||
"render.material_coat_enable": "Activar recubrimiento",
|
||||
"render.material_coat_help": "Recubrimiento dieléctrico ilustrativo sobre la apariencia opaca existente. Un peso cero conserva la base.",
|
||||
"render.material_color_map": "Imagen de color base (sRGB)",
|
||||
"render.material_color_replace": "El mapa base sustituye el color del cuerpo",
|
||||
"render.material_custom": "Óptica ilustrativa personalizada",
|
||||
"render.material_enable": "Usar estos ajustes de materiales GPU",
|
||||
"render.material_filter": "Filtrar cuerpos de la escena…",
|
||||
"render.material_filter_help": "Se muestran hasta 128 coincidencias. Ajusta el filtro para escenas grandes.",
|
||||
"render.material_glass": "Vidrio y absorción óptica",
|
||||
"render.material_glass_enable": "Usar vidrio físico en este cuerpo",
|
||||
"render.material_glass_exclusive": "Este motor no admite vidrio con recubrimiento ni mapas en el mismo cuerpo.",
|
||||
"render.material_glass_help": "Recetas originales e ilustrativas. Las muestras indican transmitancia, no un render. La absorción es −ln(transmitancia lineal) / distancia de referencia; no se cambia el alfa.",
|
||||
"render.material_gpu_required": "Estos materiales activos requieren trazado GPU. Selecciona GPU o desactiva los ajustes antes de Comprobar o Iniciar.",
|
||||
"render.material_ior": "Índice de refracción (IOR)",
|
||||
"render.material_limits": "Máximo de 128 modificaciones de cuerpos, 32 vidrios separados, 64 recubrimientos y 128 asociaciones de texturas. Los mapas idénticos comparten memoria; se mantienen los límites reales del dispositivo y de memoria total.",
|
||||
"render.material_map_invalid": "Las rutas de mapas deben ser locales y acotadas; la intensidad de normales debe ser finita y estar entre 0 y 1.",
|
||||
"render.material_map_required": "Elige una imagen de color o de normales antes de usar mapas.",
|
||||
"render.material_maps": "Mapas planos de color y normales",
|
||||
"render.material_maps_enable": "Activar mapas para este cuerpo opaco",
|
||||
"render.material_maps_help": "PNG/JPEG hasta 1024×1024; máximo total de 16 MiB codificados. U y V son vectores ortogonales de repetición en mm globales (máximo 128 repeticiones). Color sRGB y normales OpenGL +Y. Los archivos se capturan al Comprobar/Iniciar.",
|
||||
"render.material_metallic_map": "Mapa de metalicidad (lineal)",
|
||||
"render.material_normal_map": "Imagen de normales (OpenGL, +Y)",
|
||||
"render.material_normal_strength": "Intensidad de normales (0–1)",
|
||||
"render.material_origin": "Origen del mapa X · Y · Z (mm)",
|
||||
"render.material_refresh": "Actualizar cuerpos de la escena",
|
||||
"render.material_refresh_needed": "La escena ha cambiado. Actualiza la lista antes de añadir un cuerpo.",
|
||||
"render.material_remove": "Eliminar esta asignación",
|
||||
"render.material_repeat_u": "Una repetición U X · Y · Z (mm)",
|
||||
"render.material_repeat_v": "Una repetición V X · Y · Z (mm)",
|
||||
"render.material_revalidate": "Revalidar este cuerpo",
|
||||
"render.material_revalidate_needed": "Esta asignación pertenece a una revisión anterior. Revalida la identidad exacta del cuerpo antes de renderizar.",
|
||||
"render.material_roughness": "Rugosidad del recubrimiento (0,045–1)",
|
||||
"render.material_roughness_map": "Mapa de rugosidad (lineal)",
|
||||
"render.material_shadow": "Transmitir rayos de sombra rectos",
|
||||
"render.material_target_missing": "El ordinal y el nombre del cuerpo ya no coinciden. Elimina esta asignación y elige de nuevo el cuerpo deseado.",
|
||||
"render.material_thickness": "Espesor de la lámina (mm)",
|
||||
"render.material_thin": "Lámina delgada",
|
||||
"render.material_title": "Materiales de la imagen GPU",
|
||||
"render.material_transient": "Ajustes ópticos temporales de esta pestaña. No se guardan en el diseño, la configuración de render ni la biblioteca de materiales.",
|
||||
"render.material_v_up": "La coordenada V apunta hacia arriba en la imagen",
|
||||
"render.material_weight": "Peso del recubrimiento (0–1)",
|
||||
"render.method_cpu": "Trazado CPU",
|
||||
"render.method_gpu": "Trazado GPU",
|
||||
"render.method_limit_raster": "Raster utiliza la vista opaca de estudio fija. Selecciona un método de trazado de rayos para los controles ópticos compatibles.",
|
||||
"render.method_raster": "Raster CPU",
|
||||
"render.navigation_help": "La cámara se mueve como en Diseño (Preferencias › Navegación). Guardar configuración registra la cámara actual.",
|
||||
"render.nested_enable": "Dieléctricos anidados certificados",
|
||||
"render.nested_help": "Hasta 16 capas contenidas: cada padre debe ser convexo y cada hijo estar estrictamente dentro. Se rechazan intersecciones, contactos, láminas finas y sombras transmitidas en línea recta. La cámara interior usa la jerarquía certificada. No crea la superficie del líquido ni fusiona fronteras CAD en contacto.",
|
||||
"render.opaque_image_summary": "PNG de vista previa · PBR opaco · transparencia combinada",
|
||||
"render.opaque_preview_help": "PBR opaco y colores sencillos; transparencia combinada. La refracción, HDRI y el renderizado final aún no están disponibles.",
|
||||
"render.optics_remove": "Quitar óptica guardada",
|
||||
"render.optics_replace": "Sustituir explícitamente la óptica guardada del objetivo",
|
||||
"render.optics_save": "Guardar esta óptica en la toma",
|
||||
"render.optics_saved": "Objetivos ópticos guardados",
|
||||
"render.optics_saved_help": "La identidad exacta de definición, operación e instancia se conserva al reabrir sin conexión. Los objetivos ausentes, sustituidos u ocultos se rechazan; los materiales de ingeniería no cambian. Guarda o descarta los cambios numéricos antes de quitar un objetivo.",
|
||||
"render.output_format_status": "PNG es la imagen final exacta. El EXR opcional de GPU conserva radiancia lineal FLOAT32 antes de los filtros. La exportación no sustituye el resultado por la previsualización ni por otro trabajo.",
|
||||
"render.output_lock_ratio": "Bloquear proporción",
|
||||
"render.output_over_budget": "La imagen supera el presupuesto seleccionado. Elige explícitamente otro tamaño o perfil; no se reduce automáticamente.",
|
||||
"render.output_ratio_refused": "La dimensión vinculada supera el límite del método. Se conserva el tamaño anterior; desbloquea la proporción o elige un valor menor.",
|
||||
"render.output_swap_orientation": "Intercambiar ancho y alto",
|
||||
"render.page_aging": "Envejecimiento y depósitos",
|
||||
"render.page_all": "Todos los controles",
|
||||
"render.page_appearance": "Aspecto",
|
||||
"render.page_background": "Fondos",
|
||||
"render.page_camera": "Cámara",
|
||||
"render.page_diagnostics": "Diagnóstico",
|
||||
"render.page_effects": "Lente y acabados",
|
||||
"render.page_environment": "Entorno",
|
||||
"render.page_lighting": "Iluminación",
|
||||
"render.page_output": "Salida",
|
||||
"render.page_scene": "Escena",
|
||||
"render.passive_stage": "Suelo y escenario pasivo",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "Cámara en perspectiva",
|
||||
"render.physical_acknowledge": "I understand this partial reference needs grade, condition and source review",
|
||||
"render.physical_associations": "Physical candidates and roles",
|
||||
"render.physical_background_help": "Suelo y pared físicos pasivos, distintos del fondo de cámara. El ciclorama usa 24 franjas poligonales; no es infinito ni una superficie analíticamente suave. Solo sustituye el escenario con tu confirmación.",
|
||||
"render.physical_copy_plan": "Copy plan with sources and omissions",
|
||||
"render.physical_cyclorama": "Ajustar ciclorama poligonal",
|
||||
"render.physical_floor_wall": "Ajustar suelo y pared físicos",
|
||||
"render.physical_material_name": "Proposed reference material name",
|
||||
"render.physical_omissions": "Properties not representable in the native card",
|
||||
"render.physical_plan_only": "Read-only plan prepared. No material was created or assigned. Keep its extended profile and omissions when reviewing the native card.",
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.post_contrast": "Contraste",
|
||||
"render.post_gain_b": "Ganancia azul",
|
||||
"render.post_gain_g": "Ganancia verde",
|
||||
"render.post_gain_r": "Ganancia roja",
|
||||
"render.post_help": "Solo presentación creativa. Las ganancias RGB preceden al mapeo tonal; contraste, saturación y viñeta se aplican después en luz lineal de pantalla. Renderizar crea muestras nuevas. Reeditar utiliza el máster bruto retenido sin reducir ruido ni lanzar rayos nuevos.",
|
||||
"render.post_reset": "Restablecer filtros",
|
||||
"render.post_saturation": "Saturación",
|
||||
"render.post_title": "Filtros de presentación",
|
||||
"render.post_vignette": "Viñeta",
|
||||
"render.preview": "Vista previa integrada",
|
||||
"render.preview_help": "Sombreado por rasterización y transparencia combinada. La refracción, HDRI y el renderizado final aún no están disponibles.",
|
||||
"render.preview_image_settings_help": "La vista previa mantiene una iluminación de estudio fija. La exposición y la iluminación de imagen se aplican al trabajo al Comprobar o Iniciar.",
|
||||
"render.preview_retry": "Reintentar vista previa",
|
||||
"render.preview_unavailable_help": "La vista previa no está disponible. Los ajustes guardados y los controles de imagen siguen accesibles. Cambia la escena o reintenta expresamente; una escena rechazada no se reconstruye en cada fotograma.",
|
||||
"render.preview_upload": "Datos de vértices de la vista previa",
|
||||
"render.preview_upload_help": "Bytes exactos de los vértices de vista previa, no memoria total de GPU o proceso. No se simplifica la geometría. Los trabajos de imagen tienen admisión e iluminación propias.",
|
||||
"render.progressive_image_summary": "Vista previa PNG · PBR opaco · muestreo progresivo",
|
||||
"render.quality_ack": "Aceptar la proyección de presupuesto fijo y sus omisiones",
|
||||
"render.quality_apply": "Usar este presupuesto fijo",
|
||||
"render.quality_projection_help": "Los perfiles Q incluyen requisitos futuros. Esta acción proyecta solo un presupuesto PNG de muestras fijas y omite parada adaptativa, salida lineal y límites de transmisión independientes.",
|
||||
"render.quality_review": "Revisar presupuesto de muestras",
|
||||
"render.queue_pending": "Esta interfaz no contiene cola automática de producción ni renderizador de animaciones. Las imágenes terminadas se exportan por separado.",
|
||||
"render.radial_distortion": "Distorsión radial",
|
||||
"render.regrade_action": "Reeditar máster bruto (sin reducción de ruido)",
|
||||
"render.regrade_help": "Crea un PNG independiente a partir del máster bruto del resultado seleccionado y estos controles de presentación. No traza rayos, cambia tamaño, cámara o luces capturados, ni sobrescribe el EXR. No vuelve a reducir el ruido: el máster no conserva las guías del filtro. El resultado se exporta mediante los controles habituales.",
|
||||
"render.reload_settings": "Recargar ajustes guardados",
|
||||
"render.replace_ground": "Confirmar sustitución del escenario existente",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "Restaurar cámara guardada",
|
||||
"render.result_actual_help": "Un píxel de la imagen por cada píxel de la pantalla.",
|
||||
"render.result_capture": "Revisión capturada",
|
||||
"render.result_current": "La revisión capturada del modelo está actualizada.",
|
||||
"render.result_empty": "Todavía no hay ninguna imagen terminada. Comprueba los ajustes e inicia un renderizado.",
|
||||
"render.result_fit": "Ajustar imagen",
|
||||
"render.result_job": "Trabajo",
|
||||
"render.result_navigation": "El desplazamiento y el zoom siguen las preferencias de Navegación. Espacio + arrastrar desplaza la imagen.",
|
||||
"render.result_open": "Abrir la imagen terminada en el lienzo principal.",
|
||||
"render.result_preview": "Vista previa en vivo",
|
||||
"render.result_provisional": "Imagen CPU provisional",
|
||||
"render.result_provisional_help": "Este avance no se puede exportar. Exportar conserva el último resultado terminado; al cancelar se vuelve a ese resultado.",
|
||||
"render.result_reduced_display": "Vista reducida al límite del dispositivo o de la caché. El PNG conservado y la exportación mantienen la resolución completa; esta vista reducida no permite inspección nativa al 100%.",
|
||||
"render.result_retained": "Se muestra la última imagen terminada; el nuevo renderizado todavía no la ha sustituido.",
|
||||
"render.result_sequence": "Avance",
|
||||
"render.result_title": "Resultado del renderizado",
|
||||
"render.return_design": "Volver a Diseño",
|
||||
"render.review_stale": "Esta revisión ha caducado. Resuelve o comprueba de nuevo antes de aplicar.",
|
||||
"render.ribbon_aging": "Envejecimiento",
|
||||
"render.ribbon_backgrounds": "Fondos",
|
||||
"render.ribbon_check": "Comprobar",
|
||||
"render.ribbon_check_help": "Valida exactamente el borrador que enviará Render. Sin cambiar de motor, reducir resolución ni sustituir recursos silenciosamente.",
|
||||
"render.ribbon_edit_lights": "Editar luces",
|
||||
"render.ribbon_effects": "Efectos",
|
||||
"render.ribbon_environment_help": "La iluminación HDR, el fondo exclusivo de cámara y las superficies físicas son controles independientes, con confirmación para sustituirlos.",
|
||||
"render.ribbon_finish_dialog": "Finaliza antes el diálogo de archivo o confirmación.",
|
||||
"render.ribbon_frame": "Encuadrar",
|
||||
"render.ribbon_hdr_library": "Biblioteca HDR",
|
||||
"render.ribbon_job_active": "Ya hay un render en curso; cancélalo explícitamente antes de iniciar otro.",
|
||||
"render.ribbon_light_rigs": "Iluminación",
|
||||
"render.ribbon_lights_help": "Revisa conjuntos originales o edita luces compatibles; la configuración actual no se sustituye hasta aplicar el cambio.",
|
||||
"render.ribbon_materials": "Materiales",
|
||||
"render.ribbon_materials_help": "Abre el inspector compartido de apariencia y la biblioteca de superficies originales. Los cambios ópticos no alteran propiedades de ingeniería sin avisar.",
|
||||
"render.ribbon_no_active_job": "No hay ningún render activo que cancelar.",
|
||||
"render.ribbon_no_result": "Completa un render antes de exportar su imagen.",
|
||||
"render.ribbon_no_saved_camera": "Guarda una toma antes de recuperar su cámara.",
|
||||
"render.ribbon_saved_camera": "Cámara guardada",
|
||||
"render.ribbon_shots": "Tomas",
|
||||
"render.ribbon_studios": "Estudios",
|
||||
"render.ribbon_studios_help": "Explora composiciones de estudio implementadas y revisa lo que sustituyen antes de aplicarlas. Las escenas conceptuales siguen identificadas.",
|
||||
"render.ribbon_surface_maps": "Mapas",
|
||||
"render.sampling_title": "Muestreo adaptativo y transmisión",
|
||||
"render.save_continue": "Guardar y continuar",
|
||||
"render.save_setup": "Guardar configuración",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.scene_apply": "Aplicar estudio revisado",
|
||||
"render.scene_consent": "Confirmar sustitución de iluminación, entorno, exposición y escenario",
|
||||
"render.scene_preserved_fields": "Se conservan cámara, muestreo, dimensiones, asignaciones ópticas, geometría CAD y materiales físicos.",
|
||||
"render.scene_preserves_design": "Compón iluminación y escenario pasivo para el objeto visible. Geometría, materiales físicos y cámara se mantienen separados.",
|
||||
"render.scene_replaces": "Sustituye",
|
||||
"render.scene_review": "Resolver y revisar",
|
||||
"render.scene_review_help": "Revisa la composición nativa completa antes de aplicar. No se sustituyen las especificaciones SCENE avanzadas sin resolver.",
|
||||
"render.scene_scope_details": "Alcance de la composición",
|
||||
"render.setup_legacy_environment": "Esta configuración antigua usa rotación o intensidad de entorno heredadas. Se conservan esos valores; conviértelos explícitamente antes de guardar un trabajo de imagen completo.",
|
||||
"render.setup_name": "Nombre de configuración",
|
||||
"render.setup_numeric_help": "Guardar conserva el método de imagen activo y todos sus ajustes numéricos. Recargar o elegir otra configuración sustituye este borrador; la cámara se restaura por separado.",
|
||||
"render.setup_offline_help": "Puedes editar y guardar este método sin tener su motor disponible. Comprobar e Iniciar requieren un motor disponible.",
|
||||
"render.setup_runtime_unsupported": "Todavía no se puede guardar este trabajo completo: contiene mapas o asignaciones a cuerpos de la escena. Elimina esas entradas temporales antes de guardar una configuración portable.",
|
||||
"render.setup_save_missing": "No se ha encontrado la configuración guardada después de completar el comando.",
|
||||
"render.sharpening": "Realce de detalle",
|
||||
"render.shot_duplicate": "Duplicar toma guardada",
|
||||
"render.shot_manager": "Tomas guardadas",
|
||||
"render.shot_new_name": "Nombre de la nueva toma",
|
||||
"render.shot_remove": "Eliminar toma guardada",
|
||||
"render.shot_remove_help": "Elimina solo estos ajustes guardados. La geometría y las imágenes terminadas se conservan; se puede deshacer.",
|
||||
"render.shot_remove_title": "¿Eliminar toma guardada?",
|
||||
"render.shot_rename": "Renombrar toma guardada",
|
||||
"render.shot_saved_only": "Guarda primero el borrador. Duplicar y renombrar conservan los ajustes y las referencias de recursos.",
|
||||
"render.sky_ground": "Suelo · RGB lineal",
|
||||
"render.sky_horizon": "Horizonte · RGB lineal",
|
||||
"render.sky_zenith": "Cénit · RGB lineal",
|
||||
"render.soft_focus": "Enfoque suave",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.studio_add_area": "Añadir luz de área",
|
||||
"render.studio_ambient": "Radiancia constante del entorno",
|
||||
"render.studio_ambient_rgb": "Radiancia constante del entorno (RGB lineal)",
|
||||
"render.studio_aperture": "Radio de apertura",
|
||||
"render.studio_area": "Luz de área",
|
||||
"render.studio_area_help": "Hasta cuatro rectángulos de una cara. Los semiejes perpendiculares U y V definen el tamaño; U × V apunta hacia la cara emisora. Coordenadas en milímetros del mundo.",
|
||||
"render.studio_center": "Centro X, Y, Z (mm)",
|
||||
"render.studio_denoise": "Reducir ruido en la imagen terminada",
|
||||
"render.studio_denoise_help": "Filtro final que respeta los bordes; puede suavizar detalles. El vidrio y los reflejos especulares nítidos no se filtran.",
|
||||
"render.studio_direction": "Dirección hacia el sol (X, Y, Z)",
|
||||
"render.studio_environment": "Entorno",
|
||||
"render.studio_environment_bounds": "La rotación del entorno debe ser finita dentro de ±1 000 000 radianes y la intensidad debe estar entre 0 y 100.",
|
||||
"render.studio_environment_none": "Sin mapa de entorno",
|
||||
"render.studio_focus": "Distancia de enfoque en el eje",
|
||||
"render.studio_half_u": "Semieje U (mm)",
|
||||
"render.studio_half_v": "Semieje V (mm)",
|
||||
"render.studio_hdr": "Archivo Radiance HDR",
|
||||
"render.studio_hdr_browse": "Elegir HDR…",
|
||||
"render.studio_hdr_help": "Radiance .hdr, panorama 2:1, hasta 2048 × 1024. EXR no está disponible. La suposición de color sólo se aplica cuando no se especifican primarias.",
|
||||
"render.studio_hdr_required": "Elige un archivo .hdr local.",
|
||||
"render.studio_hdr_srgb": "Interpretar primarias sin especificar como sRGB lineal",
|
||||
"render.studio_intensity": "Intensidad del entorno",
|
||||
"render.studio_lens": "Profundidad de campo",
|
||||
"render.studio_lens_perspective": "La profundidad de campo requiere una cámara en perspectiva.",
|
||||
"render.studio_lighting": "Iluminación de estudio",
|
||||
"render.studio_lighting_enable": "Usar iluminación de estudio personalizada",
|
||||
"render.studio_needs_review": "Revisar método y ajustes",
|
||||
"render.studio_radiance": "Radiancia RGB lineal",
|
||||
"render.studio_ready": "Preparado para comprobar",
|
||||
"render.studio_remove_area": "Eliminar luz de área",
|
||||
"render.studio_rotation": "Rotación del entorno",
|
||||
"render.studio_runtime_help": "Los ajustes numéricos del estudio y los HDR comprobados se pueden guardar con la configuración. Las asignaciones ópticas o de materiales por cuerpo siguen siendo temporales y no cambian las apariencias guardadas.",
|
||||
"render.studio_saved": "Ajustes guardados / cámara actual",
|
||||
"render.studio_sky": "Cielo artístico",
|
||||
"render.studio_sky_help": "Gradiente de cielo para iluminar la escena; no es un modelo atmosférico calibrado.",
|
||||
"render.studio_sun": "Sol",
|
||||
"render.studio_sun_radius": "Radio angular",
|
||||
"render.studio_title": "Estudio de renderizado",
|
||||
"render.studio_tone_map": "Mapeo de tonos",
|
||||
"render.subsurface_enable": "Recorrido aleatorio de dispersión interna",
|
||||
"render.subsurface_help": "Solo dieléctricos cerrados. Dispersión y absorción RGB son coeficientes separados por mm. Las trayectorias se dispersan dentro de la geometría y se refractan o reflejan en la frontera. Desactiva sombras rectas, reducción de ruido de superficies y volumen exterior; usa un estrato Fresnel. No es un filtro de difusión, rejilla de densidad ni material medido. Los medios densos pueden requerir más muestras y profundidad.",
|
||||
"render.subsurface_rate": "Tasa de colisiones de dispersión",
|
||||
"render.transmission_scope": "El vidrio GPU admite medios separados certificados. No se admiten medios anidados sin restricciones ni un estimador de transmisión sin ruido.",
|
||||
"render.transmission_strata": "Estratos de Fresnel condicionales",
|
||||
"render.transmission_strata_help": "1 conserva la secuencia original. 2 o 4 subtrayectorias estratifican la primera decisión de reflexión o transmisión del vidrio, sin cambiar Snell ni la absorción. Aumentan el trabajo; no son un filtro, soporte de medios anidados ni una garantía de mayor velocidad.",
|
||||
"render.unavailable_preview": "Esta configuración solicita un perfil de vista previa no disponible.",
|
||||
"render.unsaved": "Cambios de vista previa sin guardar",
|
||||
"render.use_preview": "Usar vista previa integrada",
|
||||
"render.volume_albedo": "Albedo de dispersión · RGB lineal",
|
||||
"render.volume_anisotropy": "Coseno medio de fase",
|
||||
"render.volume_enable": "Activar medio participante",
|
||||
"render.volume_extinction": "Coeficiente de extinción",
|
||||
"render.volume_help": "Transporte GPU dentro de una caja finita, con atenuación de Beer y dispersión HG en trayectorias de cámara e indirectas. Utiliza luces explícitas de estudio, HDR o cielo, con atenuación de sombras. El coseno positivo dispersa hacia delante. Deben desactivarse explícitamente el vidrio y la reducción de ruido de superficies. Extinción cero conserva el transporte. No es atmósfera lunar, rejilla de densidad, emisión volumétrica, transporte espectral ni propiedad certificada.",
|
||||
"render.volume_max": "Límites máximos · mm globales",
|
||||
"render.volume_min": "Límites mínimos · mm globales",
|
||||
"render.volume_title": "Volumen homogéneo acotado",
|
||||
"sample.bracket.about": "Brida base con pestañas laterales y reborde, según una regla de 2 mm",
|
||||
"sample.bracket.name": "Soporte de chapa",
|
||||
"sample.enclosure.about": "Caja vaciada con labio, salientes para tornillos, apoyo y encaje a presión",
|
||||
@@ -1128,6 +1768,10 @@
|
||||
"toolbar.customize_note": "Pestaña {tab}. Marque un comando para añadir su botón a la barra de herramientas. También puede arrastrar una fila del desplegable de un panel a la barra, arrastrar un botón fuera de la barra para quitarlo o usar la chincheta de una fila del desplegable.",
|
||||
"toolbar.image": "IMAGEN",
|
||||
"toolbar.render": "RENDERIZAR",
|
||||
"toolbar.render_appearance": "APARIENCIA",
|
||||
"toolbar.render_camera": "CÁMARA",
|
||||
"toolbar.render_environment": "ENTORNO",
|
||||
"toolbar.render_lighting": "ILUMINACIÓN",
|
||||
"toolbar.render_scene": "ESCENA",
|
||||
"trace.points": "{count} puntos a lo largo de la trayectoria",
|
||||
"trace.stopped_by_contact": "Termina en la muestra {sample}: {a} atravesaría {b}",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Choisir…",
|
||||
"Circular": "Circulaire",
|
||||
"Circumference": "Circonférence",
|
||||
"Clockwise": "Horaire",
|
||||
"Close draft": "Fermer le brouillon",
|
||||
"Collisions": "Collisions",
|
||||
"Colour": "Couleur",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Rechercher des commandes",
|
||||
"Search this library": "Rechercher dans cette bibliothèque",
|
||||
"Section": "Coupe",
|
||||
"Section position": "Position de la section",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Sélectionner un autre élément : maintenir le bouton gauche immobile sur le modèle (ou clic droit › Sélectionner un autre…) pour lister tout ce qui se trouve sous le curseur ; cliquer de nouveau au même endroit pour sélectionner l'élément suivant. Double-cliquer avec le bouton du milieu pour revenir à l'accueil (Préférences › Navigation).",
|
||||
"Select bodies (a face picks its body)": "Sélectionner des corps (une face sélectionne son corps)",
|
||||
"Select bodies or faces instead": "Sélectionner plutôt des corps ou des faces",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft s'est fermé avant l'enregistrement de ces conceptions. Leur dernier enregistrement automatique peut être ouvert.",
|
||||
"Specialise": "Spécialiser",
|
||||
"Speed": "Vitesse",
|
||||
"Square": "Carré",
|
||||
"Stand it up": "Redresser",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Redresser : un quart de tour autour de X, sous forme d'une fonction Déplacer que vous pouvez annuler.",
|
||||
"Stand this part up?": "Redresser cette pièce ?",
|
||||
"Start angle": "Angle de départ",
|
||||
"Start bulge": "Renflement de début",
|
||||
"Start continuity": "Continuité de début",
|
||||
"Step": "Étape",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "angle, hauteur",
|
||||
"appearance.dielectric_ior": "Indice de réfraction (diélectrique)",
|
||||
"appearance.metallic": "Métallique",
|
||||
"appearance.only_available": "Apparences disponibles uniquement",
|
||||
"appearance.pbr_help": "Voir cette surface dans l'espace Rendu ou dans un PNG du produit. Sans réfraction ni transmission.",
|
||||
"appearance.pbr_opaque": "PBR opaque",
|
||||
"appearance.roughness": "Rugosité",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Nouveau matériau physique",
|
||||
"cmd.material_delete": "Supprimer le matériau physique",
|
||||
"cmd.material_edit": "Modifier le matériau physique",
|
||||
"cmd.material_inspect": "Inspecter le matériau physique",
|
||||
"cmd.material_list": "Lister les matériaux",
|
||||
"cmd.material_properties_directional": "Module d'élasticité directionnel",
|
||||
"cmd.material_properties_validate": "Valider les données du matériau physique",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Escoller…",
|
||||
"Circular": "Circular",
|
||||
"Circumference": "Circunferencia",
|
||||
"Clockwise": "Horario",
|
||||
"Close draft": "Pechar o borrador",
|
||||
"Collisions": "Colisións",
|
||||
"Colour": "Cor",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Buscar ordes",
|
||||
"Search this library": "Buscar nesta biblioteca",
|
||||
"Section": "Sección",
|
||||
"Section position": "Posición da sección",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Seleccionar outro: mantén o botón esquerdo quieto sobre o modelo (ou clic dereito › Seleccionar outro…) para listar todo o que hai baixo o cursor; fai clic de novo no mesmo punto para seleccionar o seguinte. Fai dobre clic co botón central para ir ao Inicio (Preferencias › Navegación).",
|
||||
"Select bodies (a face picks its body)": "Selecciona corpos (unha cara escolle o seu corpo)",
|
||||
"Select bodies or faces instead": "Seleccionar corpos ou caras no seu lugar",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft pechouse antes de gardar estes deseños. Pódese abrir a súa última gravación automática.",
|
||||
"Specialise": "Especializar",
|
||||
"Speed": "Velocidade",
|
||||
"Square": "Cadrado",
|
||||
"Stand it up": "Poñela de pé",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Poñela de pé: un cuarto de volta arredor de X, como unha operación Mover que podes desfacer.",
|
||||
"Stand this part up?": "Poñer esta peza de pé?",
|
||||
"Start angle": "Ángulo inicial",
|
||||
"Start bulge": "Abaulamento inicial",
|
||||
"Start continuity": "Continuidade inicial",
|
||||
"Step": "Paso",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "ángulo, altura",
|
||||
"appearance.dielectric_ior": "IOR dieléctrico",
|
||||
"appearance.metallic": "Metálico",
|
||||
"appearance.only_available": "Só aparencias dispoñibles",
|
||||
"appearance.pbr_help": "Ve esta superficie en Render ou nun PNG de produto. Sen refracción nin transmisión.",
|
||||
"appearance.pbr_opaque": "PBR opaco",
|
||||
"appearance.roughness": "Rugosidade",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Material físico novo",
|
||||
"cmd.material_delete": "Eliminar o material físico",
|
||||
"cmd.material_edit": "Editar o material físico",
|
||||
"cmd.material_inspect": "Inspeccionar o material físico",
|
||||
"cmd.material_list": "Listar os materiais",
|
||||
"cmd.material_properties_directional": "Módulo elástico direccional",
|
||||
"cmd.material_properties_validate": "Validar os datos do material físico",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Válasszon…",
|
||||
"Circular": "Kör alakú",
|
||||
"Circumference": "Kerület",
|
||||
"Clockwise": "Óramutató járásával megegyező",
|
||||
"Close draft": "Vázlat bezárása",
|
||||
"Collisions": "Ütközések",
|
||||
"Colour": "Szín",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Parancsok keresése",
|
||||
"Search this library": "Keresés ebben a könyvtárban",
|
||||
"Section": "Metszet",
|
||||
"Section position": "Szelvény helyzete",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Más kijelölése: tartsa nyomva a bal gombot egy helyen a modellen (vagy jobb kattintás › Más kijelölése…) a kurzor alatti elemek listázásához; kattintson újra ugyanarra a helyre a következő elem kijelöléséhez. A középső gomb dupla kattintása a kezdőnézetre vált (Beállítások › Navigáció).",
|
||||
"Select bodies (a face picks its body)": "Testek kijelölése (egy lap a testét jelöli ki)",
|
||||
"Select bodies or faces instead": "Inkább testek vagy lapok kijelölése",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "A SolidCraft bezárult, mielőtt ezek a tervek mentve lettek volna. Az utolsó automatikus mentésük megnyitható.",
|
||||
"Specialise": "Specializálás",
|
||||
"Speed": "Sebesség",
|
||||
"Square": "Négyzet",
|
||||
"Stand it up": "Felállítás",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Felállítás: negyedfordulat az X körül, egyetlen visszavonható Mozgatás elemként.",
|
||||
"Stand this part up?": "Felállítja ezt az alkatrészt?",
|
||||
"Start angle": "Kezdőszög",
|
||||
"Start bulge": "Kezdő ívelés",
|
||||
"Start continuity": "Kezdő folytonosság",
|
||||
"Step": "Lépés",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "szög, magasság",
|
||||
"appearance.dielectric_ior": "Dielektromos törésmutató",
|
||||
"appearance.metallic": "Fémes",
|
||||
"appearance.only_available": "Csak elérhető megjelenések",
|
||||
"appearance.pbr_help": "Tekintse meg ezt a felületet Renderelésben vagy termék-PNG-ben. Nincs fénytörés vagy áteresztés.",
|
||||
"appearance.pbr_opaque": "Átlátszatlan PBR",
|
||||
"appearance.roughness": "Érdesség",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Új fizikai anyag",
|
||||
"cmd.material_delete": "Fizikai anyag törlése",
|
||||
"cmd.material_edit": "Fizikai anyag szerkesztése",
|
||||
"cmd.material_inspect": "Fizikai anyag vizsgálata",
|
||||
"cmd.material_list": "Anyagok listázása",
|
||||
"cmd.material_properties_directional": "Irányfüggő rugalmassági modulus",
|
||||
"cmd.material_properties_validate": "Fizikai anyagadatok ellenőrzése",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Pilih…",
|
||||
"Circular": "Melingkar",
|
||||
"Circumference": "Keliling",
|
||||
"Clockwise": "Searah jarum jam",
|
||||
"Close draft": "Tutup draf",
|
||||
"Collisions": "Tabrakan",
|
||||
"Colour": "Warna",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Cari perintah",
|
||||
"Search this library": "Cari di pustaka ini",
|
||||
"Section": "Penampang",
|
||||
"Section position": "Posisi penampang",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Select Other: tahan tombol kiri diam di model (atau klik kanan › Select Other…) untuk mendaftar semua yang ada di bawah kursor; klik lagi di titik yang sama untuk memilih benda berikutnya. Klik dua kali tombol tengah untuk ke Home (Preferensi › Navigasi).",
|
||||
"Select bodies (a face picks its body)": "Pilih bodi (memilih muka berarti memilih bodinya)",
|
||||
"Select bodies or faces instead": "Pilih bodi atau muka saja",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft tertutup sebelum desain ini disimpan. Simpan otomatis terakhirnya dapat dibuka.",
|
||||
"Specialise": "Spesialisasikan",
|
||||
"Speed": "Kecepatan",
|
||||
"Square": "Persegi",
|
||||
"Stand it up": "Tegakkan",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Tegakkan: putaran seperempat terhadap X, sebagai satu fitur Move yang dapat dibatalkan.",
|
||||
"Stand this part up?": "Tegakkan part ini?",
|
||||
"Start angle": "Sudut awal",
|
||||
"Start bulge": "Bulge awal",
|
||||
"Start continuity": "Kontinuitas awal",
|
||||
"Step": "Langkah",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "sudut, tinggi",
|
||||
"appearance.dielectric_ior": "IOR Dielektrik",
|
||||
"appearance.metallic": "Metalik",
|
||||
"appearance.only_available": "Hanya tampilan yang tersedia",
|
||||
"appearance.pbr_help": "Lihat permukaan ini di Render atau PNG produk. Tanpa refraksi atau transmisi.",
|
||||
"appearance.pbr_opaque": "PBR Opak",
|
||||
"appearance.roughness": "Kekasaran",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Material Fisik Baru",
|
||||
"cmd.material_delete": "Hapus Material Fisik",
|
||||
"cmd.material_edit": "Edit Material Fisik",
|
||||
"cmd.material_inspect": "Periksa Material Fisik",
|
||||
"cmd.material_list": "Daftar Material",
|
||||
"cmd.material_properties_directional": "Modulus Elastis Arah",
|
||||
"cmd.material_properties_validate": "Validasi Data Material Fisik",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Scegli…",
|
||||
"Circular": "Circolare",
|
||||
"Circumference": "Circonferenza",
|
||||
"Clockwise": "Orario",
|
||||
"Close draft": "Chiudi bozza",
|
||||
"Collisions": "Collisioni",
|
||||
"Colour": "Colore",
|
||||
@@ -325,6 +326,7 @@
|
||||
"Search commands": "Cerca comandi",
|
||||
"Search this library": "Cerca in questa libreria",
|
||||
"Section": "Sezione",
|
||||
"Section position": "Posizione della sezione",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Seleziona altro: tieni premuto il pulsante sinistro senza muovere il puntatore sul modello (o fai clic destro › Seleziona altro…) per elencare gli oggetti sotto il cursore; fai di nuovo clic nello stesso punto per selezionare l'oggetto successivo. Fai doppio clic con il pulsante centrale per tornare alla vista iniziale (Preferenze › Navigazione).",
|
||||
"Select bodies (a face picks its body)": "Seleziona corpi (una faccia seleziona il corpo a cui appartiene)",
|
||||
"Select bodies or faces instead": "Seleziona invece corpi o facce",
|
||||
@@ -348,9 +350,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft si è chiuso prima del salvataggio di questi progetti. È possibile aprire il loro ultimo salvataggio automatico.",
|
||||
"Specialise": "Specializza",
|
||||
"Speed": "Velocità",
|
||||
"Square": "Quadrato",
|
||||
"Stand it up": "Raddrizza",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Raddrizza: un quarto di giro attorno a X, come singola lavorazione Sposta annullabile.",
|
||||
"Stand this part up?": "Raddrizzare questa parte?",
|
||||
"Start angle": "Angolo iniziale",
|
||||
"Start bulge": "Rigonfiamento iniziale",
|
||||
"Start continuity": "Continuità iniziale",
|
||||
"Step": "Passo",
|
||||
@@ -415,6 +419,7 @@
|
||||
"angle, height": "angolo, altezza",
|
||||
"appearance.dielectric_ior": "Indice di rifrazione dielettrico",
|
||||
"appearance.metallic": "Metallicità",
|
||||
"appearance.only_available": "Solo aspetti disponibili",
|
||||
"appearance.pbr_help": "Visualizza questa superficie in Rendering o in un PNG del prodotto. Senza rifrazione né trasmissione.",
|
||||
"appearance.pbr_opaque": "PBR opaco",
|
||||
"appearance.roughness": "Rugosità",
|
||||
@@ -576,6 +581,7 @@
|
||||
"cmd.material_create": "Nuovo materiale fisico",
|
||||
"cmd.material_delete": "Elimina materiale fisico",
|
||||
"cmd.material_edit": "Modifica materiale fisico",
|
||||
"cmd.material_inspect": "Ispeziona materiale fisico",
|
||||
"cmd.material_list": "Elenca materiali",
|
||||
"cmd.material_properties_directional": "Modulo elastico direzionale",
|
||||
"cmd.material_properties_validate": "Convalida dati del materiale fisico",
|
||||
|
||||
+667
-1
@@ -97,6 +97,7 @@
|
||||
"Circle center": "円の中心",
|
||||
"Circular": "円形",
|
||||
"Circumference": "円周",
|
||||
"Clockwise": "時計回り",
|
||||
"Close draft": "下書きを閉じる",
|
||||
"Collapse": "折りたたむ",
|
||||
"Collisions": "衝突",
|
||||
@@ -116,6 +117,7 @@
|
||||
"Continue on GitHub": "GitHubで続ける",
|
||||
"Continuity": "連続性",
|
||||
"Control Radius": "制御半径",
|
||||
"Copies the definition only. Assign it from Physical Material when ready.": "定義のみをコピーします。準備ができたら物理マテリアルから割り当ててください。",
|
||||
"Copy Error Message": "エラーメッセージをコピー",
|
||||
"Copy Warning Message": "警告メッセージをコピー",
|
||||
"Copy all licences": "すべてのライセンスをコピー",
|
||||
@@ -240,6 +242,7 @@
|
||||
"Horiz./Vert.": "水平 / 垂直",
|
||||
"I-Beam": "I形鋼",
|
||||
"IMAGES": "画像",
|
||||
"Import material into design": "マテリアルを設計にインポート",
|
||||
"Import…": "読み込み…",
|
||||
"In This Design": "このデザイン内",
|
||||
"In place (surfaces)": "その場で(サーフェス)",
|
||||
@@ -290,6 +293,7 @@
|
||||
"Mass Center": "重心",
|
||||
"Matched restrictions check the final values.": "条件に一致する制限ルールが最終値を確認します。",
|
||||
"Material": "材料",
|
||||
"Material copied. Existing body assignments are unchanged.": "マテリアルをコピーしました。既存のボディの割り当ては変わりません。",
|
||||
"Max": "最大",
|
||||
"Maximum": "最大",
|
||||
"Mesh body": "メッシュボディ",
|
||||
@@ -313,6 +317,7 @@
|
||||
"Move later": "後へ移動",
|
||||
"Move up": "上へ移動",
|
||||
"Name": "名前",
|
||||
"Name on import": "インポート名",
|
||||
"Nearest": "最も近い",
|
||||
"New": "新規",
|
||||
"New Comp.": "新規コンポーネント",
|
||||
@@ -322,6 +327,7 @@
|
||||
"No crash reports.": "クラッシュレポートはありません。",
|
||||
"No matching appearance presets.": "一致する外観プリセットはありません。",
|
||||
"No matching appearances": "一致する外観がありません",
|
||||
"No matching physical materials.": "一致する物理マテリアルがありません。",
|
||||
"No visible bodies or sketches to export.": "出力する表示中のボディまたはスケッチがありません。",
|
||||
"Nominal diameter": "呼び径",
|
||||
"None": "なし",
|
||||
@@ -351,6 +357,7 @@
|
||||
"Path": "パス",
|
||||
"Pattern": "パターン",
|
||||
"Per Edge": "エッジごと",
|
||||
"Physical material definitions": "物理マテリアル定義",
|
||||
"Pick the tool bodies": "ツールボディを選択",
|
||||
"Picked": "選択したもの",
|
||||
"Picked point": "選択した点",
|
||||
@@ -450,6 +457,7 @@
|
||||
"Second plane": "第2平面",
|
||||
"Section": "断面",
|
||||
"Section (optional)": "断面(任意)",
|
||||
"Section position": "断面の位置",
|
||||
"Sections (one sketch each)": "セクション (各1スケッチ)",
|
||||
"Select Other": "その他を選択",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "その他を選択: モデル上で左ボタンを長押し(または右クリック › その他を選択…)するとカーソル下の要素が一覧表示されます。同じ場所を再度クリックすると次の要素が選択されます。中ボタンをダブルクリックするとホームビューに戻ります(環境設定 › ナビゲーション)。",
|
||||
@@ -479,9 +487,11 @@
|
||||
"Specialise": "特殊操作",
|
||||
"Speed": "速度",
|
||||
"Splitting tool": "分割ツール",
|
||||
"Square": "正方形",
|
||||
"Stand it up": "正立させる",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "正立させる: 取り消し可能な1つの移動フィーチャーとして、X軸周りに90度回転します。",
|
||||
"Stand this part up?": "このパーツを正立させますか?",
|
||||
"Start angle": "開始角度",
|
||||
"Start bulge": "開始側の膨らみ",
|
||||
"Start continuity": "開始側の連続性",
|
||||
"Step": "ステップ",
|
||||
@@ -606,6 +616,7 @@
|
||||
"angle, height": "角度, 高さ",
|
||||
"appearance.dielectric_ior": "誘電体の屈折率",
|
||||
"appearance.metallic": "金属度",
|
||||
"appearance.only_available": "利用可能な外観のみ",
|
||||
"appearance.pbr_help": "この表面はレンダリング作業空間または製品PNGで確認できます。屈折や透過には対応していません。",
|
||||
"appearance.pbr_opaque": "不透明PBR",
|
||||
"appearance.roughness": "粗さ",
|
||||
@@ -634,6 +645,8 @@
|
||||
"cmd.appearance_list": "外観を一覧表示",
|
||||
"cmd.assembly_bom": "部品表",
|
||||
"cmd.body_rename": "ボディの名前を変更",
|
||||
"cmd.browser_collapse_all": "すべて折りたたむ",
|
||||
"cmd.browser_expand_all": "すべて展開",
|
||||
"cmd.browser_group": "新規グループ",
|
||||
"cmd.browser_move": "ブラウザ項目を移動",
|
||||
"cmd.browser_order": "ブラウザ項目の並び順を変更",
|
||||
@@ -770,6 +783,7 @@
|
||||
"cmd.material_create": "新規物理マテリアル",
|
||||
"cmd.material_delete": "物理マテリアルを削除",
|
||||
"cmd.material_edit": "物理マテリアルを編集",
|
||||
"cmd.material_inspect": "物理材料を確認",
|
||||
"cmd.material_list": "マテリアルを一覧表示",
|
||||
"cmd.material_properties_directional": "方向別弾性率",
|
||||
"cmd.material_properties_validate": "物理材料データを検証",
|
||||
@@ -817,14 +831,45 @@
|
||||
"cmd.plastic_rest": "レスト",
|
||||
"cmd.plastic_rules": "プラスチック ルールを一覧表示",
|
||||
"cmd.plastic_snap_fit": "スナップ フィット",
|
||||
"cmd.render_aging_describe": "レイヤー式表面エイジング",
|
||||
"cmd.render_backends": "レンダリング バックエンド",
|
||||
"cmd.render_camera_fit": "レンダー対象をフレームに合わせる",
|
||||
"cmd.render_camera_get": "レンダーカメラを確認",
|
||||
"cmd.render_cancel": "レンダリングをキャンセル",
|
||||
"cmd.render_effects_describe": "レンズとクリエイティブ効果",
|
||||
"cmd.render_export": "PNGをエクスポート",
|
||||
"cmd.render_hdr_inspect": "HDRソースを調査",
|
||||
"cmd.render_library_appearance_apply": "ライブラリの不透明外観を適用",
|
||||
"cmd.render_library_describe": "レンダリングリソースを調査",
|
||||
"cmd.render_library_environment_apply": "組み込みHDR環境を適用",
|
||||
"cmd.render_library_list": "レンダリングライブラリを参照",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_preview": "元の表面マップを確認",
|
||||
"cmd.render_library_studio_apply": "作成済みスタジオ照明を適用",
|
||||
"cmd.render_library_studio_prepare": "作成済みスタジオ照明を準備",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "作成済みサーフェスマップを準備",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "レンダリングリソースの対象を検索",
|
||||
"cmd.render_optics_bind": "光学割り当てを保存",
|
||||
"cmd.render_optics_unbind": "光学割り当てを削除",
|
||||
"cmd.render_preflight": "レンダリング要求を確認",
|
||||
"cmd.render_preset_apply": "ネイティブスタジオを適用",
|
||||
"cmd.render_preset_resolve": "ネイティブスタジオを確認",
|
||||
"cmd.render_quality_prepare": "固定サンプリング予算を確認",
|
||||
"cmd.render_result_pin": "表示中のレンダリング結果を保持",
|
||||
"cmd.render_result_regrade": "リニアマスターを再調整",
|
||||
"cmd.render_scene": "レンダリングシーンを確認",
|
||||
"cmd.render_settings_apply": "レンダリングカメラを適用",
|
||||
"cmd.render_settings_capture_hdr": "HDRとレンダリング設定を保存",
|
||||
"cmd.render_settings_get": "レンダリング設定",
|
||||
"cmd.render_settings_set": "レンダリング設定を保存",
|
||||
"cmd.render_shot_duplicate": "レンダーショットを複製",
|
||||
"cmd.render_shot_remove": "レンダーショットを削除",
|
||||
"cmd.render_shot_rename": "レンダーショットの名前を変更",
|
||||
"cmd.render_stage_backdrop": "物理レンダー背景を保存",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
"cmd.render_start": "画像をレンダリング",
|
||||
"cmd.render_status": "レンダリングの進行状況",
|
||||
"cmd.select_clear": "選択をクリア",
|
||||
@@ -959,13 +1004,20 @@
|
||||
"cmd.timeline_suppress": "フィーチャーを抑制",
|
||||
"cmd.view_ambient_occlusion": "アンビエントオクルージョン",
|
||||
"cmd.view_apply": "名前付きビューを復元",
|
||||
"cmd.view_back": "背面ビュー",
|
||||
"cmd.view_bottom": "下面ビュー",
|
||||
"cmd.view_delete": "名前付きビューを削除",
|
||||
"cmd.view_front": "正面ビュー",
|
||||
"cmd.view_graphics_preset": "グラフィックスプリセット",
|
||||
"cmd.view_isometric": "等角ビュー",
|
||||
"cmd.view_left": "左側面ビュー",
|
||||
"cmd.view_list": "名前付きビューを一覧表示",
|
||||
"cmd.view_navigate": "ビューナビゲーション",
|
||||
"cmd.view_normal_to": "選択アイテムに垂直",
|
||||
"cmd.view_rename": "名前付きビューの名前を変更",
|
||||
"cmd.view_right": "右側面ビュー",
|
||||
"cmd.view_save": "新規名前付きビュー",
|
||||
"cmd.view_top": "上面ビュー",
|
||||
"color.copy": "クリックして色の値をコピー",
|
||||
"color.edit": "クリックして色を編集",
|
||||
"color.gamma": "0〜255のガンマ空間で色の値を表示",
|
||||
@@ -1154,6 +1206,49 @@
|
||||
"manage.material_hint": "ボディを選択し、物理マテリアルを指定してください。",
|
||||
"manage.parameters_hint": "式と単位を編集してください。Enterを押すか、フィールドから移動すると変更が適用されます。",
|
||||
"manage.rules_hint": "編集するルールを選ぶか、新規ルールを作成してください。確定するとルールが保存されます。",
|
||||
"material.editor.add_property": "特性を追加",
|
||||
"material.editor.add_source": "出典を追加",
|
||||
"material.editor.assigned_density": "割り当て密度",
|
||||
"material.editor.axes": "材料軸",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"material.editor.copy_name": "{name} のコピー",
|
||||
"material.editor.density_range": "割り当て密度は 0 より大きく 1000 g/cm³ 以下にしてください。",
|
||||
"material.editor.designation": "材料名称",
|
||||
"material.editor.duplicate": "複製",
|
||||
"material.editor.engineering_card": "工学特性カード",
|
||||
"material.editor.family": "材料分類",
|
||||
"material.editor.glass": "ガラス",
|
||||
"material.editor.illustrative": "例示",
|
||||
"material.editor.invalid_property": "未対応の特性です。",
|
||||
"material.editor.isotropic": "等方性",
|
||||
"material.editor.measurement": "測定",
|
||||
"material.editor.metal": "金属",
|
||||
"material.editor.moisture": "含水率(乾量基準)",
|
||||
"material.editor.name_required": "1~128 文字の名前を入力してください。",
|
||||
"material.editor.no_draft": "材料の下書きが開かれていません。",
|
||||
"material.editor.number_required": "有限の数値を入力してください。",
|
||||
"material.editor.orthotropic": "直交異方性",
|
||||
"material.editor.other": "その他",
|
||||
"material.editor.polymer": "高分子",
|
||||
"material.editor.preserved_appearance": "保持される外観",
|
||||
"material.editor.public_reference": "公開資料",
|
||||
"material.editor.reference": "参照",
|
||||
"material.editor.save_or_discard": "材料を割り当てる前に下書きを保存または破棄してください。",
|
||||
"material.editor.saved": "材料を保存しました。ボディへの割り当ては変わりません。",
|
||||
"material.editor.scope": "保存してもボディには割り当てません。空欄の特性と条件は不明のままです。カードの密度は割り当て密度や質量を変更しません。",
|
||||
"material.editor.source_id": "出典 ID",
|
||||
"material.editor.source_kind": "出典の種類",
|
||||
"material.editor.source_title": "出典名",
|
||||
"material.editor.sources": "出典",
|
||||
"material.editor.stale": "編集中に材料が変更されました。下書きを破棄し、開き直してから保存してください。",
|
||||
"material.editor.state": "材料の状態",
|
||||
"material.editor.strain_rate": "ひずみ速度",
|
||||
"material.editor.symmetry": "弾性対称性",
|
||||
"material.editor.temperature": "温度",
|
||||
"material.editor.unknown_card": "工学特性は不明です。割り当て密度と既存の外観だけでも保存できます。",
|
||||
"material.editor.user_supplied": "ユーザー提供",
|
||||
"material.editor.wood": "木材",
|
||||
"measure.at": "位置",
|
||||
"measure.item": "項目 {number}",
|
||||
"messages.ago_h": "{n} 時間前",
|
||||
@@ -1339,21 +1434,248 @@
|
||||
"recovery.just_now": "たった今",
|
||||
"recovery.min_ago": "{count}分前",
|
||||
"recovery.never_saved": "未保存",
|
||||
"render.adaptive_absolute": "RGB 絶対誤差の下限",
|
||||
"render.adaptive_coverage": "被覆率の誤差目標",
|
||||
"render.adaptive_enable": "独立した予備サンプルで配分",
|
||||
"render.adaptive_help": "GPU 専用。独立した予備サンプルは破棄され、各ピクセルに最小16から設定上限までの本サンプルを配分します。RGB と被覆率の分散を目安にしますが、まれな経路を見逃したり上限でノイズが残ったりします。最終レポートは実際の処理量を示します。ノイズや時間を保証しません。",
|
||||
"render.adaptive_minimum": "最小本サンプル数",
|
||||
"render.adaptive_pending": "GPU の独立予備サンプルによる適応配分と条件付きフレネル層化が利用できます。収束の認証、まれな事象の保証、CPU 適応輸送は未対応です。",
|
||||
"render.adaptive_pilots": "ピクセルごとの予備サンプル",
|
||||
"render.adaptive_relative": "RGB 相対誤差の目標",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.advanced_material_scope": "明示的な制限付きで、有限の均一 GPU 媒質を利用できます。密度グリッド、ガラスとの入れ子、表面の内部散乱、ディスプレイスメント、分光輸送、未接続の高度な素材は未対応です。",
|
||||
"render.aging_add": "エイジング層を追加",
|
||||
"render.aging_airborne": "空中のほこり・散乱媒質",
|
||||
"render.aging_airborne_help": "空中のほこりは独立した有限の均一散乱ボリュームです。表面層ではなく輸送と生 EXR を変更します。ガラス・ノイズ除去との制限を維持し、大気を自動追加しません。",
|
||||
"render.aging_all_bodies": "適用可能な不透明ボディすべて",
|
||||
"render.aging_chips": "塗装の剥がれ",
|
||||
"render.aging_class_any": "すべての不透明材質",
|
||||
"render.aging_class_dielectric": "非金属表面のみ",
|
||||
"render.aging_class_metal": "金属表面のみ",
|
||||
"render.aging_color": "層の色 · sRGB",
|
||||
"render.aging_coverage": "被覆率",
|
||||
"render.aging_dust": "堆積したほこり",
|
||||
"render.aging_empty": "層なし:元の表面を保持します。",
|
||||
"render.aging_fading": "色あせた塗膜",
|
||||
"render.aging_grime": "汚れ・染み",
|
||||
"render.aging_help": "最大8層の光学的外観を順番に組み合わせます。さび・緑青は表現であり、経年や腐食の解析ではありません。スケールはワールド mm。形状・質量・工学物性を変更せず、ガラスとステージは対象外です。",
|
||||
"render.aging_metallic": "層の金属比率",
|
||||
"render.aging_origin": "フィールド原点 · ワールド mm",
|
||||
"render.aging_patina": "緑青",
|
||||
"render.aging_refresh_targets": "現在のボディを確認",
|
||||
"render.aging_roughness": "層の粗さ",
|
||||
"render.aging_rust": "鉄さび",
|
||||
"render.aging_scale": "模様のスケール",
|
||||
"render.aging_scratches": "細かい擦り傷",
|
||||
"render.aging_target": "対象と座標",
|
||||
"render.aging_target_help": "指定対象はキャプチャ時のインデックスと名前が一致する必要があります。マスクはワールド固定で可動部に追従しません。空洞検出や実際のエッジ摩耗ではありません。絞り込みで他のボディを表示できます。",
|
||||
"render.aging_target_search": "ボディ名を絞り込む",
|
||||
"render.aging_upward": "上向き面への堆積",
|
||||
"render.all_controls_help": "現在の全コントロールをまとめて表示します。各ページでは同じ要求を保ちながら項目別に編集できます。",
|
||||
"render.appearance_physics_separate": "外観の設定では、密度、熱特性などの工学的な物性値は割り当てられません。",
|
||||
"render.availability_native": "ネイティブ構成。適用前に確認してください",
|
||||
"render.availability_projection": "対応する部分適用。範囲と省略項目を確認してください",
|
||||
"render.availability_reference": "参照データ。自動割り当てではありません",
|
||||
"render.backdrop_alpha_conflict": "この背景か透明PNGのどちらかを選択してください。レンダラーは一方を無断で無視しません。",
|
||||
"render.backdrop_enable": "カメラ専用のグラデーション背景を使用",
|
||||
"render.backdrop_first": "開始色/中心色",
|
||||
"render.backdrop_help": "この画面空間の背景は、照明、影、反射、地形を生成しません。生EXRには含まれず、形状、ライト、HDR環境とは独立しています。",
|
||||
"render.backdrop_horizontal": "水平グラデーション",
|
||||
"render.backdrop_radial": "放射状グラデーション",
|
||||
"render.backdrop_radius": "半径",
|
||||
"render.backdrop_second": "終端色/周辺色",
|
||||
"render.backdrop_vertical": "垂直グラデーション",
|
||||
"render.backdrop_x": "中心X",
|
||||
"render.backdrop_y": "中心Y",
|
||||
"render.background": "シーンの背景",
|
||||
"render.background_camera_section": "カメラ背景 · PNG 表示",
|
||||
"render.background_completed_frozen": "表示中の結果は完了済みの固定画像です。背景編集で自動的には書き換わりません。カメラ背景は再調整、物理ステージ変更は新規レンダーを使います。",
|
||||
"render.background_hdr_separate": "現在の HDR リソースは照明と表面反射に使われ、被写体の背後へパノラマとして自動表示されません。グラデーション変更は照明の回転や色に影響しません。",
|
||||
"render.background_lighting_section": "HDR 照明 · カメラ背景とは独立",
|
||||
"render.background_no_alpha_override": "透明出力へ背景を自動追加しません。再調整は保持した被覆率を使い、ノイズ除去を再適用しません。元の EXR は不変です。",
|
||||
"render.background_not_light": "背景色は表示用であり、追加の光源ではありません。",
|
||||
"render.background_regrade": "保持した生マスターに適用",
|
||||
"render.background_stage_occlusion": "このショットには物理ステージがあります。大きな床や壁が画面を覆うとカメラ背景は見えません。ステージを明示的に削除・縮小するか、その反射率を変更してください。再調整では撮影済み形状を除去できません。",
|
||||
"render.background_workflow": "カメラ専用の色・グラデーション、光を受ける物理ステージ、HDR 照明は独立した設定です。ライブプレビューはモデリング表示です。カメラ仕上げは新規レンダーまたは保持マスターの再調整で確認します。",
|
||||
"render.base_appearance": "編集可能なボディの外観",
|
||||
"render.base_apply": "ボディの外観を適用",
|
||||
"render.base_apply_help": "確認した正確なボディへの、取り消し可能な外観の割り当てです。既存の面別外観と工学材料は独立して保持されます。",
|
||||
"render.base_color": "ベースカラー・sRGB",
|
||||
"render.base_metallic": "金属成分の割合",
|
||||
"render.base_opaque_only": "この編集では不透明ボディの意味を保持します。透過には明示的なガラス設定を使用してください。",
|
||||
"render.bloom_enable": "表示ブルーム",
|
||||
"render.bloom_help": "正の線形ハイライトを3回の正規化フィルターで広げる表示専用の効果です。半径は出力ピクセル単位。sRGB変換前に加算され、レンズ・体積・収束の改善ではありません。生EXRは変わりません。",
|
||||
"render.bloom_opaque": "ブルームには不透明な出力が必要です。透明PNGを暗黙に統合せず拒否します。",
|
||||
"render.bloom_radius": "ブルーム半径",
|
||||
"render.bloom_strength": "ブルーム強度",
|
||||
"render.bloom_threshold": "線形ハイライトしきい値",
|
||||
"render.browse_capabilities": "全機能仕様を確認",
|
||||
"render.browse_environments": "オリジナルHDR環境を参照",
|
||||
"render.browse_native_scenes": "ネイティブスタジオを参照",
|
||||
"render.browse_physical": "物性参照を確認",
|
||||
"render.browse_quality": "品質仕様を確認",
|
||||
"render.browse_rigs": "制作済み照明セットを参照",
|
||||
"render.browse_scene_specs": "高度なシーン仕様を参照",
|
||||
"render.browse_surfaces": "制作済み表面を参照",
|
||||
"render.browser_library": "ライブラリ",
|
||||
"render.browser_model": "モデル",
|
||||
"render.camera_distance": "視点からターゲットまでの距離",
|
||||
"render.camera_exact_help": "世界座標はmmです。角度は度で表示し、ラジアンで保存します。ナビゲーションとビューポートは同じカメラを使用します。",
|
||||
"render.camera_fov": "垂直画角",
|
||||
"render.camera_pitch": "カメラのピッチ",
|
||||
"render.camera_roll": "ロール",
|
||||
"render.camera_set": "レンダーカメラを設定",
|
||||
"render.camera_target": "ターゲット位置・mm",
|
||||
"render.camera_yaw": "ヨー",
|
||||
"render.chromatic_offset": "色収差のずれ",
|
||||
"render.clear_stage": "Remove saved stage",
|
||||
"render.copy_request": "JSONをコピー",
|
||||
"render.cpu_aa_help": "空間サンプル数を増やすと輪郭が滑らかになりますが、描画時間も増えます。",
|
||||
"render.cpu_area_add": "CPU矩形ライトを追加",
|
||||
"render.cpu_area_editor": "CPU矩形ライト",
|
||||
"render.cpu_area_editor_help": "辺の全長ベクトルをmmで指定します。UとVの外積が発光側を向きます。GPUの半辺ベクトルとは異なります。",
|
||||
"render.cpu_area_full_u": "U辺の全長・mm",
|
||||
"render.cpu_area_full_v": "V辺の全長・mm",
|
||||
"render.cpu_area_samples": "面光源のサンプル数",
|
||||
"render.cpu_binding_confirm": "このボディを確認",
|
||||
"render.cpu_binding_stale": "シーンが変更されました。レンダリング前に反射対象を再確認してください。",
|
||||
"render.cpu_body_choose": "ボディを選択",
|
||||
"render.cpu_body_filter": "名前でボディを絞り込み",
|
||||
"render.cpu_body_filter_more": "さらに表示するには絞り込んでください。",
|
||||
"render.cpu_body_missing": "反射対象が存在しない、非表示、重複名、または名前が128バイトを超えています。選び直してください。",
|
||||
"render.cpu_budget": "CPUリソースプロファイル",
|
||||
"render.cpu_budget_bodies": "ボディ数の上限",
|
||||
"render.cpu_budget_compact": "コンパクト(従来の上限)",
|
||||
"render.cpu_budget_details": "リソースの上限",
|
||||
"render.cpu_budget_help": "上限の拡大は明示的に選択します。解像度やサンプル数は自動的に減らしません。",
|
||||
"render.cpu_budget_memory": "ジョブのメモリ上限",
|
||||
"render.cpu_budget_not_guarantee": "これは受け付け上限であり、RAMの予約や速度の保証ではありません。形状、フィルム、保持中のプレビューはメモリ予算を共有します。レンダリングはキャンセルできます。",
|
||||
"render.cpu_budget_resize": "設定がCPUプロファイルまたはカメラサンプル予算を超えています。小さい寸法を明示的に確定するか、大きいプロファイルを選択してください。",
|
||||
"render.cpu_budget_studio": "スタジオ(大きな画像)",
|
||||
"render.cpu_budget_triangles": "三角形数の上限",
|
||||
"render.cpu_budget_workstation": "ワークステーション(大規模シーン)",
|
||||
"render.cpu_captured_hdr": "この画像で使用したHDR",
|
||||
"render.cpu_check_capture_help": "確認と開始は同じファイルのハッシュを検証するか、埋め込みHDRを使用します。各画像は取得済みの入力を保持します。",
|
||||
"render.cpu_check_changed": "確認後に設定またはモデルが変更されました。レンダリング前に再確認してください。",
|
||||
"render.cpu_constant_help": "一定の放射輝度を反射・透過レイに与えます。直接拡散照明には使われません。",
|
||||
"render.cpu_custom_directions": "プリセットをカスタム平行光に置換",
|
||||
"render.cpu_direction": "光源へ向かう方向(X、Y、Z)",
|
||||
"render.cpu_directional": "平行光",
|
||||
"render.cpu_directional_add": "平行光を追加",
|
||||
"render.cpu_environment": "CPU環境光",
|
||||
"render.cpu_environment_background": "画像の背景は環境照明とは別に設定されます。",
|
||||
"render.cpu_environment_bounds": "CPU強度は0~64、HDR回転は±1,000,000ラジアン以内の有限値、HDRサンプル数は1、4、16、64です。",
|
||||
"render.cpu_environment_constant": "二次レイ用の一定環境光",
|
||||
"render.cpu_environment_none": "CPU環境光なし",
|
||||
"render.cpu_environment_samples": "HDR照明サンプル数",
|
||||
"render.cpu_exposure_help": "CPU露出は−16~16 EVです。範囲外のGPU露出は、変更するまで保持されます。",
|
||||
"render.cpu_fixed": "固定画像",
|
||||
"render.cpu_hdr_help": "Radiance .hdr、2:1パノラマ、最大2048 × 1024・16 MiB。CPUではファイル内にsRGB/D65原色の明示が必要です。原色未指定やEXRは使用できません。",
|
||||
"render.cpu_hdr_reflection_help": "HDRの粗い反射には、ボディと面の完全な金属表面が必要です。未対応の組み合わせは確認時に表示されます。",
|
||||
"render.cpu_key_rim": "キーライトとリムライト",
|
||||
"render.cpu_last_check": "前回のCPU確認",
|
||||
"render.cpu_light_help": "平行光は最大8個です。カスタムリストを空にすると消灯し、プリセットを選ぶとその光源に戻ります。色はリニアRGB、強度は相対値でワットではありません。",
|
||||
"render.cpu_light_intensity": "相対強度(0~64)",
|
||||
"render.cpu_light_minimum": "減衰計算の最小距離",
|
||||
"render.cpu_light_position": "ワールド位置(X、Y、Z)",
|
||||
"render.cpu_light_reference": "強度の基準距離",
|
||||
"render.cpu_light_remove": "光源を削除",
|
||||
"render.cpu_lighting": "照明プリセット",
|
||||
"render.cpu_lights": "CPU光源",
|
||||
"render.cpu_linear_color": "リニア色(R、G、B)",
|
||||
"render.cpu_neutral": "ニュートラル",
|
||||
"render.cpu_opaque_required": "CPU レイトレーシングには不透明な背景が必要です。透明な背景を解除してください。",
|
||||
"render.cpu_options_pending": "このCPUパネルでは、発光、表面効果、ガラス、異方性はまだ編集できません。使用前にそれらのAPIオプションを解除してください。",
|
||||
"render.cpu_point": "点光源",
|
||||
"render.cpu_point_add": "点光源を追加",
|
||||
"render.cpu_point_help": "選択した平行光に最大8個の点光源を追加できます。距離はmmで、最小距離は基準距離以下にしてください。",
|
||||
"render.cpu_primary_samples": "輪郭サンプル数/ピクセル",
|
||||
"render.cpu_progressive": "CPUプログレッシブ",
|
||||
"render.cpu_progressive_help": "既存のCPU積分器を、一次サンプル1個ずつのパスで累積します。選択した反射は1サンプルが必要です。面光源、誘電体、異方性には固定画像を使用してください。",
|
||||
"render.cpu_progressive_limits": "最大1,048,576ピクセル、ピクセル×サンプルの合計は16,777,216以下です。サンプル数を変えても画像サイズは自動変更されません。",
|
||||
"render.cpu_progressive_seed": "CPUサンプリングシード",
|
||||
"render.cpu_progressive_spp": "サンプル/ピクセル",
|
||||
"render.cpu_reflection_add": "粗い反射を追加",
|
||||
"render.cpu_reflection_depth": "反射の深さ(1~8)",
|
||||
"render.cpu_reflection_empty": "対象ボディがないため、シーン反射は無効です。",
|
||||
"render.cpu_reflection_help": "ボディごとに無効・鏡面・粗い反射を選択します。粗い反射は設定済みの表面粗さを使います。サンプル数と反射回数を増やすと時間がかかります。有限の鏡面輸送であり、グローバルイルミネーションではありません。",
|
||||
"render.cpu_reflection_limit": "反射対象は最大64ボディです。",
|
||||
"render.cpu_reflection_mirror": "鏡面",
|
||||
"render.cpu_reflection_off": "無効",
|
||||
"render.cpu_reflection_rough": "粗い反射",
|
||||
"render.cpu_reflection_samples": "反射サンプル数(1~64)",
|
||||
"render.cpu_reflections": "CPU反射",
|
||||
"render.cpu_runtime_help": "照明と環境の数値設定は保存されます。ボディごとの反射とHDRファイルは一時設定です。既存の面光源とスポット円錐の値は保持されます。",
|
||||
"render.cpu_sampling_mode": "CPUサンプリング方式",
|
||||
"render.cpu_shadows": "影を落とす",
|
||||
"render.cpu_summary": "CPUレイトレーシング・反射・HDR・平行光と点光源",
|
||||
"render.cpu_warm_cool": "暖色と寒色",
|
||||
"render.diag_bodies": "表示ボディ数",
|
||||
"render.diag_job_details": "記録されたジョブの詳細",
|
||||
"render.diag_last_check": "前回の事前確認",
|
||||
"render.diag_memory": "論理メモリ受け入れ見積もり",
|
||||
"render.diag_not_implemented": "明示的な機能制限",
|
||||
"render.diag_preflight_details": "事前確認の詳細",
|
||||
"render.diag_request": "現在の正確な要求",
|
||||
"render.diag_triangles": "三角形数",
|
||||
"render.discard_continue": "下書きを破棄して続行",
|
||||
"render.draft_confirm_help": "現在のレンダー下書きには未適用の編集があります。切り替える前に保存するか、明示的に破棄するか、編集を続けてください。",
|
||||
"render.draft_confirm_title": "編集したレンダー設定を保持",
|
||||
"render.effects_gpu_only": "これらの効果には GPU パストレーシングが必要です。ページを開いてもレンダラーは切り替わりません。",
|
||||
"render.effects_help": "順序付きカラー効果と画像空間レンズ効果を組み合わせます。レンダーと生マスター再調整は同じ保存設定を使います。生 EXR は不変です。校正済みレンズや市販フィルムの模倣ではありません。",
|
||||
"render.effects_reset_lens": "レンズ効果をリセット",
|
||||
"render.effects_seed": "パターンシード",
|
||||
"render.export_display": "書き出し:表示PNG",
|
||||
"render.export_linear": "書き出し:生の線形EXR",
|
||||
"render.exr_pending": "GPUでは線形EXRを保持できます。圧縮、複数レイヤー、補助パスは未実装です。",
|
||||
"render.film_grain": "写真粒子",
|
||||
"render.fit": "製品を画面に合わせる",
|
||||
"render.flare_ghosts": "光源ごとのゴースト環",
|
||||
"render.flare_halo": "フレアのハロー",
|
||||
"render.flare_streak": "アナモルフィック風の筋",
|
||||
"render.flare_strength": "ハイライトフレア強度",
|
||||
"render.flare_threshold": "シーンリニアしきい値",
|
||||
"render.gpu_depth": "最大パス深度",
|
||||
"render.gpu_options_help": "サンプル数、深度、シード、露出をこの設定に保存します。保存するのは選択中の画像方式だけです。",
|
||||
"render.gpu_path_failed": "GPUパストレーサーを利用できません",
|
||||
"render.gpu_path_first_setup": "このGPUでの初回セットアップには数分かかることがあります。その間もSolidCraftは使用できます。以降の起動では、ドライバーが保持していればコンパイル済みのシェーダーを再利用します。",
|
||||
"render.gpu_path_preparing": "GPUパストレーサー:シェーダーをコンパイル中…",
|
||||
"render.gpu_seed": "乱数シード",
|
||||
"render.gpu_unavailable": "このデバイスでは GPU パストレーシングの準備ができていません。",
|
||||
"render.ground_apply": "床をフィットして保存",
|
||||
"render.ground_gap": "明示的なクリアランス",
|
||||
"render.ground_linear_rgb": "拡散反射率・線形RGB",
|
||||
"render.ground_margin": "床の広がりの余白",
|
||||
"render.hdr_details": "HDR入力の詳細",
|
||||
"render.hdr_embedded": "このデザインに保存されたHDR",
|
||||
"render.hdr_embedded_help": "デザイン内のデータを使用するため、元のファイルは不要です。",
|
||||
"render.hdr_file_captured": "HDRファイルを確認しました。保存時にこのデータを埋め込みます。ファイルが変更された場合は、明示的に再確認してください。",
|
||||
"render.hdr_inspect": "HDRファイルを確認",
|
||||
"render.hdr_inspect_required": "保存またはレンダリングの前にHDRファイルを選択して確認してください。",
|
||||
"render.hdr_primaries_declared": "入力には色の原色が宣言されています。",
|
||||
"render.hdr_primaries_srgb": "原色:sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "原色が宣言されていません。レンダラーの色要件を確認してください。",
|
||||
"render.hdr_resource_missing": "保存されたHDRリソースがこのデザインにありません。",
|
||||
"render.image_advanced": "GPU 詳細設定",
|
||||
"render.image_cancelled": "レンダリングをキャンセルしました",
|
||||
"render.image_cancelling": "キャンセル中",
|
||||
"render.image_completed": "画像をエクスポートできます",
|
||||
"render.image_encoding": "PNGをエンコード中",
|
||||
"render.image_export": "PNGをエクスポート",
|
||||
"render.image_export": "完成画像をエクスポート",
|
||||
"render.image_exposure": "露出",
|
||||
"render.image_failed": "レンダリングに失敗しました",
|
||||
"render.image_height": "高さ",
|
||||
"render.image_help": "CPUプレビュー画像 · PNG · 近似透過",
|
||||
"render.image_host_missing": "画像の実行ホストがありません。",
|
||||
"render.image_method": "画像の生成方式",
|
||||
"render.image_overwrite": "既存のファイルを置換",
|
||||
"render.image_preparing": "画像を準備中",
|
||||
"render.image_progressive": "プログレッシブレンダリング",
|
||||
"render.image_queued": "レンダリング待機中",
|
||||
"render.image_reduce": "画像を小さくするかシーンを簡略化してください。",
|
||||
"render.image_running": "画像をレンダリング中",
|
||||
"render.image_samples": "ピクセルあたりのサンプル数",
|
||||
"render.image_scene_stale": "確認または開始する前にモデリング操作を完了するか、シーンを更新してください。",
|
||||
"render.image_stale": "この画像は後続の変更前に取得したシーンを使用しています。",
|
||||
"render.image_start": "レンダリングを開始",
|
||||
"render.image_supported": "レンダリング要求に対応しています。開始時にキューとメモリを再確認します。",
|
||||
@@ -1363,20 +1685,347 @@
|
||||
"render.image_unknown": "レンダリング状態を取得できません",
|
||||
"render.image_use_largest": "この縦横比での最大サイズを使用:",
|
||||
"render.image_width": "幅",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspect_scene": "記録するシーンの概要を更新",
|
||||
"render.keep_editing": "編集を続ける",
|
||||
"render.layer_down": "下へ",
|
||||
"render.layer_enabled": "層を有効にする",
|
||||
"render.layer_remove": "層を削除",
|
||||
"render.layer_strength": "層の強さ",
|
||||
"render.layer_up": "上へ",
|
||||
"render.lens_effects_help": "実際のリニア画像から最大4個の離れた明るい光源を使います。ゴースト・ハロー・光の筋・色ずれ・歪みは画像空間の芸術的近似です。空間効果には不透明出力が必要で、外側は端の色を延長します。粒子は決定的です。物理・EXR・形状は変更しません。",
|
||||
"render.lens_effects_title": "レンズ風・写真効果",
|
||||
"render.library_all": "カタログ",
|
||||
"render.library_all_states": "すべての利用可能状態",
|
||||
"render.library_applied": "リソース変換を適用しました。開始前にレンダリング要求全体を確認してください。",
|
||||
"render.library_apply_hdr": "このHDR環境と一緒に保存",
|
||||
"render.library_apply_maps": "作成済みGPUサーフェスマップを使用",
|
||||
"render.library_apply_studio": "作成済みスタジオ変換を保存",
|
||||
"render.library_apply_uniform": "均一な不透明外観を適用",
|
||||
"render.library_authored_help": "独自に作成したリソースは表現用であり、測定済みの工学データではありません。各操作は明示された変換だけを適用します。",
|
||||
"render.library_blocked": "このリソースには未解決の校正または外部の太陽光源が必要なため、まだ適用できません。",
|
||||
"render.library_capabilities": "機能仕様",
|
||||
"render.library_center": "リグ中心",
|
||||
"render.library_clear_search": "クリア",
|
||||
"render.library_details": "仕様と出典",
|
||||
"render.library_emitters_only_ack": "光源のみを使用し、記載された受動反射板を省略",
|
||||
"render.library_empty": "一致するリソースがありません。検索語や利用可能状態のフィルターを変更してください。",
|
||||
"render.library_environment_concepts": "環境構想",
|
||||
"render.library_extent": "対象の大きさ",
|
||||
"render.library_favorite": "お気に入りに追加",
|
||||
"render.library_favorites": "お気に入り",
|
||||
"render.library_hdr": "組み込みHDR環境",
|
||||
"render.library_hdr_help": "元のHDRを保存設定に埋め込みます。作成時の経度原点を明示的に変換します。保存後は外部ファイルが不要です。",
|
||||
"render.library_inspect_only": "選択すると詳細を確認できます。自動適用はされません。お気に入りと履歴は、この開いている文書のセッションに属します。",
|
||||
"render.library_light_concepts": "照明構想",
|
||||
"render.library_maps_help": "Built-in maps can be saved with pinned sources and local occurrence mapping. Temporary optical overrides remain a separate mode.",
|
||||
"render.library_material_concepts": "マテリアル構想",
|
||||
"render.library_native_scenes": "ネイティブスタジオ",
|
||||
"render.library_next": "次のページ",
|
||||
"render.library_omitted": "含まれない項目",
|
||||
"render.library_physical_profiles": "Physical reference profiles",
|
||||
"render.library_previous": "前のページ",
|
||||
"render.library_quality_concepts": "品質仕様",
|
||||
"render.library_recent": "最近使用した項目",
|
||||
"render.library_replace_environment": "既存の環境を明示的に置換",
|
||||
"render.library_replace_studio": "Replace saved lighting, environment and stage",
|
||||
"render.library_results": "一致するリソース",
|
||||
"render.library_rig_help": "Fit once at an explicit center and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_rigs": "作成済み照明リグ",
|
||||
"render.library_save_maps": "Save maps to this setup",
|
||||
"render.library_scene_bounds": "取得したシーン境界を使用",
|
||||
"render.library_scenes": "シーン仕様",
|
||||
"render.library_search": "ライブラリを検索",
|
||||
"render.library_select_hint": "ライブラリのリソースを選択して、対応する操作と制限を確認してください。",
|
||||
"render.library_selene": "SELENEの不透明外観",
|
||||
"render.library_selene_shots": "SELENEショット仕様",
|
||||
"render.library_short_blocked": "利用不可",
|
||||
"render.library_short_native": "ネイティブ構成",
|
||||
"render.library_short_projection": "対応する部分適用",
|
||||
"render.library_short_reference": "参照のみ",
|
||||
"render.library_short_specification": "仕様のみ",
|
||||
"render.library_source_preview": "元のマップのプレビューを読み込む",
|
||||
"render.library_source_preview_help": "制作されたベースカラーマップです。レンダー画像や実測された材料のプレビューではありません。",
|
||||
"render.library_specification_only": "仕様のみです。完全に実行可能なプリセットではありません。必要な効果、リソース、対象の役割には実装と明示的な関連付けが必要です。",
|
||||
"render.library_specs": "仕様のみ",
|
||||
"render.library_status": "利用可能状態",
|
||||
"render.library_surfaces": "作成済みPBRサーフェス",
|
||||
"render.library_target": "対象ボディ",
|
||||
"render.library_title": "レンダリングリソースライブラリ",
|
||||
"render.library_unfavorite": "お気に入りから削除",
|
||||
"render.library_uniform_ack": "空間変化や高度な効果のない均一近似を使用",
|
||||
"render.library_usable": "実行可能な部分適用",
|
||||
"render.linear_help": "ノイズ除去、露出、トーンマッピング、フィルター、背景処理より前の32ビット浮動小数点RGBAを保持します。線形sRGB/D65で、被覆率を乗算した値です。追加メモリを明示的に見積もります。圧縮や追加パスはありません。",
|
||||
"render.linear_retain": "生の線形EXRを保持",
|
||||
"render.linear_unavailable": "選択した完了画像にEXRは保持されていません。レンダー前に保持を有効にしてください。古いPNGから生の放射輝度は復元できません。",
|
||||
"render.look_add": "カラールックを追加",
|
||||
"render.look_bleach": "銀残し風",
|
||||
"render.look_cool": "寒色",
|
||||
"render.look_cyanotype": "シアノタイプ風",
|
||||
"render.look_faded": "色あせたプリント",
|
||||
"render.look_mono": "モノクロ",
|
||||
"render.look_sepia": "セピア",
|
||||
"render.look_strength": "ルックの強さ",
|
||||
"render.look_teal_orange": "ティール・オレンジ",
|
||||
"render.look_title": "クリエイティブルックの層",
|
||||
"render.look_warm": "暖色",
|
||||
"render.mapping_scale": "物理リピート倍率",
|
||||
"render.material_absorption": "吸収 R・G・B(1/mm)",
|
||||
"render.material_add": "このボディを追加・編集",
|
||||
"render.material_assignments": "ボディへの割り当て",
|
||||
"render.material_binding_enable": "このボディの設定を含める",
|
||||
"render.material_box": "軸に平行な直方体",
|
||||
"render.material_browse": "画像を選択…",
|
||||
"render.material_certification": "閉じたガラスは形状の距離を使用します。トポロジー、向き、重なり、光学境界はGPU準備時に検証します。確認は要求の受付検査です。",
|
||||
"render.material_choose_body": "シーンのボディを選択",
|
||||
"render.material_closed": "閉じたソリッドメッシュ",
|
||||
"render.material_coat": "ベース材のクリアコート",
|
||||
"render.material_coat_enable": "クリアコートを有効化",
|
||||
"render.material_coat_help": "既存の不透明外観に参考用の誘電体コートを重ねます。重み0ではベースを変えません。",
|
||||
"render.material_color_map": "ベースカラー画像(sRGB)",
|
||||
"render.material_color_replace": "ベースマップでボディ色を置換",
|
||||
"render.material_custom": "カスタム参考光学設定",
|
||||
"render.material_enable": "GPUマテリアル設定を使用",
|
||||
"render.material_filter": "シーンのボディを絞り込み…",
|
||||
"render.material_filter_help": "一致するボディを最大128件表示します。大きなシーンでは絞り込みを調整してください。",
|
||||
"render.material_glass": "ガラスと光吸収",
|
||||
"render.material_glass_enable": "このボディに物理ガラスを使用",
|
||||
"render.material_glass_exclusive": "このレンダラーでは同じボディにガラスとクリアコートまたはマップを併用できません。",
|
||||
"render.material_glass_help": "独自の参考レシピです。色見本は透過率を示し、レンダー画像ではありません。吸収係数は−ln(線形透過率)/基準距離で計算し、アルファは変更しません。",
|
||||
"render.material_gpu_required": "有効な設定にはGPUパストレーシングが必要です。確認・開始の前にGPUを選ぶか設定を無効にしてください。",
|
||||
"render.material_ior": "屈折率(IOR)",
|
||||
"render.material_limits": "最大 128 件のボディ設定、32 個の分離したガラス、64 層のコート、128 件のテクスチャ関連付け。同一マップはメモリを共有します。実際のデバイスと総メモリの制限は有効です。",
|
||||
"render.material_map_invalid": "マップは長さ制限内のローカルパスを指定し、法線強度は0~1の有限値にしてください。",
|
||||
"render.material_map_required": "マップを使う前にカラー画像または法線画像を選んでください。",
|
||||
"render.material_maps": "平面カラーマップと法線マップ",
|
||||
"render.material_maps_enable": "この不透明ボディのマップを有効化",
|
||||
"render.material_maps_help": "PNG/JPEGは最大1024×1024、符号化データ合計16 MiB。U/Vはワールドmmで直交する周期ベクトル(最大128周期)。色はsRGB、法線はOpenGL +Yです。確認・開始時にファイルを取得します。",
|
||||
"render.material_metallic_map": "金属度マップ(リニア)",
|
||||
"render.material_normal_map": "法線画像(OpenGL、+Y)",
|
||||
"render.material_normal_strength": "法線の強さ(0~1)",
|
||||
"render.material_origin": "マップ原点 X・Y・Z(mm)",
|
||||
"render.material_refresh": "シーンのボディを更新",
|
||||
"render.material_refresh_needed": "シーンが変更されました。対象追加の前に一覧を更新してください。",
|
||||
"render.material_remove": "この割り当てを削除",
|
||||
"render.material_repeat_u": "U方向の1周期 X・Y・Z(mm)",
|
||||
"render.material_repeat_v": "V方向の1周期 X・Y・Z(mm)",
|
||||
"render.material_revalidate": "このボディを再確認",
|
||||
"render.material_revalidate_needed": "以前のシーン版への割り当てです。レンダー前にボディの識別情報を再確認してください。",
|
||||
"render.material_roughness": "コート粗さ(0.045~1)",
|
||||
"render.material_roughness_map": "粗さマップ(リニア)",
|
||||
"render.material_shadow": "直進するシャドウレイを透過",
|
||||
"render.material_target_missing": "ボディの順序と名前が一致しません。この割り当てを削除して対象を選び直してください。",
|
||||
"render.material_thickness": "薄板の厚さ(mm)",
|
||||
"render.material_thin": "薄板",
|
||||
"render.material_title": "GPU画像のマテリアル",
|
||||
"render.material_transient": "この文書タブの一時的な光学設定です。設計、レンダー設定、マテリアルライブラリには保存されません。",
|
||||
"render.material_v_up": "テクスチャV軸は画像の上向き",
|
||||
"render.material_weight": "コートの重み(0~1)",
|
||||
"render.method_cpu": "CPU レイトレーシング",
|
||||
"render.method_gpu": "GPU パストレーシング",
|
||||
"render.method_limit_raster": "ラスターは固定の不透明スタジオプレビューを使用します。対応する光学設定には明示的なレイトレーシング方式を選択してください。",
|
||||
"render.method_raster": "CPU ラスター",
|
||||
"render.navigation_help": "カメラはデザインと同じように動きます(環境設定 › ナビゲーション)。「セットアップを保存」で現在のカメラを記録します。",
|
||||
"render.nested_enable": "検証済み入れ子誘電体",
|
||||
"render.nested_help": "最大16層。親は凸形状、子は厳密に内部である必要があります。交差・接触・薄膜・直線透過影は拒否します。内部カメラは検証した階層を使います。液面の生成や接触するCAD境界の結合は行いません。",
|
||||
"render.opaque_image_summary": "プレビューPNG · 不透明PBR · アルファ合成の透明表示",
|
||||
"render.opaque_preview_help": "不透明PBRと単色表示、アルファ合成による透明表示に対応します。屈折、HDRI、最終レンダリングにはまだ対応していません。",
|
||||
"render.optics_remove": "保存済み光学設定を削除",
|
||||
"render.optics_replace": "対象の保存済み光学設定を明示的に置換",
|
||||
"render.optics_save": "この光学設定を撮影に保存",
|
||||
"render.optics_saved": "保存済み光学対象",
|
||||
"render.optics_saved_help": "定義・フィーチャー・配置の正確な識別子をオフライン再開時も保持します。欠落・置換・非表示の対象は拒否し、工学材料は変更しません。削除前に数値編集を保存または破棄してください。",
|
||||
"render.output_format_status": "PNGは完了した表示画像そのものです。GPUの任意EXRは表示フィルター前の生の線形FLOAT32放射輝度を保持します。プレビューキャッシュや別ジョブへの置換はありません。",
|
||||
"render.output_lock_ratio": "縦横比を固定",
|
||||
"render.output_over_budget": "要求画像が選択したリソース枠を超えています。対応するサイズかプロファイルを明示的に選択してください。自動的な品質低下は行いません。",
|
||||
"render.output_ratio_refused": "連動する寸法が方式の上限を超えます。以前のサイズを維持します。縦横比固定を解除するか、小さい値を選択してください。",
|
||||
"render.output_swap_orientation": "幅と高さを交換",
|
||||
"render.page_aging": "エイジング・付着物",
|
||||
"render.page_all": "全コントロール",
|
||||
"render.page_appearance": "外観",
|
||||
"render.page_background": "背景",
|
||||
"render.page_camera": "カメラ",
|
||||
"render.page_diagnostics": "診断",
|
||||
"render.page_effects": "レンズ・仕上げ効果",
|
||||
"render.page_environment": "環境",
|
||||
"render.page_lighting": "照明",
|
||||
"render.page_output": "出力",
|
||||
"render.page_scene": "シーン",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "透視投影カメラ",
|
||||
"render.physical_acknowledge": "I understand this partial reference needs grade, condition and source review",
|
||||
"render.physical_associations": "Physical candidates and roles",
|
||||
"render.physical_background_help": "カメラ背景とは別の実際の受動的な床と壁です。サイクロラマは24枚の多角形帯で近似し、無限面や解析的な滑面ではありません。保存済みステージの置換には確認が必要です。",
|
||||
"render.physical_copy_plan": "Copy plan with sources and omissions",
|
||||
"render.physical_cyclorama": "多角形サイクロラマをフィット",
|
||||
"render.physical_floor_wall": "物理的な床と壁をフィット",
|
||||
"render.physical_material_name": "Proposed reference material name",
|
||||
"render.physical_omissions": "Properties not representable in the native card",
|
||||
"render.physical_plan_only": "Read-only plan prepared. No material was created or assigned. Keep its extended profile and omissions when reviewing the native card.",
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.post_contrast": "コントラスト",
|
||||
"render.post_gain_b": "青ゲイン",
|
||||
"render.post_gain_g": "緑ゲイン",
|
||||
"render.post_gain_r": "赤ゲイン",
|
||||
"render.post_help": "表示専用の調整です。RGB ゲインはトーンマッピング前、コントラスト・彩度・ビネットは後に適用します。レンダーは新しいサンプルを生成し、再調整は保持した生マスターを使い、ノイズ除去も光線追跡も行いません。",
|
||||
"render.post_reset": "表示フィルターをリセット",
|
||||
"render.post_saturation": "彩度",
|
||||
"render.post_title": "表示フィルター",
|
||||
"render.post_vignette": "ビネット",
|
||||
"render.preview": "統合プレビュー",
|
||||
"render.preview_help": "ラスタシェーディングとブレンド透明度を使用します。屈折、HDRI、最終レンダリングはまだ利用できません。",
|
||||
"render.preview_image_settings_help": "ライブプレビューは固定のスタジオ照明を使用します。画像の露出と照明は、確認または開始時に画像ジョブへ適用されます。",
|
||||
"render.preview_retry": "ライブプレビューを再試行",
|
||||
"render.preview_unavailable_help": "ライブプレビューは利用できません。保存設定と画像ジョブの操作は使用できます。シーンを変更するか明示的に再試行してください。拒否されたシーンを毎フレーム再構築しません。",
|
||||
"render.preview_upload": "ライブプレビューの頂点データ量",
|
||||
"render.preview_upload_help": "プレビュー頂点の正確なバイト数です。GPU全体やプロセス全体のメモリ量ではありません。形状は簡略化せず、画像ジョブは独自の准入と照明を使用します。",
|
||||
"render.progressive_image_summary": "プレビューPNG · 不透明PBR · プログレッシブサンプリング",
|
||||
"render.quality_ack": "固定予算への部分適用と省略項目を確認",
|
||||
"render.quality_apply": "この固定サンプリング予算を使用",
|
||||
"render.quality_projection_help": "Qプリセットには将来の要件も含まれます。この操作は対応する固定サンプルPNG予算のみを適用し、適応的停止、生の線形出力、独立した透過制限は含みません。",
|
||||
"render.quality_review": "サンプリング予算を確認",
|
||||
"render.queue_pending": "このUIには自動の本番キューやアニメーションレンダラーはありません。完了した静止画像は個別に書き出せます。",
|
||||
"render.radial_distortion": "放射状歪み",
|
||||
"render.regrade_action": "生マスターを再調整(ノイズ除去なし)",
|
||||
"render.regrade_help": "選択した完了済み生マスターから、この表示設定で別の PNG を作成します。光線追跡、撮影サイズ・カメラ・照明の変更、EXR の上書きは行いません。ガイドを保持しないためノイズ除去は再適用しません。通常のジョブ操作で書き出せます。",
|
||||
"render.reload_settings": "保存した設定を再読み込み",
|
||||
"render.replace_ground": "既存ステージの置換を確認",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "保存したカメラを復元",
|
||||
"render.result_actual_help": "画像の1ピクセルを画面の1ピクセルで表示します。",
|
||||
"render.result_capture": "キャプチャ時のリビジョン",
|
||||
"render.result_current": "キャプチャしたモデルのリビジョンは最新です。",
|
||||
"render.result_empty": "完成した画像はまだありません。設定を確認してレンダリングを開始してください。",
|
||||
"render.result_fit": "画像全体を表示",
|
||||
"render.result_job": "ジョブ",
|
||||
"render.result_navigation": "移動とズームはナビゲーション設定に従います。スペースキーを押しながらドラッグすると移動します。",
|
||||
"render.result_open": "完成した画像をメインキャンバスに表示します。",
|
||||
"render.result_preview": "ライブプレビュー",
|
||||
"render.result_provisional": "CPU仮画像",
|
||||
"render.result_provisional_help": "この中間画像はエクスポートできません。最後に完成した結果をエクスポートします。キャンセルするとその結果に戻ります。",
|
||||
"render.result_reduced_display": "表示プレビューをビューポート機器またはキャッシュの上限に縮小しています。保持したPNGと書き出しは元の解像度です。この縮小表示ではネイティブ100%表示はできません。",
|
||||
"render.result_retained": "最後に完成した画像を表示しています。新しいレンダリングにはまだ置き換わっていません。",
|
||||
"render.result_sequence": "中間結果",
|
||||
"render.result_title": "レンダリング結果",
|
||||
"render.return_design": "設計に戻る",
|
||||
"render.review_stale": "この確認結果は古くなっています。適用前に再解決または再確認してください。",
|
||||
"render.ribbon_aging": "エイジング",
|
||||
"render.ribbon_backgrounds": "背景",
|
||||
"render.ribbon_check": "確認",
|
||||
"render.ribbon_check_help": "レンダーに送信する現在の設定をそのまま検証します。暗黙のエンジン変更、縮小、リソース置換は行いません。",
|
||||
"render.ribbon_edit_lights": "照明を編集",
|
||||
"render.ribbon_effects": "効果",
|
||||
"render.ribbon_environment_help": "HDR照明、カメラ専用背景、物理ステージは独立しており、置換には明示的な確認が必要です。",
|
||||
"render.ribbon_finish_dialog": "先にファイルまたは確認ダイアログを完了してください。",
|
||||
"render.ribbon_frame": "フレーム合わせ",
|
||||
"render.ribbon_hdr_library": "HDRライブラリ",
|
||||
"render.ribbon_job_active": "レンダーが実行中です。次の開始前に明示的にキャンセルしてください。",
|
||||
"render.ribbon_light_rigs": "照明セット",
|
||||
"render.ribbon_lights_help": "照明セットを確認、または対応ライトを編集します。明示的な適用まで現在の設定は置換されません。",
|
||||
"render.ribbon_materials": "マテリアル",
|
||||
"render.ribbon_materials_help": "共通の外観インスペクターとオリジナル表面ライブラリを開きます。光学編集が工学特性を無断で変更することはありません。",
|
||||
"render.ribbon_no_active_job": "キャンセルする実行中のレンダーはありません。",
|
||||
"render.ribbon_no_result": "画像の書き出しにはレンダーの完了が必要です。",
|
||||
"render.ribbon_no_saved_camera": "カメラを復元する前にショットを保存してください。",
|
||||
"render.ribbon_saved_camera": "保存カメラ",
|
||||
"render.ribbon_shots": "ショット",
|
||||
"render.ribbon_studios": "スタジオ",
|
||||
"render.ribbon_studios_help": "実装済みスタジオを参照し、適用前に置換対象を確認します。構想のみのシーンは区別されます。",
|
||||
"render.ribbon_surface_maps": "表面マップ",
|
||||
"render.sampling_title": "適応・透過サンプリング",
|
||||
"render.save_continue": "保存して続行",
|
||||
"render.save_setup": "セットアップを保存",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.scene_apply": "確認したスタジオを適用",
|
||||
"render.scene_consent": "照明・環境・露出・ステージの置換を確認",
|
||||
"render.scene_preserved_fields": "カメラ、サンプル設定、画像寸法、光学割り当て、CAD形状、工学材料は保持されます。",
|
||||
"render.scene_preserves_design": "表示対象に照明と受動的なステージを構成します。形状、工学材料、カメラは独立して保持します。",
|
||||
"render.scene_replaces": "置換対象",
|
||||
"render.scene_review": "解決して確認",
|
||||
"render.scene_review_help": "適用前にネイティブ構成の全体を確認してください。未接続の高度なSCENE仕様への暗黙の置換はありません。",
|
||||
"render.scene_scope_details": "構成の範囲",
|
||||
"render.setup_legacy_environment": "この旧設定には従来の環境回転または強度が含まれています。値は保持されます。画像ジョブ全体を保存する前に明示的に変換してください。",
|
||||
"render.setup_name": "セットアップ名",
|
||||
"render.setup_numeric_help": "保存すると、選択中の画像方式とその数値設定をすべて保存します。再読み込みや別の設定の選択で下書きを置き換えます。カメラは別途復元します。",
|
||||
"render.setup_offline_help": "レンダラーがなくても、この方式の設定を編集・保存できます。確認と開始には利用可能なホストが必要です。",
|
||||
"render.setup_runtime_unsupported": "このジョブにはマップまたはシーンのボディへの割り当てが含まれるため、全体を保存できません。移植可能な設定を保存する前に、一時入力を削除してください。",
|
||||
"render.setup_save_missing": "コマンド完了後に保存済みレンダリング設定を見つけられませんでした。",
|
||||
"render.sharpening": "ディテールのシャープ化",
|
||||
"render.shot_duplicate": "保存済みショットを複製",
|
||||
"render.shot_manager": "保存済みショット",
|
||||
"render.shot_new_name": "新しいショット名",
|
||||
"render.shot_remove": "保存済みショットを削除",
|
||||
"render.shot_remove_help": "この保存設定だけを削除します。元の形状と完了画像は保持され、操作は取り消せます。",
|
||||
"render.shot_remove_title": "保存済みショットを削除しますか?",
|
||||
"render.shot_rename": "保存済みショットの名前を変更",
|
||||
"render.shot_saved_only": "先に現在の下書きを保存してください。複製と名前変更では正確な保存オプションとリソース参照を保持します。",
|
||||
"render.sky_ground": "地面・線形RGB",
|
||||
"render.sky_horizon": "地平線・線形RGB",
|
||||
"render.sky_zenith": "天頂・線形RGB",
|
||||
"render.soft_focus": "ソフトフォーカス",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.studio_add_area": "エリアライトを追加",
|
||||
"render.studio_ambient": "一定の環境放射輝度",
|
||||
"render.studio_ambient_rgb": "一定の環境放射輝度(リニアRGB)",
|
||||
"render.studio_aperture": "開口半径",
|
||||
"render.studio_area": "エリアライト",
|
||||
"render.studio_area_help": "最大 4 個の片面矩形です。直交する半辺 U と V でサイズを定め、U × V が発光方向になります。座標はワールド空間の mm です。",
|
||||
"render.studio_center": "中心 X, Y, Z (mm)",
|
||||
"render.studio_denoise": "完成画像のノイズを低減",
|
||||
"render.studio_denoise_help": "輪郭を保持する最終フィルターです。微細な描写が柔らかくなることがあります。ガラスと鋭い鏡面反射は対象外です。",
|
||||
"render.studio_direction": "太陽に向かう方向 (X, Y, Z)",
|
||||
"render.studio_environment": "環境",
|
||||
"render.studio_environment_bounds": "環境回転は±1,000,000ラジアン以内の有限値、強度は0~100でなければなりません。",
|
||||
"render.studio_environment_none": "環境マップなし",
|
||||
"render.studio_focus": "光軸上の焦点距離",
|
||||
"render.studio_half_u": "半辺 U (mm)",
|
||||
"render.studio_half_v": "半辺 V (mm)",
|
||||
"render.studio_hdr": "Radiance HDR ファイル",
|
||||
"render.studio_hdr_browse": "HDR を選択…",
|
||||
"render.studio_hdr_help": "Radiance .hdr、2:1 パノラマ、最大 2048 × 1024。EXR 非対応です。色の仮定は原色未指定の場合のみ適用します。",
|
||||
"render.studio_hdr_required": "ローカルの .hdr ファイルを選択してください。",
|
||||
"render.studio_hdr_srgb": "未指定の原色をリニア sRGB として解釈",
|
||||
"render.studio_intensity": "環境の強度",
|
||||
"render.studio_lens": "被写界深度",
|
||||
"render.studio_lens_perspective": "被写界深度には透視投影カメラが必要です。",
|
||||
"render.studio_lighting": "スタジオ照明",
|
||||
"render.studio_lighting_enable": "カスタムスタジオ照明を使用",
|
||||
"render.studio_needs_review": "方式と設定を確認",
|
||||
"render.studio_radiance": "リニア RGB 放射輝度",
|
||||
"render.studio_ready": "確認の準備完了",
|
||||
"render.studio_remove_area": "エリアライトを削除",
|
||||
"render.studio_rotation": "環境の回転",
|
||||
"render.studio_runtime_help": "スタジオの数値設定と確認済みHDRは設定とともに保存できます。ボディの光学・マテリアル上書きは一時設定のままで、保存済みの外観を変更しません。",
|
||||
"render.studio_saved": "保存設定/現在のカメラ",
|
||||
"render.studio_sky": "アーティスティックな空",
|
||||
"render.studio_sky_help": "照明用のオリジナル空グラデーションです。校正された大気モデルではありません。",
|
||||
"render.studio_sun": "太陽",
|
||||
"render.studio_sun_radius": "角半径",
|
||||
"render.studio_title": "レンダースタジオ",
|
||||
"render.studio_tone_map": "トーンマッピング",
|
||||
"render.subsurface_enable": "内部散乱ランダムウォーク",
|
||||
"render.subsurface_help": "閉じた誘電体専用。散乱とRGB吸収は別々の毎mm係数です。実際の形状内で散乱し、境界で屈折・反射します。直線透過影、表面ノイズ除去、外部ボリュームを無効にし、フレネル層数を1にします。拡散シェーダー、密度グリッド、実測物性ではありません。高密度ではサンプル数と深度が必要です。",
|
||||
"render.subsurface_rate": "散乱衝突率",
|
||||
"render.transmission_scope": "GPUガラスは検証された非交差媒体に対応します。無制限の入れ子媒体やノイズのない透過推定器は提供しません。",
|
||||
"render.transmission_strata": "条件付きフレネル層数",
|
||||
"render.transmission_strata_help": "1 は従来の系列を保持します。2 または4経路で最初のガラス反射・透過の選択を層化します。スネル則と吸収則は不変です。処理量は増えます。ノイズ除去、入れ子媒質、高速化の保証ではありません。",
|
||||
"render.unavailable_preview": "このセットアップは利用できないプレビュープロファイルを要求しています。",
|
||||
"render.unsaved": "未保存のプレビュー変更",
|
||||
"render.use_preview": "統合プレビューを使用",
|
||||
"render.volume_albedo": "散乱アルベド · リニア RGB",
|
||||
"render.volume_anisotropy": "位相関数の平均余弦",
|
||||
"render.volume_enable": "散乱媒質を有効にする",
|
||||
"render.volume_extinction": "消散係数",
|
||||
"render.volume_help": "有限の箱内で GPU による Beer 減衰と HG 散乱をカメラ・間接経路に適用します。明示したスタジオ照明・HDR・空を使い、影も減衰します。平均余弦が正なら前方散乱です。ガラス境界と表面ノイズ除去は明示的に無効化してください。消散ゼロは従来の輸送を保持します。月の大気、密度グリッド、体積発光、分光輸送、認証済み物性ではありません。",
|
||||
"render.volume_max": "最大境界 · ワールド mm",
|
||||
"render.volume_min": "最小境界 · ワールド mm",
|
||||
"render.volume_title": "有限の均一ボリューム",
|
||||
"sample.bracket.about": "2 mm の板金ルールによるベース フランジ、エッジ フランジ、ヘミング",
|
||||
"sample.bracket.name": "板金ブラケット",
|
||||
"sample.enclosure.about": "リップ、ねじボス、レスト、スナップ フィットを備えたシェル化した直方体",
|
||||
@@ -1469,6 +2118,10 @@
|
||||
"toolbar.customize_note": "{tab}タブ。コマンドにチェックを入れると、ツールバーにボタンが追加されます。パネルのドロップダウンの行をツールバーにドラッグしたり、ボタンをツールバーの外にドラッグして削除したり、ドロップダウンの行のピンを使うこともできます。",
|
||||
"toolbar.image": "画像",
|
||||
"toolbar.render": "レンダリング",
|
||||
"toolbar.render_appearance": "外観",
|
||||
"toolbar.render_camera": "カメラ",
|
||||
"toolbar.render_environment": "環境",
|
||||
"toolbar.render_lighting": "照明",
|
||||
"toolbar.render_scene": "シーン",
|
||||
"trace.points": "経路上の {count} 点",
|
||||
"trace.stopped_by_contact": "サンプル {sample} で終了: {a} が {b} を通り抜けてしまいます",
|
||||
@@ -1587,6 +2240,8 @@
|
||||
"ui.agent_chat_allowed": "許可しました",
|
||||
"ui.agent_chat_answered": "回答: {option}",
|
||||
"ui.agent_chat_approval": "エージェントにこの操作を許可しますか?",
|
||||
"ui.agent_chat_attach_selection": "選択を添付",
|
||||
"ui.agent_chat_attach_selection_tip": "モデルで選択中のもの(面、エッジ、フィーチャ、ボディ)をメッセージと一緒に送り、何を指しているかをエージェントに伝えます",
|
||||
"ui.agent_chat_attach_view": "ビューを添付",
|
||||
"ui.agent_chat_attach_view_tip": "現在のビューの画像をメッセージと一緒に送ります",
|
||||
"ui.agent_chat_attachable": "画像・PDF・テキスト・CAD ファイル",
|
||||
@@ -1604,6 +2259,11 @@
|
||||
"ui.agent_chat_command": "エージェントのコマンド",
|
||||
"ui.agent_chat_connect": "接続",
|
||||
"ui.agent_chat_copy": "コピー",
|
||||
"ui.agent_chat_ctx_bodies": "ボディ",
|
||||
"ui.agent_chat_ctx_elements": "要素",
|
||||
"ui.agent_chat_ctx_features": "フィーチャ",
|
||||
"ui.agent_chat_ctx_more": "ほか{n}件",
|
||||
"ui.agent_chat_ctx_other": "その他",
|
||||
"ui.agent_chat_custom_hint": "標準入出力で Agent Client Protocol を話す任意のプログラム。シェルは使いません。",
|
||||
"ui.agent_chat_denied": "拒否しました",
|
||||
"ui.agent_chat_deny": "拒否",
|
||||
@@ -1662,6 +2322,8 @@
|
||||
"ui.agent_chat_paste_picture": "画像を貼り付け",
|
||||
"ui.agent_chat_permission": "エージェントが実行の許可を求めています: {title}",
|
||||
"ui.agent_chat_pick": "エージェント",
|
||||
"ui.agent_chat_pick_context": "コンテキストを選ぶ",
|
||||
"ui.agent_chat_pick_context_tip": "エージェントに見てほしい面、エッジ、フィーチャ、ボディをモデルから選び、OK を押します",
|
||||
"ui.agent_chat_placeholder": "デザインの変更をエージェントに依頼…",
|
||||
"ui.agent_chat_placeholder_busy": "エージェントの作業が終わったら送るメッセージを入力(Ctrl+Enter: 今すぐ送信)",
|
||||
"ui.agent_chat_pop_out": "独立したウィンドウで開く(別の画面に移動できます)",
|
||||
@@ -2043,6 +2705,8 @@
|
||||
"ui.hideOrigin": "原点を非表示",
|
||||
"ui.hidePlanes": "平面を非表示",
|
||||
"ui.hideProfile": "プロファイルを非表示",
|
||||
"ui.hide_origin_by_default": "原点を既定で非表示",
|
||||
"ui.hide_origin_note": "新しいデザインは原点フォルダーを非表示にして始まります。原点の表示/非表示を切り替えたデザインは、その設定を保持します。",
|
||||
"ui.history_back": "1ステップ戻る",
|
||||
"ui.history_below_browser": "ブラウザーの下",
|
||||
"ui.history_edge_hint": "端をダブルクリック",
|
||||
@@ -2061,6 +2725,7 @@
|
||||
"ui.hole_type": "穴タイプ",
|
||||
"ui.home": "ホーム",
|
||||
"ui.homeView": "ホームビュー",
|
||||
"ui.horizontal_constraint": "水平拘束",
|
||||
"ui.horizontal_vertical": "水平/垂直",
|
||||
"ui.import_ellipsis": "インポート…",
|
||||
"ui.infinite": "無限",
|
||||
@@ -2341,6 +3006,7 @@
|
||||
"ui.untitled": "無題",
|
||||
"ui.up_axis_note": "ビュー(軸ビュー、ホーム、正面視)で上向きにする軸を指定します。デザインデータ自体は変更されません。",
|
||||
"ui.updateToCurrentView": "現在のビューに更新",
|
||||
"ui.vertical_constraint": "垂直拘束",
|
||||
"ui.view_centre": "ビュー中心",
|
||||
"ui.visual_shaded_hidden_edges": "隠線付きシェーディング",
|
||||
"ui.visual_shaded_with_edges": "エッジ付きシェーディング",
|
||||
|
||||
+131
-1
@@ -72,6 +72,7 @@
|
||||
"Choose…": "선택…",
|
||||
"Circular": "원형",
|
||||
"Circumference": "원주",
|
||||
"Clockwise": "시계 방향",
|
||||
"Close draft": "초안 닫기",
|
||||
"Collisions": "충돌",
|
||||
"Colour": "색상",
|
||||
@@ -323,6 +324,7 @@
|
||||
"Search commands": "명령 검색",
|
||||
"Search this library": "이 라이브러리 검색",
|
||||
"Section": "단면",
|
||||
"Section position": "단면 위치",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "다른 항목 선택: 모델 위에서 왼쪽 버튼을 가만히 누르고 있거나(또는 오른쪽 클릭 › 다른 항목 선택…) 커서 아래의 모든 항목을 나열합니다. 같은 위치를 다시 클릭하면 다음 항목이 선택됩니다. 가운데 버튼을 더블 클릭하면 홈으로 이동합니다(환경설정 › 탐색).",
|
||||
"Select bodies (a face picks its body)": "바디 선택(면을 클릭하면 해당 바디 선택)",
|
||||
"Select bodies or faces instead": "대신 바디 또는 면을 선택하세요",
|
||||
@@ -346,9 +348,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "이 디자인들이 저장되기 전에 SolidCraft가 종료되었습니다. 마지막 자동 저장본을 열 수 있습니다.",
|
||||
"Specialise": "특수화",
|
||||
"Speed": "속도",
|
||||
"Square": "정사각형",
|
||||
"Stand it up": "세우기",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "세우기: X축 기준 90도 회전으로, 실행 취소할 수 있는 하나의 이동 피처로 적용됩니다.",
|
||||
"Stand this part up?": "이 부품을 세울까요?",
|
||||
"Start angle": "시작 각도",
|
||||
"Start bulge": "시작 벌지",
|
||||
"Start continuity": "시작 연속성",
|
||||
"Step": "단계",
|
||||
@@ -413,6 +417,7 @@
|
||||
"angle, height": "각도, 높이",
|
||||
"appearance.dielectric_ior": "유전체 굴절률",
|
||||
"appearance.metallic": "금속성",
|
||||
"appearance.only_available": "사용 가능한 외관만",
|
||||
"appearance.pbr_help": "이 표면은 렌더링 작업 공간이나 제품 PNG에서 확인하세요. 굴절과 투과는 지원하지 않습니다.",
|
||||
"appearance.pbr_opaque": "불투명 PBR",
|
||||
"appearance.roughness": "거칠기",
|
||||
@@ -574,6 +579,7 @@
|
||||
"cmd.material_create": "새 물리 재질",
|
||||
"cmd.material_delete": "물리 재질 삭제",
|
||||
"cmd.material_edit": "물리 재질 편집",
|
||||
"cmd.material_inspect": "물리 재질 검사",
|
||||
"cmd.material_list": "재질 목록",
|
||||
"cmd.material_properties_directional": "방향별 탄성 계수",
|
||||
"cmd.material_properties_validate": "물리 재질 데이터 검증",
|
||||
@@ -620,13 +626,32 @@
|
||||
"cmd.plastic_rules": "플라스틱 규칙 목록",
|
||||
"cmd.plastic_snap_fit": "스냅핏",
|
||||
"cmd.render_backends": "렌더링 백엔드",
|
||||
"cmd.render_camera_fit": "렌더 대상 화면 맞춤",
|
||||
"cmd.render_camera_get": "렌더 카메라 확인",
|
||||
"cmd.render_cancel": "렌더링 취소",
|
||||
"cmd.render_export": "PNG 내보내기",
|
||||
"cmd.render_hdr_inspect": "HDR 소스 검사",
|
||||
"cmd.render_library_appearance_apply": "라이브러리 불투명 외관 적용",
|
||||
"cmd.render_library_describe": "렌더 리소스 검사",
|
||||
"cmd.render_library_environment_apply": "내장 HDR 환경 적용",
|
||||
"cmd.render_library_list": "렌더 라이브러리 탐색",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_studio_apply": "제작된 스튜디오 조명 적용",
|
||||
"cmd.render_library_studio_prepare": "제작된 스튜디오 조명 준비",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "제작된 표면 맵 준비",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "렌더 리소스 대상 찾기",
|
||||
"cmd.render_preflight": "렌더 요청 확인",
|
||||
"cmd.render_result_pin": "표시된 렌더 결과 유지",
|
||||
"cmd.render_scene": "렌더링 장면 검사",
|
||||
"cmd.render_settings_apply": "렌더링 카메라 적용",
|
||||
"cmd.render_settings_capture_hdr": "HDR과 렌더 설정 저장",
|
||||
"cmd.render_settings_get": "렌더링 설정",
|
||||
"cmd.render_settings_set": "렌더링 설정 저장",
|
||||
"cmd.render_stage_backdrop": "물리 렌더 배경 저장",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
"cmd.render_start": "이미지 렌더링",
|
||||
"cmd.render_status": "렌더링 진행 상황",
|
||||
"cmd.select_clear": "선택 지우기",
|
||||
@@ -1004,13 +1029,33 @@
|
||||
"recovery.just_now": "방금",
|
||||
"recovery.min_ago": "{count}분 전",
|
||||
"recovery.never_saved": "저장된 적 없음",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.background": "장면 배경",
|
||||
"render.bloom_enable": "표시 블룸",
|
||||
"render.bloom_help": "양의 선형 하이라이트를 세 번의 정규화 필터로 확산하는 출력 전용 효과입니다. 반경은 출력 픽셀 단위이며 sRGB 전에 더합니다. 렌즈·볼륨·수렴 개선이 아니며 원본 EXR은 변하지 않습니다.",
|
||||
"render.bloom_opaque": "블룸에는 불투명 출력이 필요합니다. 투명 PNG를 몰래 합성하지 않고 거부합니다.",
|
||||
"render.bloom_radius": "블룸 반경",
|
||||
"render.bloom_strength": "블룸 강도",
|
||||
"render.bloom_threshold": "선형 하이라이트 임계값",
|
||||
"render.clear_stage": "Remove saved stage",
|
||||
"render.cpu_budget": "CPU 리소스 프로필",
|
||||
"render.cpu_budget_bodies": "바디 수 상한",
|
||||
"render.cpu_budget_compact": "컴팩트 (기존 제한)",
|
||||
"render.cpu_budget_details": "리소스 제한",
|
||||
"render.cpu_budget_help": "더 큰 제한은 명시적으로 선택합니다. 해상도와 샘플 수를 자동으로 줄이지 않습니다.",
|
||||
"render.cpu_budget_memory": "작업 메모리 상한",
|
||||
"render.cpu_budget_not_guarantee": "이 값은 허용 상한이며 RAM 예약이나 속도 보장이 아닙니다. 형상, 필름, 보관된 미리보기가 메모리 예산을 공유합니다. 렌더링은 취소할 수 있습니다.",
|
||||
"render.cpu_budget_resize": "설정이 CPU 프로필이나 카메라 샘플 예산을 초과합니다. 더 작은 크기를 명시적으로 적용하거나 더 큰 프로필을 선택하세요.",
|
||||
"render.cpu_budget_studio": "스튜디오 (큰 이미지)",
|
||||
"render.cpu_budget_triangles": "삼각형 수 상한",
|
||||
"render.cpu_budget_workstation": "워크스테이션 (대규모 장면)",
|
||||
"render.exr_pending": "GPU는 원본 선형 EXR을 보존할 수 있습니다. 압축, 다중 레이어 이미지 및 보조 렌더 패스는 아직 사용할 수 없습니다.",
|
||||
"render.fit": "제품에 맞추기",
|
||||
"render.image_cancelled": "렌더링 취소됨",
|
||||
"render.image_cancelling": "취소 중",
|
||||
"render.image_completed": "이미지 내보내기 준비됨",
|
||||
"render.image_encoding": "PNG 인코딩 중",
|
||||
"render.image_export": "PNG 내보내기",
|
||||
"render.image_export": "완료된 이미지 내보내기",
|
||||
"render.image_failed": "렌더링 실패",
|
||||
"render.image_height": "높이",
|
||||
"render.image_help": "CPU 미리 보기 이미지 · PNG · 근사 투명도",
|
||||
@@ -1028,17 +1073,98 @@
|
||||
"render.image_unknown": "렌더 상태를 확인할 수 없습니다",
|
||||
"render.image_use_largest": "이 비율에서 가장 큰 크기 사용:",
|
||||
"render.image_width": "너비",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.library_applied": "리소스 변환을 적용했습니다. 시작 전에 전체 렌더 요청을 확인하세요.",
|
||||
"render.library_apply_hdr": "이 HDR 환경과 함께 저장",
|
||||
"render.library_apply_maps": "제작된 GPU 표면 맵 사용",
|
||||
"render.library_apply_studio": "제작된 스튜디오 변환 저장",
|
||||
"render.library_apply_uniform": "균일한 불투명 외관 적용",
|
||||
"render.library_authored_help": "독자적으로 제작한 리소스는 표현용이며 측정된 공학 데이터가 아닙니다. 각 동작은 명시된 변환만 적용합니다.",
|
||||
"render.library_blocked": "이 리소스에는 미해결 보정 또는 외부 태양 광원이 필요하여 아직 적용할 수 없습니다.",
|
||||
"render.library_center": "리그 중심",
|
||||
"render.library_emitters_only_ack": "광원만 사용하고 명시된 수동 반사판은 생략",
|
||||
"render.library_environment_concepts": "환경 구상",
|
||||
"render.library_extent": "대상 크기",
|
||||
"render.library_hdr": "내장 HDR 환경",
|
||||
"render.library_hdr_help": "원본 HDR을 저장 설정에 포함합니다. 제작된 경도 원점을 명시적으로 변환하며 저장 후 외부 파일이 필요하지 않습니다.",
|
||||
"render.library_light_concepts": "조명 구상",
|
||||
"render.library_maps_help": "Built-in maps can be saved with pinned sources and local occurrence mapping. Temporary optical overrides remain a separate mode.",
|
||||
"render.library_material_concepts": "재질 구상",
|
||||
"render.library_next": "다음 페이지",
|
||||
"render.library_physical_profiles": "Physical reference profiles",
|
||||
"render.library_previous": "이전 페이지",
|
||||
"render.library_quality_concepts": "품질 사양",
|
||||
"render.library_replace_environment": "기존 환경을 명시적으로 교체",
|
||||
"render.library_replace_studio": "Replace saved lighting, environment and stage",
|
||||
"render.library_results": "일치하는 리소스",
|
||||
"render.library_rig_help": "Fit once at an explicit center and physical extent. Complete rigs include passive cards; calibration blockers still refuse. Conservative emitter/card clearance is checked before saving.",
|
||||
"render.library_rigs": "제작된 조명 리그",
|
||||
"render.library_save_maps": "Save maps to this setup",
|
||||
"render.library_scene_bounds": "캡처된 장면 범위 사용",
|
||||
"render.library_scenes": "장면 사양",
|
||||
"render.library_search": "라이브러리 검색",
|
||||
"render.library_selene": "SELENE 불투명 외관",
|
||||
"render.library_specification_only": "사양만 제공되며 완전히 실행 가능한 프리셋이 아닙니다. 필요한 효과, 리소스 및 대상 역할은 명시적인 구현과 연결이 필요합니다.",
|
||||
"render.library_surfaces": "제작된 PBR 표면",
|
||||
"render.library_target": "대상 바디",
|
||||
"render.library_title": "렌더 리소스 라이브러리",
|
||||
"render.library_uniform_ack": "공간 변화나 고급 효과 없는 균일 근사 사용",
|
||||
"render.material_color_replace": "기본 맵으로 바디 색상 교체",
|
||||
"render.material_limits": "최대 128개 바디 설정, 분리된 유리 32개, 코팅 64개, 텍스처 연결 128개. 같은 맵은 메모리를 공유하며 실제 장치 및 전체 메모리 제한은 유지됩니다.",
|
||||
"render.material_metallic_map": "금속성 맵 (선형)",
|
||||
"render.material_roughness_map": "거칠기 맵 (선형)",
|
||||
"render.material_v_up": "텍스처 V축은 이미지 위쪽",
|
||||
"render.navigation_help": "카메라는 디자인에서와 같이 움직입니다(환경설정 › 탐색). 설정 저장은 현재 카메라를 기록합니다.",
|
||||
"render.opaque_image_summary": "미리보기 PNG · 불투명 PBR · 블렌딩 투명도",
|
||||
"render.opaque_preview_help": "불투명 PBR 및 단색 표시, 블렌딩 투명도를 지원합니다. 굴절, HDRI 및 최종 렌더링은 아직 지원하지 않습니다.",
|
||||
"render.output_format_status": "PNG는 완료된 표시 이미지 그대로입니다. 선택적 GPU EXR은 표시 필터 전 선형 FLOAT32 방사 휘도를 보존합니다. 미리보기 캐시나 다른 작업으로 바꾸어 내보내지 않습니다.",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "원근 카메라",
|
||||
"render.physical_acknowledge": "I understand this partial reference needs grade, condition and source review",
|
||||
"render.physical_associations": "Physical candidates and roles",
|
||||
"render.physical_copy_plan": "Copy plan with sources and omissions",
|
||||
"render.physical_material_name": "Proposed reference material name",
|
||||
"render.physical_omissions": "Properties not representable in the native card",
|
||||
"render.physical_plan_only": "Read-only plan prepared. No material was created or assigned. Keep its extended profile and omissions when reviewing the native card.",
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.preview": "통합 미리보기",
|
||||
"render.preview_help": "래스터 셰이딩과 블렌딩 투명도를 사용합니다. 굴절, HDRI 및 최종 렌더링은 아직 지원하지 않습니다.",
|
||||
"render.reload_settings": "저장된 설정 다시 불러오기",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "저장된 카메라 복원",
|
||||
"render.result_reduced_display": "표시 미리보기를 뷰포트 장치 또는 캐시 제한에 맞춰 축소했습니다. 보관된 PNG와 내보내기는 전체 해상도를 유지합니다. 이 축소 보기에서는 원본 100% 검사가 불가능합니다.",
|
||||
"render.return_design": "설계로 돌아가기",
|
||||
"render.ribbon_backgrounds": "배경",
|
||||
"render.ribbon_check": "검사",
|
||||
"render.ribbon_check_help": "렌더에 제출할 현재 설정을 그대로 검증합니다. 엔진 전환, 축소, 리소스 교체를 몰래 수행하지 않습니다.",
|
||||
"render.ribbon_edit_lights": "조명 편집",
|
||||
"render.ribbon_environment_help": "HDR 조명, 카메라 전용 배경, 물리 무대는 독립된 설정이며 교체에는 명시적 확인이 필요합니다.",
|
||||
"render.ribbon_finish_dialog": "먼저 파일 또는 확인 대화 상자를 완료하세요.",
|
||||
"render.ribbon_frame": "화면 맞춤",
|
||||
"render.ribbon_hdr_library": "HDR 라이브러리",
|
||||
"render.ribbon_job_active": "렌더링이 진행 중입니다. 새 작업 전에 명시적으로 취소하세요.",
|
||||
"render.ribbon_light_rigs": "조명 구성",
|
||||
"render.ribbon_lights_help": "조명 구성을 검토하거나 지원 조명을 편집합니다. 명시적으로 적용하기 전에는 현재 설정을 교체하지 않습니다.",
|
||||
"render.ribbon_materials": "재질",
|
||||
"render.ribbon_materials_help": "공용 외관 검사기와 원본 표면 라이브러리를 엽니다. 광학 편집은 공학 속성을 임의로 변경하지 않습니다.",
|
||||
"render.ribbon_no_active_job": "취소할 활성 렌더링이 없습니다.",
|
||||
"render.ribbon_no_result": "이미지를 내보내려면 렌더링을 완료하세요.",
|
||||
"render.ribbon_no_saved_camera": "카메라 복원 전에 샷을 저장하세요.",
|
||||
"render.ribbon_saved_camera": "저장 카메라",
|
||||
"render.ribbon_shots": "샷",
|
||||
"render.ribbon_studios": "스튜디오",
|
||||
"render.ribbon_studios_help": "구현된 스튜디오를 찾아보고 적용 전에 교체 항목을 검토합니다. 개념 장면은 구분됩니다.",
|
||||
"render.ribbon_surface_maps": "표면 맵",
|
||||
"render.save_setup": "설정 저장",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.setup_name": "설정 이름",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.unavailable_preview": "이 설정은 사용할 수 없는 미리보기 프로필을 요청합니다.",
|
||||
"render.unsaved": "저장하지 않은 미리보기 변경 사항",
|
||||
"render.use_preview": "통합 미리보기 사용",
|
||||
@@ -1126,6 +1252,10 @@
|
||||
"toolbar.customize_note": "{tab} 탭입니다. 명령을 선택하면 도구 모음에 해당 버튼이 추가됩니다. 패널의 드롭다운에서 행을 도구 모음으로 끌거나, 버튼을 도구 모음 밖으로 끌어 제거하거나, 드롭다운 행의 고정 핀을 사용할 수도 있습니다.",
|
||||
"toolbar.image": "이미지",
|
||||
"toolbar.render": "렌더링",
|
||||
"toolbar.render_appearance": "외관",
|
||||
"toolbar.render_camera": "카메라",
|
||||
"toolbar.render_environment": "환경",
|
||||
"toolbar.render_lighting": "조명",
|
||||
"toolbar.render_scene": "장면",
|
||||
"trace.points": "경로를 따라 {count}개 점",
|
||||
"trace.stopped_by_contact": "샘플 {sample}에서 끝남: {a}이(가) {b}을(를) 통과합니다",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Pilih…",
|
||||
"Circular": "Bulat",
|
||||
"Circumference": "Lilitan",
|
||||
"Clockwise": "Ikut arah jam",
|
||||
"Close draft": "Tutup draf",
|
||||
"Collisions": "Perlanggaran",
|
||||
"Colour": "Warna",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Cari arahan",
|
||||
"Search this library": "Cari dalam koleksi ini",
|
||||
"Section": "Keratan",
|
||||
"Section position": "Kedudukan keratan",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Pilih Lain: tahan butang kiri pada model tanpa bergerak (atau klik kanan › Pilih Lain…) untuk senarai objek di bawah kursor. Klik tempat sama untuk objek seterusnya. Klik dua kali butang tengah untuk ke Utama (Tetapan › Navigasi).",
|
||||
"Select bodies (a face picks its body)": "Pilih jasad (klik muka untuk pilih jasadnya)",
|
||||
"Select bodies or faces instead": "Pilih jasad atau muka",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft ditutup sebelum reka bentuk disimpan. Buka simpanan automatik terakhirnya.",
|
||||
"Specialise": "Khususkan",
|
||||
"Speed": "Kelajuan",
|
||||
"Square": "Segi empat sama",
|
||||
"Stand it up": "Tegakkan",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Tegakkan: suku putaran pada X, satu ciri Alih yang boleh dibatalkan.",
|
||||
"Stand this part up?": "Tegakkan bahagian ini?",
|
||||
"Start angle": "Sudut mula",
|
||||
"Start bulge": "Bonjolan permulaan",
|
||||
"Start continuity": "Keselanjaran permulaan",
|
||||
"Step": "Langkah",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "sudut, ketinggian",
|
||||
"appearance.dielectric_ior": "IOR Dielektrik",
|
||||
"appearance.metallic": "Sifat Logam",
|
||||
"appearance.only_available": "Rupa yang tersedia sahaja",
|
||||
"appearance.pbr_help": "Lihat dalam Render atau PNG produk. Tiada pembiasan atau penembusan cahaya.",
|
||||
"appearance.pbr_opaque": "PBR Legap",
|
||||
"appearance.roughness": "Kekasaran",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Bahan Fizikal Baharu",
|
||||
"cmd.material_delete": "Padam Bahan Fizikal",
|
||||
"cmd.material_edit": "Sunting Bahan Fizikal",
|
||||
"cmd.material_inspect": "Periksa Bahan Fizikal",
|
||||
"cmd.material_list": "Senarai Bahan",
|
||||
"cmd.material_properties_directional": "Modulus Keanjalan Berarah",
|
||||
"cmd.material_properties_validate": "Sahkan Data Bahan Fizikal",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Kiezen…",
|
||||
"Circular": "Cirkelvormig",
|
||||
"Circumference": "Omtrek",
|
||||
"Clockwise": "Met de klok mee",
|
||||
"Close draft": "Concept sluiten",
|
||||
"Collisions": "Botsingen",
|
||||
"Colour": "Kleur",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Opdrachten zoeken",
|
||||
"Search this library": "Deze bibliotheek doorzoeken",
|
||||
"Section": "Doorsnede",
|
||||
"Section position": "Positie van de doorsnede",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Overige selecteren: houd de linkermuisknop stil op het model (of klik met rechts › Overige selecteren…) om alles onder de cursor weer te geven; klik opnieuw op dezelfde plek om het volgende item daar te selecteren. Dubbelklik met de middelste knop om naar Home te gaan (Voorkeuren › Navigatie).",
|
||||
"Select bodies (a face picks its body)": "Lichamen selecteren (een vlak kiest zijn lichaam)",
|
||||
"Select bodies or faces instead": "In plaats daarvan lichamen of vlakken selecteren",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft is gesloten voordat deze ontwerpen zijn opgeslagen. Hun laatste automatische opslag kan worden geopend.",
|
||||
"Specialise": "Specialiseren",
|
||||
"Speed": "Snelheid",
|
||||
"Square": "Vierkant",
|
||||
"Stand it up": "Rechtop zetten",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Rechtop zetten: een kwartslag om X, als één Verplaatsen-kenmerk dat u ongedaan kunt maken.",
|
||||
"Stand this part up?": "Dit onderdeel rechtop zetten?",
|
||||
"Start angle": "Beginhoek",
|
||||
"Start bulge": "Beginbolling",
|
||||
"Start continuity": "Begincontinuïteit",
|
||||
"Step": "Stap",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "hoek, hoogte",
|
||||
"appearance.dielectric_ior": "Diëlektrische IOR",
|
||||
"appearance.metallic": "Metaalachtig",
|
||||
"appearance.only_available": "Alleen beschikbare verschijningen",
|
||||
"appearance.pbr_help": "Bekijk dit oppervlak in Render of een product-PNG. Geen breking of transmissie.",
|
||||
"appearance.pbr_opaque": "Ondoorzichtige PBR",
|
||||
"appearance.roughness": "Ruwheid",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Nieuw fysiek materiaal",
|
||||
"cmd.material_delete": "Fysiek materiaal verwijderen",
|
||||
"cmd.material_edit": "Fysiek materiaal bewerken",
|
||||
"cmd.material_inspect": "Fysiek materiaal inspecteren",
|
||||
"cmd.material_list": "Materialen weergeven",
|
||||
"cmd.material_properties_directional": "Richtingsafhankelijke elasticiteitsmodulus",
|
||||
"cmd.material_properties_validate": "Gegevens fysiek materiaal valideren",
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
"Choose…": "Wybierz…",
|
||||
"Circular": "Kołowy",
|
||||
"Circumference": "Obwód",
|
||||
"Clockwise": "Zgodnie z ruchem wskazówek zegara",
|
||||
"Close draft": "Zamknij szkic zgłoszenia",
|
||||
"Collisions": "Kolizje",
|
||||
"Colour": "Kolor",
|
||||
@@ -339,6 +340,7 @@
|
||||
"Search commands": "Szukaj poleceń",
|
||||
"Search this library": "Przeszukaj tę bibliotekę",
|
||||
"Section": "Przekrój",
|
||||
"Section position": "Położenie przekroju",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Wybierz inny: przytrzymaj nieruchomo lewy przycisk na modelu (lub prawy przycisk › Wybierz inny…), aby wyświetlić wszystko pod kursorem; kliknij ponownie w tym samym miejscu, aby zaznaczyć kolejny obiekt. Dwukrotne kliknięcie środkowym przyciskiem przechodzi do widoku głównego (Preferencje › Nawigacja).",
|
||||
"Select bodies (a face picks its body)": "Zaznacz bryły (ściana wybiera swoją bryłę)",
|
||||
"Select bodies or faces instead": "Zamiast tego zaznacz bryły lub ściany",
|
||||
@@ -362,9 +364,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft zamknął się, zanim te projekty zostały zapisane. Można otworzyć ich ostatni autozapis.",
|
||||
"Specialise": "Uszczegółów",
|
||||
"Speed": "Prędkość",
|
||||
"Square": "Kwadrat",
|
||||
"Stand it up": "Postaw",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Postaw: obrót o ćwierć obrotu wokół osi X, jako jedna funkcja Przesuń, którą można cofnąć.",
|
||||
"Stand this part up?": "Postawić tę część?",
|
||||
"Start angle": "Kąt początkowy",
|
||||
"Start bulge": "Wybrzuszenie początku",
|
||||
"Start continuity": "Ciągłość początku",
|
||||
"Step": "Krok",
|
||||
@@ -460,6 +464,7 @@
|
||||
"angle, height": "kąt, wysokość",
|
||||
"appearance.dielectric_ior": "Współczynnik załamania dielektryka (IOR)",
|
||||
"appearance.metallic": "Metaliczność",
|
||||
"appearance.only_available": "Tylko dostępne wyglądy",
|
||||
"appearance.pbr_help": "Zobacz tę powierzchnię w renderowaniu lub w obrazie PNG produktu. Bez załamania i przepuszczania światła.",
|
||||
"appearance.pbr_opaque": "Nieprzezroczysty PBR",
|
||||
"appearance.roughness": "Chropowatość",
|
||||
@@ -621,6 +626,7 @@
|
||||
"cmd.material_create": "Nowy materiał fizyczny",
|
||||
"cmd.material_delete": "Usuń materiał fizyczny",
|
||||
"cmd.material_edit": "Edytuj materiał fizyczny",
|
||||
"cmd.material_inspect": "Sprawdź materiał fizyczny",
|
||||
"cmd.material_list": "Lista materiałów",
|
||||
"cmd.material_properties_directional": "Kierunkowy moduł sprężystości",
|
||||
"cmd.material_properties_validate": "Sprawdź dane materiału fizycznego",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Escolher…",
|
||||
"Circular": "Circular",
|
||||
"Circumference": "Circunferência",
|
||||
"Clockwise": "Horário",
|
||||
"Close draft": "Fechar rascunho",
|
||||
"Collisions": "Colisões",
|
||||
"Colour": "Cor",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Pesquisar comandos",
|
||||
"Search this library": "Pesquisar nesta biblioteca",
|
||||
"Section": "Seção",
|
||||
"Section position": "Posição da seção",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Selecionar outro: mantenha o botão esquerdo parado sobre o modelo (ou clique com o botão direito › Selecionar outro…) para listar tudo sob o cursor; clique de novo no mesmo ponto para selecionar o próximo item ali. Clique duas vezes com o botão do meio para ir ao Início (Preferências › Navegação).",
|
||||
"Select bodies (a face picks its body)": "Selecione corpos (uma face seleciona seu corpo)",
|
||||
"Select bodies or faces instead": "Selecionar corpos ou faces em vez disso",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "O SolidCraft fechou antes de estes projetos serem salvos. O último salvamento automático deles pode ser aberto.",
|
||||
"Specialise": "Especializar",
|
||||
"Speed": "Velocidade",
|
||||
"Square": "Quadrado",
|
||||
"Stand it up": "Colocar em pé",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Colocar em pé: um quarto de volta em torno de X, como um recurso Mover que pode ser desfeito.",
|
||||
"Stand this part up?": "Colocar esta peça em pé?",
|
||||
"Start angle": "Ângulo inicial",
|
||||
"Start bulge": "Abaulamento inicial",
|
||||
"Start continuity": "Continuidade inicial",
|
||||
"Step": "Passo",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "ângulo, altura",
|
||||
"appearance.dielectric_ior": "IOR dielétrico",
|
||||
"appearance.metallic": "Metálico",
|
||||
"appearance.only_available": "Somente aparências disponíveis",
|
||||
"appearance.pbr_help": "Veja esta superfície em Renderizar ou em um PNG de produto. Sem refração nem transmissão.",
|
||||
"appearance.pbr_opaque": "PBR opaco",
|
||||
"appearance.roughness": "Rugosidade",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Novo material físico",
|
||||
"cmd.material_delete": "Excluir material físico",
|
||||
"cmd.material_edit": "Editar material físico",
|
||||
"cmd.material_inspect": "Inspecionar material físico",
|
||||
"cmd.material_list": "Listar materiais",
|
||||
"cmd.material_properties_directional": "Módulo de elasticidade direcional",
|
||||
"cmd.material_properties_validate": "Validar dados do material físico",
|
||||
@@ -759,12 +765,19 @@
|
||||
"cmd.timeline_suppress": "Suprimir recurso",
|
||||
"cmd.view_ambient_occlusion": "Oclusão de ambiente",
|
||||
"cmd.view_apply": "Restaurar vista nomeada",
|
||||
"cmd.view_back": "Vista traseira",
|
||||
"cmd.view_bottom": "Vista inferior",
|
||||
"cmd.view_delete": "Excluir vista nomeada",
|
||||
"cmd.view_front": "Vista frontal",
|
||||
"cmd.view_graphics_preset": "Predefinição gráfica",
|
||||
"cmd.view_isometric": "Vista isométrica",
|
||||
"cmd.view_left": "Vista esquerda",
|
||||
"cmd.view_list": "Listar vistas nomeadas",
|
||||
"cmd.view_navigate": "Navegar na vista",
|
||||
"cmd.view_rename": "Renomear vista nomeada",
|
||||
"cmd.view_right": "Vista direita",
|
||||
"cmd.view_save": "Nova vista nomeada",
|
||||
"cmd.view_top": "Vista superior",
|
||||
"color.copy": "Clique para copiar os valores da cor",
|
||||
"color.edit": "Clique para editar a cor",
|
||||
"color.gamma": "Mostrando valores de cor no espaço gama 0-255",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Alegeți…",
|
||||
"Circular": "Circular",
|
||||
"Circumference": "Circumferință",
|
||||
"Clockwise": "În sens orar",
|
||||
"Close draft": "Închide ciorna",
|
||||
"Collisions": "Coliziuni",
|
||||
"Colour": "Culoare",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Caută comenzi",
|
||||
"Search this library": "Caută în această bibliotecă",
|
||||
"Section": "Secțiune",
|
||||
"Section position": "Poziția secțiunii",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Selectează altul: țineți apăsat butonul stâng nemișcat pe model (sau clic dreapta › Selectează altul…) pentru a lista tot ce se află sub cursor; faceți clic din nou în același loc pentru a selecta următorul element. Dublu clic pe butonul din mijloc pentru a merge Acasă (Preferințe › Navigare).",
|
||||
"Select bodies (a face picks its body)": "Selectați corpuri (o față alege corpul ei)",
|
||||
"Select bodies or faces instead": "Selectați în schimb corpuri sau fețe",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft s-a închis înainte ca aceste proiecte să fie salvate. Ultima lor salvare automată poate fi deschisă.",
|
||||
"Specialise": "Specializează",
|
||||
"Speed": "Viteză",
|
||||
"Square": "Pătrat",
|
||||
"Stand it up": "Ridică-l în picioare",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Ridică-l în picioare: un sfert de rotație în jurul lui X, ca o singură operație de mutare ce poate fi anulată.",
|
||||
"Stand this part up?": "Ridicați această piesă în picioare?",
|
||||
"Start angle": "Unghi de început",
|
||||
"Start bulge": "Bombare inițială",
|
||||
"Start continuity": "Continuitate inițială",
|
||||
"Step": "Pas",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "unghi, înălțime",
|
||||
"appearance.dielectric_ior": "IOR dielectric",
|
||||
"appearance.metallic": "Metalic",
|
||||
"appearance.only_available": "Doar aspecte disponibile",
|
||||
"appearance.pbr_help": "Vizualizați această suprafață în Randare sau într-un PNG de produs. Fără refracție sau transmisie.",
|
||||
"appearance.pbr_opaque": "PBR opac",
|
||||
"appearance.roughness": "Rugozitate",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Material fizic nou",
|
||||
"cmd.material_delete": "Șterge materialul fizic",
|
||||
"cmd.material_edit": "Editează materialul fizic",
|
||||
"cmd.material_inspect": "Inspectează materialul fizic",
|
||||
"cmd.material_list": "Listează materialele",
|
||||
"cmd.material_properties_directional": "Modul de elasticitate direcțional",
|
||||
"cmd.material_properties_validate": "Validează datele materialului fizic",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Выбрать…",
|
||||
"Circular": "Круговой",
|
||||
"Circumference": "Окружность",
|
||||
"Clockwise": "По часовой стрелке",
|
||||
"Close draft": "Закрыть анализ уклонов",
|
||||
"Collisions": "Столкновения",
|
||||
"Colour": "Цвет",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Поиск команд",
|
||||
"Search this library": "Поиск в этой библиотеке",
|
||||
"Section": "Сечение",
|
||||
"Section position": "Положение сечения",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Выбрать другое: удерживайте левую кнопку на модели (или правый щелчок › Выбрать другое…), чтобы увидеть всё под курсором; повторный щелчок в том же месте выбирает следующий объект. Двойной щелчок средней кнопкой — «Главная» (Настройки › Навигация).",
|
||||
"Select bodies (a face picks its body)": "Выберите тела (выбор грани выбирает её тело)",
|
||||
"Select bodies or faces instead": "Вместо этого выберите тела или грани",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft закрылся до сохранения этих дизайнов. Можно открыть последнюю автосохранённую версию.",
|
||||
"Specialise": "Специализировать",
|
||||
"Speed": "Скорость",
|
||||
"Square": "Квадрат",
|
||||
"Stand it up": "Поставить вертикально",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Поставить вертикально: четверть оборота вокруг X одной операцией «Переместить», которую можно отменить.",
|
||||
"Stand this part up?": "Поставить эту деталь вертикально?",
|
||||
"Start angle": "Начальный угол",
|
||||
"Start bulge": "Выпуклость в начале",
|
||||
"Start continuity": "Непрерывность в начале",
|
||||
"Step": "Шаг",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "угол, высота",
|
||||
"appearance.dielectric_ior": "Показатель преломления диэлектрика",
|
||||
"appearance.metallic": "Металличность",
|
||||
"appearance.only_available": "Только доступные внешние виды",
|
||||
"appearance.pbr_help": "Просмотр поверхности во вкладке Рендер или на PNG изделия. Без преломления и пропускания света.",
|
||||
"appearance.pbr_opaque": "Непрозрачный PBR",
|
||||
"appearance.roughness": "Шероховатость",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Новый физический материал",
|
||||
"cmd.material_delete": "Удалить физический материал",
|
||||
"cmd.material_edit": "Изменить физический материал",
|
||||
"cmd.material_inspect": "Проверить физический материал",
|
||||
"cmd.material_list": "Список материалов",
|
||||
"cmd.material_properties_directional": "Направленный модуль упругости",
|
||||
"cmd.material_properties_validate": "Проверить данные физического материала",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Välj…",
|
||||
"Circular": "Cirkulär",
|
||||
"Circumference": "Omkrets",
|
||||
"Clockwise": "Medurs",
|
||||
"Close draft": "Stäng utkast",
|
||||
"Collisions": "Kollisioner",
|
||||
"Colour": "Färg",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Sök kommandon",
|
||||
"Search this library": "Sök i detta bibliotek",
|
||||
"Section": "Sektion",
|
||||
"Section position": "Profilens läge",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Markera annan: håll vänsterknappen stilla på modellen (eller högerklicka › Markera annan…) för att lista allt under markören; klicka igen på samma plats för att markera nästa objekt där. Dubbelklicka med mittenknappen för att gå till Hem (Inställningar › Navigering).",
|
||||
"Select bodies (a face picks its body)": "Markera kroppar (en yta väljer sin kropp)",
|
||||
"Select bodies or faces instead": "Markera kroppar eller ytor istället",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft stängdes innan dessa konstruktioner sparades. Deras senaste autospar kan öppnas.",
|
||||
"Specialise": "Specialisera",
|
||||
"Speed": "Hastighet",
|
||||
"Square": "Kvadrat",
|
||||
"Stand it up": "Res upp den",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Res upp den: ett kvartsvarv runt X, som en enda Flytta-funktion som du kan ångra.",
|
||||
"Stand this part up?": "Resa upp denna del?",
|
||||
"Start angle": "Startvinkel",
|
||||
"Start bulge": "Startbukt",
|
||||
"Start continuity": "Startkontinuitet",
|
||||
"Step": "Steg",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "vinkel, höjd",
|
||||
"appearance.dielectric_ior": "Dielektriskt IOR",
|
||||
"appearance.metallic": "Metallisk",
|
||||
"appearance.only_available": "Endast tillgängliga utseenden",
|
||||
"appearance.pbr_help": "Visa den här ytan i Rendering eller en produkt-PNG. Ingen refraktion eller transmission.",
|
||||
"appearance.pbr_opaque": "Ogenomskinlig PBR",
|
||||
"appearance.roughness": "Skrovlighet",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Nytt fysiskt material",
|
||||
"cmd.material_delete": "Ta bort fysiskt material",
|
||||
"cmd.material_edit": "Redigera fysiskt material",
|
||||
"cmd.material_inspect": "Granska fysiskt material",
|
||||
"cmd.material_list": "Lista material",
|
||||
"cmd.material_properties_directional": "Riktningsberoende elasticitetsmodul",
|
||||
"cmd.material_properties_validate": "Validera fysiska materialdata",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Seç…",
|
||||
"Circular": "Dairesel",
|
||||
"Circumference": "Çevre",
|
||||
"Clockwise": "Saat yönünde",
|
||||
"Close draft": "Taslağı kapat",
|
||||
"Collisions": "Çarpışmalar",
|
||||
"Colour": "Renk",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "Komutlarda ara",
|
||||
"Search this library": "Bu kitaplıkta ara",
|
||||
"Section": "Kesit",
|
||||
"Section position": "Kesit konumu",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Diğerini seç: İmlecin altındaki her şeyi listelemek için sol tuşu model üzerinde hareket ettirmeden basılı tutun (veya sağ tık › Diğerini seç…); oradaki bir sonraki öğeyi seçmek için aynı noktaya tekrar tıklayın. Başlangıç görünümüne dönmek için orta tuşla çift tıklayın (Ayarlar › Gezinme).",
|
||||
"Select bodies (a face picks its body)": "Gövdeleri seçin (bir yüz kendi gövdesini seçer)",
|
||||
"Select bodies or faces instead": "Bunun yerine gövde veya yüz seçin",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft bu tasarımlar kaydedilmeden önce kapandı. Son otomatik kayıtları açılabilir.",
|
||||
"Specialise": "Özelleştir",
|
||||
"Speed": "Hız",
|
||||
"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 part up?": "Bu parça dik çevrilsin mi?",
|
||||
"Start angle": "Başlangıç açısı",
|
||||
"Start bulge": "Başlangıç şişkinliği",
|
||||
"Start continuity": "Başlangıç sürekliliği",
|
||||
"Step": "Adım",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "açı, yükseklik",
|
||||
"appearance.dielectric_ior": "Dielektrik kırılma indisi",
|
||||
"appearance.metallic": "Metaliklik",
|
||||
"appearance.only_available": "Yalnızca kullanılabilir görünümler",
|
||||
"appearance.pbr_help": "Bu yüzeyi Render'da veya bir ürün PNG'sinde görüntüleyin. Kırılma veya geçirgenlik yok.",
|
||||
"appearance.pbr_opaque": "Opak PBR",
|
||||
"appearance.roughness": "Pürüzlülük",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "Yeni fiziksel malzeme",
|
||||
"cmd.material_delete": "Fiziksel malzemeyi sil",
|
||||
"cmd.material_edit": "Fiziksel malzemeyi düzenle",
|
||||
"cmd.material_inspect": "Fiziksel malzemeyi incele",
|
||||
"cmd.material_list": "Malzemeleri listele",
|
||||
"cmd.material_properties_directional": "Yöne bağlı elastisite modülü",
|
||||
"cmd.material_properties_validate": "Fiziksel malzeme verilerini kontrol et",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Вибрати…",
|
||||
"Circular": "Круговий",
|
||||
"Circumference": "Довжина кола",
|
||||
"Clockwise": "За годинниковою стрілкою",
|
||||
"Close draft": "Закрити чернетку",
|
||||
"Collisions": "Зіткнення",
|
||||
"Colour": "Колір",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Пошук команд",
|
||||
"Search this library": "Пошук у цій бібліотеці",
|
||||
"Section": "Переріз",
|
||||
"Section position": "Положення перерізу",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Вибір іншого: утримуйте ліву кнопку нерухомо на моделі (або клацніть правою › Вибрати інше…), щоб побачити список усього під курсором; клацніть ще раз у тому ж місці, щоб вибрати наступний об'єкт там. Двічі клацніть середньою кнопкою, щоб перейти до головного виду (Налаштування › Навігація).",
|
||||
"Select bodies (a face picks its body)": "Виділяти тіла (грань виділяє своє тіло)",
|
||||
"Select bodies or faces instead": "Натомість виділіть тіла або грані",
|
||||
@@ -345,9 +347,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft закрився до того, як ці проєкти було збережено. Можна відкрити їхнє останнє автозбереження.",
|
||||
"Specialise": "Спеціалізувати",
|
||||
"Speed": "Швидкість",
|
||||
"Square": "Квадрат",
|
||||
"Stand it up": "Вирівняти",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Вирівняти: поворот на чверть оберту навколо X як одна операція переміщення, яку можна скасувати.",
|
||||
"Stand this part up?": "Вирівняти цю деталь?",
|
||||
"Start angle": "Початковий кут",
|
||||
"Start bulge": "Роздуття початку",
|
||||
"Start continuity": "Неперервність початку",
|
||||
"Step": "Крок",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "кут, висота",
|
||||
"appearance.dielectric_ior": "Діелектричний IOR",
|
||||
"appearance.metallic": "Металевість",
|
||||
"appearance.only_available": "Лише доступні зовнішні вигляди",
|
||||
"appearance.pbr_help": "Перегляньте цю поверхню в режимі рендерингу або як PNG-зображення виробу. Без заломлення чи пропускання.",
|
||||
"appearance.pbr_opaque": "Непрозорий PBR",
|
||||
"appearance.roughness": "Шорсткість",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Новий фізичний матеріал",
|
||||
"cmd.material_delete": "Видалити фізичний матеріал",
|
||||
"cmd.material_edit": "Редагувати фізичний матеріал",
|
||||
"cmd.material_inspect": "Перевірити фізичний матеріал",
|
||||
"cmd.material_list": "Список матеріалів",
|
||||
"cmd.material_properties_directional": "Спрямований модуль пружності",
|
||||
"cmd.material_properties_validate": "Перевірити дані фізичного матеріалу",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "Chọn…",
|
||||
"Circular": "Tròn",
|
||||
"Circumference": "Chu vi",
|
||||
"Clockwise": "Theo chiều kim đồng hồ",
|
||||
"Close draft": "Đóng bản nháp",
|
||||
"Collisions": "Va chạm",
|
||||
"Colour": "Màu sắc",
|
||||
@@ -322,6 +323,7 @@
|
||||
"Search commands": "Tìm kiếm lệnh",
|
||||
"Search this library": "Tìm trong thư viện này",
|
||||
"Section": "Mặt cắt",
|
||||
"Section position": "Vị trí mặt cắt",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Chọn đối tượng khác: giữ nút chuột trái đứng yên trên mô hình (hoặc nhấp chuột phải › Chọn đối tượng khác…) để liệt kê mọi đối tượng dưới con trỏ; nhấp lại vào cùng vị trí đó để chọn đối tượng kế tiếp. Nhấp đúp chuột giữa để về Góc nhìn chuẩn (Tùy chọn cài đặt › Điều hướng).",
|
||||
"Select bodies (a face picks its body)": "Chọn thân khối (chọn một mặt sẽ chọn cả thân khối)",
|
||||
"Select bodies or faces instead": "Chọn thân khối hoặc bề mặt thay thế",
|
||||
@@ -345,9 +347,11 @@
|
||||
"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.",
|
||||
"Specialise": "Chuyên biệt hóa",
|
||||
"Speed": "Tốc độ",
|
||||
"Square": "Hình vuông",
|
||||
"Stand it up": "Dựng đứng đối tượng",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "Dựng đứng đối tượng: xoay 90° quanh trục X, dưới dạng một tính năng Di chuyển có thể hoàn tác.",
|
||||
"Stand this part up?": "Dựng đứng chi tiết này lên?",
|
||||
"Start angle": "Góc bắt đầu",
|
||||
"Start bulge": "Độ phình đầu",
|
||||
"Start continuity": "Độ liên tục đầu",
|
||||
"Step": "Bước",
|
||||
@@ -412,6 +416,7 @@
|
||||
"angle, height": "góc, chiều cao",
|
||||
"appearance.dielectric_ior": "Chỉ số khúc xạ điện môi (IOR)",
|
||||
"appearance.metallic": "Độ kim loại",
|
||||
"appearance.only_available": "Chỉ các kiểu bề ngoài khả dụng",
|
||||
"appearance.pbr_help": "Xem bề mặt này trong chế độ Kết xuất hoặc ảnh PNG sản phẩm. Không có khúc xạ hay truyền sáng.",
|
||||
"appearance.pbr_opaque": "PBR không trong suốt",
|
||||
"appearance.roughness": "Độ nhám bề mặt",
|
||||
@@ -573,6 +578,7 @@
|
||||
"cmd.material_create": "Tạo vật liệu vật lý mới",
|
||||
"cmd.material_delete": "Xóa vật liệu vật lý",
|
||||
"cmd.material_edit": "Chỉnh sửa vật liệu vật lý",
|
||||
"cmd.material_inspect": "Kiểm tra vật liệu vật lý",
|
||||
"cmd.material_list": "Danh sách vật liệu",
|
||||
"cmd.material_properties_directional": "Mô đun đàn hồi theo hướng",
|
||||
"cmd.material_properties_validate": "Xác thực dữ liệu thuộc tính vật liệu",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Choose…": "選擇…",
|
||||
"Circular": "環形",
|
||||
"Circumference": "周長",
|
||||
"Clockwise": "順時針",
|
||||
"Close draft": "關閉草稿",
|
||||
"Collisions": "碰撞",
|
||||
"Colour": "顏色",
|
||||
@@ -321,6 +322,7 @@
|
||||
"Search commands": "搜尋命令",
|
||||
"Search this library": "搜尋此零件庫",
|
||||
"Section": "剖面",
|
||||
"Section position": "截面位置",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "「選擇其他」:在模型上按住左鍵(或右鍵點擊 › 選擇其他…)列出游標下的所有物件;在同一位置再次點擊可選擇該處的下一個物件。雙擊中鍵轉到主檢視(偏好設定 › 導覽)。",
|
||||
"Select bodies (a face picks its body)": "選擇實體(點擊面即選擇其所屬實體)",
|
||||
"Select bodies or faces instead": "改為選擇實體或面",
|
||||
@@ -344,9 +346,11 @@
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft 在這些設計儲存前已關閉。可以開啟它們的上次自動儲存。",
|
||||
"Specialise": "專用操作",
|
||||
"Speed": "速度",
|
||||
"Square": "正方形",
|
||||
"Stand it up": "將其立起",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "將其立起:繞 X 軸旋轉四分之一週,作為一個可復原的移動特徵。",
|
||||
"Stand this part up?": "立起此零件?",
|
||||
"Start angle": "起始角度",
|
||||
"Start bulge": "起始鼓度",
|
||||
"Start continuity": "起始連續性",
|
||||
"Step": "步驟",
|
||||
@@ -411,6 +415,7 @@
|
||||
"angle, height": "角度、高度",
|
||||
"appearance.dielectric_ior": "介電折射率",
|
||||
"appearance.metallic": "金屬度",
|
||||
"appearance.only_available": "僅顯示可用外觀",
|
||||
"appearance.pbr_help": "在彩現工作區或產品 PNG 中檢視此表面。不支援折射或透射。",
|
||||
"appearance.pbr_opaque": "不透明 PBR",
|
||||
"appearance.roughness": "粗糙度",
|
||||
@@ -572,6 +577,7 @@
|
||||
"cmd.material_create": "新建物理材質",
|
||||
"cmd.material_delete": "刪除物理材質",
|
||||
"cmd.material_edit": "編輯物理材質",
|
||||
"cmd.material_inspect": "檢查物理材質",
|
||||
"cmd.material_list": "列出材質",
|
||||
"cmd.material_properties_directional": "方向彈性模量",
|
||||
"cmd.material_properties_validate": "驗證物理材質資料",
|
||||
|
||||
+667
-1
@@ -97,6 +97,7 @@
|
||||
"Circle center": "圆心",
|
||||
"Circular": "圆周",
|
||||
"Circumference": "周长",
|
||||
"Clockwise": "顺时针",
|
||||
"Close draft": "关闭草稿",
|
||||
"Collapse": "折叠",
|
||||
"Collisions": "碰撞",
|
||||
@@ -116,6 +117,7 @@
|
||||
"Continue on GitHub": "在GitHub中继续",
|
||||
"Continuity": "连续性",
|
||||
"Control Radius": "控制半径",
|
||||
"Copies the definition only. Assign it from Physical Material when ready.": "仅复制定义。准备好后可在物理材质中指定。",
|
||||
"Copy Error Message": "复制错误消息",
|
||||
"Copy Warning Message": "复制警告消息",
|
||||
"Copy all licences": "复制所有许可证",
|
||||
@@ -240,6 +242,7 @@
|
||||
"Horiz./Vert.": "水平 / 垂直",
|
||||
"I-Beam": "工字钢",
|
||||
"IMAGES": "图像",
|
||||
"Import material into design": "将材质导入设计",
|
||||
"Import…": "导入…",
|
||||
"In This Design": "在此设计中",
|
||||
"In place (surfaces)": "原位(曲面)",
|
||||
@@ -290,6 +293,7 @@
|
||||
"Mass Center": "质心",
|
||||
"Matched restrictions check the final values.": "满足条件的限制规则检查最终值。",
|
||||
"Material": "材质",
|
||||
"Material copied. Existing body assignments are unchanged.": "材质已复制。现有实体指定保持不变。",
|
||||
"Max": "最大",
|
||||
"Maximum": "最大",
|
||||
"Mesh body": "网格实体",
|
||||
@@ -313,6 +317,7 @@
|
||||
"Move later": "向后移动",
|
||||
"Move up": "上移",
|
||||
"Name": "名称",
|
||||
"Name on import": "导入名称",
|
||||
"Nearest": "最近",
|
||||
"New": "新建",
|
||||
"New Comp.": "新建组件",
|
||||
@@ -322,6 +327,7 @@
|
||||
"No crash reports.": "没有崩溃报告。",
|
||||
"No matching appearance presets.": "没有匹配的外观预设。",
|
||||
"No matching appearances": "没有匹配的外观",
|
||||
"No matching physical materials.": "没有匹配的物理材质。",
|
||||
"No visible bodies or sketches to export.": "没有可导出的可见实体或草图。",
|
||||
"Nominal diameter": "公称直径",
|
||||
"None": "无",
|
||||
@@ -351,6 +357,7 @@
|
||||
"Path": "路径",
|
||||
"Pattern": "阵列",
|
||||
"Per Edge": "每条边",
|
||||
"Physical material definitions": "物理材质定义",
|
||||
"Pick the tool bodies": "选择工具实体",
|
||||
"Picked": "所选",
|
||||
"Picked point": "选取的点",
|
||||
@@ -450,6 +457,7 @@
|
||||
"Second plane": "第二个平面",
|
||||
"Section": "剖面",
|
||||
"Section (optional)": "截面(可选)",
|
||||
"Section position": "截面位置",
|
||||
"Sections (one sketch each)": "截面(每个一个草图)",
|
||||
"Select Other": "选择其他",
|
||||
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "“选择其他”:在模型上按住左键(或右键单击 › 选择其他…)列出光标下的所有对象;在同一位置再次单击可选择该处的下一个对象。双击中键转到主视图(首选项 › 导航)。",
|
||||
@@ -479,9 +487,11 @@
|
||||
"Specialise": "专用操作",
|
||||
"Speed": "速度",
|
||||
"Splitting tool": "分割工具",
|
||||
"Square": "正方形",
|
||||
"Stand it up": "将其立起",
|
||||
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "将其立起:绕 X 轴旋转四分之一周,作为一个可撤销的移动特征。",
|
||||
"Stand this part up?": "立起此零件?",
|
||||
"Start angle": "起始角度",
|
||||
"Start bulge": "起始鼓度",
|
||||
"Start continuity": "起始连续性",
|
||||
"Step": "步骤",
|
||||
@@ -606,6 +616,7 @@
|
||||
"angle, height": "角度、高度",
|
||||
"appearance.dielectric_ior": "电介质折射率",
|
||||
"appearance.metallic": "金属度",
|
||||
"appearance.only_available": "仅显示可用外观",
|
||||
"appearance.pbr_help": "在渲染工作区或产品 PNG 中查看此表面。不支持折射或透射。",
|
||||
"appearance.pbr_opaque": "不透明 PBR",
|
||||
"appearance.roughness": "粗糙度",
|
||||
@@ -634,6 +645,8 @@
|
||||
"cmd.appearance_list": "列出外观",
|
||||
"cmd.assembly_bom": "物料清单",
|
||||
"cmd.body_rename": "重命名实体",
|
||||
"cmd.browser_collapse_all": "全部折叠",
|
||||
"cmd.browser_expand_all": "全部展开",
|
||||
"cmd.browser_group": "新建组",
|
||||
"cmd.browser_move": "移动浏览器项目",
|
||||
"cmd.browser_order": "排列浏览器项目",
|
||||
@@ -770,6 +783,7 @@
|
||||
"cmd.material_create": "新建物理材质",
|
||||
"cmd.material_delete": "删除物理材质",
|
||||
"cmd.material_edit": "编辑物理材质",
|
||||
"cmd.material_inspect": "检查物理材质",
|
||||
"cmd.material_list": "列出材质",
|
||||
"cmd.material_properties_directional": "方向弹性模量",
|
||||
"cmd.material_properties_validate": "验证物理材料数据",
|
||||
@@ -817,14 +831,45 @@
|
||||
"cmd.plastic_rest": "垫块",
|
||||
"cmd.plastic_rules": "列出塑料规则",
|
||||
"cmd.plastic_snap_fit": "卡扣",
|
||||
"cmd.render_aging_describe": "分层表面老化",
|
||||
"cmd.render_backends": "渲染后端",
|
||||
"cmd.render_camera_fit": "为渲染主体取景",
|
||||
"cmd.render_camera_get": "检查渲染相机",
|
||||
"cmd.render_cancel": "取消渲染",
|
||||
"cmd.render_effects_describe": "镜头与创意效果",
|
||||
"cmd.render_export": "导出 PNG",
|
||||
"cmd.render_hdr_inspect": "检查 HDR 源",
|
||||
"cmd.render_library_appearance_apply": "应用库中的不透明外观",
|
||||
"cmd.render_library_describe": "检查渲染库资源",
|
||||
"cmd.render_library_environment_apply": "应用内置 HDR 环境",
|
||||
"cmd.render_library_list": "浏览渲染库",
|
||||
"cmd.render_library_physical_prepare": "准备物理参考资料",
|
||||
"cmd.render_library_preview": "检查原始表面贴图",
|
||||
"cmd.render_library_studio_apply": "应用已制作的工作室灯光",
|
||||
"cmd.render_library_studio_prepare": "准备已制作的工作室灯光",
|
||||
"cmd.render_library_surface_bind": "保存表面绑定",
|
||||
"cmd.render_library_surface_prepare": "准备已制作的表面贴图",
|
||||
"cmd.render_library_surface_unbind": "移除表面绑定",
|
||||
"cmd.render_library_targets": "查找渲染库目标",
|
||||
"cmd.render_optics_bind": "保存光学绑定",
|
||||
"cmd.render_optics_unbind": "移除光学绑定",
|
||||
"cmd.render_preflight": "检查渲染请求",
|
||||
"cmd.render_preset_apply": "应用原生工作室",
|
||||
"cmd.render_preset_resolve": "审阅原生工作室",
|
||||
"cmd.render_quality_prepare": "审阅固定采样预算",
|
||||
"cmd.render_result_pin": "保留当前显示的渲染结果",
|
||||
"cmd.render_result_regrade": "重新调整线性母版",
|
||||
"cmd.render_scene": "检查渲染场景",
|
||||
"cmd.render_settings_apply": "应用渲染相机",
|
||||
"cmd.render_settings_capture_hdr": "保存渲染设置及 HDR",
|
||||
"cmd.render_settings_get": "渲染设置",
|
||||
"cmd.render_settings_set": "保存渲染设置",
|
||||
"cmd.render_shot_duplicate": "复制渲染镜头",
|
||||
"cmd.render_shot_remove": "删除渲染镜头",
|
||||
"cmd.render_shot_rename": "重命名渲染镜头",
|
||||
"cmd.render_stage_backdrop": "保存物理渲染背景",
|
||||
"cmd.render_stage_clear": "移除渲染舞台",
|
||||
"cmd.render_stage_ground": "保存渲染地面",
|
||||
"cmd.render_start": "渲染图像",
|
||||
"cmd.render_status": "渲染进度",
|
||||
"cmd.select_clear": "清除选择",
|
||||
@@ -959,13 +1004,20 @@
|
||||
"cmd.timeline_suppress": "抑制特征",
|
||||
"cmd.view_ambient_occlusion": "环境光遮蔽",
|
||||
"cmd.view_apply": "还原命名视图",
|
||||
"cmd.view_back": "后视图",
|
||||
"cmd.view_bottom": "仰视图",
|
||||
"cmd.view_delete": "删除命名视图",
|
||||
"cmd.view_front": "前视图",
|
||||
"cmd.view_graphics_preset": "图形预设",
|
||||
"cmd.view_isometric": "等轴测视图",
|
||||
"cmd.view_left": "左视图",
|
||||
"cmd.view_list": "列出命名视图",
|
||||
"cmd.view_navigate": "导航视图",
|
||||
"cmd.view_normal_to": "垂直于所选面",
|
||||
"cmd.view_rename": "重命名命名视图",
|
||||
"cmd.view_right": "右视图",
|
||||
"cmd.view_save": "新建命名视图",
|
||||
"cmd.view_top": "俯视图",
|
||||
"color.copy": "单击复制颜色值",
|
||||
"color.edit": "单击编辑颜色",
|
||||
"color.gamma": "以 0–255 伽马空间显示颜色值",
|
||||
@@ -1154,6 +1206,49 @@
|
||||
"manage.material_hint": "选择实体并指定其物理材质。",
|
||||
"manage.parameters_hint": "编辑表达式和单位。按 Enter 或离开字段时应用更改。",
|
||||
"manage.rules_hint": "选择要编辑的规则,或创建新规则。确认以保存规则。",
|
||||
"material.editor.add_property": "添加属性",
|
||||
"material.editor.add_source": "添加来源",
|
||||
"material.editor.assigned_density": "指定密度",
|
||||
"material.editor.axes": "材料轴",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"material.editor.copy_name": "{name} 的副本",
|
||||
"material.editor.density_range": "指定密度必须大于 0 且不超过 1000 g/cm³。",
|
||||
"material.editor.designation": "材料名称",
|
||||
"material.editor.duplicate": "复制",
|
||||
"material.editor.engineering_card": "工程属性卡",
|
||||
"material.editor.family": "材料类别",
|
||||
"material.editor.glass": "玻璃",
|
||||
"material.editor.illustrative": "示例",
|
||||
"material.editor.invalid_property": "不支持的属性类型。",
|
||||
"material.editor.isotropic": "各向同性",
|
||||
"material.editor.measurement": "测量",
|
||||
"material.editor.metal": "金属",
|
||||
"material.editor.moisture": "含水率(干基)",
|
||||
"material.editor.name_required": "请输入 1–128 个字符的名称。",
|
||||
"material.editor.no_draft": "未打开材料草稿。",
|
||||
"material.editor.number_required": "请输入有限数值。",
|
||||
"material.editor.orthotropic": "正交各向异性",
|
||||
"material.editor.other": "其他",
|
||||
"material.editor.polymer": "聚合物",
|
||||
"material.editor.preserved_appearance": "保留的外观",
|
||||
"material.editor.public_reference": "公开参考资料",
|
||||
"material.editor.reference": "参考",
|
||||
"material.editor.save_or_discard": "指定材料前,请保存或放弃材料草稿。",
|
||||
"material.editor.saved": "材料已保存。实体的材料指定未变。",
|
||||
"material.editor.scope": "保存材料不会将其指定给实体。空白属性和条件仍为未知。属性卡密度不会改变指定密度或质量。",
|
||||
"material.editor.source_id": "来源 ID",
|
||||
"material.editor.source_kind": "来源类型",
|
||||
"material.editor.source_title": "来源标题",
|
||||
"material.editor.sources": "来源",
|
||||
"material.editor.stale": "草稿打开期间材料已改变。请放弃并重新打开后再保存。",
|
||||
"material.editor.state": "材料状态",
|
||||
"material.editor.strain_rate": "应变速率",
|
||||
"material.editor.symmetry": "弹性对称性",
|
||||
"material.editor.temperature": "温度",
|
||||
"material.editor.unknown_card": "工程属性未知。可以只保存指定密度和现有外观。",
|
||||
"material.editor.user_supplied": "用户提供",
|
||||
"material.editor.wood": "木材",
|
||||
"measure.at": "位置",
|
||||
"measure.item": "项目 {number}",
|
||||
"messages.ago_h": "{n} 小时前",
|
||||
@@ -1339,21 +1434,248 @@
|
||||
"recovery.just_now": "刚刚",
|
||||
"recovery.min_ago": "{count} 分钟前",
|
||||
"recovery.never_saved": "从未保存",
|
||||
"render.adaptive_absolute": "RGB 绝对误差下限",
|
||||
"render.adaptive_coverage": "覆盖率误差目标",
|
||||
"render.adaptive_enable": "使用独立预采样分配样本",
|
||||
"render.adaptive_help": "仅限 GPU。丢弃独立预采样后,每像素分配至少16个正式样本,最多达到每像素样本数上限。RGB 和覆盖率方差仅用于指导分配;可能遗漏罕见路径,达到上限后仍可能有噪声。最终报告记录实际工作量,不保证噪声或耗时。",
|
||||
"render.adaptive_minimum": "最少正式样本数",
|
||||
"render.adaptive_pending": "GPU 支持独立预采样自适应分配和条件菲涅耳分层。尚不支持认证收敛、罕见事件保证及 CPU 自适应光传输。",
|
||||
"render.adaptive_pilots": "每像素预采样数",
|
||||
"render.adaptive_relative": "RGB 相对误差目标",
|
||||
"render.add_ground": "向设置添加适配地面",
|
||||
"render.advanced_material_scope": "可使用具有明确限制的单个有限均匀 GPU 介质。尚不支持密度网格、嵌套玻璃与体积、次表面散射表面、置换、光谱传输及未实现的高级材料概念。",
|
||||
"render.aging_add": "添加老化层",
|
||||
"render.aging_airborne": "悬浮灰尘 / 参与介质",
|
||||
"render.aging_airborne_help": "悬浮灰尘是独立的有限均匀散射体积。改变光传输和原始 EXR,而不是表面层。保留体积与玻璃、降噪之间的限制;不自动添加大气。",
|
||||
"render.aging_all_bodies": "所有符合条件的不透明实体",
|
||||
"render.aging_chips": "油漆剥落",
|
||||
"render.aging_class_any": "所有不透明材质",
|
||||
"render.aging_class_dielectric": "仅非金属表面",
|
||||
"render.aging_class_metal": "仅金属表面",
|
||||
"render.aging_color": "层颜色 · sRGB",
|
||||
"render.aging_coverage": "覆盖率",
|
||||
"render.aging_dust": "沉积灰尘",
|
||||
"render.aging_empty": "没有老化层:保留原始表面。",
|
||||
"render.aging_fading": "褪色涂层",
|
||||
"render.aging_grime": "污垢与污渍",
|
||||
"render.aging_help": "按顺序组合最多8层光学外观。锈蚀和铜绿是艺术表现,不是老化或腐蚀模拟。尺度使用世界坐标毫米。不改变几何、质量或工程属性;排除玻璃和被动舞台。",
|
||||
"render.aging_metallic": "层金属比例",
|
||||
"render.aging_origin": "场原点 · 世界坐标 mm",
|
||||
"render.aging_patina": "铜绿",
|
||||
"render.aging_refresh_targets": "检查当前实体",
|
||||
"render.aging_roughness": "层粗糙度",
|
||||
"render.aging_rust": "铁锈",
|
||||
"render.aging_scale": "图案尺度",
|
||||
"render.aging_scratches": "细小划痕",
|
||||
"render.aging_target": "目标与坐标",
|
||||
"render.aging_target_help": "指定目标必须匹配捕获时的索引和名称。遮罩固定于世界坐标,不随运动零件移动。不是凹槽检测或真实边缘磨损。筛选列表可查找其他实体。",
|
||||
"render.aging_target_search": "筛选实体名称",
|
||||
"render.aging_upward": "向上表面沉积",
|
||||
"render.all_controls_help": "集中显示当前所有控件;各分页可针对相应任务编辑,不改变底层请求。",
|
||||
"render.appearance_physics_separate": "视觉外观不会分配密度、热学数据或其他工程属性。",
|
||||
"render.availability_native": "原生组合;应用前请审阅",
|
||||
"render.availability_projection": "支持的部分映射;请查看范围和省略项",
|
||||
"render.availability_reference": "参考数据;不会自动分配",
|
||||
"render.backdrop_alpha_conflict": "请选择此背景或透明 PNG 输出;渲染器不会暗中忽略任一设置。",
|
||||
"render.backdrop_enable": "使用相机专用渐变背景",
|
||||
"render.backdrop_first": "起始/中心颜色",
|
||||
"render.backdrop_help": "此屏幕空间背景不发光、不投影、不参与反射,也不代表地形;不包含在原始 EXR 中,与几何、灯光和 HDR 环境相互独立。",
|
||||
"render.backdrop_horizontal": "水平渐变",
|
||||
"render.backdrop_radial": "径向渐变",
|
||||
"render.backdrop_radius": "半径",
|
||||
"render.backdrop_second": "终止/边缘颜色",
|
||||
"render.backdrop_vertical": "垂直渐变",
|
||||
"render.backdrop_x": "中心 X",
|
||||
"render.backdrop_y": "中心 Y",
|
||||
"render.background": "场景背景",
|
||||
"render.background_camera_section": "相机背景 · PNG 显示",
|
||||
"render.background_completed_frozen": "当前结果是已完成的固定图像。编辑背景不会自动重绘结果。相机背景请重新调整;物理舞台更改请重新渲染。",
|
||||
"render.background_hdr_separate": "当前 HDR 资源用于照明和表面反射,不会自动作为主体后方的全景显示。改变渐变不会旋转或改变照明颜色。",
|
||||
"render.background_lighting_section": "HDR 照明 · 独立于相机背景",
|
||||
"render.background_no_alpha_override": "不会悄悄将相机背景添加到透明输出。母版重新调整使用已捕获的覆盖率,不再次降噪;原始 EXR 保持不变。",
|
||||
"render.background_not_light": "背景颜色仅用于呈现,不是额外光源。",
|
||||
"render.background_regrade": "应用于保留的原始母版",
|
||||
"render.background_stage_occlusion": "此镜头包含物理舞台。大地面或墙壁可能覆盖画面并遮住相机背景。请明确清除或调整舞台,或改变其物理反射率。重新调整不能删除已捕获的几何。",
|
||||
"render.background_workflow": "相机专用颜色/渐变、接收光照的物理舞台和 HDR 照明是独立设置。实时预览是建模视图;新建渲染或重新调整保留母版才能查看相机背景。",
|
||||
"render.base_appearance": "可编辑的实体外观",
|
||||
"render.base_apply": "应用实体外观",
|
||||
"render.base_apply_help": "对已确认的精确实体进行一次可撤销的外观分配;现有逐面外观和工程材料保持独立。",
|
||||
"render.base_color": "基础颜色 · sRGB",
|
||||
"render.base_metallic": "金属比例",
|
||||
"render.base_opaque_only": "此编辑器保留不透明实体语义;光学透射请使用明确的玻璃控件。",
|
||||
"render.bloom_enable": "显示泛光",
|
||||
"render.bloom_help": "仅用于输出的创意辉光,将正线性高光经过三次归一化滤波扩散。半径以输出像素计,在 sRGB 前叠加;不模拟镜头或体积,也不改善收敛。原始 EXR 不变。",
|
||||
"render.bloom_opaque": "泛光需要不透明输出;会拒绝透明 PNG,而非暗中合成背景。",
|
||||
"render.bloom_radius": "泛光半径",
|
||||
"render.bloom_strength": "泛光强度",
|
||||
"render.bloom_threshold": "线性高光阈值",
|
||||
"render.browse_capabilities": "查看完整能力目录",
|
||||
"render.browse_environments": "浏览原创 HDR 环境",
|
||||
"render.browse_native_scenes": "浏览原生工作室",
|
||||
"render.browse_physical": "查看物理参考资料",
|
||||
"render.browse_quality": "查看质量规格",
|
||||
"render.browse_rigs": "浏览已制作的灯光组合",
|
||||
"render.browse_scene_specs": "浏览高级场景规格",
|
||||
"render.browse_surfaces": "浏览已制作的表面",
|
||||
"render.browser_library": "资源库",
|
||||
"render.browser_model": "模型",
|
||||
"render.camera_distance": "视点到目标的距离",
|
||||
"render.camera_exact_help": "世界坐标以毫米为单位;角度显示为度、保存为弧度。导航与视口使用同一相机。",
|
||||
"render.camera_fov": "垂直视场角",
|
||||
"render.camera_pitch": "相机俯仰",
|
||||
"render.camera_roll": "滚转",
|
||||
"render.camera_set": "设置渲染相机",
|
||||
"render.camera_target": "目标位置 · mm",
|
||||
"render.camera_yaw": "偏航",
|
||||
"render.chromatic_offset": "边缘色差偏移",
|
||||
"render.clear_stage": "移除已保存的舞台",
|
||||
"render.copy_request": "复制 JSON",
|
||||
"render.cpu_aa_help": "增加空间采样可改善边缘,但会增加渲染时间。",
|
||||
"render.cpu_area_add": "添加 CPU 矩形光源",
|
||||
"render.cpu_area_editor": "CPU 矩形光源",
|
||||
"render.cpu_area_editor_help": "完整边向量以毫米表示;U 叉乘 V 指向发光侧。这与 GPU 的半边向量不同。",
|
||||
"render.cpu_area_full_u": "完整 U 边 · mm",
|
||||
"render.cpu_area_full_v": "完整 V 边 · mm",
|
||||
"render.cpu_area_samples": "面光源采样数",
|
||||
"render.cpu_binding_confirm": "确认此实体",
|
||||
"render.cpu_binding_stale": "场景已更改。请在渲染前重新确认此反射目标。",
|
||||
"render.cpu_body_choose": "选择实体",
|
||||
"render.cpu_body_filter": "按名称筛选实体",
|
||||
"render.cpu_body_filter_more": "请缩小筛选范围以显示更多实体。",
|
||||
"render.cpu_body_missing": "反射目标不存在、已隐藏、名称有歧义或超过128字节。请重新选择。",
|
||||
"render.cpu_budget": "CPU 资源配置",
|
||||
"render.cpu_budget_bodies": "实体数上限",
|
||||
"render.cpu_budget_compact": "紧凑型(旧版限制)",
|
||||
"render.cpu_budget_details": "资源限制",
|
||||
"render.cpu_budget_help": "请明确选择更大的限制;不会自动降低分辨率或样本数。",
|
||||
"render.cpu_budget_memory": "任务内存上限",
|
||||
"render.cpu_budget_not_guarantee": "这些是准入上限,不是预留内存或速度保证。几何、图像缓冲和保留的预览共用内存预算;渲染仍可取消。",
|
||||
"render.cpu_budget_resize": "草稿超出此 CPU 配置或相机样本预算;请明确接受较小尺寸,或选择更大的配置。",
|
||||
"render.cpu_budget_studio": "工作室型(大图像)",
|
||||
"render.cpu_budget_triangles": "三角形数上限",
|
||||
"render.cpu_budget_workstation": "工作站型(重型场景)",
|
||||
"render.cpu_captured_hdr": "此图像捕获的HDR",
|
||||
"render.cpu_check_capture_help": "检查和开始会验证相同的文件哈希,或使用嵌入的HDR。每张图像保留各自捕获的源数据。",
|
||||
"render.cpu_check_changed": "设置或模型在上次检查后发生了变化。请在渲染前重新检查。",
|
||||
"render.cpu_constant_help": "恒定辐亮度作用于反射或透射光线,不提供直接漫反射照明。",
|
||||
"render.cpu_custom_directions": "用自定义平行光替代预设",
|
||||
"render.cpu_direction": "朝向光源的方向(X、Y、Z)",
|
||||
"render.cpu_directional": "平行光",
|
||||
"render.cpu_directional_add": "添加平行光",
|
||||
"render.cpu_environment": "CPU环境",
|
||||
"render.cpu_environment_background": "图像背景与环境照明分开设置。",
|
||||
"render.cpu_environment_bounds": "CPU强度须为0–64,HDR旋转须为±1,000,000弧度以内的有限值,HDR采样数为1、4、16或64。",
|
||||
"render.cpu_environment_constant": "用于次级光线的恒定环境",
|
||||
"render.cpu_environment_none": "无CPU环境",
|
||||
"render.cpu_environment_samples": "HDR照明采样数",
|
||||
"render.cpu_exposure_help": "CPU曝光必须在−16至16 EV之间。超出此范围的GPU曝光会保留,直到你修改。",
|
||||
"render.cpu_fixed": "固定图像",
|
||||
"render.cpu_hdr_help": "支持Radiance .hdr、2:1全景图,最大2048 × 1024、16 MiB。CPU要求文件明确声明sRGB/D65原色,不接受未指定原色或EXR。",
|
||||
"render.cpu_hdr_reflection_help": "HDR粗糙反射要求实体及其面的表面完全为金属。检查会报告不支持的组合。",
|
||||
"render.cpu_key_rim": "主光与轮廓光",
|
||||
"render.cpu_last_check": "上次CPU检查",
|
||||
"render.cpu_light_help": "最多8个平行光。自定义列表为空时关闭平行光;选择预设可恢复预设光源。颜色为线性RGB,强度为相对值而非瓦特。",
|
||||
"render.cpu_light_intensity": "相对强度(0–64)",
|
||||
"render.cpu_light_minimum": "衰减的最小距离",
|
||||
"render.cpu_light_position": "世界位置(X、Y、Z)",
|
||||
"render.cpu_light_reference": "强度的参考距离",
|
||||
"render.cpu_light_remove": "移除光源",
|
||||
"render.cpu_lighting": "照明预设",
|
||||
"render.cpu_lights": "CPU光源",
|
||||
"render.cpu_linear_color": "线性颜色(R、G、B)",
|
||||
"render.cpu_neutral": "中性",
|
||||
"render.cpu_opaque_required": "CPU 光线追踪需要不透明背景。请关闭透明背景。",
|
||||
"render.cpu_options_pending": "此CPU面板暂不支持编辑自发光、表面效果、玻璃或各向异性。使用前请清除这些API选项。",
|
||||
"render.cpu_point": "点光源",
|
||||
"render.cpu_point_add": "添加点光源",
|
||||
"render.cpu_point_help": "最多可在所选平行光照明基础上添加8个点光源。距离单位为mm,最小距离不得大于参考距离。",
|
||||
"render.cpu_primary_samples": "每像素边缘采样",
|
||||
"render.cpu_progressive": "CPU渐进渲染",
|
||||
"render.cpu_progressive_help": "使用现有CPU积分器,每轮累积一个主采样。所选反射需要单采样;面光源、电介质和各向异性需要固定图像模式。",
|
||||
"render.cpu_progressive_limits": "最多1,048,576像素,像素×采样总数不超过16,777,216。更改采样数不会自动调整图像尺寸。",
|
||||
"render.cpu_progressive_seed": "CPU采样种子",
|
||||
"render.cpu_progressive_spp": "每像素采样数",
|
||||
"render.cpu_reflection_add": "添加粗糙反射",
|
||||
"render.cpu_reflection_depth": "反射深度(1–8)",
|
||||
"render.cpu_reflection_empty": "尚未选择实体,场景反射已关闭。",
|
||||
"render.cpu_reflection_help": "为实体选择关闭、镜面或粗糙反射。粗糙反射使用已指定的表面粗糙度。更多采样和反弹会增加耗时;这属于有界镜面传输,不计算全局照明。",
|
||||
"render.cpu_reflection_limit": "最多支持64个反射实体。",
|
||||
"render.cpu_reflection_mirror": "镜面",
|
||||
"render.cpu_reflection_off": "关闭",
|
||||
"render.cpu_reflection_rough": "粗糙反射",
|
||||
"render.cpu_reflection_samples": "反射采样数(1–64)",
|
||||
"render.cpu_reflections": "CPU反射",
|
||||
"render.cpu_runtime_help": "照明和环境的数值设置会随配置保存。实体反射和HDR文件仍为临时设置。已有面光源和聚光锥数值会保留。",
|
||||
"render.cpu_sampling_mode": "CPU采样模式",
|
||||
"render.cpu_shadows": "投射阴影",
|
||||
"render.cpu_summary": "CPU光线追踪 · 反射 · HDR · 平行光与点光源",
|
||||
"render.cpu_warm_cool": "暖色与冷色",
|
||||
"render.diag_bodies": "可见实体数",
|
||||
"render.diag_job_details": "已捕获任务详情",
|
||||
"render.diag_last_check": "上次预检",
|
||||
"render.diag_memory": "逻辑内存准入估算",
|
||||
"render.diag_not_implemented": "明确的能力边界",
|
||||
"render.diag_preflight_details": "预检详情",
|
||||
"render.diag_request": "当前精确请求",
|
||||
"render.diag_triangles": "三角形数",
|
||||
"render.discard_continue": "放弃草稿并继续",
|
||||
"render.draft_confirm_help": "当前渲染草稿有尚未应用的修改;切换前请保存、明确放弃,或继续编辑。",
|
||||
"render.draft_confirm_title": "保留已编辑的渲染设置",
|
||||
"render.effects_gpu_only": "这些效果需要 GPU 路径追踪。打开页面不会自动切换渲染器。",
|
||||
"render.effects_help": "组合有序颜色风格和图像空间镜头效果。渲染和原始母版重新调整使用相同保存设置。原始 EXR 保持不变。这些是原创艺术控制,不是校准镜头或品牌胶片仿真。",
|
||||
"render.effects_reset_lens": "重置镜头效果",
|
||||
"render.effects_seed": "图案种子",
|
||||
"render.export_display": "导出:显示 PNG",
|
||||
"render.export_linear": "导出:原始线性 EXR",
|
||||
"render.exr_pending": "GPU 可保留线性 EXR;压缩、多层和辅助通道仍未实现。",
|
||||
"render.film_grain": "摄影颗粒",
|
||||
"render.fit": "适配产品视图",
|
||||
"render.flare_ghosts": "每光源鬼影环数",
|
||||
"render.flare_halo": "耀斑光晕",
|
||||
"render.flare_streak": "变形镜头风格光条",
|
||||
"render.flare_strength": "高光耀斑强度",
|
||||
"render.flare_threshold": "场景线性耀斑阈值",
|
||||
"render.gpu_depth": "最大路径深度",
|
||||
"render.gpu_options_help": "采样数、深度、种子和曝光会随此配置保存。仅保存当前图像方法。",
|
||||
"render.gpu_path_failed": "GPU 路径追踪器不可用",
|
||||
"render.gpu_path_first_setup": "首次在此 GPU 上设置可能需要几分钟,期间 SolidCraft 仍可正常使用。之后启动时,如果驱动程序保留了已编译的着色器,将直接复用。",
|
||||
"render.gpu_path_preparing": "GPU 路径追踪器:正在编译着色器…",
|
||||
"render.gpu_seed": "随机种子",
|
||||
"render.gpu_unavailable": "此设备上的 GPU 路径追踪尚未就绪。",
|
||||
"render.ground_apply": "适配并保存地面",
|
||||
"render.ground_gap": "明确的间隙",
|
||||
"render.ground_linear_rgb": "漫反射率 · 线性 RGB",
|
||||
"render.ground_margin": "地面范围余量",
|
||||
"render.hdr_details": "HDR源详情",
|
||||
"render.hdr_embedded": "HDR已保存在此设计中",
|
||||
"render.hdr_embedded_help": "渲染使用设计内保存的字节,不再需要原始文件。",
|
||||
"render.hdr_file_captured": "已检查HDR文件。保存时会嵌入这些字节;若文件发生变化,请明确重新检查。",
|
||||
"render.hdr_inspect": "检查HDR文件",
|
||||
"render.hdr_inspect_required": "保存或渲染前,请选择并检查HDR文件。",
|
||||
"render.hdr_primaries_declared": "源文件声明了颜色原色。",
|
||||
"render.hdr_primaries_srgb": "颜色原色:sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "源文件未声明原色;请查看渲染器的颜色要求。",
|
||||
"render.hdr_resource_missing": "此设计缺少已保存的HDR资源。",
|
||||
"render.image_advanced": "GPU 高级设置",
|
||||
"render.image_cancelled": "渲染已取消",
|
||||
"render.image_cancelling": "正在取消",
|
||||
"render.image_completed": "图像可导出",
|
||||
"render.image_encoding": "正在编码 PNG",
|
||||
"render.image_export": "导出 PNG",
|
||||
"render.image_export": "导出完成图像",
|
||||
"render.image_exposure": "曝光",
|
||||
"render.image_failed": "渲染失败",
|
||||
"render.image_height": "高度",
|
||||
"render.image_help": "CPU 预览图像 · PNG · 近似透明度",
|
||||
"render.image_host_missing": "未安装图像执行主机。",
|
||||
"render.image_method": "图像生成方式",
|
||||
"render.image_overwrite": "替换现有文件",
|
||||
"render.image_preparing": "正在准备图像",
|
||||
"render.image_progressive": "渐进式渲染",
|
||||
"render.image_queued": "等待渲染",
|
||||
"render.image_reduce": "请尝试更小的图像或更简单的场景。",
|
||||
"render.image_running": "正在渲染图像",
|
||||
"render.image_samples": "每像素采样数",
|
||||
"render.image_scene_stale": "检查或开始图像前,请完成建模操作或刷新场景。",
|
||||
"render.image_stale": "此图像使用后续更改之前捕获的场景。",
|
||||
"render.image_start": "开始渲染",
|
||||
"render.image_supported": "支持此渲染请求;开始时将再次检查队列和内存池。",
|
||||
@@ -1363,20 +1685,347 @@
|
||||
"render.image_unknown": "渲染状态不可用",
|
||||
"render.image_use_largest": "使用此宽高比下的最大尺寸:",
|
||||
"render.image_width": "宽度",
|
||||
"render.include_rig_cards": "包含被动反光板和遮光板",
|
||||
"render.inspect_scene": "刷新捕获的场景摘要",
|
||||
"render.keep_editing": "继续编辑",
|
||||
"render.layer_down": "下移",
|
||||
"render.layer_enabled": "启用此层",
|
||||
"render.layer_remove": "删除层",
|
||||
"render.layer_strength": "层强度",
|
||||
"render.layer_up": "上移",
|
||||
"render.lens_effects_help": "耀斑使用实际线性图像中最多4个分离的明亮光源。鬼影、光晕、光条、色差和畸变是图像空间的艺术近似。空间效果需要不透明输出;边界外采样延伸边缘颜色。颗粒具有确定性。不改变物理、EXR 或几何。",
|
||||
"render.lens_effects_title": "镜头风格与摄影",
|
||||
"render.library_all": "目录",
|
||||
"render.library_all_states": "全部可用状态",
|
||||
"render.library_applied": "资源映射已应用;开始前请检查完整渲染请求。",
|
||||
"render.library_apply_hdr": "使用此 HDR 环境保存",
|
||||
"render.library_apply_maps": "使用已制作的 GPU 表面贴图",
|
||||
"render.library_apply_studio": "保存已制作的工作室映射",
|
||||
"render.library_apply_uniform": "应用均匀不透明外观",
|
||||
"render.library_authored_help": "原创制作资源用于示意,不是实测工程数据;每项操作仅应用其声明的映射。",
|
||||
"render.library_blocked": "受阻/需要校准",
|
||||
"render.library_capabilities": "能力规格",
|
||||
"render.library_center": "灯光组合中心",
|
||||
"render.library_clear_search": "清除",
|
||||
"render.library_details": "规格与来源",
|
||||
"render.library_emitters_only_ack": "仅使用发光体;省略已说明的被动反光板",
|
||||
"render.library_empty": "没有匹配的资源;请更改搜索词或可用性筛选。",
|
||||
"render.library_environment_concepts": "环境概念",
|
||||
"render.library_extent": "主体范围",
|
||||
"render.library_favorite": "添加收藏",
|
||||
"render.library_favorites": "收藏",
|
||||
"render.library_hdr": "内置 HDR 环境",
|
||||
"render.library_hdr_help": "将原始 HDR 嵌入已保存设置。明确转换创作时的经度原点;保存后不再需要外部文件。",
|
||||
"render.library_inspect_only": "选择仅用于检查,不会自动应用;收藏和最近记录属于当前打开的文档会话。",
|
||||
"render.library_light_concepts": "照明概念",
|
||||
"render.library_maps_help": "内置贴图可连同固定源和局部实例映射一起保存;临时光学覆盖仍属于独立模式。",
|
||||
"render.library_material_concepts": "材质概念",
|
||||
"render.library_native_scenes": "原生工作室",
|
||||
"render.library_next": "下一页",
|
||||
"render.library_omitted": "未包含的内容",
|
||||
"render.library_physical_profiles": "物理参考配置",
|
||||
"render.library_previous": "上一页",
|
||||
"render.library_quality_concepts": "质量规格",
|
||||
"render.library_recent": "最近使用",
|
||||
"render.library_replace_environment": "明确替换现有环境",
|
||||
"render.library_replace_studio": "替换已保存的照明、环境和舞台",
|
||||
"render.library_results": "匹配资源",
|
||||
"render.library_rig_help": "在明确的中心和物理范围下适配一次。完整组合包含被动反光板;需要校准时仍会拒绝。保存前检查发光体及反光板的保守间隙。",
|
||||
"render.library_rigs": "已制作的灯光组合",
|
||||
"render.library_save_maps": "将贴图保存到此设置",
|
||||
"render.library_scene_bounds": "使用捕获的场景边界",
|
||||
"render.library_scenes": "场景规格",
|
||||
"render.library_search": "搜索资源库",
|
||||
"render.library_select_hint": "在资源库中选择资源,以查看支持的操作和限制。",
|
||||
"render.library_selene": "SELENE 不透明外观",
|
||||
"render.library_selene_shots": "SELENE 镜头规格",
|
||||
"render.library_short_blocked": "不可用",
|
||||
"render.library_short_native": "原生组合",
|
||||
"render.library_short_projection": "支持的部分映射",
|
||||
"render.library_short_reference": "仅供参考",
|
||||
"render.library_short_specification": "仅为规格",
|
||||
"render.library_source_preview": "载入原始贴图预览",
|
||||
"render.library_source_preview_help": "这是制作的基础颜色源贴图,不是渲染图像或实测材质预览。",
|
||||
"render.library_specification_only": "仅为规格,不是完整可执行预设;所需效果、资源和主体角色仍需明确实现和绑定。",
|
||||
"render.library_specs": "仅为规格",
|
||||
"render.library_status": "可用性",
|
||||
"render.library_surfaces": "已制作的 PBR 表面",
|
||||
"render.library_target": "目标实体",
|
||||
"render.library_title": "渲染资源库",
|
||||
"render.library_unfavorite": "移除收藏",
|
||||
"render.library_uniform_ack": "使用不含空间或高级效果的均匀近似",
|
||||
"render.library_usable": "可执行映射",
|
||||
"render.linear_help": "保留降噪、曝光、色调映射、滤镜和背景处理前的 32 位浮点 RGBA。线性 sRGB/D65,预乘覆盖率。额外内存经明确准入检查;无压缩或额外通道。",
|
||||
"render.linear_retain": "保留原始线性 EXR",
|
||||
"render.linear_unavailable": "所选已完成图像没有保留 EXR。请在渲染前启用保留;旧 PNG 无法恢复原始辐亮度。",
|
||||
"render.look_add": "添加颜色风格",
|
||||
"render.look_bleach": "漂白旁路风格",
|
||||
"render.look_cool": "冷色",
|
||||
"render.look_cyanotype": "蓝晒风格",
|
||||
"render.look_faded": "褪色印相",
|
||||
"render.look_mono": "黑白",
|
||||
"render.look_sepia": "棕褐色",
|
||||
"render.look_strength": "风格强度",
|
||||
"render.look_teal_orange": "青橙",
|
||||
"render.look_title": "创意风格叠层",
|
||||
"render.look_warm": "暖色",
|
||||
"render.mapping_scale": "物理重复倍率",
|
||||
"render.material_absorption": "吸收 R · G · B(每毫米)",
|
||||
"render.material_add": "添加或编辑此实体",
|
||||
"render.material_assignments": "实体分配",
|
||||
"render.material_binding_enable": "包含此实体的设置",
|
||||
"render.material_box": "轴对齐长方体",
|
||||
"render.material_browse": "选择图像…",
|
||||
"render.material_certification": "封闭玻璃使用几何距离。拓扑、朝向、重叠和光学边界在 GPU 准备时验证;检查仅验证请求准入。",
|
||||
"render.material_choose_body": "选择场景实体",
|
||||
"render.material_closed": "封闭实体网格",
|
||||
"render.material_coat": "基础材质上的透明涂层",
|
||||
"render.material_coat_enable": "启用透明涂层",
|
||||
"render.material_coat_help": "在现有不透明外观上叠加示意介电涂层。权重为零时保持基础材质不变。",
|
||||
"render.material_color_map": "基础颜色图像(sRGB)",
|
||||
"render.material_color_replace": "基础贴图替换实体颜色",
|
||||
"render.material_custom": "自定义示意光学设置",
|
||||
"render.material_enable": "使用这些 GPU 材质设置",
|
||||
"render.material_filter": "筛选场景实体…",
|
||||
"render.material_filter_help": "最多显示 128 个匹配实体。大型场景请细化筛选条件。",
|
||||
"render.material_glass": "玻璃与光学吸收",
|
||||
"render.material_glass_enable": "对此实体使用物理玻璃",
|
||||
"render.material_glass_exclusive": "此渲染器不支持在同一实体上同时使用玻璃与透明涂层或贴图。",
|
||||
"render.material_glass_help": "原创示意配方。色样表示透射率,并非渲染预览。吸收系数为 −ln(线性透射率)/参考距离;不改变透明度。",
|
||||
"render.material_gpu_required": "启用的设置需要 GPU 路径追踪。检查或开始前请选择 GPU,或停用这些设置。",
|
||||
"render.material_ior": "折射率(IOR)",
|
||||
"render.material_limits": "最多 128 个实体设置、32 个分离的玻璃实体、64 个涂层和 128 个纹理绑定。相同贴图共享内存;实际设备和总内存限制仍然有效。",
|
||||
"render.material_map_invalid": "贴图必须使用有长度限制的本地路径;法线强度必须是 0 到 1 之间的有限值。",
|
||||
"render.material_map_required": "使用贴图前请选择颜色图像或法线图像。",
|
||||
"render.material_maps": "平面颜色与法线贴图",
|
||||
"render.material_maps_enable": "为此不透明实体启用贴图",
|
||||
"render.material_maps_help": "PNG/JPEG 最大 1024×1024,编码数据总计不超过 16 MiB。U/V 是世界毫米单位的正交重复向量(最多 128 次)。颜色使用 sRGB,法线使用 OpenGL +Y。检查/开始时捕获文件。",
|
||||
"render.material_metallic_map": "金属度贴图(线性)",
|
||||
"render.material_normal_map": "法线图像(OpenGL,+Y)",
|
||||
"render.material_normal_strength": "法线强度(0–1)",
|
||||
"render.material_origin": "映射原点 X · Y · Z(mm)",
|
||||
"render.material_refresh": "刷新场景实体",
|
||||
"render.material_refresh_needed": "场景已变化。添加目标前请刷新实体列表。",
|
||||
"render.material_remove": "删除此分配",
|
||||
"render.material_repeat_u": "U 单次重复向量 X · Y · Z(mm)",
|
||||
"render.material_repeat_v": "V 单次重复向量 X · Y · Z(mm)",
|
||||
"render.material_revalidate": "重新验证此实体",
|
||||
"render.material_revalidate_needed": "此分配属于较早的场景版本。渲染前请重新验证实体的确切身份。",
|
||||
"render.material_roughness": "涂层粗糙度(0.045–1)",
|
||||
"render.material_roughness_map": "粗糙度贴图(线性)",
|
||||
"render.material_shadow": "透射直线阴影光线",
|
||||
"render.material_target_missing": "实体序号与名称不再匹配。请删除此分配,并重新明确选择目标实体。",
|
||||
"render.material_thickness": "薄片厚度(mm)",
|
||||
"render.material_thin": "薄片",
|
||||
"render.material_title": "GPU 图像材质",
|
||||
"render.material_transient": "此文档标签页的临时光学设置,不保存到设计、渲染设置或材质库中。",
|
||||
"render.material_v_up": "纹理 V 轴指向图像上方",
|
||||
"render.material_weight": "涂层权重(0–1)",
|
||||
"render.method_cpu": "CPU 光线追踪",
|
||||
"render.method_gpu": "GPU 路径追踪",
|
||||
"render.method_limit_raster": "光栅化使用固定的不透明工作室预览;要使用受支持的光学控件,请明确选择光线追踪方式。",
|
||||
"render.method_raster": "CPU 光栅",
|
||||
"render.navigation_help": "相机的操作与设计中相同(首选项 › 导航)。保存设置会记录当前相机。",
|
||||
"render.nested_enable": "经验证的嵌套介质",
|
||||
"render.nested_help": "最多16层包含关系。父体必须凸,子体必须严格位于内部。拒绝相交、接触、薄片和直线透射阴影。内部相机使用经验证的层次结构。不会创建液面或合并接触的CAD边界。",
|
||||
"render.opaque_image_summary": "预览 PNG · 不透明 PBR · 混合透明",
|
||||
"render.opaque_preview_help": "不透明 PBR 和纯色;透明效果使用混合。不支持折射、HDRI 和最终渲染。",
|
||||
"render.optics_remove": "移除已保存光学设置",
|
||||
"render.optics_replace": "明确替换此目标的已保存光学设置",
|
||||
"render.optics_save": "将此光学设置保存到场景",
|
||||
"render.optics_saved": "已保存光学目标",
|
||||
"render.optics_saved_help": "定义、特征及实例的确切标识在离线重开后保留。拒绝缺失、替换或隐藏的目标;工程材料保持不变。移除目标前先保存或放弃数值编辑。",
|
||||
"render.output_format_status": "PNG 是完成的显示图像。可选 GPU EXR 保留显示滤镜前的原始线性 FLOAT32 辐亮度;导出不会替换成预览缓存或其他任务。",
|
||||
"render.output_lock_ratio": "锁定宽高比",
|
||||
"render.output_over_budget": "请求图像超出所选资源范围;请明确选择兼容尺寸或配置,不会自动降级。",
|
||||
"render.output_ratio_refused": "关联尺寸超出此方式的上限;保留原尺寸。请解锁宽高比或选择较小值。",
|
||||
"render.output_swap_orientation": "交换宽度和高度",
|
||||
"render.page_aging": "老化与沉积",
|
||||
"render.page_all": "全部控件",
|
||||
"render.page_appearance": "外观",
|
||||
"render.page_background": "背景",
|
||||
"render.page_camera": "相机",
|
||||
"render.page_diagnostics": "诊断",
|
||||
"render.page_effects": "镜头与后期效果",
|
||||
"render.page_environment": "环境",
|
||||
"render.page_lighting": "照明",
|
||||
"render.page_output": "输出",
|
||||
"render.page_scene": "场景",
|
||||
"render.passive_stage": "地面和被动舞台",
|
||||
"render.passive_stage_help": "有限的被动面板仅属于渲染图像,不增加 CAD 实体或质量。应用后位置固定,与主体边界相交时会拒绝。CPU 不提供漫反射间接照明。",
|
||||
"render.perspective": "透视相机",
|
||||
"render.physical_acknowledge": "我理解此部分参考仍需审阅牌号、条件和来源",
|
||||
"render.physical_associations": "物理候选资料与角色",
|
||||
"render.physical_background_help": "真实的被动地面和墙面,独立于相机背景。弧形背景采用 24 条多边形带近似,不是无限面或解析光滑表面;仅在确认后替换已保存的舞台。",
|
||||
"render.physical_copy_plan": "复制包含来源和省略项的计划",
|
||||
"render.physical_cyclorama": "适配多边形弧形背景",
|
||||
"render.physical_floor_wall": "适配物理地面和墙面",
|
||||
"render.physical_material_name": "拟用参考材料名称",
|
||||
"render.physical_omissions": "原生材料卡无法表示的属性",
|
||||
"render.physical_plan_only": "只读计划已准备,未创建或分配材料。审阅原生材料卡时请保留其扩展配置和省略项。",
|
||||
"render.physical_prepare_plan": "准备创建计划(不应用)",
|
||||
"render.physical_separate": "外观不等于材料识别。这些是有来源的参考,不是经认证的等效属性。现有质量、工程材料和光学设置保持不变。",
|
||||
"render.physical_unknown": "尚未确定数值候选资料。必须指定牌号、配方或构造;未知不等于零。",
|
||||
"render.post_contrast": "对比度",
|
||||
"render.post_gain_b": "蓝色增益",
|
||||
"render.post_gain_g": "绿色增益",
|
||||
"render.post_gain_r": "红色增益",
|
||||
"render.post_help": "仅调整显示。RGB 增益在色调映射前应用,对比度、饱和度和暗角在其后以显示线性光应用。渲染生成新样本;重新调整使用保留的原始母版,不降噪或追踪新光线。",
|
||||
"render.post_reset": "重置呈现滤镜",
|
||||
"render.post_saturation": "饱和度",
|
||||
"render.post_title": "呈现滤镜",
|
||||
"render.post_vignette": "暗角",
|
||||
"render.preview": "集成预览",
|
||||
"render.preview_help": "光栅着色和混合透明度。暂不支持折射、HDRI 和最终渲染。",
|
||||
"render.preview_image_settings_help": "实时预览使用固定工作室照明。曝光和图像照明在检查或开始时应用于图像任务。",
|
||||
"render.preview_retry": "重试实时预览",
|
||||
"render.preview_unavailable_help": "实时预览不可用,但已保存设置和图像任务控件仍可访问。请修改场景或明确重试;被拒绝的场景不会每帧重建。",
|
||||
"render.preview_upload": "实时预览顶点数据量",
|
||||
"render.preview_upload_help": "这是精确的预览顶点字节数,不是 GPU 或进程总内存;几何不会简化。图像任务使用各自的准入检查和照明。",
|
||||
"render.progressive_image_summary": "预览 PNG · 不透明 PBR · 渐进采样",
|
||||
"render.quality_ack": "确认固定预算映射和省略项",
|
||||
"render.quality_apply": "使用此固定采样预算",
|
||||
"render.quality_projection_help": "Q 预设包含未来需求。此操作仅映射受支持的固定样本 PNG 预算,明确省略自适应停止、原始线性输出和独立透射限制。",
|
||||
"render.quality_review": "审阅采样预算",
|
||||
"render.queue_pending": "此界面没有自动生产队列或动画渲染器;已完成的静止图像仍可单独导出。",
|
||||
"render.radial_distortion": "径向畸变",
|
||||
"render.regrade_action": "重新调整原始母版(不降噪)",
|
||||
"render.regrade_help": "根据所选已完成原始母版和这些显示设置创建独立 PNG。不追踪光线,不改变已捕获的尺寸、相机或灯光,也不覆盖 EXR。原始母版不保留降噪辅助数据,因此不重新降噪。可通过相同任务控件导出派生结果。",
|
||||
"render.reload_settings": "重新加载已保存设置",
|
||||
"render.replace_ground": "确认替换现有舞台",
|
||||
"render.replace_saved_surface": "替换此目标已有的保存绑定",
|
||||
"render.restore_camera": "恢复已保存相机",
|
||||
"render.result_actual_help": "一个图像像素对应一个屏幕像素。",
|
||||
"render.result_capture": "捕获版本",
|
||||
"render.result_current": "捕获的模型版本为当前版本。",
|
||||
"render.result_empty": "尚无已完成的图像。请检查设置,然后开始渲染。",
|
||||
"render.result_fit": "适合画布",
|
||||
"render.result_job": "任务",
|
||||
"render.result_navigation": "平移和缩放遵循导航设置。按住空格键并拖动可平移。",
|
||||
"render.result_open": "在主画布中打开已完成的图像。",
|
||||
"render.result_preview": "实时预览",
|
||||
"render.result_provisional": "CPU临时图像",
|
||||
"render.result_provisional_help": "此中间结果无法导出。导出始终使用最后完成的结果;取消后会返回该结果。",
|
||||
"render.result_reduced_display": "显示预览已缩小到视口设备或缓存限制。保留的 PNG 和导出仍为完整分辨率;此缩小视图不能进行原生 100% 检查。",
|
||||
"render.result_retained": "正在显示最后完成的图像;较新的渲染尚未替换它。",
|
||||
"render.result_sequence": "中间结果",
|
||||
"render.result_title": "渲染结果",
|
||||
"render.return_design": "返回设计",
|
||||
"render.review_stale": "此审阅结果已过期;应用前请重新解析或检查。",
|
||||
"render.ribbon_aging": "老化",
|
||||
"render.ribbon_backgrounds": "背景",
|
||||
"render.ribbon_check": "检查",
|
||||
"render.ribbon_check_help": "验证渲染将提交的当前设置;不会暗中切换渲染器、缩小图像或替换资源。",
|
||||
"render.ribbon_edit_lights": "编辑灯光",
|
||||
"render.ribbon_effects": "效果",
|
||||
"render.ribbon_environment_help": "HDR 照明、相机专用背景和物理舞台独立控制,替换需明确确认。",
|
||||
"render.ribbon_finish_dialog": "请先完成文件或确认对话框。",
|
||||
"render.ribbon_frame": "取景",
|
||||
"render.ribbon_hdr_library": "HDR 库",
|
||||
"render.ribbon_job_active": "渲染正在进行;开始新任务前请明确取消。",
|
||||
"render.ribbon_light_rigs": "灯光组合",
|
||||
"render.ribbon_lights_help": "检查原创灯光组合或编辑支持的灯光;明确应用前不会替换当前设置。",
|
||||
"render.ribbon_materials": "材质",
|
||||
"render.ribbon_materials_help": "打开共用外观面板和原创表面库;光学编辑不会暗中更改工程属性。",
|
||||
"render.ribbon_no_active_job": "没有可取消的活动渲染。",
|
||||
"render.ribbon_no_result": "请先完成渲染再导出图像。",
|
||||
"render.ribbon_no_saved_camera": "恢复相机前请先保存镜头。",
|
||||
"render.ribbon_saved_camera": "已存相机",
|
||||
"render.ribbon_shots": "镜头",
|
||||
"render.ribbon_studios": "工作室",
|
||||
"render.ribbon_studios_help": "浏览已实现的工作室并在应用前检查替换内容;概念场景仍有明确标记。",
|
||||
"render.ribbon_surface_maps": "表面贴图",
|
||||
"render.sampling_title": "自适应与透射采样",
|
||||
"render.save_continue": "保存并继续",
|
||||
"render.save_setup": "保存设置",
|
||||
"render.saved_maps_runtime_conflict": "已保存表面绑定不能与临时光学覆盖或未保存 HDR 混用。请明确保存 HDR 或移除临时输入。",
|
||||
"render.saved_surface_remove": "移除已保存绑定",
|
||||
"render.saved_surfaces": "已保存表面绑定",
|
||||
"render.saved_surfaces_help": "固定的内置贴图以局部毫米坐标跟随选定实例。目标被替换或缺失时会报错,绝不自动重新分配。",
|
||||
"render.scene_apply": "应用已审阅的工作室",
|
||||
"render.scene_consent": "确认替换照明、环境、曝光和舞台",
|
||||
"render.scene_preserved_fields": "保留相机、采样、尺寸、光学绑定、CAD 几何和工程材料。",
|
||||
"render.scene_preserves_design": "为可见主体组合照明和被动舞台;几何、工程材料和相机保持独立。",
|
||||
"render.scene_replaces": "替换内容",
|
||||
"render.scene_review": "解析并审阅",
|
||||
"render.scene_review_help": "应用前请审阅完整原生组合;不会替换为未绑定的高级 SCENE 规格。",
|
||||
"render.scene_scope_details": "组合范围",
|
||||
"render.setup_legacy_environment": "此旧设置使用旧版环境旋转或强度。这些值会保留;保存完整图像任务前,请明确转换它们。",
|
||||
"render.setup_name": "设置名称",
|
||||
"render.setup_numeric_help": "保存会记录当前图像方法及其全部数值设置。重新加载或选择其他设置会替换此草稿;相机需单独恢复。",
|
||||
"render.setup_offline_help": "即使渲染器不可用,也可以编辑和保存此方法。检查和开始需要可用的执行器。",
|
||||
"render.setup_runtime_unsupported": "此完整任务暂时无法保存:其中包含贴图或场景实体绑定。保存可移植设置前,请移除这些临时输入。",
|
||||
"render.setup_save_missing": "命令完成后未找到保存的渲染设置。",
|
||||
"render.sharpening": "细节锐化",
|
||||
"render.shot_duplicate": "复制已保存镜头",
|
||||
"render.shot_manager": "已保存镜头",
|
||||
"render.shot_new_name": "新镜头名称",
|
||||
"render.shot_remove": "删除已保存镜头",
|
||||
"render.shot_remove_help": "仅删除此保存设置;源几何和已完成图像保持不变,操作可撤销。",
|
||||
"render.shot_remove_title": "删除已保存镜头?",
|
||||
"render.shot_rename": "重命名已保存镜头",
|
||||
"render.shot_saved_only": "请先保存当前草稿;复制和重命名会保留精确的保存选项与资源引用。",
|
||||
"render.sky_ground": "地面 · 线性 RGB",
|
||||
"render.sky_horizon": "地平线 · 线性 RGB",
|
||||
"render.sky_zenith": "天顶 · 线性 RGB",
|
||||
"render.soft_focus": "柔焦",
|
||||
"render.stage_panel_count": "已保存面板",
|
||||
"render.studio_add_area": "添加面光源",
|
||||
"render.studio_ambient": "恒定环境辐亮度",
|
||||
"render.studio_ambient_rgb": "恒定环境辐亮度(线性RGB)",
|
||||
"render.studio_aperture": "光圈半径",
|
||||
"render.studio_area": "面光源",
|
||||
"render.studio_area_help": "最多四个单面矩形。正交半边 U 和 V 定义尺寸;U × V 指向发光侧。坐标采用世界空间毫米。",
|
||||
"render.studio_center": "中心 X, Y, Z(mm)",
|
||||
"render.studio_denoise": "降低最终图像噪点",
|
||||
"render.studio_denoise_help": "最终滤波保留边缘,但可能柔化细节。玻璃与锐利镜面不参与滤波。",
|
||||
"render.studio_direction": "朝向太阳的方向 (X, Y, Z)",
|
||||
"render.studio_environment": "环境",
|
||||
"render.studio_environment_bounds": "环境旋转必须为±1,000,000弧度以内的有限值,强度必须在0至100之间。",
|
||||
"render.studio_environment_none": "无环境贴图",
|
||||
"render.studio_focus": "轴向对焦距离",
|
||||
"render.studio_half_u": "半边 U(mm)",
|
||||
"render.studio_half_v": "半边 V(mm)",
|
||||
"render.studio_hdr": "Radiance HDR 文件",
|
||||
"render.studio_hdr_browse": "选择 HDR…",
|
||||
"render.studio_hdr_help": "Radiance .hdr,2:1 全景,最大 2048 × 1024。不支持 EXR。色彩假设仅适用于未指定原色的文件。",
|
||||
"render.studio_hdr_required": "请选择本地 .hdr 文件。",
|
||||
"render.studio_hdr_srgb": "将未指定原色解释为线性 sRGB",
|
||||
"render.studio_intensity": "环境强度",
|
||||
"render.studio_lens": "景深",
|
||||
"render.studio_lens_perspective": "景深需要透视相机。",
|
||||
"render.studio_lighting": "工作室照明",
|
||||
"render.studio_lighting_enable": "使用自定义工作室照明",
|
||||
"render.studio_needs_review": "检查方式和设置",
|
||||
"render.studio_radiance": "线性 RGB 辐亮度",
|
||||
"render.studio_ready": "可以检查",
|
||||
"render.studio_remove_area": "移除面光源",
|
||||
"render.studio_rotation": "环境旋转",
|
||||
"render.studio_runtime_help": "工作室数值设置和已检查的HDR可随配置保存。实体光学或材质覆盖仍为临时设置,不改变已保存的外观。",
|
||||
"render.studio_saved": "已保存设置/当前相机",
|
||||
"render.studio_sky": "艺术天空",
|
||||
"render.studio_sky_help": "原创天空渐变用于照明,并非校准的大气模型。",
|
||||
"render.studio_sun": "太阳",
|
||||
"render.studio_sun_radius": "角半径",
|
||||
"render.studio_title": "渲染工作室",
|
||||
"render.studio_tone_map": "色调映射",
|
||||
"render.subsurface_enable": "内部散射随机游走",
|
||||
"render.subsurface_help": "仅适用于封闭介质。散射和RGB吸收使用独立的每毫米系数。路径在实际几何内部散射,并在边界折射或反射。关闭直线透射阴影、表面降噪和外部体积;使用一个菲涅耳分层。这不是扩散着色器、密度网格或实测材料。高密度可能需要更多样本和路径深度。",
|
||||
"render.subsurface_rate": "散射碰撞率",
|
||||
"render.transmission_scope": "GPU 玻璃支持经过验证且互不相交的介质;不支持任意嵌套介质,也不提供无噪声透射估计器。",
|
||||
"render.transmission_strata": "条件菲涅耳分层数",
|
||||
"render.transmission_strata_help": "1保留原始序列。2或4条子路径对首次玻璃反射或透射选择进行分层,不改变斯涅尔定律和吸收规律。更多路径增加计算量;这不是降噪、嵌套介质支持或加速保证。",
|
||||
"render.unavailable_preview": "此设置请求了不可用的预览配置。",
|
||||
"render.unsaved": "未保存的预览更改",
|
||||
"render.use_preview": "使用集成预览",
|
||||
"render.volume_albedo": "散射反照率 · 线性 RGB",
|
||||
"render.volume_anisotropy": "相函数平均余弦",
|
||||
"render.volume_enable": "启用参与介质",
|
||||
"render.volume_extinction": "消光系数",
|
||||
"render.volume_help": "在一个有限盒内进行 GPU 光传输,对相机和间接路径应用 Beer 衰减与 HG 散射。使用明确设置的工作室灯光、HDR 或天空,并衰减阴影连接。平均余弦为正表示前向散射。必须明确关闭玻璃边界和表面降噪。零消光不改变光传输。这不是月球大气、密度网格、体积发光、光谱传输或认证材料属性。",
|
||||
"render.volume_max": "最大边界 · 世界坐标 mm",
|
||||
"render.volume_min": "最小边界 · 世界坐标 mm",
|
||||
"render.volume_title": "有界均匀体积",
|
||||
"sample.bracket.about": "基于 2 mm 钣金规则的基础法兰、边线法兰和卷边",
|
||||
"sample.bracket.name": "钣金支架",
|
||||
"sample.enclosure.about": "带凸缘、螺钉凸台、垫块和卡扣的抽壳长方体",
|
||||
@@ -1469,6 +2118,10 @@
|
||||
"toolbar.customize_note": "{tab} 选项卡。勾选命令可将其按钮添加到工具栏。您也可以将面板下拉菜单中的某一行拖到工具栏,将按钮拖出工具栏以移除,或使用下拉菜单行中的固定图标。",
|
||||
"toolbar.image": "图像",
|
||||
"toolbar.render": "渲染",
|
||||
"toolbar.render_appearance": "外观",
|
||||
"toolbar.render_camera": "相机",
|
||||
"toolbar.render_environment": "环境",
|
||||
"toolbar.render_lighting": "照明",
|
||||
"toolbar.render_scene": "场景",
|
||||
"trace.points": "路径上的 {count} 个点",
|
||||
"trace.stopped_by_contact": "在采样 {sample} 处结束:{a} 会穿过 {b}",
|
||||
@@ -1587,6 +2240,8 @@
|
||||
"ui.agent_chat_allowed": "已允许",
|
||||
"ui.agent_chat_answered": "回答:{option}",
|
||||
"ui.agent_chat_approval": "允许智能体执行此操作吗?",
|
||||
"ui.agent_chat_attach_selection": "附加选择",
|
||||
"ui.agent_chat_attach_selection_tip": "随消息发送模型中当前选中的内容(面、边、特征、实体),让智能体知道你指的是什么",
|
||||
"ui.agent_chat_attach_view": "附加视图",
|
||||
"ui.agent_chat_attach_view_tip": "随消息发送当前视图的图片",
|
||||
"ui.agent_chat_attachable": "图片、PDF、文本和 CAD 文件",
|
||||
@@ -1604,6 +2259,11 @@
|
||||
"ui.agent_chat_command": "智能体命令",
|
||||
"ui.agent_chat_connect": "连接",
|
||||
"ui.agent_chat_copy": "复制",
|
||||
"ui.agent_chat_ctx_bodies": "实体",
|
||||
"ui.agent_chat_ctx_elements": "元素",
|
||||
"ui.agent_chat_ctx_features": "特征",
|
||||
"ui.agent_chat_ctx_more": "另有 {n} 项",
|
||||
"ui.agent_chat_ctx_other": "其他",
|
||||
"ui.agent_chat_custom_hint": "任何通过标准输入输出使用 Agent Client Protocol 的程序。不经过 shell 运行。",
|
||||
"ui.agent_chat_denied": "已拒绝",
|
||||
"ui.agent_chat_deny": "拒绝",
|
||||
@@ -1662,6 +2322,8 @@
|
||||
"ui.agent_chat_paste_picture": "粘贴图片",
|
||||
"ui.agent_chat_permission": "智能体请求运行:{title}",
|
||||
"ui.agent_chat_pick": "智能体",
|
||||
"ui.agent_chat_pick_context": "选择上下文",
|
||||
"ui.agent_chat_pick_context_tip": "在模型中选择要让智能体查看的面、边、特征和实体,然后点击确定",
|
||||
"ui.agent_chat_placeholder": "让智能体修改设计…",
|
||||
"ui.agent_chat_placeholder_busy": "输入消息,待智能体完成后发送(Ctrl+Enter:立即发送)",
|
||||
"ui.agent_chat_pop_out": "在独立窗口中打开(可移到另一个屏幕)",
|
||||
@@ -2043,6 +2705,8 @@
|
||||
"ui.hideOrigin": "隐藏原点",
|
||||
"ui.hidePlanes": "隐藏平面",
|
||||
"ui.hideProfile": "隐藏轮廓",
|
||||
"ui.hide_origin_by_default": "默认隐藏原点",
|
||||
"ui.hide_origin_note": "新设计开始时原点文件夹处于隐藏状态。显示或隐藏过原点的设计会保留自己的原点设置。",
|
||||
"ui.history_back": "后退一步",
|
||||
"ui.history_below_browser": "浏览器下方",
|
||||
"ui.history_edge_hint": "双击边缘",
|
||||
@@ -2061,6 +2725,7 @@
|
||||
"ui.hole_type": "孔类型",
|
||||
"ui.home": "主页",
|
||||
"ui.homeView": "主视图",
|
||||
"ui.horizontal_constraint": "水平约束",
|
||||
"ui.horizontal_vertical": "水平/垂直",
|
||||
"ui.import_ellipsis": "导入…",
|
||||
"ui.infinite": "无限",
|
||||
@@ -2341,6 +3006,7 @@
|
||||
"ui.untitled": "无标题",
|
||||
"ui.up_axis_note": "视图中朝上的轴(轴视图、主视图、注视)。设计本身不变。",
|
||||
"ui.updateToCurrentView": "更新为当前视图",
|
||||
"ui.vertical_constraint": "垂直约束",
|
||||
"ui.view_centre": "视图中心",
|
||||
"ui.visual_shaded_hidden_edges": "带隐藏边的着色",
|
||||
"ui.visual_shaded_with_edges": "带边着色",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Recipe and generator receipts hash canonical bytes on every platform.
|
||||
*.json text eol=lf
|
||||
*.py text eol=lf
|
||||
*.md text eol=lf
|
||||
*.png binary
|
||||
*.hdr binary
|
||||
@@ -0,0 +1,14 @@
|
||||
# Runtime render catalog exports
|
||||
|
||||
These JSON files are necessary runtime exports of the editable authoring catalogs in
|
||||
`docs/render-materials/`. Do not edit both copies. `python -B tools/render-library/generate.py`
|
||||
copies the original bytes and updates the Rust lookup; `--check` verifies exact equality.
|
||||
The application includes these asset exports, never files from the documentation tree.
|
||||
|
||||
The 192 texture maps and 24 HDR files are separate from this metadata. They are included
|
||||
only with the engine's `bundled-render-library` feature. Desktop builds enable it by
|
||||
default. Standalone CLI and web builds do not; use their same-named feature to opt in.
|
||||
Discovery and uniform appearances remain available without the image pack. Requests
|
||||
requiring missing bytes fail explicitly before document mutation; no network is used.
|
||||
GPU/UI test targets opt in deliberately. Exercise the engine's no-pack negative tests
|
||||
separately from its feature-enabled resource tests.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,759 @@
|
||||
{
|
||||
"metadata": {
|
||||
"schema_version": "0.2.0",
|
||||
"language": "en",
|
||||
"status": "specified_unbound",
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": "Q-001",
|
||||
"name": "Interactive Draft",
|
||||
"status": "specified_unbound",
|
||||
"goal": "preview",
|
||||
"resolution": {
|
||||
"width": 960,
|
||||
"height": 540
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 8,
|
||||
"maximum_samples": 64,
|
||||
"relative_error_target": 0.12,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 4,
|
||||
"maximum_transmission_depth": 2,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_buffer",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-002",
|
||||
"name": "Balanced Product",
|
||||
"status": "specified_unbound",
|
||||
"goal": "presentation",
|
||||
"resolution": {
|
||||
"width": 1600,
|
||||
"height": 900
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 32,
|
||||
"maximum_samples": 512,
|
||||
"relative_error_target": 0.035,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 8,
|
||||
"maximum_transmission_depth": 6,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": true,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_buffer",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-065",
|
||||
"CAP-073",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-003",
|
||||
"name": "Product Portfolio",
|
||||
"status": "specified_unbound",
|
||||
"goal": "presentation",
|
||||
"resolution": {
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 64,
|
||||
"maximum_samples": 2048,
|
||||
"relative_error_target": 0.015,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 12,
|
||||
"maximum_transmission_depth": 10,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": true,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_buffer",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-065",
|
||||
"CAP-073",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-004",
|
||||
"name": "Glass and Layers",
|
||||
"status": "specified_unbound",
|
||||
"goal": "optics",
|
||||
"resolution": {
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 128,
|
||||
"maximum_samples": 4096,
|
||||
"relative_error_target": 0.01,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 20,
|
||||
"maximum_transmission_depth": 16,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": true,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-025",
|
||||
"CAP-026",
|
||||
"CAP-027",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-065",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-005",
|
||||
"name": "LED Optical Study",
|
||||
"status": "specified_unbound",
|
||||
"goal": "optics",
|
||||
"resolution": {
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 128,
|
||||
"maximum_samples": 4096,
|
||||
"relative_error_target": 0.01,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 20,
|
||||
"maximum_transmission_depth": 16,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-025",
|
||||
"CAP-026",
|
||||
"CAP-027",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-006",
|
||||
"name": "Lunar Hero Master",
|
||||
"status": "specified_unbound",
|
||||
"goal": "lunar",
|
||||
"resolution": {
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 256,
|
||||
"maximum_samples": 8192,
|
||||
"relative_error_target": 0.005,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 24,
|
||||
"maximum_transmission_depth": 20,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-025",
|
||||
"CAP-026",
|
||||
"CAP-027",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085",
|
||||
"CAP-105"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-007",
|
||||
"name": "Lunar Sample Macro",
|
||||
"status": "specified_unbound",
|
||||
"goal": "lunar",
|
||||
"resolution": {
|
||||
"width": 3072,
|
||||
"height": 3072
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 256,
|
||||
"maximum_samples": 8192,
|
||||
"relative_error_target": 0.005,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 24,
|
||||
"maximum_transmission_depth": 20,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-025",
|
||||
"CAP-026",
|
||||
"CAP-027",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085",
|
||||
"CAP-105"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-008",
|
||||
"name": "Animation Preview",
|
||||
"status": "specified_unbound",
|
||||
"goal": "animation",
|
||||
"resolution": {
|
||||
"width": 1280,
|
||||
"height": 720
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 16,
|
||||
"maximum_samples": 256,
|
||||
"relative_error_target": 0.06,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 8,
|
||||
"maximum_transmission_depth": 6,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": true
|
||||
},
|
||||
"motion": {
|
||||
"enabled": true,
|
||||
"shutter_fraction": 0.5,
|
||||
"temporal_samples": 8,
|
||||
"requires_approved_bake": true,
|
||||
"sample_budget_policy": "One shutter-time sample per camera path, stratified over temporal_samples intervals; temporal_samples does not multiply the spatial sample budget.",
|
||||
"shutter_alignment": "centered_on_frame_time",
|
||||
"frame_rate_binding": "positive_finite_shot_frame_rate_hz_required"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-053",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-078",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085",
|
||||
"CAP-111",
|
||||
"CAP-112",
|
||||
"CAP-119"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-009",
|
||||
"name": "Animation Final",
|
||||
"status": "specified_unbound",
|
||||
"goal": "animation",
|
||||
"resolution": {
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 128,
|
||||
"maximum_samples": 4096,
|
||||
"relative_error_target": 0.012,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 16,
|
||||
"maximum_transmission_depth": 12,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": true
|
||||
},
|
||||
"motion": {
|
||||
"enabled": true,
|
||||
"shutter_fraction": 0.5,
|
||||
"temporal_samples": 32,
|
||||
"requires_approved_bake": true,
|
||||
"sample_budget_policy": "One shutter-time sample per camera path, stratified over temporal_samples intervals; temporal_samples does not multiply the spatial sample budget.",
|
||||
"shutter_alignment": "centered_on_frame_time",
|
||||
"frame_rate_binding": "positive_finite_shot_frame_rate_hz_required"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-053",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-078",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085",
|
||||
"CAP-105",
|
||||
"CAP-111",
|
||||
"CAP-112",
|
||||
"CAP-119"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
},
|
||||
{
|
||||
"id": "Q-010",
|
||||
"name": "Reference Convergence",
|
||||
"status": "specified_unbound",
|
||||
"goal": "reference",
|
||||
"resolution": {
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"integrator_intent": "path_tracing",
|
||||
"sampling": {
|
||||
"minimum_samples": 1024,
|
||||
"maximum_samples": 16384,
|
||||
"relative_error_target": 0.002,
|
||||
"error_estimator": "Versioned relative standard error of scene-linear luminance with a documented dark-signal floor; adapter must bind an estimator before use.",
|
||||
"maximum_samples_action": "Finish with an unconverged flag when the target is not met.",
|
||||
"scope": "Estimated Monte Carlo uncertainty for the bound estimator, not total optical error, finite-depth bias, rare-path coverage or temporal error.",
|
||||
"stopping_rule_binding": "Require a versioned pixel/tile aggregation rule and dark-signal floor before execution."
|
||||
},
|
||||
"transport": {
|
||||
"maximum_depth": 32,
|
||||
"maximum_transmission_depth": 24,
|
||||
"russian_roulette_after_depth": 3,
|
||||
"roulette_policy": "Compensated stochastic termination; finite depth is a declared truncation."
|
||||
},
|
||||
"denoising": {
|
||||
"enabled": false,
|
||||
"preserve_raw": true,
|
||||
"temporal_validation_required": false
|
||||
},
|
||||
"motion": {
|
||||
"enabled": false,
|
||||
"shutter_fraction": 0.0,
|
||||
"temporal_samples": 0,
|
||||
"requires_approved_bake": false,
|
||||
"sample_budget_policy": "No time integration.",
|
||||
"shutter_alignment": "instantaneous",
|
||||
"frame_rate_binding": "not_applicable"
|
||||
},
|
||||
"output": {
|
||||
"master": "linear_exr",
|
||||
"presentation": "png",
|
||||
"color_transform": "project_declared",
|
||||
"exposure_policy": "manual_locked"
|
||||
},
|
||||
"seed": 21026,
|
||||
"required_capabilities": [
|
||||
"CAP-001",
|
||||
"CAP-002",
|
||||
"CAP-003",
|
||||
"CAP-004",
|
||||
"CAP-005",
|
||||
"CAP-006",
|
||||
"CAP-025",
|
||||
"CAP-026",
|
||||
"CAP-027",
|
||||
"CAP-057",
|
||||
"CAP-058",
|
||||
"CAP-059",
|
||||
"CAP-073",
|
||||
"CAP-074",
|
||||
"CAP-081",
|
||||
"CAP-083",
|
||||
"CAP-085"
|
||||
],
|
||||
"budget_policy": "Resolve memory and time against the selected executor; never switch devices or downgrade silently.",
|
||||
"baseline_compatibility": "Future authoring target; resolve every field against the current executor before use.",
|
||||
"validation": [
|
||||
"Measure convergence in dark regolith and bright metal or glass regions.",
|
||||
"Compare raw and finished results; preserve labels, fibers and thin wires.",
|
||||
"Report elapsed time, peak memory and incomplete quality targets.",
|
||||
"Compare multiple seeds and increased sample/depth budgets; an estimated noise threshold alone does not establish reference accuracy."
|
||||
],
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"seed_policy": "Base seed; bind a versioned frame/pixel/sample/time-stratum stream policy and record it in the render manifest."
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
# Physical material integration contract
|
||||
|
||||
This resource slice is based on `6d79d44fa403581e4508d7c9df5e163ff85085bf`.
|
||||
It does not edit the parallel renderer implementation or the native document
|
||||
format. The native candidate-card schema is in
|
||||
[`crates/doc/src/physical_material.rs`](../../../crates/doc/src/physical_material.rs).
|
||||
The personal integration branch separately implements design-owned cards and
|
||||
library v2; capability checks must use the actual executing build.
|
||||
|
||||
## Three independent representations
|
||||
|
||||
1. **Extended reference profile:** the authoritative physical data with quantities,
|
||||
individual source values, SI conversions, conditions, ranges, uncertainty,
|
||||
directions and unresolved applicability. It is not a solver material model.
|
||||
2. **Native schema-1 card:** only the supported scalar point properties and complete
|
||||
admitted elastic blocks. Unsupported data remains in the extended profile and
|
||||
is listed in `not_projected`; it is never silently discarded.
|
||||
3. **Assigned document material:** the application's material object, its explicit
|
||||
mass density, optional physical card and optional appearance. A profile link in
|
||||
the render catalog is not evidence that this object has been created or assigned.
|
||||
|
||||
`exports/native-cards.json` is a bundle of individually valid card objects plus
|
||||
projection metadata. It is not `solidcraft-library/1`, `solidcraft-library/2`, or
|
||||
an application command script. Do not pass its whole envelope as a single card.
|
||||
|
||||
## Supported current commands
|
||||
|
||||
The baseline read-only API is:
|
||||
|
||||
```json
|
||||
{"command":"material.properties.validate","params":{"card":"<individual card object>"}}
|
||||
```
|
||||
|
||||
Replace the placeholder string with the actual JSON object. It validates
|
||||
numerical/structural consistency and reports missing conditions and source review;
|
||||
it does not assign, persist or authenticate the data.
|
||||
|
||||
The parallel personal runtime's persistence contract, inspected in its engine
|
||||
source, is `material.create` / `material.edit` with an explicit `physical_card`:
|
||||
|
||||
```text
|
||||
material.create {name, density_g_cm3, physical_card}
|
||||
material.edit {material, physical_card}
|
||||
```
|
||||
|
||||
A host must first verify that its registered command specification supports
|
||||
`physical_card`; older command implementations may ignore fields they do not know.
|
||||
The generated `prepare` plan names this prerequisite and is not executed here.
|
||||
It does not issue `material.assign`, guess body names or create geometry.
|
||||
|
||||
On the persistence implementation, **editing the physical card does not silently
|
||||
replace the document's mass density**. A discrepancy between card density in kg/m3
|
||||
and assigned density in g/cm3 must be shown and explicitly resolved. The creation
|
||||
plan uses the same selected point density in both fields. A range, missing density
|
||||
or unselected formulation cannot create a falsely precise material.
|
||||
|
||||
For an existing body, retain its current physical material until a user explicitly
|
||||
selects a compatible reference profile. Changing a visual finish must retain
|
||||
physical fields, mass, joint geometry, body dimensions and material axes. Conversely,
|
||||
changing an engineering card must not recolor the body or replace its PBR maps.
|
||||
All document mutations must use the engine command/undo transaction, not direct
|
||||
JSON mutation or a Python runtime dependency.
|
||||
|
||||
## Projection policy
|
||||
|
||||
The current native schema permits density, isotropic/orthotropic elasticity,
|
||||
scalar tensile/compressive/yield/shear strengths, thermal conductivity/expansion
|
||||
and specific heat. This exporter deliberately does not manufacture missing
|
||||
constants to fill those fields.
|
||||
|
||||
- An isotropic block requires a same-source compatible E and Poisson ratio. Where
|
||||
Poisson ratio is explicitly derived from the same source's E and G, the formula
|
||||
and derived status are retained and identified in the native condition text.
|
||||
- A single directional Young modulus is not a complete orthotropic tensor. Wood
|
||||
flexural values and printed XY/Z coupon values stay directional in the extended
|
||||
data; no isotropic substitute is introduced.
|
||||
- Lower/upper bounds and intervals do not become native nominal point values.
|
||||
They remain listed omissions. No midpoint or minimum-as-typical substitution.
|
||||
- Directional thermal data is not copied into three axes. A repeated thermal
|
||||
diagonal is allowed only for a profile explicitly marked as an isotropic
|
||||
reference approximation, which the native state text discloses.
|
||||
- Each native property retains its own temperature, moisture and strain-rate
|
||||
fields. Other source conditions, including an interval or test method, are
|
||||
retained in its state text. Unknown conditions are null, not assumed room values.
|
||||
- Electrical data, hardness scales, radiative properties, porosity and transition
|
||||
temperatures remain in the richer profile. Typed runtime support for these
|
||||
quantities is separate work; preserve the extended data when designing it.
|
||||
|
||||
A structurally valid empty card is not a usable numerical material. The bundle
|
||||
labels it `extended_data_only`; the coverage and native report separate those
|
||||
eleven records from the 48 nonempty partial cards.
|
||||
|
||||
## Layers, compounds and analogues
|
||||
|
||||
`bindings.json` states whether a concept is a bulk body, layer, deposit, treated
|
||||
surface, composite, textile, panel, granular material, device or assembly. Read
|
||||
both `physical_role` and every reference's `relation` before offering assignment.
|
||||
|
||||
A constituent reference cannot be directly used as the effective mass density or
|
||||
stiffness of a foam, laminate, populated PCB, honeycomb or multi-layer blanket.
|
||||
Layer properties need thickness/coverage; homogenized properties need an explicit
|
||||
construction and admissible model. Do not turn an unqualified comparison into a
|
||||
default because it is the first reference in a list.
|
||||
|
||||
Lunar-like concepts use named terrestrial simulants only where stated. Bulk
|
||||
packing density differs from grain density. Angle of repose is not substituted
|
||||
for an internal friction angle, and terrestrial packing data does not certify
|
||||
vacuum, gravity or thermal behavior on the Moon.
|
||||
|
||||
## Future library v2 export
|
||||
|
||||
The integrated runtime's `solidcraft_io::catalog` owns library serialization.
|
||||
It computes entry revisions from its compact serde representation of provenance
|
||||
and definition. Do not calculate an assumed equivalent Python hash or hand-write
|
||||
a catalog revision: cross-language float spelling and omitted fields can differ.
|
||||
|
||||
The next runtime adapter should construct `ValidatedCard` through native admission,
|
||||
use the runtime's catalog types, retain provenance and the extended-profile ID,
|
||||
and generate the canonical revision through `Entry::new` / `content_revision`.
|
||||
Tests must cover import, undo/redo, saved reopen, unchanged appearance, density
|
||||
comparison and retention of unsupported extended fields. This slice performs
|
||||
none of those document mutations and does not claim them tested.
|
||||
|
||||
## Validation boundaries
|
||||
|
||||
The supplied runner can invoke a trusted installed CLI only for read-only card
|
||||
validation. The report identifies its binary hash and explicitly says that it
|
||||
was not rebuilt by this gate. Numeric admission is not a source-license decision,
|
||||
a physical experiment, a constitutive validation, a safety factor, a whole-app
|
||||
build, or evidence of physics-driven rendering.
|
||||
|
||||
|
||||
## Safe native library exporter
|
||||
|
||||
`tools/export_library.py --acknowledge-reference` prepares a non-executing plan
|
||||
for the 46 point-density references and identifies 13 omitted profiles. Omission
|
||||
is explicit: the application requires a scalar mass density, but these profiles
|
||||
have no defensible scalar value. Full source profiles remain authoritative.
|
||||
|
||||
With `--cli` the helper checks the executable's registered command contract before
|
||||
creating a new review folder or running a material mutation. It requires explicit
|
||||
physical-card support, native inspection and library-v2 export. It uses a fresh
|
||||
CLI process, no geometry and no existing user design. The actual application
|
||||
serializes the v2 catalog and its revisions; Python does not approximate serde
|
||||
canonicalization. Every card, source, condition and density is compared before
|
||||
and after a separate-process cold reopen/re-export. The extended unsupported
|
||||
properties remain in this package, not falsely marked as embedded in schema 1.
|
||||
|
||||
The helper is an offline authoring/integration tool, not an application dependency.
|
||||
It never runs `material.assign` or changes a PBR appearance. Passing plan and
|
||||
refusal tests does not imply that modern-runtime persistence was executed; only
|
||||
a successful helper receipt establishes that separate result. Baseline read-only
|
||||
native admission and complete library export are deliberately distinct gates.
|
||||
@@ -0,0 +1,133 @@
|
||||
# Sourced physical material references
|
||||
|
||||
Expanded data checkpoint: **2026-10-22**. Physical engineering data is maintained
|
||||
separately from the authored render appearance. The original source files below
|
||||
are authoritative; exported native cards are reproducible projections, not a
|
||||
second independently edited dataset.
|
||||
|
||||
## Delivered coverage
|
||||
|
||||
| Collection | Current coverage |
|
||||
| --- | --- |
|
||||
| Named reference profiles | **59**, with **416 numerical records** covering **46 quantity types** |
|
||||
| Public primary source records | **50**, with locators, retrieval date and review limitations |
|
||||
| Material concept specifications | **600/600** have an explicit physical role, identification requirements and unknowns |
|
||||
| Concepts with reference candidates | **306**; these can be substrate, constituent, comparison or named-grade candidates |
|
||||
| Concepts still requiring a specific formulation | **294**; no unrelated numerical material is substituted |
|
||||
| Authored PBR surface associations | **48/48** linked to reviewed reference candidates and explicit physical-role rules |
|
||||
| Schema-1 native projections | **59 envelopes**: **48 nonempty**, **11 extended-only**, **113 native property blocks** |
|
||||
| References eligible for material creation | **46** have a supported point density; other references do not acquire an invented mass density |
|
||||
|
||||
A surface reference association is **not identification of a manufactured part**.
|
||||
A metallic-looking coating is not a metal substrate; a fibre is not a laminate;
|
||||
feedstock is not an isotropic printed part; loose granular density is not grain
|
||||
density. References remain explicitly named and require grade, processing and
|
||||
conditions to match the intended application. No physical material is silently
|
||||
assigned to a body, and no appearance edit changes its engineering data.
|
||||
|
||||
## Data and relationships
|
||||
|
||||
- [profiles.json](profiles.json): the 59 exact material identities, numerical
|
||||
values/ranges, original units, SI conversion, measurement conditions and limits.
|
||||
- [sources.json](sources.json): primary-source URLs, selected locators and review
|
||||
records. Public availability is not a redistribution licence or authentication.
|
||||
- [quantities.json](quantities.json): units, dimensions and bounds. Hardness scales,
|
||||
thermal transitions, frequencies and directional measurements remain distinct.
|
||||
- [bindings.json](bindings.json): all 600 concept specifications and 48 authored
|
||||
surface relationships, including substrate/stack/recipe dependencies.
|
||||
- [exports/native-cards.json](exports/native-cards.json): conservative native
|
||||
schema-1 projections, with every excluded property identified and retained in
|
||||
the extended profiles. This is not itself a native library import file.
|
||||
- [exports/coverage.json](exports/coverage.json): generated coverage and exclusions.
|
||||
|
||||
The references cover metals and solders, engineering polymers, silicones and
|
||||
resins, additive-manufacturing feedstock and specimens, woods, cork/MDF, glass and
|
||||
ceramics, PCB and composite constituents, coatings and terrestrial lunar
|
||||
simulants. New named references include PMMA sheet, PVC stock, Kevlar 49 fibre,
|
||||
cured epoxy, UV epoxy and specific alkyd, stoving-enamel and acrylic coatings.
|
||||
|
||||
## Properties preserved
|
||||
|
||||
Mechanical records include density, Young/shear/Poisson measurements, tensile,
|
||||
yield, compression, shear, flexural properties, elongation, fracture/tear data
|
||||
and explicitly identified hardness scales where published. Thermal records
|
||||
include conductivity, expansion, heat capacity, glass transition, melting,
|
||||
decomposition and qualified service-temperature statements. Electrical records
|
||||
retain frequency-specific permittivity/loss, resistivity and dielectric strength.
|
||||
Optical, moisture, granular and application-thickness records retain their own
|
||||
units and meaning; they are not reinterpreted as native elastic constants.
|
||||
|
||||
Each numerical record preserves a source, original value/unit, conversion,
|
||||
qualifier, condition fields and limitations. A range is not reduced to its
|
||||
midpoint; a lower-bound strength is not a typical value. Missing conditions and
|
||||
uncertainties remain null/unknown. Per-property cure schedules survive native
|
||||
projection. An isotropic elastic block refuses mismatched source, temperature,
|
||||
moisture, rate, state or direction rather than combining unrelated constants.
|
||||
|
||||
Some new coating profiles contain only published temperature or film-thickness
|
||||
information. Their cured density, modulus and strength remain unknown. In
|
||||
particular, liquid/mixed-resin density and package weight are not cured-film
|
||||
material properties. See [source review](SOURCE_REVIEW.md).
|
||||
|
||||
## Validate and inspect
|
||||
|
||||
All tools use Python 3.11+ standard-library code. From the repository root:
|
||||
|
||||
```sh
|
||||
python -B assets/render/physical/tools/physical.py validate
|
||||
python -B -m unittest discover -s assets/render/physical/tools -p 'test_*.py'
|
||||
python -B assets/render/physical/tools/check_physical.py --cli /trusted/solidcraft-cli
|
||||
python -B assets/render/physical/tools/physical.py resolve SURF-001
|
||||
python -B assets/render/physical/tools/physical.py prepare steel-c45 --acknowledge-reference
|
||||
```
|
||||
|
||||
The native check calls the read-only `material.properties.validate` command. It
|
||||
checks numerical admission and property preservation, **not** source authenticity,
|
||||
material assignment, solver correctness, persistence or library import. Evidence
|
||||
and executable hashes stay in ignored `target/physical-material-review/`.
|
||||
|
||||
## Native library export without data loss
|
||||
|
||||
Generate a non-executing plan for all point-density references:
|
||||
|
||||
```sh
|
||||
python -B assets/render/physical/tools/export_library.py --acknowledge-reference
|
||||
```
|
||||
|
||||
With a trusted runtime that actually supports physical-card persistence and
|
||||
library v2, create and verify a separate reference library:
|
||||
|
||||
```sh
|
||||
python -B assets/render/physical/tools/export_library.py \
|
||||
--acknowledge-reference --cli /trusted/card-capable/solidcraft-cli
|
||||
```
|
||||
|
||||
Optional repeated `--profile ID` arguments restrict the selection. The exporter
|
||||
first verifies the command contract, then uses a fresh CLI design with no
|
||||
geometry, writes a native v2 library and design into a new `target/` directory,
|
||||
checks every card/source/condition/density, asks the native library inspector to
|
||||
verify content revisions, and cold-reopens/re-exports the design. It does not
|
||||
manually approximate Rust's canonical revision serialization. Existing files,
|
||||
live GUI sessions, user models and body assignments are untouched.
|
||||
|
||||
**The baseline Pegasus CLI validates cards but cannot persist them in materials;
|
||||
the exporter therefore refuses it before creating anything.** Unit tests and that
|
||||
refusal are not a successful end-to-end v2 export. A successful modern-runtime run
|
||||
writes its own receipt; no such runtime receipt is implied by the authored data.
|
||||
The complete extended dataset must accompany the narrower native library.
|
||||
Electrical, hardness, ranges, directional measurements and unsupported quantities
|
||||
must not be claimed to have been embedded in schema 1 merely because a profile
|
||||
has a native projection.
|
||||
|
||||
## Integration and publication
|
||||
|
||||
Use [INTEGRATION.md](INTEGRATION.md) to connect the records to the separate Render
|
||||
branch. `runtime_assignment` remains false until actual target selection and
|
||||
application acceptance are performed. No native document migration, material-card
|
||||
schema expansion, rendering shader, solver, model, appearance texture or optical
|
||||
preset is changed here. Full workspace CI remains a separate integration gate.
|
||||
|
||||
All new curation, validators and tooling are original contributor work under
|
||||
MIT OR Apache-2.0. Publisher data remains attributed to its sources; supplier
|
||||
brand/grade names do not imply affiliation or certification. Selected numerical
|
||||
facts are documented without bundling supplier tables, PDFs, artwork or code.
|
||||
@@ -0,0 +1,140 @@
|
||||
# Source review and interpretation limits
|
||||
|
||||
Research date: 2026-10-22. Exact URLs and source locators are stored in
|
||||
[sources.json](sources.json); each numerical record in [profiles.json](profiles.json)
|
||||
points to one of those references. Selection and normalization are original work.
|
||||
Supplier publications retain their own rights and are not bundled or relicensed.
|
||||
|
||||
## Evidence levels
|
||||
|
||||
The profiles distinguish typical values, published intervals, lower/upper bounds
|
||||
and explicitly calculated values. A manufacturer datasheet is evidence for the
|
||||
named grade and stated test, not identification of an object from its rendering.
|
||||
No record claims certified design allowables. A public URL and retrieval date are
|
||||
traceability metadata, not a signed source archive or proof that the URL can never
|
||||
change. Verify the relevant current datasheet and certificate before engineering use.
|
||||
|
||||
Missing temperature, strain rate, specimen orientation or test method is marked
|
||||
unknown. Published crosshead speed is retained as speed, not guessed strain rate.
|
||||
A source's plus/minus notation is preserved without inventing its confidence level.
|
||||
|
||||
## Conflicts and exclusions retained for review
|
||||
|
||||
| Source or material | Treatment |
|
||||
| --- | --- |
|
||||
| Sandmeyer 304/304L | Use the identified main physical/plate tables; do not average different FAQ values. Typical plate strengths are not minimum-grade specifications. |
|
||||
| Elgiloy Nickel 200 | Keep the cited metric expansion value; a conflicting imperial entry is not used to create a second inconsistent constant. |
|
||||
| SAC305 solder | A field with resistivity units but a conductivity label is excluded rather than silently reinterpreted. Solid alloy data does not identify flux-bearing paste. |
|
||||
| PolyLite ABS | Product-page and wiki densities disagree, so density remains unresolved. The suspect modulus unit is not repaired by intuition. The retained XY/Z strengths remain directional. |
|
||||
| Isola 370HR | The modulus row cites a flexural test; retain it as flexural modulus, not a complete orthotropic elastic tensor. Dielectric-strength unit entries are not silently reconciled. |
|
||||
| Fused silica | A softening value is not used as a melting point; uncertain or inconsistent auxiliary optical entries were excluded. |
|
||||
| Amorim TPS | Use the cited aerospace table rather than mix differing values from another brand page. Room-condition reference properties do not prove ablation performance. |
|
||||
|
||||
Every exclusion stays explicit in the relevant profile. Reference candidates that
|
||||
would imply wrong chemistry were removed during association review: HDPE is not a
|
||||
vinyl-flooring default; a glass profile is not a polymer interlayer; MDF is not an
|
||||
unspecified insulation core. Wrought 6061 may only be an explicitly labelled
|
||||
comparison for an unidentified casting, never a cast-alloy strength certificate.
|
||||
|
||||
## Materials requiring special treatment
|
||||
|
||||
### Wood and engineered panels
|
||||
|
||||
USDA clear-wood results identify species, moisture and test orientation. Clear
|
||||
specimen means are not graded structural-lumber design values. Their bending
|
||||
modulus is not renamed tensile modulus or combined with an invented Poisson ratio.
|
||||
The specific-gravity basis is retained. For the cited 12% moisture rows, wet mass
|
||||
at the stated specimen volume is derived as `SG * 1000 * (1 + 0.12)` kg/m3, with
|
||||
1000 kg/m3 explicitly identified as the water-reference convention. That formula
|
||||
is recorded, checked and not extrapolated to another moisture content.
|
||||
|
||||
Birch specimen properties are a veneer/constituent reference, not effective plywood
|
||||
properties. Panel layup, glue, moisture, thickness class and density must be known.
|
||||
MEDITE PREMIER >12 to 19 mm values are bounded panel specifications; the missing
|
||||
board density is not invented. Cork's MDFACADE product name is not confused with
|
||||
medium-density fibreboard.
|
||||
|
||||
### Printing and composites
|
||||
|
||||
Printed PLA/ABS coupon directions and reported spreads remain distinct. Feedstock
|
||||
solid density is not an infilled-part envelope density. SLS PA12 is not automatically
|
||||
a valid MJF material model. TPU density intervals remain intervals.
|
||||
|
||||
AS4 fibre data describes a constituent. AS4/8552 unidirectional laminate data
|
||||
requires the stated fibre volume, cure and orientation. Neither describes a woven
|
||||
twill part simply because its texture resembles carbon fibre. The woven aramid
|
||||
surface remains unresolved until a particular fibre/resin/layup is selected.
|
||||
|
||||
### Electronics, elastomers and coatings
|
||||
|
||||
FR-4 dielectric values retain frequency, and expansion retains axis and thermal
|
||||
regime. A solder-mask appearance is not a single FR-4 property card for the whole
|
||||
board. Copper thickness, laminate construction, mask, components and interfaces
|
||||
need separate treatment.
|
||||
|
||||
Dragon Skin 20's stress at 100% extension is not Young modulus. A reference casting
|
||||
silicone is not automatically qualified for cable insulation, optical lenses or
|
||||
space seals. Filled potting and IC mould compounds need their actual filler/cure
|
||||
recipe; unfilled casting epoxy is only a labelled comparison.
|
||||
|
||||
AZ-93 thermal emittance and solar absorptance retain their coating context and
|
||||
thickness condition. They are not visible RGB, material emission strength or a
|
||||
bulk heat capacity. A coating's nominal application thickness is not an automatic
|
||||
thickness assignment to a CAD model.
|
||||
|
||||
### Lunar-like resources
|
||||
|
||||
The four Exolith datasets are terrestrial laboratory analogues. Grain density,
|
||||
packing density, void ratio, porosity and apparatus-dependent repose angle remain
|
||||
separate. They do not identify a geological site, vacuum condition, internal
|
||||
friction law or reduced-gravity mechanical response. Rock concepts are not assigned
|
||||
loose-soil density merely to increase numeric coverage.
|
||||
|
||||
## Review backlog
|
||||
|
||||
The 294 concepts without an applicable named reference need a selected recipe,
|
||||
grade or multi-material construction. The 306 with candidates still require review
|
||||
of their stated relation and conditions; some references are constituents or
|
||||
explicit comparisons, not effective-property defaults. No numerical completeness
|
||||
percentage is derived from these association counts.
|
||||
|
||||
Further evidence is especially needed for actual paint/cure stacks, woven aramid
|
||||
laminates, named glass/polymer optical grades, flexible-cable formulations, filled
|
||||
thermal interfaces, resin systems, foams, friction materials and aerospace-qualified
|
||||
processes. Temperature-dependent curves, fatigue, creep, damping, outgassing and
|
||||
failure envelopes should be added as documented quantities/models, not filled with
|
||||
uncited family averages.
|
||||
|
||||
|
||||
## Added source review — 2026-10-22
|
||||
|
||||
Eight additional primary supplier/manufacturer references add 43 selected records,
|
||||
bringing the dataset to 59 profiles, 50 source records and 416 numerical records.
|
||||
All 48 authored surfaces now have an explicit reference-candidate relationship.
|
||||
This does not make the 600 concepts numerically complete or identify their actual
|
||||
manufacturing recipe.
|
||||
|
||||
PMMA sheet preserves published intervals for stiffness, Poisson ratio, heat
|
||||
capacity, thermal expansion/conductivity and electrical resistivity; no midpoint
|
||||
is selected for elasticity. Rigid PVC stock data does not identify plasticized
|
||||
cable insulation. Kevlar 49 axial fibre data does not establish cured laminate or
|
||||
meta-aramid paper/honeycomb properties; those mappings remain separate.
|
||||
|
||||
Sikafloor 161 HC compressive and flexural data retain the 28-day cure at 23 C;
|
||||
its Shore D datum retains the 7-day cure. The manufacturer's mixed-liquid density
|
||||
is not assigned to the cured resin. UV22 retains two different glass-transition
|
||||
ranges, distinguishing UV-only cure from thermal post-cure. Its refractive index
|
||||
is not a spectral model or certified optical transmission curve.
|
||||
|
||||
C71 Speedline, Stoving Enamel Hammer and Acrythane SC601 remain named coating
|
||||
candidates with only the published temperature and/or coverage-basis dry-film
|
||||
thickness recorded. Temperature statements without duration are upper-bound
|
||||
manufacturer references, not continuous-use allowables. No cured density, modulus,
|
||||
strength or film mass is inferred from paint package weights, liquid densities,
|
||||
nominal coverage, visual roughness or colour. Those unknowns remain visible.
|
||||
|
||||
The inspected Kuhn PVC page contains blank mechanical cells and a hardness row
|
||||
with inconsistent units. Neither is imported. Public reference metadata preserves
|
||||
the source relationship without claiming that an openly accessible supplier page
|
||||
has a permissive dataset licence. No PDF, table layout, prose, logo or image from
|
||||
those publishers is included in this repository.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"schema": "solidcraft-physical-coverage/1",
|
||||
"profile_count": 59,
|
||||
"source_count": 50,
|
||||
"property_records": 416,
|
||||
"catalog_specifications": 600,
|
||||
"concepts_with_reference_candidates": 306,
|
||||
"concepts_needing_specific_recipe": 294,
|
||||
"surface_specifications": 48,
|
||||
"surfaces_with_reference_candidates": 48,
|
||||
"native_property_blocks": 113,
|
||||
"nonempty_native_cards": 48,
|
||||
"extended_only_profiles": 11,
|
||||
"profiles_with_point_density": 46,
|
||||
"quantities": {
|
||||
"angle_of_repose": 8,
|
||||
"compressive_modulus": 2,
|
||||
"compressive_strength": 14,
|
||||
"decomposition_temperature": 2,
|
||||
"density": 49,
|
||||
"dielectric_strength": 7,
|
||||
"dry_film_thickness": 4,
|
||||
"electrical_conductivity_iacs": 3,
|
||||
"elongation_break": 19,
|
||||
"flexural_modulus": 14,
|
||||
"flexural_strength": 16,
|
||||
"fracture_toughness": 1,
|
||||
"glass_transition": 11,
|
||||
"grain_density": 4,
|
||||
"hardness_brinell": 2,
|
||||
"hardness_janka": 10,
|
||||
"hardness_knoop": 2,
|
||||
"hardness_shore_a": 2,
|
||||
"hardness_shore_d": 11,
|
||||
"heat_deflection": 9,
|
||||
"internal_bond_strength": 1,
|
||||
"loss_tangent": 9,
|
||||
"mean_particle_size": 4,
|
||||
"melting_temperature": 7,
|
||||
"poisson_ratio": 8,
|
||||
"porosity": 4,
|
||||
"refractive_index": 6,
|
||||
"relative_permittivity": 10,
|
||||
"service_temperature": 2,
|
||||
"shear_modulus": 3,
|
||||
"shear_strength": 10,
|
||||
"solar_absorptance": 1,
|
||||
"specific_gravity": 10,
|
||||
"specific_heat": 16,
|
||||
"stress_at_strain": 1,
|
||||
"tear_strength": 1,
|
||||
"tensile_strength": 24,
|
||||
"thermal_conductivity": 24,
|
||||
"thermal_emittance": 1,
|
||||
"thermal_expansion": 26,
|
||||
"thickness_swelling": 1,
|
||||
"void_ratio": 4,
|
||||
"volume_resistivity": 14,
|
||||
"water_absorption": 3,
|
||||
"yield_strength": 10,
|
||||
"young_modulus": 26
|
||||
},
|
||||
"runtime_assignment": false,
|
||||
"numerically_complete_catalog_claim": false
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"schema": "solidcraft-physical-quantities/1",
|
||||
"units": {
|
||||
"density": "kg/m^3",
|
||||
"young_modulus": "Pa",
|
||||
"poisson_ratio": "1",
|
||||
"shear_modulus": "Pa",
|
||||
"tensile_strength": "Pa",
|
||||
"yield_strength": "Pa",
|
||||
"compressive_strength": "Pa",
|
||||
"flexural_strength": "Pa",
|
||||
"flexural_modulus": "Pa",
|
||||
"elongation_break": "1",
|
||||
"thermal_conductivity": "W/(m K)",
|
||||
"thermal_expansion": "1/K",
|
||||
"specific_heat": "J/(kg K)",
|
||||
"glass_transition": "K",
|
||||
"melting_temperature": "K",
|
||||
"heat_deflection": "K",
|
||||
"volume_resistivity": "ohm m",
|
||||
"relative_permittivity": "1",
|
||||
"loss_tangent": "1",
|
||||
"dielectric_strength": "V/m",
|
||||
"water_absorption": "1",
|
||||
"hardness_shore_a": "1",
|
||||
"hardness_shore_d": "1",
|
||||
"hardness_knoop": "1",
|
||||
"hardness_janka": "N",
|
||||
"service_temperature": "K",
|
||||
"specific_gravity": "1",
|
||||
"stress_at_strain": "Pa",
|
||||
"tear_strength": "N/m",
|
||||
"refractive_index": "1",
|
||||
"decomposition_temperature": "K",
|
||||
"compressive_modulus": "Pa",
|
||||
"electrical_conductivity_iacs": "1",
|
||||
"fracture_toughness": "Pa sqrt(m)",
|
||||
"shear_strength": "Pa",
|
||||
"hardness_brinell": "1",
|
||||
"grain_density": "kg/m^3",
|
||||
"porosity": "1",
|
||||
"void_ratio": "1",
|
||||
"mean_particle_size": "m",
|
||||
"angle_of_repose": "rad",
|
||||
"thermal_emittance": "1",
|
||||
"solar_absorptance": "1",
|
||||
"dry_film_thickness": "m",
|
||||
"internal_bond_strength": "Pa",
|
||||
"thickness_swelling": "1"
|
||||
},
|
||||
"conversions": {
|
||||
"kg/m^3": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"g/cm^3": {
|
||||
"scale": 1000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"Pa": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"kPa": {
|
||||
"scale": 1000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"MPa": {
|
||||
"scale": 1000000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"GPa": {
|
||||
"scale": 1000000000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"psi": {
|
||||
"scale": 6894.757293168,
|
||||
"offset": 0.0
|
||||
},
|
||||
"ksi": {
|
||||
"scale": 6894757.293168,
|
||||
"offset": 0.0
|
||||
},
|
||||
"1": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"%": {
|
||||
"scale": 0.01,
|
||||
"offset": 0.0
|
||||
},
|
||||
"W/(m K)": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"1/K": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"ppm/K": {
|
||||
"scale": 1e-06,
|
||||
"offset": 0.0
|
||||
},
|
||||
"1/degF": {
|
||||
"scale": 1.8,
|
||||
"offset": 0.0
|
||||
},
|
||||
"J/(kg K)": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"J/(g K)": {
|
||||
"scale": 1000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"K": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"degC": {
|
||||
"scale": 1.0,
|
||||
"offset": 273.15
|
||||
},
|
||||
"ohm m": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"ohm cm": {
|
||||
"scale": 0.01,
|
||||
"offset": 0.0
|
||||
},
|
||||
"microohm cm": {
|
||||
"scale": 1e-08,
|
||||
"offset": 0.0
|
||||
},
|
||||
"ohm mm^2/m": {
|
||||
"scale": 1e-06,
|
||||
"offset": 0.0
|
||||
},
|
||||
"V/m": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"kV/mm": {
|
||||
"scale": 1000000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"V/mil": {
|
||||
"scale": 39370.07874015748,
|
||||
"offset": 0.0
|
||||
},
|
||||
"N": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"N/m": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"pli": {
|
||||
"scale": 175.1268352465,
|
||||
"offset": 0.0
|
||||
},
|
||||
"lb/in^3": {
|
||||
"scale": 27679.904710203,
|
||||
"offset": 0.0
|
||||
},
|
||||
"Btu/(h ft degF)": {
|
||||
"scale": 1.730734666371,
|
||||
"offset": 0.0
|
||||
},
|
||||
"Btu/(lb degF)": {
|
||||
"scale": 4186.8,
|
||||
"offset": 0.0
|
||||
},
|
||||
"MPa sqrt(m)": {
|
||||
"scale": 1000000.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"Pa sqrt(m)": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"degF": {
|
||||
"scale": 0.5555555555555556,
|
||||
"offset": 255.3722222222222
|
||||
},
|
||||
"micrometre": {
|
||||
"scale": 1e-06,
|
||||
"offset": 0.0
|
||||
},
|
||||
"mil": {
|
||||
"scale": 2.54e-05,
|
||||
"offset": 0.0
|
||||
},
|
||||
"degree": {
|
||||
"scale": 0.017453292519943295,
|
||||
"offset": 0.0
|
||||
},
|
||||
"rad": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
},
|
||||
"m": {
|
||||
"scale": 1.0,
|
||||
"offset": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
{
|
||||
"schema": "solidcraft-physical-sources/1",
|
||||
"sources": [
|
||||
{
|
||||
"id": "sandmeyer-304",
|
||||
"title": "Sandmeyer Steel Alloy 304/304L plate",
|
||||
"url": "https://www.sandmeyersteel.com/alloy-304-304l/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Main Physical Properties and Typical Mechanical Properties (.375 in plate), not FAQ",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "alfa-6061",
|
||||
"title": "Alfa Chemistry aluminium alloy 6061",
|
||||
"url": "https://alloys.alfa-chemistry.com/aluminum-alloy-6061.html",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical properties and T6 sheet (0.020-0.500 in) typical properties",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "metalcor-ti5",
|
||||
"title": "Metalcor titanium grade 5 3.7164/65",
|
||||
"url": "https://www.metalcor.de/en/datenblatt/125/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Mechanical and Physical Properties at 20 C",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "cda-c11000",
|
||||
"title": "Copper Development Association C11000",
|
||||
"url": "https://alloys.copper.org/alloy/C11000",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical properties table; property-specific temperatures",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "cda-c36000",
|
||||
"title": "Copper Development Association C36000",
|
||||
"url": "https://alloys.copper.org/alloy/C36000",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical properties table; property-specific temperatures",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "cda-c93200",
|
||||
"title": "Copper Development Association C93200",
|
||||
"url": "https://alloys.copper.org/alloy/C93200",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical properties table; property-specific temperatures",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "elgiloy-ni200",
|
||||
"title": "Elgiloy Nickel 200 and 201 strip",
|
||||
"url": "https://www.elgiloy.com/strip-nickel-200-and-201-alloys",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical properties; room-temperature modulus table",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "feinhuette-sac305",
|
||||
"title": "Feinhuette SAC305 electronic solder",
|
||||
"url": "https://www.feinhuette.de/en/metals/sn965ag3cu05",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical Data",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-abs-stock",
|
||||
"title": "Ensinger TECARAN ABS grey",
|
||||
"url": "https://www.ensingerplastics.com/en/shapes/tecaran-abs-grey",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details; exact grade/stock-shape values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-pom-c",
|
||||
"title": "Ensinger TECAFORM AH natural POM-C",
|
||||
"url": "https://www.ensingerplastics.com/en-gb/shapes/acetal-tecaform-ah-natural",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details; exact grade/stock-shape values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-peek",
|
||||
"title": "Ensinger TECAPEEK natural PEEK",
|
||||
"url": "https://www.ensingerplastics.com/en/shapes/peek-tecapeek-natural",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details; exact grade/stock-shape values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-pc",
|
||||
"title": "Ensinger TECANAT natural PC",
|
||||
"url": "https://www.ensingerplastics.com/en-gb/shapes/polycarbonate-tecanat-natural",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details; exact grade/stock-shape values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-pa6-stock",
|
||||
"title": "Ensinger TECAMID 6 natural PA6",
|
||||
"url": "https://www.ensingerplastics.com/en/shapes/pa6-tecamid-6-natural",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details; exact grade/stock-shape values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-ptfe",
|
||||
"title": "Ensinger TECAFLON PTFE natural",
|
||||
"url": "https://www.ensingerplastics.com/en/shapes/tecaflon-ptfe-natural",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Facts and Technical details",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "goodfellow-kapton",
|
||||
"title": "Goodfellow Kapton HN PI coil",
|
||||
"url": "https://www.goodfellow.com/global/kapton-hn-pi-coil-group",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical properties of supplied coil",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ovako-c45",
|
||||
"title": "Ovako C45 steel navigator",
|
||||
"url": "https://steelnavigator.ovako.com/steel-grades/c45/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Other properties; general grade, not an unspecified heat-treatment strength",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-pp",
|
||||
"title": "Ensinger TECAFINE PP grey",
|
||||
"url": "https://www.ensingerplastics.com/en-sg/shapes/polypropylene-tecafine-pp-grey",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical details for stock shape",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "ensinger-hdpe",
|
||||
"title": "Ensinger TECAFINE PE 300 black",
|
||||
"url": "https://www.ensingerplastics.com/en-gb/shapes/polyethylene-tecafine-pe-300-black",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical details for stock shape",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "schott-borofloat",
|
||||
"title": "SCHOTT BOROFLOAT 33 technical details",
|
||||
"url": "https://www.schott.com/en-us/products/borofloat-p1000314/technical-details",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical, thermal, mechanical and optical tables",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "crystran-silica",
|
||||
"title": "Crystran fused silica SiO2",
|
||||
"url": "https://www.crystran.com/optical-materials/fused-silica-sio2/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Optical material data table; inconsistent molecular/softening labels not imported",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "crystran-sapphire",
|
||||
"title": "Crystran sapphire Al2O3",
|
||||
"url": "https://www.crystran.com/optical-materials/sapphire-al2o3/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical and optical constants; crystal orientation explicit",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "coorstek-ad96",
|
||||
"title": "CoorsTek alumina AD-96",
|
||||
"url": "https://www2.coorstek.com/en/materials/alumina/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "AD-96 column, nominal material-property comparison",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "smoothon-ds20",
|
||||
"title": "Smooth-On Dragon Skin 20",
|
||||
"url": "https://www.smooth-on.com/products/dragon-skin-20/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical data; 100% modulus is a finite-strain stress, not Young modulus",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "smoothon-ep690",
|
||||
"title": "Smooth-On EpoxAcast 690",
|
||||
"url": "https://www.smooth-on.com/products/epoxacast-690/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Cured casting technical properties",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "polymaker-pla",
|
||||
"title": "Polymaker PolyLite PLA technical sheet",
|
||||
"url": "https://wiki.polymaker.com/polymaker-products/more-about-our-products/documents/technical-data-sheets/pla/polylite-tm-pla",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Thermal and XY/Z mechanical properties of specified printed test specimens",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "polymaker-abs",
|
||||
"title": "Polymaker PolyLite ABS product specification",
|
||||
"url": "https://shop.polymaker.com/products/polylite-abs/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Mechanical XY/Z and thermal table; conflicting density/modulus excluded",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "polymaker-abs-wiki",
|
||||
"title": "Polymaker PolyLite ABS wiki sheet",
|
||||
"url": "https://wiki.polymaker.com/polymaker-products/more-about-our-products/documents/technical-data-sheets/abs-asa/polylite-tm-abs",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Density discrepancy, retained for resolution rather than averaged",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "polymaker-tpu",
|
||||
"title": "Polymaker PolyFlex TPU95 technical sheet",
|
||||
"url": "https://wiki.polymaker.com/polymaker-products/more-about-our-products/documents/technical-data-sheets/tpu/polyflex-tm-tpu95",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Material density range and nominal Shore hardness",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "eos-pa2200",
|
||||
"title": "EOS PA 2200 PA12 reference",
|
||||
"url": "https://www.eos.info/polymer-solutions/polymer-materials/biocompatible",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "PA 2200 typical part properties; not the different CarbonReduced record",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "isola-370hr",
|
||||
"title": "Isola 370HR laminate and prepreg",
|
||||
"url": "https://www.isola-group.com/pcb-laminates-prepreg/370hr-laminate-prepreg/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Typical Values, revision E (2024-06); not construction-specific Dk tables",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "hexcel-as4",
|
||||
"title": "Hexcel HexTow AS4 continuous fibre and laminate data",
|
||||
"url": "https://www.hexcel.com/Products/Carbon-Fiber/HexTow-Continuous-Carbon-Fiber/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "AS4 12K fibre and AS4/8552 unidirectional laminate columns",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "usda-wood-2021",
|
||||
"title": "USDA Wood Handbook 2021 Chapter 5",
|
||||
"url": "https://research.fs.usda.gov/download/treesearch/62244.pdf",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Table 5-3a, printed pages 5-4, 5-6 and 5-7; 12% moisture clear wood",
|
||||
"license": "US federal government publication; source notice should still be reviewed",
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "amorim-md-facade",
|
||||
"title": "Amorim MDFACADE decorative cork board",
|
||||
"url": "https://www.amorimcorkinsulation.com/en/applications/Decorative-board-Cork-at-sight/162/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical Features, additive-free decorative expanded cork",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "amorim-tps",
|
||||
"title": "Amorim aerospace TPS P45/P50",
|
||||
"url": "https://amorimcorksolutions.com/en-us/materials-applications/aerospace/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Metric TPS materials table; this page is distinct from legacy brand-page values",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "std-polyester-powder",
|
||||
"title": "Standard Group MT-D1036 polyester powder",
|
||||
"url": "https://www.std-coatings.com/Powder/564.html",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Powder properties, colour-dependent specific-gravity range; not an Interpon product",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "az93",
|
||||
"title": "AZ Technology AZ-93 inorganic coating",
|
||||
"url": "https://www.aztechnology.com/product/1/az-93",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Cured AZ-93 specifications; radiative properties are not visible RGB or volumetric emission",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "az-primer",
|
||||
"title": "AZ Technology MLP-300-AZ primer",
|
||||
"url": "https://www.aztechnology.com/product/29/mlp-300-az",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Cured primer specifications",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "medite-premier",
|
||||
"title": "MEDITE PREMIER datasheet prem-ds-en-13",
|
||||
"url": "https://medite-smartply.files.svdcdn.com/production/files/MEDITE-PREMIER-Datasheet-prem-ds-en-13.pdf",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "PDF page 5, Technical Specification Sheet; >12 to 19 mm column",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "exolith-lms-1",
|
||||
"title": "Exolith Lab LMS-1 mare simulant",
|
||||
"url": "https://exolithsimulants.com/collections/regolith-simulants/products/lms-1-lunar-mare-simulant",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical Properties; terrestrial simulant reference, not an Apollo sample",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "exolith-lhs-1",
|
||||
"title": "Exolith Lab LHS-1 highlands simulant",
|
||||
"url": "https://exolithsimulants.com/collections/regolith-simulants/products/lhs-1-lunar-highlands-simulant",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical Properties; terrestrial simulant reference, not an Apollo sample",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "exolith-lms-1d",
|
||||
"title": "Exolith Lab LMS-1D mare dust simulant",
|
||||
"url": "https://exolithsimulants.com/collections/regolith-simulants/products/lms-1d",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical Properties; terrestrial simulant reference, not an Apollo sample",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "exolith-lhs-1d",
|
||||
"title": "Exolith Lab LHS-1D highlands dust simulant",
|
||||
"url": "https://exolithsimulants.com/collections/regolith-simulants/products/lhs-1d-lunar-highland-dust-simulant",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical Properties; terrestrial simulant reference, not an Apollo sample",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts transcribed with original structure; no supplier document, image, implementation or complete table is redistributed."
|
||||
},
|
||||
{
|
||||
"id": "goodfellow-pmma-sheet",
|
||||
"title": "Goodfellow PMMA film and sheet reference",
|
||||
"url": "https://www.goodfellow.com/eu/pmma-film-group",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical, electrical, mechanical and thermal property sections; ranges retain their endpoints.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "goodfellow-kevlar49",
|
||||
"title": "Goodfellow Kevlar 49 polyaramid fibre",
|
||||
"url": "https://www.goodfellow.com/global/kevlar-49-polyaramid-fibre-group",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Physical, thermal and mechanical properties of the supplied fibre, not a cured woven laminate.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "kuhn-pvc-stock",
|
||||
"title": "Kuhn PVC stock-material reference",
|
||||
"url": "https://www.kuhn-marsberg.de/en/product/PVC/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Density, thermal conductivity and electrical properties; ambiguous hardness-unit and empty cells excluded.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "sika-161-cured",
|
||||
"title": "Sika Sikafloor 161 HC cured resin reference",
|
||||
"url": "https://phl.sika.com/en/construction/flooring/industry-wet-areas/epoxy-flooring-system/sikafloor-161-hc.html",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Cured resin hardness at 7 days and strengths at 28 days, +23 C. Mixed-resin density is not cured density.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "masterbond-uv22",
|
||||
"title": "Master Bond UV22 UV-cured epoxy",
|
||||
"url": "https://www.masterbond.com/tds/uv22",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Typical properties and cure-specific glass-transition ranges; no numerical outgassing result imported.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "hmg-c71",
|
||||
"title": "HMG C71 Speedline machinery enamel",
|
||||
"url": "https://hmgpaint.mybigcommerce.com/c71-speedline/",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Manufacturer product description: temperature resistance up to 170 C, dependent on colour; matt, satin and gloss variants.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "hmg-hammer-stoving",
|
||||
"title": "HMG Stoving Enamel Hammer TOPSTV",
|
||||
"url": "https://www.hmgpaint.com/products/all-products/topcoat/1928/stoving-enamel-hammer",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Technical properties: coverage basis at 25 micrometres DFT and temperature resistance 160 C.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
},
|
||||
{
|
||||
"id": "hmg-sc601-clear",
|
||||
"title": "HMG Acrythane SC601 Clearcoat",
|
||||
"url": "https://hmgpaint.com/products/all-products/topcoat/1942/acrythane-sc601-clearcoat",
|
||||
"accessed_on": "2026-10-22",
|
||||
"kind": "public_reference",
|
||||
"locator": "Two-component acrylic/isocyanate clearcoat; stated coverage basis 25 micrometres DFT. No cured density or modulus stated.",
|
||||
"license": null,
|
||||
"review": "Selected numerical facts and explicit source conditions, not a copied supplier table. Publicly indexed manufacturer/supplier data were reviewed; publisher rights are not relicensed. No safety or grade certificate is implied."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run physical-data checks and optional read-only native card admission.
|
||||
|
||||
The optional --cli must point to a trusted existing SolidCraft CLI executable.
|
||||
It only runs material.properties.validate in fresh CLI processes; it never runs
|
||||
material.create, material.assign, opens a user's document or writes a native design.
|
||||
Evidence stays under ignored target/. This is not aggregate workspace CI.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import copy
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import physical
|
||||
|
||||
|
||||
def digest_file(path):
|
||||
h=hashlib.sha256()
|
||||
with path.open('rb') as f:
|
||||
for block in iter(lambda:f.read(1024*1024),b''):h.update(block)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def snapshot():
|
||||
paths=[p for p in physical.PACK.rglob('*') if p.is_file() and '__pycache__' not in p.parts]
|
||||
paths += [physical.ROOT/p for p in ('docs/render-materials/materials.json','assets/render/starter/materials/manifest.json',
|
||||
'crates/doc/src/physical_material.rs','crates/engine/src/cmd/material_properties.rs','ATTRIBUTION.md')]
|
||||
return {p.relative_to(physical.ROOT).as_posix():digest_file(p) for p in sorted(paths)}
|
||||
|
||||
|
||||
def invoke(cli,card):
|
||||
payload=json.dumps({'card':card},ensure_ascii=True,separators=(',',':'),allow_nan=False)
|
||||
physical.require(len(payload)<65536,'native candidate exceeds invocation budget')
|
||||
result=subprocess.run([str(cli),'exec','material.properties.validate',payload],cwd=physical.ROOT,
|
||||
capture_output=True,timeout=30)
|
||||
physical.require(len(result.stdout)+len(result.stderr)<4*1024*1024,'native output exceeds budget')
|
||||
if result.returncode:return result,None
|
||||
return result,json.loads(result.stdout,object_pairs_hook=physical.unique,parse_constant=physical.reject_constant)
|
||||
|
||||
|
||||
def native_check(cli,items):
|
||||
physical.require(cli.is_file(),'trusted native CLI not found')
|
||||
identity={'name':cli.name,'sha256':digest_file(cli),'rebuilt_by_this_gate':False}
|
||||
receipts=[]
|
||||
for i,item in enumerate(items):
|
||||
result,value=invoke(cli,item['card'])
|
||||
physical.require(result.returncode==0 and isinstance(value,dict) and value.get('valid') is True,
|
||||
f"native card admission failed: {item['profile_id']}: {result.stderr.decode(errors='replace')[-500:]}")
|
||||
report=value.get('validation',{})
|
||||
expected=sorted(r['data']['kind'] for r in item['card']['properties'])
|
||||
physical.require(sorted(report.get('property_kinds',[]))==expected,'native property kinds changed or were dropped')
|
||||
receipts.append({'profile_id':item['profile_id'],'valid':True,'property_kinds':expected,
|
||||
'empty_projection':not expected,'source_review_required':report.get('source_review_required'),
|
||||
'missing_condition_fields':report.get('missing_condition_fields'),
|
||||
'isotropic_moduli':report.get('isotropic_moduli')})
|
||||
if (i+1)%12==0:print(json.dumps({'native_cards_checked':i+1,'total':len(items)}),flush=True)
|
||||
template=next(x['card'] for x in items if x['profile_id']=='steel-c45')
|
||||
bad=[]
|
||||
x=copy.deepcopy(template);next(r for r in x['properties'] if r['data']['kind']=='elasticity')['data']['model']['poisson_ratio']=.5;bad.append(('unstable-isotropic',x))
|
||||
x=copy.deepcopy(template);x['properties'][0]['source_id']='missing';bad.append(('unknown-source',x))
|
||||
x=copy.deepcopy(template);x['properties'].append(copy.deepcopy(x['properties'][0]));bad.append(('duplicate-property',x))
|
||||
x=copy.deepcopy(template);next(r for r in x['properties'] if r['data']['kind']=='density')['data']['kg_m3']=-1;bad.append(('negative-density',x))
|
||||
refused=[]
|
||||
for label,card in bad:
|
||||
result,value=invoke(cli,card)
|
||||
physical.require(result.returncode!=0 or isinstance(value,dict) and value.get('valid') is False,
|
||||
f'hostile card was accepted: {label}')
|
||||
refused.append(label)
|
||||
return {'binary':identity,'admitted_card_envelopes':len(receipts),
|
||||
'nonempty_cards':sum(not r['empty_projection'] for r in receipts),
|
||||
'empty_cards_not_ready':sum(r['empty_projection'] for r in receipts),
|
||||
'hostile_cases_refused':refused,'receipts':receipts,'persistence_tested':False,'body_assignment_tested':False}
|
||||
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--cli',type=Path)
|
||||
args=parser.parse_args();stamp=datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ')
|
||||
folder=physical.ROOT/'target/physical-material-review'/stamp;folder.mkdir(parents=True,exist_ok=False)
|
||||
start=time.monotonic();before=snapshot();report={'schema':'solidcraft-physical-check/1','status':'fail','source_inputs':before,
|
||||
'python':sys.version.split()[0],'full_workspace_ci':'not_run_by_this_gate','runtime_assignment':False}
|
||||
exit_code=1
|
||||
try:
|
||||
result=subprocess.run([sys.executable,'-B','-m','unittest','discover','-s','assets/render/physical/tools','-p','test_*.py'],
|
||||
cwd=physical.ROOT,capture_output=True,timeout=120)
|
||||
(folder/'python-tests.stdout.txt').write_bytes(result.stdout);(folder/'python-tests.stderr.txt').write_bytes(result.stderr)
|
||||
physical.require(result.returncode==0,'physical Python regressions failed')
|
||||
report['python_tests']=result.stderr.decode(errors='replace')[-1000:]
|
||||
report['coverage']=physical.validate()
|
||||
bundle=physical.read(physical.PACK/'exports/native-cards.json')
|
||||
report['native']=native_check(args.cli,bundle['items']) if args.cli else {'status':'not_requested'}
|
||||
after=snapshot();physical.require(before==after,'physical/source inputs changed during validation')
|
||||
report['source_inputs_unchanged']=True;report['status']='pass';exit_code=0
|
||||
except (OSError,ValueError,TypeError,KeyError,subprocess.SubprocessError) as error:
|
||||
report['error']=str(error)
|
||||
report['seconds']=round(time.monotonic()-start,3)
|
||||
(folder/'report.json').write_bytes(physical.encoded(report))
|
||||
print(json.dumps({'status':report['status'],'report':str((folder/'report.json').relative_to(physical.ROOT)),
|
||||
'native_requested':bool(args.cli),'runtime_assignment':False,'error':report.get('error')},indent=2))
|
||||
return exit_code
|
||||
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export chosen reference materials through a trusted card-capable SolidCraft CLI.
|
||||
|
||||
A fresh command-line session creates no geometry or body assignments. The native
|
||||
application owns library-v2 serialization and content revisions. All output stays
|
||||
in a new review directory under target/. Older scalar-only executables refuse
|
||||
before any material is created. Public reference data is not design certification.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import physical as p
|
||||
|
||||
MAX_OUTPUT = 16 * 1024 * 1024
|
||||
PACK_ID = "tangency.physical-references"
|
||||
SOURCE_FILES = ("profiles.json", "sources.json", "bindings.json", "quantities.json",
|
||||
"exports/native-cards.json", "tools/physical.py", "tools/export_library.py")
|
||||
|
||||
|
||||
def input_pins() -> dict[str, str]:
|
||||
return {name: p.sha(p.PACK/name) for name in SOURCE_FILES}
|
||||
|
||||
|
||||
def selection(ids: list[str] | None, acknowledge: bool) -> dict:
|
||||
p.require(acknowledge, "Explicit --acknowledge-reference is required")
|
||||
before = input_pins()
|
||||
p.validate()
|
||||
profiles, sources, _ = p.load()
|
||||
selected, omitted = [], []
|
||||
names = sorted(profiles) if ids is None else ids
|
||||
p.require(isinstance(names, list) and 0 < len(names) <= 256, "Select 1..256 profiles")
|
||||
p.require(all(isinstance(name, str) for name in names) and len(names) == len(set(names)), "Duplicate or invalid selected profile")
|
||||
for id in names:
|
||||
p.require(id in profiles, f"Unknown profile: {id}")
|
||||
native = p.native_card(profiles[id], sources)
|
||||
density = next((row for row in native['card']['properties'] if row['data']['kind'] == 'density'), None)
|
||||
if density is None:
|
||||
omitted.append({'profile_id': id, 'reason': 'No supported point density; no nominal midpoint or unrelated substrate is substituted.'})
|
||||
continue
|
||||
selected.append({'profile_id': id, 'material_form': profiles[id]['material_form'],
|
||||
'command': p.prepare(id, True)['commands'][0],
|
||||
'extended_property_ids': [row['id'] for row in native['not_projected']]})
|
||||
p.require(selected, "No selected reference has a supported point density")
|
||||
p.require(before == input_pins(), "Source revision changed during plan preparation")
|
||||
return {'schema': 'solidcraft-physical-library-plan/1', 'executed': False,
|
||||
'reference_selection_required': True, 'assigns_bodies': False,
|
||||
'id': PACK_ID, 'input_sha256': before, 'materials': selected, 'omitted': omitted,
|
||||
'preserve_extended_profiles': True,
|
||||
'required_contract': 'material.create physical_card, material.inspect, solidcraft-library/2'}
|
||||
|
||||
|
||||
def registry_check(registry: object) -> None:
|
||||
p.require(isinstance(registry, list) and len(registry) <= 4096, "Invalid native command registry")
|
||||
p.require(all(isinstance(row, dict) and isinstance(row.get('id'), str) for row in registry), "Malformed native command record")
|
||||
commands = {row['id']: row for row in registry}
|
||||
p.require(len(commands) == len(registry), "Duplicate command ID")
|
||||
for name in ('file.new', 'material.create', 'material.inspect', 'library.export', 'library.inspect'):
|
||||
p.require(name in commands, f"Native command unavailable: {name}")
|
||||
p.require(all(isinstance(commands[name].get('params'), str) for name in ('material.create', 'library.export')), 'Malformed native parameter documentation')
|
||||
p.require('physical_card' in commands['material.create'].get('params', ''),
|
||||
"This executable cannot preserve physical cards; scalar material creation is refused")
|
||||
p.require('solidcraft-library/2' in commands['library.export'].get('params', ''),
|
||||
"Native library-v2 export is required; scalar export would lose engineering data")
|
||||
|
||||
|
||||
def invoke(cli: Path, arguments: list[str]) -> object:
|
||||
# Capture into temporary files, then enforce the JSON byte budget before reading.
|
||||
with tempfile.TemporaryFile() as out, tempfile.TemporaryFile() as err:
|
||||
result = subprocess.run([str(cli), *arguments], cwd=p.ROOT, stdout=out, stderr=err, timeout=180)
|
||||
p.require(out.tell() <= MAX_OUTPUT and err.tell() <= MAX_OUTPUT, "CLI output exceeds the diagnostic budget")
|
||||
err.seek(0)
|
||||
p.require(result.returncode == 0, 'Native command failed: ' + err.read(2048).decode(errors='replace'))
|
||||
out.seek(0)
|
||||
return json.load(out, object_pairs_hook=p.unique, parse_constant=p.reject_constant)
|
||||
|
||||
|
||||
def verify_catalog(catalog: object, plan: dict) -> None:
|
||||
p.require(isinstance(catalog, dict) and catalog.get('format') == 'solidcraft-library/2', "Native export did not produce library v2")
|
||||
p.require(catalog.get('id') == PACK_ID, "Wrong native library identity")
|
||||
entries = catalog.get('entries')
|
||||
p.require(isinstance(entries, list) and len(entries) == len(plan['materials']), "Missing or extra native materials")
|
||||
expected = {row['command']['params']['name']: row['command']['params'] for row in plan['materials']}
|
||||
found = set()
|
||||
for entry in entries:
|
||||
p.require(isinstance(entry, dict), "Invalid native entry")
|
||||
definition = entry.get('definition', {})
|
||||
p.require(isinstance(definition, dict) and definition.get('kind') == 'material', "Unexpected appearance entry")
|
||||
value = definition.get('value', {})
|
||||
p.require(isinstance(value, dict), "Invalid material definition")
|
||||
name = value.get('name')
|
||||
p.require(name in expected and name not in found, "Unknown or duplicate exported material")
|
||||
found.add(name)
|
||||
reference = expected[name]
|
||||
p.require(value.get('density_g_cm3') == reference['density_g_cm3'], "Assigned reference density changed")
|
||||
p.require(value.get('physical_card') == reference['physical_card'], "A physical card, source or condition was changed or dropped")
|
||||
p.require(value.get('appearance') is None, "Physical export must not assign a visual appearance")
|
||||
revision = entry.get('revision', '')
|
||||
p.require(isinstance(revision, str) and len(revision) == 64 and all(c in '0123456789abcdef' for c in revision), "Invalid native revision")
|
||||
# Revisions are subsequently verified by the real library.inspect command,
|
||||
# not a parallel Python approximation of serde's ordering/float formatting.
|
||||
|
||||
|
||||
def library_command(path: Path) -> dict:
|
||||
return {'command': 'library.export', 'params': {
|
||||
'path': str(path), 'id': PACK_ID, 'name': 'Physical references - select grade and conditions',
|
||||
'format': 'solidcraft-library/2', 'overwrite': False,
|
||||
'provenance': {'license': 'MIT OR Apache-2.0', 'author': 'SolidCraft contributors',
|
||||
'source_url': 'https://github.com/0xlillith/solidcraft/tree/assets/material-physical-properties/assets/render/physical'}}}
|
||||
|
||||
|
||||
def export(cli: Path, plan: dict) -> dict:
|
||||
cli = cli.resolve(strict=True)
|
||||
p.require(cli.is_file(), "Trusted CLI executable not found")
|
||||
p.require(plan.get("input_sha256") == input_pins(), "Stale physical reference plan")
|
||||
registry_check(invoke(cli, ['commands']))
|
||||
# No live app, existing document, source profile, output file or library is touched.
|
||||
stamp = datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ')
|
||||
folder = p.ROOT / 'target/physical-library-exports' / stamp
|
||||
p.require(not folder.exists(), "Review output already exists")
|
||||
folder.mkdir(parents=True, exist_ok=False)
|
||||
output, cold = folder/'physical-reference-library.json', folder/'cold-reopened-library.json'
|
||||
design = folder/'physical-reference-library-design.json'
|
||||
script = folder/'create.json'
|
||||
commands = [{'command': 'file.new', 'params': {'name': 'Physical reference library'}}]
|
||||
commands += [row['command'] for row in plan['materials']]
|
||||
commands.append(library_command(output))
|
||||
script.write_bytes(p.encoded({'commands': commands}))
|
||||
before = input_pins()
|
||||
p.require(before == plan['input_sha256'], 'Source changed after native preflight')
|
||||
invoke(cli, ['run', str(script), '--results', '--save', str(design)])
|
||||
catalog = p.read(output)
|
||||
verify_catalog(catalog, plan)
|
||||
inspected = invoke(cli, ['exec', 'library.inspect', json.dumps({'path': str(output)})])
|
||||
p.require(isinstance(inspected, dict) and inspected.get('catalog') == catalog, "Native library inspection disagrees with its export")
|
||||
# New process, cold document load and native re-export must preserve every card.
|
||||
reopen = folder/'reopen.json'
|
||||
reopen.write_bytes(p.encoded({'commands': [library_command(cold)]}))
|
||||
invoke(cli, ['run', str(reopen), '--in', str(design), '--results'])
|
||||
restored = p.read(cold)
|
||||
verify_catalog(restored, plan)
|
||||
p.require(restored == catalog, "Cold reopen changed the native material library")
|
||||
p.require(before == input_pins(), "Source revision changed during library export")
|
||||
receipt = {'schema': 'solidcraft-physical-library-export-receipt/1', 'status': 'pass',
|
||||
'cli_sha256': p.sha(cli), 'input_sha256': before, 'library_sha256': p.sha(output),
|
||||
'material_count': len(plan['materials']), 'omitted': plan['omitted'],
|
||||
'native_inspection': True, 'cold_reopen': True, 'body_assignment': False,
|
||||
'engineering_certification': False, 'extended_data_embedded': False,
|
||||
'library': str(output.relative_to(p.ROOT))}
|
||||
(folder/'receipt.json').write_bytes(p.encoded(receipt))
|
||||
return receipt
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--profile', action='append', help='Exact reference ID; default selects all point-density references')
|
||||
parser.add_argument('--acknowledge-reference', action='store_true')
|
||||
parser.add_argument('--cli', type=Path, help='Trusted card-capable executable; absent means a non-executing JSON plan only')
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
plan = selection(args.profile, args.acknowledge_reference)
|
||||
result = export(args.cli, plan) if args.cli else plan
|
||||
print(json.dumps(result, indent=2, ensure_ascii=True, allow_nan=False))
|
||||
return 0
|
||||
except (OSError, ValueError, KeyError, TypeError, subprocess.SubprocessError) as error:
|
||||
print(json.dumps({'status': 'fail', 'error': str(error)}), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,348 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate physical references and prepare non-executing schema-1 material cards.
|
||||
|
||||
JSON masters retain provenance, directional data, limits and unsupported quantities.
|
||||
No CAD document is opened, no body is assigned and no missing constant is invented.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
from collections import Counter
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
PACK = ROOT / 'assets/render/physical'
|
||||
MAX_BYTES = 8 * 1024 * 1024
|
||||
ID = re.compile(r'[a-z][a-z0-9-]{0,63}\Z')
|
||||
CORE = {'density','elasticity','tensile_strength','yield_strength','compressive_strength','shear_strength','thermal_conductivity','thermal_expansion','specific_heat'}
|
||||
PRESSURE = {'young_modulus','shear_modulus','tensile_strength','yield_strength','compressive_strength','shear_strength','flexural_strength','flexural_modulus','compressive_modulus','stress_at_strain','internal_bond_strength'}
|
||||
TEMPERATURE = {'glass_transition','melting_temperature','heat_deflection','service_temperature','decomposition_temperature'}
|
||||
DIMENSIONLESS = {'poisson_ratio','elongation_break','relative_permittivity','loss_tangent','water_absorption','hardness_shore_a','hardness_shore_d','hardness_brinell','hardness_knoop','specific_gravity','electrical_conductivity_iacs','refractive_index','porosity','void_ratio','thermal_emittance','solar_absorptance','thickness_swelling'}
|
||||
CONVERSIONS = {
|
||||
'kg/m^3':('density',1.,0.), 'g/cm^3':('density',1000.,0.), 'lb/in^3':('density',27679.904710203,0.),
|
||||
'Pa':('pressure',1.,0.), 'kPa':('pressure',1e3,0.), 'MPa':('pressure',1e6,0.), 'GPa':('pressure',1e9,0.),
|
||||
'psi':('pressure',6894.757293168,0.), 'ksi':('pressure',6894757.293168,0.),
|
||||
'1':('ratio',1.,0.), '%':('ratio',.01,0.), 'W/(m K)':('conductivity',1.,0.),
|
||||
'Btu/(h ft degF)':('conductivity',1.730734666371,0.), '1/K':('expansion',1.,0.),
|
||||
'ppm/K':('expansion',1e-6,0.), '1/degF':('expansion',1.8,0.),
|
||||
'J/(kg K)':('heat',1.,0.), 'J/(g K)':('heat',1000.,0.), 'Btu/(lb degF)':('heat',4186.8,0.),
|
||||
'K':('temperature',1.,0.), 'degC':('temperature',1.,273.15), 'degF':('temperature',5/9,255.3722222222222),
|
||||
'ohm m':('resistivity',1.,0.), 'ohm cm':('resistivity',.01,0.), 'microohm cm':('resistivity',1e-8,0.), 'ohm mm^2/m':('resistivity',1e-6,0.),
|
||||
'V/m':('field',1.,0.), 'kV/mm':('field',1e6,0.), 'V/mil':('field',1/.0000254,0.),
|
||||
'N':('force',1.,0.), 'N/m':('tear',1.,0.), 'pli':('tear',175.1268352465,0.),
|
||||
'Pa sqrt(m)':('toughness',1.,0.), 'MPa sqrt(m)':('toughness',1e6,0.),
|
||||
'm':('length',1.,0.), 'micrometre':('length',1e-6,0.), 'mil':('length',.0000254,0.),
|
||||
'rad':('angle',1.,0.), 'degree':('angle',math.pi/180,0.)}
|
||||
QUANTITY = {q:('pressure','Pa') for q in PRESSURE}
|
||||
QUANTITY.update({q:('temperature','K') for q in TEMPERATURE})
|
||||
QUANTITY.update({q:('ratio','1') for q in DIMENSIONLESS})
|
||||
QUANTITY.update({'density':('density','kg/m^3'),'grain_density':('density','kg/m^3'),
|
||||
'thermal_conductivity':('conductivity','W/(m K)'), 'thermal_expansion':('expansion','1/K'),
|
||||
'specific_heat':('heat','J/(kg K)'), 'volume_resistivity':('resistivity','ohm m'),
|
||||
'dielectric_strength':('field','V/m'), 'hardness_janka':('force','N'), 'tear_strength':('tear','N/m'),
|
||||
'fracture_toughness':('toughness','Pa sqrt(m)'), 'mean_particle_size':('length','m'),
|
||||
'dry_film_thickness':('length','m'), 'angle_of_repose':('angle','rad')})
|
||||
|
||||
class Invalid(ValueError):
|
||||
"""A physical reference violates the reviewed contract."""
|
||||
|
||||
def require(ok, message):
|
||||
if not ok: raise Invalid(message)
|
||||
|
||||
def unique(pairs):
|
||||
out = {}
|
||||
for key, value in pairs:
|
||||
require(key not in out, f'duplicate JSON field: {key}')
|
||||
out[key] = value
|
||||
return out
|
||||
|
||||
def reject_constant(value):
|
||||
raise Invalid(f'non-finite JSON constant: {value}')
|
||||
|
||||
def read(path):
|
||||
require(path.is_file() and not path.is_symlink(), f'expected regular input: {path.name}')
|
||||
require(path.stat().st_size <= MAX_BYTES, f'oversized input: {path.name}')
|
||||
raw = path.read_bytes();require(len(raw) <= MAX_BYTES, 'input grew beyond byte budget')
|
||||
data = json.loads(raw, object_pairs_hook=unique, parse_constant=reject_constant)
|
||||
require(isinstance(data, dict), 'expected JSON object')
|
||||
return data
|
||||
|
||||
def text(value, label, limit=2048):
|
||||
require(isinstance(value,str) and 0 < len(value.encode('utf-8')) <= limit and not any(ord(c)<32 for c in value), f'invalid {label}')
|
||||
|
||||
def number(value, low=-1e30, high=1e30):
|
||||
require(type(value) in (int,float) and low <= value <= high and math.isfinite(value), 'invalid bounded number')
|
||||
return float(value)
|
||||
|
||||
def close(a,b):
|
||||
return math.isclose(a,b,rel_tol=2e-11,abs_tol=1e-14*max(abs(b),1e-20))
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
def encoded(value):
|
||||
return (json.dumps(value,ensure_ascii=True,indent=2,allow_nan=False)+'\n').encode()
|
||||
|
||||
def check_conditions(c):
|
||||
base={'temperature_k','temperature_interval_k','moisture_dry_basis_kg_kg','strain_rate_per_s','state','direction','test_method'}
|
||||
numeric={'crosshead_speed_mm_min','frequency_hz','specimen_thickness_mm','engineering_strain','heating_rate_k_min',
|
||||
'test_stress_pa','wavelength_nm','minimum_film_thickness_m','immersion_hours','specimen_mass_kg'}
|
||||
strings={'environment','thermal_regime','density_basis','excitation'}
|
||||
require(isinstance(c,dict) and base<=set(c)<=base|numeric|strings|{'lower_thickness_exclusive','thickness_range_mm'},'unknown or missing condition field')
|
||||
for key in numeric & set(c): number(c[key],0,1e18)
|
||||
for key in strings & set(c): text(c[key],key,256)
|
||||
if 'lower_thickness_exclusive' in c: require(type(c['lower_thickness_exclusive']) is bool,'thickness endpoint flag must be Boolean')
|
||||
if 'thickness_range_mm' in c:
|
||||
bounds=c['thickness_range_mm']
|
||||
require(isinstance(bounds,list) and len(bounds)==2 and 0<number(bounds[0])<number(bounds[1]),'invalid specimen thickness range')
|
||||
if c['temperature_k'] is not None: number(c['temperature_k'],1e-20,20000)
|
||||
|
||||
def check_property(p, sources):
|
||||
require(isinstance(p,dict),'property must be an object')
|
||||
required={'id','quantity','value','unit','qualifier','source_id','source_locator','original','conditions','note','uncertainty'}
|
||||
require(required <= set(p) <= required|{'derivation'},'unknown or missing property fields')
|
||||
text(p['id'],'property ID',128)
|
||||
q=p['quantity'];require(q in QUANTITY and p['unit']==QUANTITY[q][1],'unknown quantity or wrong SI unit')
|
||||
require(p['source_id'] in sources,'unresolved property source');text(p['source_locator'],'source locator')
|
||||
require(p['qualifier'] in {'typical','reported_range','lower_bound','upper_bound','derived'},'invalid qualifier')
|
||||
orig=p['original'];require(isinstance(orig,dict) and set(orig)=={'value','unit','scale_to_si','offset_to_si'},'invalid original quantity')
|
||||
require(orig['unit'] in CONVERSIONS,'unknown source unit')
|
||||
dim,scale,offset=CONVERSIONS[orig['unit']]
|
||||
require(dim==QUANTITY[q][0],'source quantity has incompatible dimensions')
|
||||
require(number(orig['scale_to_si'])==scale and number(orig['offset_to_si'])==offset,'conversion recipe altered')
|
||||
value,raw=p['value'],orig['value'];is_range=isinstance(value,list)
|
||||
require(is_range==isinstance(raw,list),'range/scalar mismatch')
|
||||
if is_range:
|
||||
require(len(value)==len(raw)==2 and p['qualifier']=='reported_range','range needs two endpoints and range qualifier')
|
||||
require(number(value[0])<=number(value[1]),'reversed range')
|
||||
else: require(p['qualifier']!='reported_range','scalar cannot claim range')
|
||||
for v,r in zip(value if is_range else [value],raw if is_range else [raw]):
|
||||
v,r=number(v),number(r);require(close(v,r*scale+offset),'SI value does not reproduce cited original')
|
||||
if q not in {'thermal_expansion','poisson_ratio'}: require(v>=0,'negative physical value')
|
||||
if q in TEMPERATURE|{'density','grain_density','young_modulus','shear_modulus','specific_heat','thermal_conductivity','relative_permittivity','refractive_index'}:require(v>0,'positive physical quantity required')
|
||||
if q in {'porosity','thermal_emittance','solar_absorptance'}:require(v<=1,'fraction above one')
|
||||
if q.startswith('hardness_shore_'):require(v<=100,'Shore hardness above 100')
|
||||
c=p['conditions'];check_conditions(c)
|
||||
for key in ['temperature_k','moisture_dry_basis_kg_kg','strain_rate_per_s']:
|
||||
require(key in c,'condition field must be explicit even when unknown')
|
||||
if c[key] is not None:number(c[key],0,1e12)
|
||||
if c.get('temperature_interval_k') is not None:
|
||||
interval=c['temperature_interval_k'];require(isinstance(interval,list) and len(interval)==2,'temperature interval shape')
|
||||
require(0<number(interval[0])<=number(interval[1])<=20000,'temperature interval bounds')
|
||||
for key in ('state','direction','test_method'):text(c.get(key),key,1024)
|
||||
if p['uncertainty'] is not None:
|
||||
u=p['uncertainty'];require(isinstance(u,dict) and set(u)=={'reported_plus_minus','interpretation'},'invalid uncertainty')
|
||||
number(u['reported_plus_minus'],0);text(u['interpretation'],'uncertainty interpretation')
|
||||
require((p['qualifier']=='derived')==('derivation' in p),'derived value needs a calculation receipt')
|
||||
|
||||
def check_derivation(record, properties):
|
||||
d=record['derivation'];require(isinstance(d,dict),'invalid derivation')
|
||||
require(all(key in properties for key in d.get('input_property_ids',[])),'missing derivation input')
|
||||
if d.get('formula')=='young_modulus/(2*shear_modulus)-1':
|
||||
require(record['quantity']=='poisson_ratio','wrong modulus-derived quantity')
|
||||
e,g=properties['young_modulus'],properties['shear_modulus']
|
||||
require(e['source_id']==g['source_id']==record['source_id'],'mixed-source elastic derivation')
|
||||
expected=number(e['value'])/(2*number(g['value'],1e-30))-1
|
||||
require(-1<expected<.5 and close(record['value'],expected),'incorrect derived Poisson ratio')
|
||||
elif d.get('formula')=='specific_gravity*1000*(1+moisture_dry_basis_kg_kg)':
|
||||
require(record['quantity']=='density','wrong moisture-derived quantity')
|
||||
moisture=number(d.get('moisture_dry_basis_kg_kg'),0,100)
|
||||
require(d.get('water_reference_density_kg_m3')==1000 and record['conditions']['moisture_dry_basis_kg_kg']==moisture,'moisture-density conditions mismatch')
|
||||
expected=number(properties['specific_gravity']['value'])*1000*(1+moisture)
|
||||
require(close(record['value'],expected),'incorrect moisture-derived density')
|
||||
else:raise Invalid('unreviewed derivation formula')
|
||||
|
||||
def validate_data(data, source_data, binding, registry, root=ROOT):
|
||||
require(data.get('schema')=='solidcraft-physical-reference-profiles/1' and data.get('runtime_assignment') is False,'unknown profile schema or false runtime claim')
|
||||
require(source_data.get('schema')=='solidcraft-physical-sources/1','unknown source schema')
|
||||
require(binding.get('schema')=='solidcraft-physical-bindings/1','unknown binding schema')
|
||||
require(registry.get('units')=={q:u for q,(_,u) in QUANTITY.items()},'quantity registry changed without validator review')
|
||||
require(registry.get('conversions')=={k:{'scale':v[1],'offset':v[2]} for k,v in CONVERSIONS.items()},'unit conversion registry drift')
|
||||
require(isinstance(source_data.get('sources'),list) and 1<=len(source_data['sources'])<=256,'source count')
|
||||
sources={}
|
||||
for s in source_data['sources']:
|
||||
require(isinstance(s,dict) and isinstance(s.get('id'),str) and ID.fullmatch(s['id']) is not None and s['id'] not in sources,'invalid/duplicate source')
|
||||
text(s.get('title'),'source title',256);text(s.get('url'),'source URL')
|
||||
require(s['url'].startswith('https://') and s.get('kind')=='public_reference','source must identify public HTTPS reference')
|
||||
require(s.get('license') is None or isinstance(s['license'],str),'invalid source rights metadata')
|
||||
sources[s['id']]=s
|
||||
profiles={};require(isinstance(data.get('profiles'),list) and 1<=len(data['profiles'])<=256,'profile count')
|
||||
for p in data['profiles']:
|
||||
require(isinstance(p,dict) and isinstance(p.get('id'),str) and ID.fullmatch(p['id']) is not None and p['id'] not in profiles,'invalid/duplicate profile')
|
||||
require(p.get('family') in {'wood','polymer','glass','metal','other'},'unknown native material family')
|
||||
require(p.get('source_id') in sources and p.get('certified_design_allowables') is False,'invalid provenance or false certification')
|
||||
require(type(p.get('isotropic_reference_model')) is bool,'isotropic policy must be Boolean')
|
||||
text(p.get('designation'),'designation',256);text(p.get('reference_state'),'state',800)
|
||||
allowed={'id','designation','family','material_form','reference_state','identity_status','isotropic_reference_model','source_id','properties','limitations','certified_design_allowables','quarantined_source_ids'}
|
||||
require(set(p)<=allowed,'unknown profile field')
|
||||
require(all(x in sources for x in p.get('quarantined_source_ids',[])),'unresolved quarantined source')
|
||||
require(isinstance(p.get('properties'),list) and len(p['properties'])<=128,'property list bounds')
|
||||
seen={}
|
||||
for r in p['properties']:
|
||||
check_property(r,sources);require(r['id'] not in seen,'duplicate property ID');seen[r['id']]=r
|
||||
for r in seen.values():
|
||||
if r['qualifier']=='derived':check_derivation(r,seen)
|
||||
profiles[p['id']]=p
|
||||
expected={'catalog':('docs/render-materials/materials.json',600),'surfaces':('assets/render/starter/materials/manifest.json',48)}
|
||||
authorities={}
|
||||
for key,(path,count) in expected.items():
|
||||
spec=binding.get('inputs',{}).get(key,{})
|
||||
require(spec.get('path')==path and type(spec.get('count')) is int and spec['count']==count,'authority path/count mismatch')
|
||||
require(spec.get('sha256')==sha(root/path),'catalog changed: explicit binding review required')
|
||||
authorities[key]=read(root/path)['items'];require(len(authorities[key])==count,'authority count mismatch')
|
||||
concepts={c['id']:c for c in authorities['catalog']}
|
||||
require(len(binding.get('catalog',[]))==600 and len(binding.get('surfaces',[]))==48,'all concepts/surfaces need physical specifications')
|
||||
checked={}
|
||||
for b in binding['catalog']:
|
||||
id=b.get('catalog_id');require(id in concepts and id not in checked and b.get('name')==concepts[id]['name'],'invalid/duplicate concept binding')
|
||||
require(b.get('auto_assign_body') is False and b.get('preserve_existing_material') is True and b.get('unknown_is_zero') is False,'appearance must not overwrite host physics')
|
||||
require(b.get('physical_role') in binding.get('role_definitions',{}),'unknown physical role')
|
||||
require(isinstance(b.get('required_definition_fields'),list) and len(b['required_definition_fields'])>0,'physical requirements cannot be empty')
|
||||
refs=b.get('references');require(isinstance(refs,list) and len(refs)<=16,'reference list bounds');pairs=set()
|
||||
for ref in refs:
|
||||
require(ref.get('profile_id') in profiles,'unresolved physical reference');text(ref.get('relation'),'reference relationship',256)
|
||||
pair=(ref['profile_id'],ref['relation']);require(pair not in pairs,'duplicate reference');pairs.add(pair)
|
||||
require(b.get('status')==('reference_selection_required' if refs else 'specific_recipe_required'),'status conflicts with references')
|
||||
checked[id]=b
|
||||
surface_ids=set();originals={s['id']:s for s in authorities['surfaces']}
|
||||
for s in binding['surfaces']:
|
||||
id=s.get('surface_id');require(id in originals and id not in surface_ids,'invalid surface ID');original=originals[id]
|
||||
require(s.get('catalog_ids')==original['catalog_ids']==s.get('physical_binding_ids'),'surface physical association drift')
|
||||
require(s.get('name')==original['name'] and s.get('auto_assign_body') is False and s.get('preserve_existing_material') is True,'surface scope/name mismatch')
|
||||
first=checked[original['catalog_ids'][0]]
|
||||
require(s.get('status')==first['status'] and s.get('physical_role')==first['physical_role'],'surface status/role drift');surface_ids.add(id)
|
||||
return profiles,sources
|
||||
|
||||
def load():
|
||||
data,sources,binding,registry=[read(PACK/name) for name in ('profiles.json','sources.json','bindings.json','quantities.json')]
|
||||
profiles,source_map=validate_data(data,sources,binding,registry)
|
||||
return profiles,source_map,binding
|
||||
|
||||
def native_condition(p,r):
|
||||
c=r['conditions'];extra={k:v for k,v in c.items() if k not in {'state','temperature_k','moisture_dry_basis_kg_kg','strain_rate_per_s'} and v is not None}
|
||||
state=c['state']+' | '+r['qualifier']+' reference; source review required; not design allowables.'
|
||||
if extra:state+=' | '+json.dumps(extra,sort_keys=True,separators=(',',':'))
|
||||
if r['uncertainty'] is not None:state+=' | Reported uncertainty retained in extended profile.'
|
||||
if r['qualifier']=='derived':state+=' | Derived value; formula retained in extended profile.'
|
||||
require(len(state.encode())<=1024,'native condition overflow')
|
||||
return {k:c[k] for k in ('temperature_k','moisture_dry_basis_kg_kg','strain_rate_per_s')}|{'state':state}
|
||||
|
||||
def native_card(p,sources):
|
||||
selected=[];used=set();properties=p['properties'];by_q={}
|
||||
for r in properties:by_q.setdefault(r['quantity'],[]).append(r)
|
||||
def point(q):
|
||||
rows=by_q.get(q,[])
|
||||
if len(rows)!=1:return None
|
||||
r=rows[0]
|
||||
return r if type(r['value']) in (int,float) and r['qualifier'] in {'typical','derived'} and r['conditions']['direction'] in {'not_reported','isotropic'} else None
|
||||
def add(r,data,extra=()):
|
||||
selected.append({'data':data,'source_id':r['source_id'],'conditions':native_condition(p,r)})
|
||||
used.add(r['id']);used.update(extra)
|
||||
rho=point('density')
|
||||
if rho:add(rho,{'kind':'density','kg_m3':rho['value']})
|
||||
cp=point('specific_heat')
|
||||
if cp:add(cp,{'kind':'specific_heat','j_kg_k':cp['value']})
|
||||
for q in ('tensile_strength','yield_strength','compressive_strength','shear_strength'):
|
||||
r=point(q)
|
||||
if r:add(r,{'kind':q,'pa':r['value']})
|
||||
if p['isotropic_reference_model']:
|
||||
e,nu=point('young_modulus'),point('poisson_ratio')
|
||||
if e and nu:
|
||||
keys=('temperature_k','temperature_interval_k','moisture_dry_basis_kg_kg','strain_rate_per_s','state','direction','environment','thermal_regime','specimen_thickness_mm','heating_rate_k_min')
|
||||
require(e['source_id']==nu['source_id'] and all(e['conditions'].get(k)==nu['conditions'].get(k) for k in keys),'mixed elastic source/conditions')
|
||||
require(-1<number(nu['value'])<.5,'unstable isotropic Poisson ratio')
|
||||
add(e,{'kind':'elasticity','model':{'symmetry':'isotropic','young_modulus_pa':e['value'],'poisson_ratio':nu['value']}},[nu['id']])
|
||||
selected[-1]['conditions']['state']+=' | Isotropic reference model; not validated part behavior.'
|
||||
if nu['qualifier']=='derived':selected[-1]['conditions']['state']+=' Poisson ratio derived from same-source E and G, not independently measured.'
|
||||
for q,field in [('thermal_conductivity','w_m_k'),('thermal_expansion','per_k')]:
|
||||
r=point(q)
|
||||
if r:
|
||||
add(r,{'kind':q,field:[r['value']]*3,'axes':'material123'})
|
||||
selected[-1]['conditions']['state']+=' | Isotropic reference approximation, not measured directional tensor.'
|
||||
selected.sort(key=lambda r:r['data']['kind']);source_ids=sorted({r['source_id'] for r in selected} or {p['source_id']})
|
||||
card={'schema_version':1,'designation':p['designation'],'family':p['family'],
|
||||
'sources':[{'id':id,'title':sources[id]['title'],'kind':'public_reference','license':sources[id]['license'],'reference':sources[id]['url']} for id in source_ids],
|
||||
'properties':selected}
|
||||
return {'profile_id':p['id'],'card':card,
|
||||
'native_projection_status':'partial_native_card' if selected else 'extended_data_only',
|
||||
'exported_property_ids':sorted(used),
|
||||
'not_projected':[{'id':r['id'],'quantity':r['quantity'],'reason':'Retained in extended profile: unsupported native quantity, range/bound, directional measurement or incomplete constitutive model.'} for r in properties if r['id'] not in used],
|
||||
'missing_native_kinds':sorted(CORE-{r['data']['kind'] for r in selected}),
|
||||
'reference_selection_required':True,'runtime_assignment':False}
|
||||
|
||||
def make_exports():
|
||||
profiles,sources,bindings=load();cards=[native_card(p,sources) for p in profiles.values()]
|
||||
pin={name:sha(PACK/name) for name in ('sources.json','profiles.json','quantities.json','bindings.json')}
|
||||
data={'schema':'solidcraft-physical-card-bundle/1','native_card_schema':1,'native_library_format':False,
|
||||
'source_sha256':pin,'generator_sha256':sha(Path(__file__)),'runtime_assignment':False,'items':cards}
|
||||
coverage={'schema':'solidcraft-physical-coverage/1','profile_count':len(profiles),'source_count':len(sources),
|
||||
'property_records':sum(len(p['properties']) for p in profiles.values()),'catalog_specifications':len(bindings['catalog']),
|
||||
'concepts_with_reference_candidates':sum(bool(c['references']) for c in bindings['catalog']),
|
||||
'concepts_needing_specific_recipe':sum(not c['references'] for c in bindings['catalog']),
|
||||
'surface_specifications':len(bindings['surfaces']),
|
||||
'surfaces_with_reference_candidates':sum(s['status']=='reference_selection_required' for s in bindings['surfaces']),
|
||||
'native_property_blocks':sum(len(c['card']['properties']) for c in cards),
|
||||
'nonempty_native_cards':sum(bool(c['card']['properties']) for c in cards),
|
||||
'extended_only_profiles':sum(not c['card']['properties'] for c in cards),
|
||||
'profiles_with_point_density':sum(any(r['data']['kind']=='density' for r in c['card']['properties']) for c in cards),
|
||||
'quantities':dict(sorted(Counter(r['quantity'] for p in profiles.values() for r in p['properties']).items())),
|
||||
'runtime_assignment':False,'numerically_complete_catalog_claim':False}
|
||||
return {'native-cards.json':data,'coverage.json':coverage}
|
||||
|
||||
def build():
|
||||
outputs=make_exports();folder=PACK/'exports';folder.mkdir(exist_ok=True)
|
||||
for name,data in outputs.items():
|
||||
path=folder/name;require(not path.is_symlink(),'refusing symlink export');path.write_bytes(encoded(data))
|
||||
return outputs['coverage.json']
|
||||
|
||||
def validate():
|
||||
outputs=make_exports()
|
||||
for name,data in outputs.items():
|
||||
path=PACK/'exports'/name
|
||||
require(path.is_file() and not path.is_symlink() and path.read_bytes()==encoded(data),f'stale export: {name}; review source changes before rebuilding')
|
||||
return {'status':'pass',**outputs['coverage.json']}
|
||||
|
||||
def resolve(id):
|
||||
profiles,_,binding=load()
|
||||
if id.startswith('SURF-'):
|
||||
row=next((s for s in binding['surfaces'] if s['surface_id']==id),None)
|
||||
require(row is not None,'unknown surface ID');id=row['catalog_ids'][0]
|
||||
row=next((c for c in binding['catalog'] if c['catalog_id']==id),None)
|
||||
require(row is not None,'unknown catalog ID')
|
||||
return {'binding':row,'profiles':[profiles[r['profile_id']] for r in row['references']],'runtime_assignment':False}
|
||||
|
||||
def prepare(id,acknowledge):
|
||||
require(acknowledge,'--acknowledge-reference is required; these are not certified design allowables')
|
||||
profiles,sources,_=load();require(id in profiles,'unknown reference profile')
|
||||
p=profiles[id];result=native_card(p,sources)
|
||||
densities=[v for v in result['card']['properties'] if v['data']['kind']=='density']
|
||||
require(len(densities)==1,'no single supported density; select a reviewed point value/grade before material creation')
|
||||
name='REF '+p['designation'];require(len(name.encode())<=128,'material name too long')
|
||||
return {'schema':'solidcraft-physical-command-plan/1',
|
||||
'requires':['material.create must explicitly support physical_card; refuse older command contracts',
|
||||
'review grade, form, temperature, moisture, process and density basis before execution',
|
||||
'body assignment is a separate explicit operation; preserve existing appearances'],
|
||||
'executed':False,'assigns_bodies':False,'profile_id':id,
|
||||
'commands':[{'command':'material.create','params':{'name':name,'density_g_cm3':densities[0]['data']['kg_m3']/1000,'physical_card':result['card']}}],
|
||||
'extended_profile':'assets/render/physical/profiles.json#'+id,'limitations':p['limitations'],
|
||||
'omitted_native_properties':result['not_projected']}
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('command',choices=['build','validate','resolve','prepare']);parser.add_argument('id',nargs='?')
|
||||
parser.add_argument('--acknowledge-reference',action='store_true');args=parser.parse_args()
|
||||
try:
|
||||
if args.command=='build':result=build()
|
||||
elif args.command=='validate':result=validate()
|
||||
elif args.command=='resolve':result=resolve(args.id or '')
|
||||
else:result=prepare(args.id or '',args.acknowledge_reference)
|
||||
print(json.dumps(result,ensure_ascii=True,indent=2,allow_nan=False));return 0
|
||||
except (ValueError,OSError,TypeError,KeyError,AttributeError,RecursionError) as error:
|
||||
print(json.dumps({'status':'fail','error':str(error)}),file=sys.stderr);return 1
|
||||
|
||||
if __name__=='__main__':
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,121 @@
|
||||
"""Regression checks for explicit, no-loss physical-library export planning."""
|
||||
import copy
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import export_library as e
|
||||
import physical as p
|
||||
|
||||
|
||||
def modern_registry():
|
||||
rows = [{'id': name, 'params': ''} for name in ('file.new', 'material.create', 'material.inspect', 'library.export', 'library.inspect')]
|
||||
rows[1]['params'] = 'physical_card: schema 1'
|
||||
rows[3]['params'] = 'format solidcraft-library/2'
|
||||
return rows
|
||||
|
||||
|
||||
def projected_catalog(plan):
|
||||
entries = []
|
||||
for i, row in enumerate(plan['materials']):
|
||||
params = row['command']['params']
|
||||
entries.append({'id': e.PACK_ID + '/material-' + str(i), 'revision': 'a'*64,
|
||||
'definition': {'kind': 'material', 'value': copy.deepcopy(params)}})
|
||||
return {'format': 'solidcraft-library/2', 'id': e.PACK_ID, 'entries': entries}
|
||||
|
||||
|
||||
class ExportLibraryTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.plan = e.selection(None, True)
|
||||
|
||||
def test_plan_covers_every_point_density_without_part_assignment(self):
|
||||
self.assertEqual(len(self.plan['materials']), 46)
|
||||
self.assertEqual(len(self.plan['omitted']), 13)
|
||||
self.assertFalse(self.plan['assigns_bodies'])
|
||||
self.assertFalse(self.plan['executed'])
|
||||
self.assertTrue(self.plan['preserve_extended_profiles'])
|
||||
ids = {x['profile_id'] for x in self.plan['materials']}
|
||||
omitted = {x['profile_id'] for x in self.plan['omitted']}
|
||||
self.assertFalse(ids & omitted)
|
||||
self.assertEqual(len(ids | omitted), 59)
|
||||
for row in self.plan['materials']:
|
||||
self.assertEqual(row['command']['command'], 'material.create')
|
||||
self.assertEqual(set(row['command']['params']), {'name', 'density_g_cm3', 'physical_card'})
|
||||
|
||||
def test_acknowledgement_unknown_duplicate_and_empty_selections_refuse(self):
|
||||
for ids, acknowledge in [(None, False), ([], True), (['unknown'], True), (['steel-c45']*2, True)]:
|
||||
with self.subTest(ids=ids), self.assertRaises(p.Invalid):
|
||||
e.selection(ids, acknowledge)
|
||||
|
||||
def test_ranges_and_coatings_without_density_are_not_assigned(self):
|
||||
omitted = {x['profile_id'] for x in self.plan['omitted']}
|
||||
self.assertTrue({'c71-enamel', 'hmg-stoving-hammer', 'hmg-sc601-clear', 'uv22-coating'} <= omitted)
|
||||
with self.assertRaises(p.Invalid):
|
||||
e.selection(['c71-enamel'], True)
|
||||
plan = e.selection(['pmma-goodfellow-sheet'], True)
|
||||
params = plan['materials'][0]['command']['params']
|
||||
self.assertAlmostEqual(params['density_g_cm3'], 1.19)
|
||||
self.assertNotIn('elasticity', {r['data']['kind'] for r in params['physical_card']['properties']})
|
||||
|
||||
def test_old_scalar_registry_refuses_and_modern_contract_is_recognized(self):
|
||||
e.registry_check(modern_registry())
|
||||
for field, replacement in [(1, 'density and colour only'), (3, 'scalar library/1')]:
|
||||
rows = modern_registry()
|
||||
rows[field]['params'] = replacement
|
||||
with self.assertRaises(p.Invalid):
|
||||
e.registry_check(rows)
|
||||
for value in [None, {}, [None], modern_registry()+[modern_registry()[0]]]:
|
||||
with self.subTest(value=value), self.assertRaises(p.Invalid):
|
||||
e.registry_check(value)
|
||||
|
||||
def test_catalog_retains_every_native_value_source_and_condition(self):
|
||||
catalog = projected_catalog(self.plan)
|
||||
e.verify_catalog(catalog, self.plan)
|
||||
for mutation in ('drop_card', 'density', 'appearance', 'source', 'state', 'revision', 'duplicate', 'missing'):
|
||||
value = copy.deepcopy(catalog)
|
||||
material = value['entries'][0]['definition']['value']
|
||||
if mutation == 'drop_card':material.pop('physical_card')
|
||||
elif mutation == 'density':material['density_g_cm3'] *= 2
|
||||
elif mutation == 'appearance':material['appearance'] = {'name': 'unrequested optical change'}
|
||||
elif mutation == 'source':material['physical_card']['sources'][0]['reference'] = 'changed'
|
||||
elif mutation == 'state':material['physical_card']['properties'][0]['conditions']['state'] = 'wrong condition'
|
||||
elif mutation == 'revision':value['entries'][0]['revision'] = 'not a revision'
|
||||
elif mutation == 'duplicate':value['entries'][1] = copy.deepcopy(value['entries'][0])
|
||||
elif mutation == 'missing':value['entries'].pop()
|
||||
with self.subTest(mutation=mutation), self.assertRaises(p.Invalid):
|
||||
e.verify_catalog(value, self.plan)
|
||||
|
||||
def test_legacy_refusal_does_not_create_output_or_run_mutations(self):
|
||||
rows = modern_registry()
|
||||
rows[1]['params'] = 'no card persistence'
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
cli = root/'trusted-cli-fixture'
|
||||
cli.write_bytes(b'unit test marker; not executable')
|
||||
with patch.object(p, 'ROOT', root), patch.object(e, 'invoke', return_value=rows) as invoke:
|
||||
with self.assertRaises(p.Invalid):e.export(cli, self.plan)
|
||||
invoke.assert_called_once_with(cli.resolve(), ['commands'])
|
||||
self.assertFalse((root/'target').exists())
|
||||
|
||||
def test_stale_plan_refuses_before_executable_invocation(self):
|
||||
plan = copy.deepcopy(self.plan)
|
||||
plan['input_sha256']['profiles.json'] = '0'*64
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
cli = Path(temporary)/'fixture'
|
||||
cli.write_bytes(b'fixture')
|
||||
with patch.object(e, 'invoke') as invoke:
|
||||
with self.assertRaises(p.Invalid):e.export(cli, plan)
|
||||
invoke.assert_not_called()
|
||||
|
||||
def test_library_command_has_no_overwrite_and_no_body_targets(self):
|
||||
command = e.library_command(Path('review.json'))
|
||||
self.assertEqual(command['command'], 'library.export')
|
||||
self.assertEqual(command['params']['format'], 'solidcraft-library/2')
|
||||
self.assertIs(command['params']['overwrite'], False)
|
||||
self.assertNotIn('targets', command['params'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,277 @@
|
||||
"""Regression tests for reference data, physical scope and loss-aware projection."""
|
||||
import copy
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import physical as p
|
||||
|
||||
class PhysicalTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.data,cls.sources,cls.bindings,cls.registry=[p.read(p.PACK/name) for name in ('profiles.json','sources.json','bindings.json','quantities.json')]
|
||||
cls.profiles,cls.source_map=p.validate_data(cls.data,cls.sources,cls.bindings,cls.registry)
|
||||
|
||||
def mutated(self,which,change):
|
||||
args=copy.deepcopy([self.data,self.sources,self.bindings,self.registry]);change(args[which])
|
||||
with self.assertRaises((p.Invalid,KeyError,TypeError)):p.validate_data(*args)
|
||||
|
||||
def row(self,id,quantity):
|
||||
return next(x for x in self.profiles[id]['properties'] if x['quantity']==quantity)
|
||||
|
||||
def test_all_profiles_and_associations_validate(self):
|
||||
self.assertGreaterEqual(len(self.profiles),51)
|
||||
self.assertEqual(len(self.bindings['catalog']),600)
|
||||
self.assertEqual(len(self.bindings['surfaces']),48)
|
||||
|
||||
def test_duplicate_json_fields_and_nonfinite_literals_refuse(self):
|
||||
with self.assertRaises(p.Invalid):json.loads('{"density":1,"density":2}',object_pairs_hook=p.unique)
|
||||
for value in ('NaN','Infinity','-Infinity'):
|
||||
with self.assertRaises(p.Invalid):json.loads('{"value":'+value+'}',parse_constant=p.reject_constant)
|
||||
|
||||
def test_numeric_boolean_text_infinity_and_huge_integers_refuse(self):
|
||||
for v in (True,False,'1',float('nan'),float('inf'),10**400,-10**400):
|
||||
with self.subTest(v=repr(v)[:20]),self.assertRaises(p.Invalid):p.number(v)
|
||||
|
||||
def test_units_and_source_arithmetic_are_checked(self):
|
||||
row=copy.deepcopy(self.row('aluminium-6061-t6','young_modulus'))
|
||||
for change in (lambda x:x.update(unit='MPa'),lambda x:x.update(value=x['value']/1000),
|
||||
lambda x:x['original'].update(scale_to_si=1),lambda x:x['original'].update(unit='degC')):
|
||||
bad=copy.deepcopy(row);change(bad)
|
||||
with self.assertRaises(p.Invalid):p.check_property(bad,self.source_map)
|
||||
|
||||
def test_temperature_conversions_are_affine_not_scalar(self):
|
||||
r=self.row('epoxy-690','heat_deflection')
|
||||
self.assertAlmostEqual(r['value'],(115-32)*5/9+273.15,places=9)
|
||||
self.assertIsNone(r['conditions']['temperature_k'])
|
||||
self.assertAlmostEqual(self.row('pom-c','glass_transition')['value'],213.15)
|
||||
|
||||
def test_electrical_resistivity_and_breakdown_have_distinct_units(self):
|
||||
self.assertAlmostEqual(self.row('steel-304-plate','volume_resistivity')['value'],74e-8)
|
||||
self.assertAlmostEqual(self.row('ptfe','dielectric_strength')['value'],80e6)
|
||||
self.assertAlmostEqual(self.row('silicone-ds20','dielectric_strength')['value'],350/.0000254,delta=1e-4)
|
||||
|
||||
def test_ranges_never_become_a_midpoint(self):
|
||||
result=p.native_card(self.profiles['tpu95-feedstock'],self.source_map)
|
||||
self.assertFalse(any(r['data']['kind']=='density' for r in result['card']['properties']))
|
||||
with self.assertRaises(p.Invalid):p.prepare('tpu95-feedstock',True)
|
||||
|
||||
def test_reversed_range_and_wrong_range_qualifier_refuse(self):
|
||||
r=copy.deepcopy(self.row('tpu95-feedstock','density'));r['value'].reverse()
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
r=copy.deepcopy(self.row('tpu95-feedstock','density'));r['qualifier']='typical'
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
|
||||
def test_limits_are_not_native_nominal_strengths(self):
|
||||
result=p.native_card(self.profiles['titanium-grade5'],self.source_map)
|
||||
kinds={r['data']['kind'] for r in result['card']['properties']}
|
||||
self.assertNotIn('yield_strength',kinds);self.assertNotIn('tensile_strength',kinds)
|
||||
|
||||
def test_missing_poisson_ratio_does_not_invent_elasticity(self):
|
||||
for id in ('steel-304-plate','peek','pa6-stock','epoxy-690'):
|
||||
result=p.native_card(self.profiles[id],self.source_map)
|
||||
self.assertNotIn('elasticity',{r['data']['kind'] for r in result['card']['properties']})
|
||||
|
||||
def test_native_steel_c45_analytic_elastic_constants(self):
|
||||
result=p.native_card(self.profiles['steel-c45'],self.source_map)
|
||||
model=next(r['data']['model'] for r in result['card']['properties'] if r['data']['kind']=='elasticity')
|
||||
self.assertEqual(model['young_modulus_pa'],210e9)
|
||||
self.assertAlmostEqual(model['young_modulus_pa']/(2*(1+model['poisson_ratio'])),80.76923076923077e9)
|
||||
|
||||
def test_derived_poisson_is_not_presented_as_measured(self):
|
||||
result=p.native_card(self.profiles['c11000'],self.source_map)
|
||||
elastic=next(r for r in result['card']['properties'] if r['data']['kind']=='elasticity')
|
||||
self.assertIn('derived',elastic['conditions']['state'])
|
||||
self.assertAlmostEqual(elastic['data']['model']['poisson_ratio'],17000/(2*6400)-1)
|
||||
|
||||
def test_derived_value_without_receipt_refuses(self):
|
||||
r=copy.deepcopy(self.row('c11000','poisson_ratio'));del r['derivation']
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
|
||||
def test_wood_moisture_density_not_dry_mass_specific_gravity(self):
|
||||
r=self.row('wood-white-oak','density')
|
||||
self.assertAlmostEqual(r['value'],761.6)
|
||||
self.assertNotEqual(r['value'],680)
|
||||
self.assertEqual(r['conditions']['moisture_dry_basis_kg_kg'],.12)
|
||||
|
||||
def test_wood_flexure_not_isotropic_young_modulus(self):
|
||||
result=p.native_card(self.profiles['wood-white-oak'],self.source_map)
|
||||
self.assertNotIn('elasticity',{r['data']['kind'] for r in result['card']['properties']})
|
||||
self.assertNotIn('compressive_strength',{r['data']['kind'] for r in result['card']['properties']})
|
||||
self.assertIn('flexural_modulus',{r['quantity'] for r in result['not_projected']})
|
||||
|
||||
def test_print_directions_and_uncertainty_are_preserved(self):
|
||||
profile=self.profiles['pla-printed']
|
||||
strengths=[x for x in profile['properties'] if x['quantity']=='tensile_strength']
|
||||
self.assertEqual({x['conditions']['direction'] for x in strengths},{'XY','Z'})
|
||||
self.assertTrue(all(x['uncertainty'] is not None for x in strengths))
|
||||
self.assertNotIn('tensile_strength',{r['data']['kind'] for r in p.native_card(profile,self.source_map)['card']['properties']})
|
||||
|
||||
def test_finite_strain_stress_never_becomes_elastic_modulus(self):
|
||||
profile=self.profiles['silicone-ds20']
|
||||
self.assertEqual(self.row('silicone-ds20','stress_at_strain')['conditions']['engineering_strain'],1)
|
||||
self.assertNotIn('young_modulus',{r['quantity'] for r in profile['properties']})
|
||||
|
||||
def test_source_conflicts_stay_quarantined(self):
|
||||
profile=self.profiles['abs-printed']
|
||||
self.assertTrue(profile['quarantined_source_ids'])
|
||||
self.assertNotIn('density',{r['quantity'] for r in profile['properties']})
|
||||
with self.assertRaises(p.Invalid):p.prepare('abs-printed',True)
|
||||
|
||||
def test_fr4_frequency_and_cte_regimes_stay_distinct(self):
|
||||
profile=self.profiles['fr4-370hr']
|
||||
eps=[r for r in profile['properties'] if r['quantity']=='relative_permittivity']
|
||||
self.assertEqual(len({r['conditions']['frequency_hz'] for r in eps}),5)
|
||||
z=[r for r in profile['properties'] if r['quantity']=='thermal_expansion' and r['conditions']['direction']=='Z']
|
||||
self.assertEqual({r['conditions']['thermal_regime'] for r in z},{'pre-Tg','post-Tg'})
|
||||
self.assertNotIn('elasticity',{r['data']['kind'] for r in p.native_card(profile,self.source_map)['card']['properties']})
|
||||
|
||||
def test_silica_and_sapphire_are_not_the_same_material_model(self):
|
||||
self.assertTrue(self.profiles['fused-silica']['isotropic_reference_model'])
|
||||
self.assertFalse(self.profiles['sapphire']['isotropic_reference_model'])
|
||||
self.assertNotIn('thermal_expansion',{r['data']['kind'] for r in p.native_card(self.profiles['sapphire'],self.source_map)['card']['properties']})
|
||||
|
||||
def test_references_do_not_relicense_supplier_publications(self):
|
||||
self.assertIsNone(self.source_map['isola-370hr']['license'])
|
||||
self.assertIsNone(self.source_map['schott-borofloat']['license'])
|
||||
|
||||
def test_simulant_bulk_and_grain_density_remain_distinct(self):
|
||||
self.assertEqual(self.row('lms-1','density')['value'],1560)
|
||||
self.assertEqual(self.row('lms-1','grain_density')['value'],2920)
|
||||
self.assertIn('NOT measured lunar soil',self.profiles['lms-1']['reference_state'])
|
||||
|
||||
def test_coating_preserves_substrate_and_has_no_invented_density(self):
|
||||
result=p.resolve('SURF-045')
|
||||
self.assertEqual(result['binding']['physical_role'],'layer')
|
||||
self.assertTrue(result['binding']['preserve_existing_material'])
|
||||
self.assertFalse(result['binding']['auto_assign_body'])
|
||||
with self.assertRaises(p.Invalid):p.prepare('az93-coating',True)
|
||||
|
||||
def test_no_preparation_without_explicit_reference_acknowledgement(self):
|
||||
with self.assertRaises(p.Invalid):p.prepare('steel-c45',False)
|
||||
result=p.prepare('steel-c45',True)
|
||||
self.assertFalse(result['executed']);self.assertFalse(result['assigns_bodies'])
|
||||
self.assertEqual(result['commands'][0]['params']['density_g_cm3'],7.8)
|
||||
self.assertEqual(result['commands'][0]['command'],'material.create')
|
||||
self.assertNotIn('appearance',result['commands'][0]['params'])
|
||||
|
||||
def test_unresolved_ids_fail_not_fallback_to_generic_material(self):
|
||||
for id in ('MAT-999','SURF-999','__proto__',''):
|
||||
with self.assertRaises(p.Invalid):p.resolve(id)
|
||||
|
||||
def test_false_ready_certification_and_zero_unknown_claims_refuse(self):
|
||||
self.mutated(0,lambda d:d.update(runtime_assignment=True))
|
||||
self.mutated(0,lambda d:d['profiles'][0].update(certified_design_allowables=True))
|
||||
self.mutated(2,lambda d:d['catalog'][0].update(unknown_is_zero=True))
|
||||
self.mutated(2,lambda d:d['catalog'][0].update(auto_assign_body=True))
|
||||
|
||||
def test_duplicate_profiles_sources_properties_refuse(self):
|
||||
self.mutated(0,lambda d:d['profiles'].append(d['profiles'][0]))
|
||||
self.mutated(1,lambda d:d['sources'].append(d['sources'][0]))
|
||||
self.mutated(0,lambda d:d['profiles'][0]['properties'].append(d['profiles'][0]['properties'][0]))
|
||||
|
||||
def test_catalog_surface_drift_and_missing_records_refuse(self):
|
||||
self.mutated(2,lambda d:d['catalog'].pop())
|
||||
self.mutated(2,lambda d:d['surfaces'].pop())
|
||||
self.mutated(2,lambda d:d['surfaces'][0].update(physical_binding_ids=['MAT-003']))
|
||||
self.mutated(2,lambda d:d['inputs']['catalog'].update(sha256='0'*64))
|
||||
self.mutated(2,lambda d:d['inputs']['catalog'].update(path='../../secret'))
|
||||
|
||||
def test_undefined_property_source_and_profile_refuse(self):
|
||||
self.mutated(0,lambda d:d['profiles'][0]['properties'][0].update(source_id='absent'))
|
||||
self.mutated(2,lambda d:d['catalog'][0]['references'][0].update(profile_id='absent'))
|
||||
|
||||
def test_nonfinite_frequency_and_unknown_conditions_refuse(self):
|
||||
r=copy.deepcopy(self.row('fr4-370hr','relative_permittivity'))
|
||||
r['conditions']['frequency_hz']=float('nan')
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
r=copy.deepcopy(self.row('fr4-370hr','relative_permittivity'));r['conditions']['temperature']=20
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
|
||||
def test_negative_and_impossible_fraction_refuse(self):
|
||||
for id,q,value in [('steel-c45','density',-1),('lms-1','porosity',2)]:
|
||||
r=copy.deepcopy(self.row(id,q));r['value']=value
|
||||
r['original']={'value':value,'unit':r['unit'],'scale_to_si':1.,'offset_to_si':0.}
|
||||
with self.assertRaises(p.Invalid):p.check_property(r,self.source_map)
|
||||
|
||||
def test_native_projection_has_bounded_unique_kinds(self):
|
||||
for profile in self.profiles.values():
|
||||
card=p.native_card(profile,self.source_map)['card']
|
||||
self.assertLessEqual(len(card['properties']),16)
|
||||
kinds=[r['data']['kind'] for r in card['properties']]
|
||||
self.assertEqual(len(kinds),len(set(kinds)))
|
||||
self.assertTrue(all(len(r['conditions']['state'].encode())<=1024 for r in card['properties']))
|
||||
|
||||
def test_authority_bytes_and_exports_are_deterministic(self):
|
||||
first=p.make_exports();second=p.make_exports()
|
||||
self.assertEqual(p.encoded(first),p.encoded(second))
|
||||
self.assertFalse(first['coverage.json']['numerically_complete_catalog_claim'])
|
||||
|
||||
def test_bounded_input_and_array_top_level_refuse(self):
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
path=Path(folder)/'input.json';path.write_text('[]')
|
||||
with self.assertRaises(p.Invalid):p.read(path)
|
||||
with path.open('wb') as stream:stream.truncate(p.MAX_BYTES+1)
|
||||
with self.assertRaises(p.Invalid):p.read(path)
|
||||
|
||||
def test_empty_native_projection_is_explicit_not_reported_ready(self):
|
||||
for id in ('fr4-370hr','az93-coating','mdf-premier-18'):
|
||||
result=p.native_card(self.profiles[id],self.source_map)
|
||||
self.assertEqual(result['native_projection_status'],'extended_data_only')
|
||||
self.assertFalse(result['card']['properties'])
|
||||
self.assertTrue(result['not_projected'])
|
||||
|
||||
def test_wrong_chemistry_is_not_a_convenient_density_fallback(self):
|
||||
by_id={row['catalog_id']:row for row in self.bindings['catalog']}
|
||||
for id,wrong in [('MAT-145','hdpe'),('MAT-248','borofloat-33'),('MAT-439','mdf-premier-18')]:
|
||||
self.assertNotIn(wrong,{r['profile_id'] for r in by_id[id]['references']})
|
||||
self.assertNotIn('c11000',{r['profile_id'] for r in by_id['MAT-398']['references']})
|
||||
|
||||
def test_no_reference_profile_is_duplicated_with_two_roles(self):
|
||||
for row in self.bindings['catalog']:
|
||||
ids=[r['profile_id'] for r in row['references']]
|
||||
self.assertEqual(len(ids),len(set(ids)),row['catalog_id'])
|
||||
|
||||
def test_incomplete_coverage_is_not_reported_numerically_complete(self):
|
||||
c=p.make_exports()['coverage.json']
|
||||
self.assertEqual(c['nonempty_native_cards']+c['extended_only_profiles'],c['profile_count'])
|
||||
self.assertEqual(c['concepts_with_reference_candidates']+c['concepts_needing_specific_recipe'],600)
|
||||
self.assertFalse(c['numerically_complete_catalog_claim'])
|
||||
self.assertEqual(c['surfaces_with_reference_candidates'],48)
|
||||
|
||||
def test_cured_resin_state_survives_native_projection(self):
|
||||
result=p.native_card(self.profiles['sikafloor161-cured'],self.source_map)
|
||||
row=next(r for r in result['card']['properties'] if r['data']['kind']=='compressive_strength')
|
||||
self.assertIn('28 days',row['conditions']['state'])
|
||||
self.assertEqual(row['conditions']['temperature_k'],296.15)
|
||||
self.assertNotIn('density',{r['data']['kind'] for r in result['card']['properties']})
|
||||
|
||||
def test_distinct_elastic_conditions_cannot_be_mixed(self):
|
||||
for field,value in [('state','other temper'),('moisture_dry_basis_kg_kg',.1),('strain_rate_per_s',1.0)]:
|
||||
profile=copy.deepcopy(self.profiles['steel-c45'])
|
||||
nu=next(r for r in profile['properties'] if r['quantity']=='poisson_ratio')
|
||||
nu['conditions'][field]=value
|
||||
with self.subTest(field=field),self.assertRaises(p.Invalid):
|
||||
p.native_card(profile,self.source_map)
|
||||
|
||||
def test_new_reference_ranges_and_fibre_axes_are_not_flattened(self):
|
||||
pmma=p.native_card(self.profiles['pmma-goodfellow-sheet'],self.source_map)
|
||||
self.assertNotIn('elasticity',{r['data']['kind'] for r in pmma['card']['properties']})
|
||||
fibre=p.native_card(self.profiles['kevlar49-fibre'],self.source_map)
|
||||
self.assertNotIn('elasticity',{r['data']['kind'] for r in fibre['card']['properties']})
|
||||
self.assertNotIn('tensile_strength',{r['data']['kind'] for r in fibre['card']['properties']})
|
||||
self.assertNotIn('thermal_expansion',{r['data']['kind'] for r in fibre['card']['properties']})
|
||||
|
||||
def test_named_coating_candidates_do_not_invent_bulk_density(self):
|
||||
for id in ('c71-enamel','hmg-stoving-hammer','hmg-sc601-clear','uv22-coating'):
|
||||
profile=self.profiles[id]
|
||||
self.assertNotIn('density',{r['quantity'] for r in profile['properties']})
|
||||
with self.assertRaises(p.Invalid):p.prepare(id,True)
|
||||
|
||||
def test_para_aramid_not_assigned_as_meta_aramid_honeycomb(self):
|
||||
row=next(r for r in self.bindings['catalog'] if r['catalog_id']=='MAT-482')
|
||||
self.assertNotIn('kevlar49-fibre',{r['profile_id'] for r in row['references']})
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Raspberry Pi 5 visual reconstruction
|
||||
|
||||
The electronics work uses original SolidCraft geometry to replace the source board's generic port and GPIO envelopes with recognizable packages, connectors and contacts. It is a dimension-informed visual model for close inspection and rendering. It is not a complete electrical BOM, netlist, PCB fabrication file or manufacturer-certified enclosure model.
|
||||
|
||||
## Reference geometry
|
||||
|
||||
The [Raspberry Pi 5 mechanical drawing](https://datasheets.raspberrypi.com/rpi5/raspberry-pi-5-mechanical-drawing.pdf) gives an approximately **85 × 56 mm** board outline, **58 × 49 mm** mounting-hole spacing, **3.5 mm** offsets to the nearby edges and **2.7 mm** mounting-hole diameter. The manufacturer explicitly describes its dimensions as approximate and leaves some components out of the drawing. These are visual reference dimensions, not manufacturing tolerances.
|
||||
|
||||
The existing SELENE PCB uses a **1.6 mm** modeled thickness. Its final placement must be read from the evaluated source: the source timeline contains later translations, so the early sketch plane is not the assembled board elevation. The component generator preserves the original mounting position and documents its exact world-coordinate origin.
|
||||
|
||||
The [official GPIO documentation](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#gpio-and-the-40-pin-header) establishes a **2.54 mm** pitch. The visual header therefore uses two rows of 20 individually modeled pins, with a separate dark carrier and visible solder/pad details.
|
||||
|
||||
## Component identity and connector inventory
|
||||
|
||||
The manufacturer's [Pi 5 introduction](https://www.raspberrypi.com/news/introducing-raspberry-pi-5/) identifies the BCM2712 application processor, LPDDR4X memory, RP1 I/O controller, DA9091 power-management IC, CYW43455 wireless chip and BCM54213 Ethernet PHY. The PHY is visibly rotated 45 degrees. These identities guide named geometry rather than copied chip artwork or logos.
|
||||
|
||||
The [current official board documentation](https://www.raspberrypi.com/documentation/computers/sbcs.html#raspberry-pi-5-ports) provides the connector inventory:
|
||||
|
||||
| Interface | Visual modeling target |
|
||||
|---|---|
|
||||
| USB-A | Two stacked USB 2.0 ports with black tongues, two USB 3.0 ports with blue tongues; hollow metal shells and visible contacts. |
|
||||
| Ethernet | RJ45 cavity, eight contact representations and two LED windows. |
|
||||
| GPIO | 40 pins in two rows of 20. |
|
||||
| Display output | Two micro-HDMI connector shells and contact representations. |
|
||||
| Power | USB-C shell and tongue. |
|
||||
| Camera/display | Two 22-contact MIPI FFC connectors at 0.5 mm pitch. |
|
||||
| PCIe | One 16-contact FFC connector at 0.5 mm pitch. |
|
||||
| Auxiliary headers | Four-pin fan, three-pin UART, two-pin RTC and four-pin PoE. |
|
||||
| Storage | Underside microSD cage and contact representations. |
|
||||
| Board details | Power button, status LED, shields, crystals, inductors, representative passives and plated holes. |
|
||||
|
||||
The [manufacturer's PCIe connector specification](https://datasheets.raspberrypi.com/pcie/pcie-connector-standard.pdf) independently confirms the 16-contact, 0.5 mm-pitch interface. Detailed solder terminations, internal contact spring shapes and production-specific component populations remain simplified.
|
||||
|
||||
## Rendering and assembly contract
|
||||
|
||||
A separate component groups the new electronics and attaches rigidly to the original avionics assembly. Ports have openings, tongues and contacts; separate materials distinguish solder mask, package epoxy, ceramic, connector polymer, shields, heat spreaders, solder and gold-colored plating. Appearance values are illustrative PBR controls. A bulk Brass material on a gold-colored contact is a density proxy, not a claim that the contact is solid gold.
|
||||
|
||||
Exact body counts, removed placeholder names, generator hash and native validation results belong in the generated build evidence. No count or completed validation result is inferred from this reference document. Before shipping, check the evaluated component position, mounting-hole and header spacing, representative connector cavities, the rigid attachment and a close-up native render.
|
||||
|
||||
All added geometry and documentation are original. No Raspberry Pi trademark artwork, manufacturer CAD, PCB texture or photograph is distributed with the model.
|
||||
@@ -0,0 +1,137 @@
|
||||
# SELENE mechanism design and verification contract
|
||||
|
||||
The improved native source already contains assembly structure, solar-actuator loops, wheel links and a tour. The functional derivative builds on those mechanisms through SolidCraft commands. This document distinguishes inspected source facts from reconstruction targets and the numeric checks needed to accept the result. It does not certify an unexecuted generator or replace native validation evidence.
|
||||
|
||||
## Source assembly
|
||||
|
||||
Read-only inspection of the pinned source in [SOURCE.md](SOURCE.md) confirms 49 joints, nine motion links and the 120-step `SELENE tour`. Joint IDs below belong to that source and must be resolved again if a derivative deletes and recreates joints.
|
||||
|
||||
| Source mechanism | Native source identity | Relation |
|
||||
|---|---|---|
|
||||
| Wheel train | `Wheel axis -1:-90` through `Wheel axis 1:90`, IDs 1–6 | Five links, ratio +1 between neighboring wheel joints. |
|
||||
| Solar wings | Port/starboard tilt, IDs 9–10 | Mirrored rotation, ratio −1. |
|
||||
| Solar actuators | Four sets of root pin, stroke and wing pin, IDs 18–29 | Each rod follows a closed loop; slider limits −6 to +0.4 mm. |
|
||||
| Sensor and dish yaw | Turret ID 7, dish ID 16 | Source demonstrator gear, radii 24:36, ratio −2/3. |
|
||||
| Moving demonstration track | `Track slide`, ID 48 | Source rack coupling to wheel ID 1, nominal radius 38 mm, reversed. |
|
||||
| Vial cap | `Vial cap thread`, ID 49 | Cylindrical joint; 1.5 mm axial travel per full turn; slide limits 0–6 mm. |
|
||||
|
||||
The source turret elevation is saved at −12 degrees. New bearing geometry and motion links must be constructed in a deliberately restored common neutral pose; mixing that saved pose with zero-angle link offsets can rotate new parts unexpectedly.
|
||||
|
||||
## Reconstruction targets
|
||||
|
||||
The individual component scripts and the executed derivative are the authority for implementation. The following bounds are deliberately narrower than the source's broad demonstration ranges. They define an inspection envelope to be checked, not a proof of global collision freedom.
|
||||
|
||||
| Driver | Intended limits, degrees | Purpose |
|
||||
|---|---:|---|
|
||||
| Sensor azimuth | −135 to +135 | Independent pointing with a bounded cable envelope. |
|
||||
| Sensor elevation | −25 to +45 | Controlled sensor-head tilt. |
|
||||
| Dish azimuth | −120 to +120 | Independent dish pointing. |
|
||||
| Dish elevation | −35 to +40 | Controlled dish tilt. |
|
||||
| Arm azimuth | −45 to +45 | Keep a conservative showcase sweep. |
|
||||
| Shoulder | −35 to +15 | Restrict travel around the modeled clevis. |
|
||||
| Elbow | −30 to +55 | Articulate the rebuilt link stack. |
|
||||
| Wrist and tool tilt | −45 to +45 each | Bound the local tool envelope. |
|
||||
| Port solar wing | 0 to +30 | Remain within the inherited actuator stroke. |
|
||||
| Starboard solar wing | −30 to 0 | Mirror the port driver. |
|
||||
| Gripper jaw driver | −15 to +18 | Move two independently mounted jaws with opposite signs. |
|
||||
| Suspension arm | −4 to +1.5 | Short-travel closed-loop damper demonstration. |
|
||||
|
||||
Remove the source's illustrative sensor-to-dish gear link so either assembly can point without moving the other. Transfer wheel shafts, flanges, hubs and retaining hardware to the parts they physically rotate with. The track remains an optional visualization helper. A 40 mm nominal coupling may match the grouser envelope, but it does not solve discrete grouser contact, slip or rover traction.
|
||||
|
||||
The gripper requires separate jaw components, concentric pivot sleeves, opposite revolute motion and contact pads. A revolute joint by itself is insufficient if the jaw is still part of the fixed gripper body. The geometric envelope needs a sweep check independently of the linked angle values.
|
||||
|
||||
## Rolling-element bearings
|
||||
|
||||
The bearing reconstruction separates the outer race, inner race, cage and each ball. The outer race follows its housing; the inner race follows the shaft. The cage revolves around the shaft axis, and each ball spins relative to the cage while its center orbits with it. Grooved races and spaced cage bridges provide a recognizable section and visible rolling elements.
|
||||
|
||||
Let **R** be pitch radius, **r** ball radius, and **θ** the shaft angle relative to the housing. For radial contact and an ideal no-slip bearing with a fixed outer ring:
|
||||
|
||||
```text
|
||||
cage angle relative to housing = 0.5 × (1 − r/R) × θ
|
||||
ball spin relative to cage = −0.5 × (R/r − r/R) × θ
|
||||
ball spin relative to housing = −(R/r) × cage angle
|
||||
```
|
||||
|
||||
The sign assumes all revolute axes use the same positive direction. The ball's CAD joint is relative to the cage; substituting an absolute spin rate there produces the wrong motion. These relations follow the cage and rolling-element frequencies in [Schaeffler, An Overview of Bearing Vibration Analysis, section 3](https://www.schaeffler.com/remotemedien/media/_shared_media/08_media_library/01_publications/schaeffler_2/technicalpaper_1/download_1/vibration_analysis_en_en.pdf), specialized to zero contact angle.
|
||||
|
||||
The design uses visual clearance between ideal raceway surfaces and balls. It does not solve Hertzian contact, lubrication, cage slip, preload, bearing life or load ratings. The equations drive a kinematic demonstration; no ball-to-race contact force is inferred.
|
||||
|
||||
For every bearing, validate a neutral pose, an interior nonzero shaft angle and its return to neutral. Compare both cage angle and relative ball spin with the equations. Also compare a ball's center of mass with its expected orbit; angle labels alone cannot prove that the component frame is correct. The spherical appearance of a ball makes spin visually ambiguous, so the joint readback is part of the evidence.
|
||||
|
||||
## Plain yaw supports
|
||||
|
||||
[yaw_supports.py](tools/yaw_supports.py) replaces the three source stacks of solid yaw disks with plain journal and thrust geometry. The fixed housing, rotating disk, existing component ownership and joint frames remain in place. Each housing receives a flanged brass bushing; its rotating disk gains an integral hollow steel journal. A stationary retaining pin captures the rotor inside a recess below the unchanged mast or clevis mounting plane.
|
||||
|
||||
| Support | Fixed housing / rotor diameter, mm | Steel journal diameter, mm | Brass bore diameter, mm | Retaining pin diameter, mm |
|
||||
|---|---:|---:|---:|---:|
|
||||
| Arm | 42 / 36 | 12 | 12.2 | 5 |
|
||||
| Dish | 20 / 18 | 6 | 6.2 | 2.4 |
|
||||
| Sensor turret | 28 / 26 | 8 | 8.2 | 3.6 |
|
||||
|
||||
The flanged thrust seats are 0.3 mm thick, with nominal seated contact against the rotating disks. Journal radial clearance is 0.1 mm; the retaining pins clear the hollow journals by 0.15 mm radially. Recessed heads provide 0.1 mm axial retention play. Four local reliefs also remove the dish housing's approximately 21.33 mm³ overlap with each original mounting head. This stage adds six bodies and no components or joints. Retainer threads use nominal cylindrical seats; fit classes, preload, friction, wear and structural capacity require separate engineering work.
|
||||
|
||||
The official 0.18.2 reduced native fixture reproduced the actual support and neighboring mast/clevis envelopes. Its 101 commands produced 20 bodies and 67 features without timeline errors or warnings. All 44 scoped interference checks, six source-range endpoint drives, nine analytic volume checks and twelve seating/separation measurements passed; each rebuilt journal, bushing and retainer is one connected shell. The largest volume discrepancy was 0.0156%, within the stated 0.02% numerical tolerance. Native section and exterior views were inspected. This fixture evidence does not replace final integration validation; the derivative's narrower pointing limits above remain unchanged.
|
||||
|
||||
## Closed-loop checks
|
||||
|
||||
### Solar actuators
|
||||
|
||||
For each actuator, rotate the tip point **T** about the wing hinge **H** and compute:
|
||||
|
||||
```text
|
||||
stroke(θ) = length(T(θ) − R) − length(T(0) − R)
|
||||
```
|
||||
|
||||
Here **R** is the fixed root pin. The source port hinge is at `(0, −140, 158)`, the root at `(x, −91, 134)`, and the tip at `(x, −180.40678269379407, 169.70686616300375)`, with `x = −62` or `+62`. Positive port tilt rotates about +X. At **20 degrees**, the expected stroke is approximately **−2.8662098186 mm**. The starboard wing has mirrored geometry and a negative drive angle. Verify all four sliders, not only one.
|
||||
|
||||
The [SolidCraft mechanism reference](https://github.com/tangency-labs/solidcraft/blob/ac1768e08b83ed33212459951f5b50aa7a57cddc/skills/solidcraft-mechanisms/reference.md) documents this closed-loop pattern, `flip: true` for co-directed frames and comparison with independent length calculations. Do not key the root pins, sliders or wing pins in a study; they are followers.
|
||||
|
||||
### Suspension dampers
|
||||
|
||||
The short-travel reconstruction gives each drive carrier its own hinge and splits each damper into barrel and rod. With the chosen neutral frame, the root and tip separation is 22 mm. Its analytic stroke relation is:
|
||||
|
||||
```text
|
||||
stroke(θ) = hypot(35 cos θ − 20 sin θ − 35,
|
||||
−35 sin θ − 20 cos θ − 2) − 22
|
||||
```
|
||||
|
||||
Angles in this formula are radians. Expected strokes are **−2.4462732115 mm at −4 degrees** and **+0.9155981856 mm at +1.5 degrees**. Validate every closed loop against its actual reconstructed world points before using these numbers. Solid coil springs and rigid motor wires do not deform; hide them in moving inspection profiles unless a later animation model replaces them.
|
||||
|
||||
The suspension generator retains the original `Damper piston …` and `Suspension bearing …` body labels to avoid costly late rebuilds of the source history. The piston label also names the new rod component; the pivot ring functions as a brass plain bushing and the carrier ring as a fixed spacer. Those retained labels do not alter the geometry or joint behavior.
|
||||
|
||||
### Screw cap
|
||||
|
||||
The expected axial displacement is `1.5 × angle_degrees / 360` mm. A 360-degree drive gives 1.5 mm; 1,440 degrees gives 6 mm. The angular and axial limits should describe the same four-turn travel. This is an ideal screw coupling; modeled thread surface contact and sealing compression require separate work.
|
||||
|
||||
## Native acceptance
|
||||
|
||||
Use the model's own saved studies and exact joint names. Save the final derivative with all independent drivers at the agreed neutral pose. A study should return its drivers to neutral so opening another study starts predictably.
|
||||
|
||||
The pinned authoring executor is the official v0.18.2 CLI described in [SOURCE.md](SOURCE.md), producing format 28 for compatibility with the personal render branch. Once the master is saved and its bytes are fixed, run the independent validator from the repository root:
|
||||
|
||||
```sh
|
||||
PYTHONDONTWRITEBYTECODE=1 python3 assets/render/selene/tools/validate_native.py \
|
||||
--cli /path/to/solidcraft-cli \
|
||||
--model assets/render/selene/models/SELENE-functional.solidcraft \
|
||||
--out target/selene/validation-final \
|
||||
--interference-pairs assets/render/selene/motion/interference-pairs.json
|
||||
```
|
||||
|
||||
Use a new output directory for every run. The default suite performs 25 sampled driven cases and a final neutral check. Before each case it reads all independent joint coordinates, resets those that are nonzero, and verifies every primary coordinate is neutral. It compares actual native joint readbacks and world-coordinate centers of mass, retaining requests, responses, hashes, tolerances and failures. It drives an in-memory copy and never saves test poses to the master. The input model and pinned original must have identical hashes before and after validation.
|
||||
|
||||
Run full-model native processes serially. The validator confines its native subprocess to two Rayon workers and sets one glibc allocation arena with 64 KiB mmap and trim thresholds. These resource settings are recorded in the report alongside the unchanged geometric tolerances.
|
||||
|
||||
Optional `--interference-pairs path/to/pairs.json` accepts a JSON array of exact body-name pairs. The committed [selection](motion/interference-pairs.json) requests seven neutral-pose checks for opposing arm links, the tool wrist, gripper jaws and PCB connector clearances. Each pair receives its own bounded native interference check. The result records whether conservative broad-phase exclusion or exact Boolean intersection resolved it. Missing bodies, skipped or unchecked pairs, truncation and budget exhaustion remain failures or incomplete checks. A request to run the suite is not a passing result; report the returned status and evidence path explicitly.
|
||||
|
||||
The minimum evidence for each accepted mechanism is:
|
||||
|
||||
- A native timeline with no unreviewed errors or geometry warnings.
|
||||
- A grounded assembly chain and a clean joint graph; no unexplained floating mechanism, loop conflict or coupling error.
|
||||
- Actual movement of the intended occurrence, with positions or centers of mass checked before and after.
|
||||
- Numeric follower agreement at selected interior and endpoint values, with native degrees/mm distinguished from persisted radians/mm.
|
||||
- Scoped interference checks between parts that must clear each other. Timeouts and unchecked pairs remain incomplete checks, never passes.
|
||||
- A native view or render showing the actual geometry. A diagram or an inferred body count cannot substitute for this review.
|
||||
|
||||
Broad all-body pair checks are expensive and can confuse deliberate mating contact with penetration. Check the relevant opposing link plates, clevis/race seats, shaft/bore and gripper contacts explicitly. A few passing samples do not prove clearance across every possible combination of joint angles.
|
||||
|
||||
Lunar gravity, loads, motor torque, thermal behavior, flexible wiring, suspension spring dynamics, granular terrain and autonomous sample capture remain separate simulation and animation work.
|
||||
@@ -0,0 +1,89 @@
|
||||
# SELENE functional showcase
|
||||
|
||||
This package develops the **author-supplied improved SELENE** into an editable native model for close-up rendering and subsequent mechanism animation. The input is SychPL's `SELENE-showcase.solidcraft`, matched byte for byte to his published file. The original is retained unchanged; the enhanced derivative is [models/SELENE-functional.solidcraft](models/SELENE-functional.solidcraft).
|
||||
|
||||
Open the derivative in the personal SolidCraft render branch. The model contains the geometry, component ownership, joints, motion links, physical-material proxies, appearances, browser groups, saved views and inspection studies. Python is only a development tool for reproducing the changes; opening and using the design does not require Python.
|
||||
|
||||

|
||||
|
||||
*Actual native Design preview of the neutral master. Close-ups and the product-render executor's current limits are documented in [RENDER.md](RENDER.md).*
|
||||
|
||||
## What changed
|
||||
|
||||
| Area | Native implementation |
|
||||
|---|---|
|
||||
| Rolling-element bearings | Ten open radial bearings at the arm and sensor head. Each has grooved steel races, eight individually represented balls and a brass cage. The inner race follows the shaft, the outer race follows the housing, and linked revolutes drive cage orbit and relative ball spin. |
|
||||
| Arm joints | Revised plate spacing, bored seats, stepped clamp hubs, shafts, spacers, locking screws and a machined wrist tongue. Rigid decorative hydraulic cylinders that would detach during movement are removed. |
|
||||
| Gripper | Two separate moving jaw components, concentric brass plain sleeves, opposite revolute motion and elastomer contact pads. Its commanded range is −15° to +18° at the driver. |
|
||||
| Suspension | Six hinged trailing carriers with reinforcing gussets. Separate hollow damper barrels and rods form six closed revolute–slider–revolute loops. Local support reliefs clear the moving eyes and arms over the bounded travel. |
|
||||
| Drivetrain | Wheel shafts, hubs, flanges and retaining screws belong to the rotating wheels. Wheel joints attach to the moving carriers. The optional demonstration track uses a 40 mm nominal rolling radius. |
|
||||
| Yaw supports and pointing | Three solid-disk placeholders become journal supports with flanged brass bushings, hollow rotating journals and recessed axial retaining pins. Sensor and dish pointing are independent; the illustrative gear coupling is removed. |
|
||||
| Raspberry Pi 5 | A board with rounded corners, mounting holes, plated pads and vias, plus 491 new bodies for packages, shields, passives, headers, connector housings, contacts, solder details and mounting tabs. Hollow ports replace solid envelopes. |
|
||||
| Materials and appearance | Retained orange/charcoal identity with distinct metals, polymer, elastomer, FR4, silicon and optical surfaces. Opaque bodies carry PBR values; physical density proxies are explicitly separate from optical properties. |
|
||||
| Sample laboratory | Each glass vial is one hollow native solid with an integral bottom, retaining its original external dimensions. The existing screw-driven cap retains 1.5 mm travel per revolution. The source rock is grounded as demonstration scenery. |
|
||||
| Inspection | Body groups by function, ten named views with render setup records, seven focused motion studies, and an adapted copy of the author's original tour. |
|
||||
|
||||
The native build and independent acceptance run have separate evidence. See [VALIDATION.md](VALIDATION.md) for the final hash, actual counts, executor, completed checks and remaining limitations. [MECHANISMS.md](MECHANISMS.md) gives the joint conventions and independent equations; [ELECTRONICS.md](ELECTRONICS.md) explains the board reconstruction and its fidelity boundaries.
|
||||
|
||||
## Using the model
|
||||
|
||||
The file opens in the neutral pose: all independent drivers are at zero, including sensor elevation. Saved views are named `SELENE - Whole rover`, `Electronics`, `Shoulder bearing`, `Elbow bearing`, `Gripper`, `Sensor head`, `Sample laboratory`, `Drivetrain`, `Suspension` and `Solar cells`, each with the same `SELENE - ` prefix.
|
||||
|
||||
Use the seven inspection studies for drivetrain, solar deployment, arm articulation, gripper, independent sensor pointing, sample cap and suspension. They return their independent drivers to neutral. The inherited tour is named **`SELENE - Legacy author tour (adapted limits)`**; it preserves the author's keyed motion while resolving recreated wheel joints and clamping the selected limits. A keyed study is an authoring resource, not evidence that every frame of every combined pose has been cleared.
|
||||
|
||||
For suspension motion, hide the six rigid spring solids and twelve motor leads. They remain useful neutral-pose render details but do not deform. The `motion` visibility profile in [tools/presentation.py](tools/presentation.py) performs this selection and also hides the optional track and source flexible-hose display geometry. Export or save inspection poses to a separate file; keep the master neutral.
|
||||
|
||||
The source cap has an ideal screw relation. The six complete vials remain in the sample laboratory assembly. Independent grasp, release, free flight and capture are future work; the current cap motion does not implement those events.
|
||||
|
||||
## Reproduce the native derivative
|
||||
|
||||
Use Python 3.11+ and the **official SolidCraft v0.18.2 CLI** identified in [SOURCE.md](SOURCE.md). That executor writes `solidcraft/28`, readable by the personal render branch's format-29 reader. The newer official v0.19.0 writes format 30 and is unsuitable as a drop-in authoring replacement for that branch. No format marker is edited to bypass compatibility.
|
||||
|
||||
From the repository root:
|
||||
|
||||
```sh
|
||||
PYTHONDONTWRITEBYTECODE=1 python3 assets/render/selene/tools/build.py \
|
||||
--cli /path/to/solidcraft-cli \
|
||||
--work target/selene/rebuild \
|
||||
--output target/selene/SELENE-functional.solidcraft
|
||||
```
|
||||
|
||||
The builder checks the pinned original, evaluates it, then uses only native commands. Stages run in fresh processes so the large model's undo history remains bounded. Each stage retains its command script, full native results, timing trace and saved checkpoint under the selected work directory. Every checkpoint must have a clean feature timeline, unique live body names and a clean joint graph. The build history records hashes of the source, executor, recipes, results and checkpoints.
|
||||
|
||||
Resume an interrupted build by repeating the command with `--resume`. The builder rejects changed recipes, executables, results or checkpoints. `--until` stops at a named stage for inspection. Inspect failures in their logs; use a separate work directory when changing an already completed stage.
|
||||
|
||||
Run independent acceptance on the saved derivative:
|
||||
|
||||
```sh
|
||||
PYTHONDONTWRITEBYTECODE=1 python3 assets/render/selene/tools/validate_native.py \
|
||||
--cli /path/to/solidcraft-cli \
|
||||
--model target/selene/SELENE-functional.solidcraft \
|
||||
--interference-pairs assets/render/selene/motion/interference-pairs.json \
|
||||
--out target/selene/acceptance
|
||||
```
|
||||
|
||||
This drives an in-memory copy and compares native joint readbacks and occurrence centers of mass with independent calculations. It never saves test poses over the master. Optional exact-name interference pairs are bounded and report unchecked pairs as incomplete. Detailed execution evidence stays in `target/`; production native files and English documentation are the shipped resources.
|
||||
|
||||
## Render preparation and the wider catalog
|
||||
|
||||
The full-detail [native 4K studio render](RENDER.md#full-detail-4k-path-traced-studio-image-2026-10-22) now provides a path-traced showcase of the unchanged functional master. It preserves all original visible geometry, uses explicit glass and authored materials, and ships with its exact [request/provenance manifest](scenes/studio-hero.json). The Design previews remain distinct geometry-inspection resources.
|
||||
|
||||
The ten saved camera/setup records and the model's body appearances are concrete native resources. [RENDER.md](RENDER.md) documents the actual image workflow and any executor limits. Transparent viewport appearances alone do not establish physical refraction, and density does not supply roughness, friction, electrical behavior or optical transmission.
|
||||
|
||||
The existing [48-appearance pack](materials/appearance-pack.json), [33 semantic roles](scenes/roles.json), [ten stage specifications](scenes/stages.json), [12 shots](scenes/shots.json), [UI flow](ui/demo-flow.json) and [future sample dynamics sequence](motion/sample-sequence.json) remain a broader authoring specification. The source is now pinned; those resources still need their individual geometry bindings and renderer admission. The catalog's `runtime_ready: false` status is intentional. No lunar terrain, dust dynamics, calibrated optical library or throw-and-catch simulation is implied by the native model's completion.
|
||||
|
||||
```sh
|
||||
python3 docs/render-materials/validate_catalog.py
|
||||
python3 assets/render/selene/tools/validate_prepared.py
|
||||
cargo xtask ci
|
||||
```
|
||||
|
||||
The Python checks validate prepared data and the source contract. They do not replace native geometry, mechanism or visual checks. Repository-wide gate status is recorded separately in the validation report.
|
||||
|
||||
## Provenance and scope
|
||||
|
||||
[SOURCE.md](SOURCE.md) and [source-lock.json](source-lock.json) pin the exact source bytes and author history. The original rover is credited to 0xlillith, the improved showcase assembly to SychPL, and the emblem to SolidCraft contributors. Ubuntu Light lettering retains its [Ubuntu Font Licence notice](licenses/UFL.txt). The source branch has no separate file-specific license declaration for the showcase additions; that provenance distinction is preserved.
|
||||
|
||||
New geometry, procedural scripts and documentation are original contributions under MIT OR Apache-2.0. Exact non-Markdown asset rows are in [ATTRIBUTION.md](../../../ATTRIBUTION.md). Manufacturer CAD, PCB artwork, logos and netlists are not embedded.
|
||||
|
||||
The model demonstrates geometric detail and ideal kinematics. It is not a manufacturing release, a complete electrical design, a load-rated bearing selection or a physics simulation. Joint limits are a documented inspection envelope; sampled checks do not certify every simultaneous arm, solar and suspension configuration.
|
||||
@@ -0,0 +1,124 @@
|
||||
# SELENE native rendering and reproducible studio showcase
|
||||
|
||||
## Full-detail 4K path-traced studio image (2026-10-22)
|
||||
|
||||

|
||||
|
||||
The selected [3840 x 2400 PNG](exports/SELENE-studio-4k.png) is a completed native SolidCraft GPU-path render of the latest functional master, not a Design screenshot, a generated illustration, a painted geometry replacement or an upscaled preview. The exact request, original resource hashes, editable source and executable identities are retained in [studio-hero.json](scenes/studio-hero.json).
|
||||
|
||||
| Property | Verified value |
|
||||
|---|---|
|
||||
| Editable authority | `models/SELENE-functional.solidcraft`, original bytes unchanged |
|
||||
| Functional source commit | `cf8e651022deee528b26c303fde58bf3eb8a22a5` |
|
||||
| Native model SHA-256 | `3bd2bfa1c6336394c4a4208d30b52c80d06658a3bd7ea57cc93b774411d1bd68` |
|
||||
| Evaluated native bodies | 2,116; zero timeline errors or warnings |
|
||||
| Original visible subject | 2,094 bodies; 2,144,099 triangles |
|
||||
| Separate render-only stage | One passive ground rectangle; 2 triangles |
|
||||
| Optical bodies | 12 explicitly selected closed dielectric bodies; topology and medium-overlap checks retained |
|
||||
| Authored surface detail | 48 exact body bindings across six original surface families |
|
||||
| Output | 3840 x 2400, RGBA8 PNG, sRGB |
|
||||
| Sampling | 1,024 samples per pixel; maximum path depth 16; seed 21026 |
|
||||
| Presentation | ACES-fitted tone mapping and edge-aware a-trous denoising |
|
||||
| Lighting | Original RIG-002 rectangular emitters, explicit 1/16 creative radiance gain, original HDR-002 fill at intensity 0.12 |
|
||||
| Camera | Perspective fit to all captured body bounding boxes; 8% frame margin |
|
||||
| Native executable source | `895704a2fdc96dabb9a2afb2e548a8896e4b1e79` |
|
||||
| Native executable SHA-256 | `3421d538c571647c1f24fd74d63487c4ba4ab597980cfeea111a01c0db94e699` |
|
||||
| Completed PNG SHA-256 | `40a492e7979137d0f4027300da3d8af7ca1008c1aab2c309259e65d309a17316` |
|
||||
| PNG length | 2,388,114 bytes; chunk CRCs, bounded scanlines and final-frame hash verified |
|
||||
|
||||
The image uses the original saved visibility and neutral pose. There is no mesh simplification, geometry removal, hidden resolution downgrade, engineering-material reassignment or software-device fallback. The native job's logical admission estimate was 2,814,770,732 bytes; this is not a peak-RSS or GPU-memory measurement. Hardware-only policy and Vulkan were enforced on Pegasus; the hardware survey identifies its AMD Radeon 8060S.
|
||||
|
||||
### Reproduction
|
||||
|
||||
Build the native CLI once, then reuse the loaded model and device:
|
||||
|
||||
```sh
|
||||
cargo build --locked --profile ci -p solidcraft-cli --bin solidcraft-cli
|
||||
python -i tools/render-library/selene_studio.py --cli /path/to/solidcraft-cli --out /new/output/directory
|
||||
```
|
||||
|
||||
In the resulting interactive studio:
|
||||
|
||||
```python
|
||||
from selene_recipe import hero_request
|
||||
request = hero_request(studio, width=3840, height=2400, samples=1024)
|
||||
receipt = studio.render("selene-studio-4k", request, timeout=7200)
|
||||
studio.close()
|
||||
```
|
||||
|
||||
The helper checks the pinned master and binary, public-command preparation, resource hashes, actual executor, exact requested dimensions and exported frame bytes. The frame is not automatically declared visually accepted. The original camera-fit/publication tools and seven independent Python tests are under `tools/render-library/`; provisional images, native-pixel crops and execution logs stay outside the shipped resource collection.
|
||||
|
||||
### Quality and scope
|
||||
|
||||
The complete image and four unscaled detail crops were visually reviewed: subject and gripper framing, mechanical edges, electronic connectors, glass and highlights remain readable. Residual Monte Carlo grain is visible at native pixel scale in some vial/lens regions; the current denoiser deliberately does not reconstruct those transmission paths. This is a high-quality native showcase, not proof of zero residual noise or a completed maximum-quality renderer roadmap.
|
||||
|
||||
RGB absorption and material recipes are illustrative authored optical choices, not measured glass spectra or engineering properties. The explicit rig gain is a creative lighting adjustment, not an unchanged photometric calibration. Normal maps alter shading, not CAD geometry. LED diffusers are transmitted surfaces, not validated volumetric/mesh emitters. The static image does not establish collision-free motion, contact physics, lunar dust or dynamics.
|
||||
|
||||
Native renderer tests passed 457/457. The hardware GPU suite passed 95 tests with three explicitly ignored tests, and the official 12-crate library/web WASM check passed. Whole-workspace type checking, strict lint, resource/persistence command checks and camera/publication tests have their own evidence. Interactive GUI acceptance and whole-project CI are not inferred from this image. The focused Render-workspace harness also passed 58 tests with no failures; its click-stability repair and remaining whole-project acceptance scope are recorded in the batch ledger and PR #7.
|
||||
|
||||
## Historical Design previews and earlier CPU-product evidence
|
||||
|
||||
The sections below preserve the earlier `10ada1b4` CPU-product/Design observations. Their resource ceilings describe that legacy raster executor, **not** the current native GPU path or the explicit larger CPU raytrace profiles. The whole-master GPU limitation described in that historical workflow is now resolved by the completed image above.
|
||||
|
||||
|
||||
The enhanced native master is the editable authority. Its ten named camera and render-setup records make close inspections reproducible. Body appearances distinguish metals, painted structure, elastomer, FR4, packages, contacts and optical surfaces. The orange and charcoal identity is retained.
|
||||
|
||||
## Reusable Design previews
|
||||
|
||||
The package ships three previews generated directly by SolidCraft from the final neutral master: a whole-rover overview, the Raspberry Pi assembly and an exposed elbow bearing. They use native Design shading. They are intended for the model's README and showcase preparation; they are not photographs or path-traced optical renders. No raster image generator or painted replacement geometry is involved.
|
||||
|
||||
| Preview | Resource | Purpose |
|
||||
|---|---|---|
|
||||
| Whole rover | [SELENE-overview.png](exports/SELENE-overview.png) | Overall form, component placement and retained visual identity. |
|
||||
| Electronics | [SELENE-electronics.png](exports/SELENE-electronics.png) | Board, mounting, packages and connector mouths, viewed from the +X side. |
|
||||
| Open bearing | [SELENE-bearing.png](exports/SELENE-bearing.png) | Grooved races, individual balls and the brass cage. |
|
||||
|
||||
Regenerate them in a fresh output directory:
|
||||
|
||||
```sh
|
||||
PYTHONDONTWRITEBYTECODE=1 python3 assets/render/selene/tools/export_views.py \
|
||||
--cli /path/to/solidcraft-cli \
|
||||
--model assets/render/selene/models/SELENE-functional.solidcraft \
|
||||
--out target/selene/previews
|
||||
```
|
||||
|
||||
The exporter opens the entire native model once, changes only transient body visibility and cameras, and requests three native MCP screenshots. It saves no changes to the master and verifies its SHA-256 afterward. The output report records the actual capture metadata, image hashes, dimensions, cameras and executor hash. Its default size is 1400 × 1000 pixels.
|
||||
|
||||
The body selector for electronics retains the PCB, all `Pi5 ` componentry and the `Pi M2.5` mounting hardware. The bearing selector isolates `Bearing Elbow port`. The full overview hides the optional track and source flexible-hose display geometry. None of these visibility changes delete geometry.
|
||||
|
||||
## Actual product-render checks
|
||||
|
||||
The personal fork at `10ada1b45a4eb285ce752ac72f9aaa968ff8b5c4` was compiled and exercised using its native `cpu-product` executor. The binary reports version 0.18.2 and writes native format 29. Its binary SHA-256 was `2a5485f7c7832d29b6340988837316e247b94eeeb9d4f7333ee616cea38c6826`.
|
||||
|
||||
Two bounded opaque PBR images passed native preflight and rendering:
|
||||
|
||||
| Actual subject | Visible bodies | Triangles | Admitted job estimate | Output |
|
||||
|---|---:|---:|---:|---|
|
||||
| Fresh single arm-bearing fixture generated by `bearings.py` | 20 | 93,654 | 43,594,876 bytes | 768 × 576 PNG, 51,705 bytes |
|
||||
| Pi isolated from the actual integrated stage-03 model | 504 | 103,004 | 50,848,960 bytes | 768 × 576 PNG, 42,351 bytes |
|
||||
|
||||
Both returned no preflight warnings and were visually inspected. The Pi geometry was taken from the integrated rover checkpoint, not a replacement board illustration. The single-bearing image was a reduced fixture of the production geometry; it was not a rendering of the whole rover. Their raw logs, transient native files and review images belong under ignored `target/selene/render-review/`. The final model and reusable Design previews have separate hashes in [VALIDATION.md](VALIDATION.md).
|
||||
|
||||
That historical `cpu-product` raster path uses three fixed directional studio lights. Pure metals look dark away from their highlights because it does not provide an ambient or HDRI contribution in this path. This behavior does not mean the material assignments were lost. Use the Design previews to inspect geometry, and inspect PBR behavior with the product executor's actual lighting limits in mind.
|
||||
|
||||
## Historical whole-model CPU-product resource limit
|
||||
|
||||
At this fork revision the CPU product-image path admits at most **262,144 triangles**, **128 MiB of source geometry**, **384 MiB per job estimate** and **128 million projected pixel tests**. A single arm ball has 10,224 reference-mesh triangles; the 64 arm balls alone account for 654,336 triangles, before the head bearings or rover are included. The full-detail model therefore exceeds this CPU product triangle cap.
|
||||
|
||||
Reducing output dimensions reduces image buffers, not reference-mesh triangle count. Changing viewport display quality does not lower the meshes used by this product renderer. Do not bypass the admission check or silently remove mechanical detail from the master. Use the whole native Design preview, isolate a component for current CPU PBR work, or author a separately documented reduced-visibility render scene. A future whole-rover render executor must admit the complete scene or explicitly support a documented mesh-detail policy.
|
||||
|
||||
CAD evaluation is additional to the render-job estimate. Opening the integrated stage-03 model during these checks took about 102 seconds and peaked near 3.76 GiB RSS. Later assemblies are larger. Run the native builder, validation and full-model image export **sequentially**. The provided tools constrain native worker threads and use an explicit allocator policy; detailed evidence records resource failures and recovered attempts rather than treating them as passes.
|
||||
|
||||
## Material and optical boundaries
|
||||
|
||||
- Opaque PBR values are authored visual parameters, not measured BRDF data. Painted orange and charcoal surfaces retain dielectric/coated appearances; exposed races, balls, contacts and shafts have separate metal responses.
|
||||
- Engineering-material density is a nominal proxy. It does not establish the complete component mass, electrical specification, thermal performance or contact friction.
|
||||
- Each glass vial is one hollow native solid with an integral bottom. This supplies coherent geometry for later closed-medium admission.
|
||||
- Viewport opacity is not physical refraction. Camera lenses, diffusers and vials require explicit optical descriptors, lighting and medium validation; the current studio recipe above supplies and validates them without rewriting the native master.
|
||||
- No lunar terrain, illumination ephemeris, dust simulation, HDRI or manufacturer PCB artwork is bundled in the native derivative.
|
||||
|
||||
## Preparing animation shots
|
||||
|
||||
Use the seven focused studies to inspect the actual joint chains. Hide the six rigid suspension coils and twelve motor leads while the suspension moves; these neutral render details do not deform. The `motion` profile in `presentation.py` selects that view. Removed arm hydraulic display cylinders do not reappear during motion.
|
||||
|
||||
Keep the final master neutral and export motion/render copies separately. The adapted author tour and focused studies are kinematic authoring resources. A complete animated shot still needs its selected combined path checked for collisions, a timing choice, flexible-detail treatment and any physical contact model it intends to claim. Throwing and catching a free vial remains future dynamics work.
|
||||
@@ -0,0 +1,70 @@
|
||||
# SELENE native source and lineage
|
||||
|
||||
The owner supplied **`SELENE-showcase.solidcraft`**, the improved mechanism demonstration published by **SychPL (Mateusz Sych)**. Its bytes match the file added to the author's `media/selene-showcase` branch on 2026-10-21. The unchanged source is retained at [source/SELENE-showcase.solidcraft](source/SELENE-showcase.solidcraft); [source-lock.json](source-lock.json) pins its identity and records the review.
|
||||
|
||||
The functional showcase is a new derivative of this file. The older `Rover-v7.solidcraft` remains a historical reference, not the modeling input.
|
||||
|
||||
## Exact identity
|
||||
|
||||
| Field | Verified value |
|
||||
|---|---|
|
||||
| Author repository | `SychPL/solidcraft` |
|
||||
| Source branch | `media/selene-showcase` |
|
||||
| Commit | `32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9` |
|
||||
| Published timestamp | `2026-10-21T20:00:01Z` |
|
||||
| Repository path | `SELENE-showcase.solidcraft` |
|
||||
| Git blob SHA-1 | `a06fee2c8a839f5efccc75ae6de4e68f951cb266` |
|
||||
| SHA-256 | `1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677` |
|
||||
| Length | 314,452 bytes |
|
||||
| Native container | ZIP with `document.json` and `container.json` |
|
||||
| Native source format | `solidcraft/23` |
|
||||
| Units | Millimeters; Z up. Stored angles are radians; joint commands accept degrees. |
|
||||
|
||||
The [source commit](https://github.com/SychPL/solidcraft/commit/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9) identifies the design as Rover-v7 with closed-loop actuators, links, gears and the SELENE tour study. Both the Git blob hash and SHA-256 were computed independently from the supplied attachment on 2026-10-22.
|
||||
|
||||
Read-only container inspection found **3,378 features, 47 component definitions, 47 occurrences, 49 joints, nine motion links and one motion study**. These are source-document counts. They do not establish that every feature evaluates, that every body survives the timeline, or that the assembly is collision-free. Native evaluation and derivative checks are separate evidence.
|
||||
|
||||
## Following the original clue
|
||||
|
||||
The owner's [exact pinned mechanism reference](https://github.com/tangency-labs/solidcraft/blob/ac1768e08b83ed33212459951f5b50aa7a57cddc/skills/solidcraft-mechanisms/reference.md) describes the SELENE solar-actuator loops, wheel and solar motion links, grounded modules and visibility treatment. It also specifies command units, joint-origin conventions and validation methods. Those descriptions led to the author's showcase history.
|
||||
|
||||
| Evidence | What it establishes |
|
||||
|---|---|
|
||||
| [Native source at `32ec1720`](https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft) | The exact improved design supplied by the owner. |
|
||||
| [Parent media commit `df2e7423`](https://github.com/SychPL/solidcraft/commit/df2e74230e6659409d65501b5d9396b55c6503d3) | Three earlier GIF demonstrations, with credit to 0xlillith and Apache-2.0/MIT for the original model. |
|
||||
| [Author's showcase comment on PR 1540](https://github.com/tangency-labs/solidcraft/pull/1540#issuecomment-6205857321) | The combined demonstration and the motivation for its added mechanisms. |
|
||||
| [Motion export PR 1680](https://github.com/tangency-labs/solidcraft/pull/1680) | The exact showcase filename and tour/export examples. |
|
||||
| [Original rover repository](https://github.com/0xlillith/solidcraft-rover/tree/b32437915372d32b71419dc8f5143fe22ff1e869) | The owner's original Rover-v7 model and its attribution. |
|
||||
|
||||
The source lock preserves the earlier bounded public search as historical evidence. That search had inspected the media branch before the native file was added. Its former `awaiting_native_source` outcome is superseded by the supplied file and the new author commit; it is not a current blocker.
|
||||
|
||||
## Authorship and notices
|
||||
|
||||
The [original rover attribution](https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/ATTRIBUTION.md) offers the original model under **MIT OR Apache-2.0** and credits the SolidCraft emblem to SolidCraft contributors. The original modeled lettering follows **Ubuntu Light** outlines by Canonical Ltd., under the **Ubuntu Font Licence 1.0**. Its exact notice is retained in [licenses/UFL.txt](licenses/UFL.txt). No font binary is added.
|
||||
|
||||
SychPL is credited for the improved assembly, helper geometry and showcase study.
|
||||
On 2026-10-23T22:13:37Z, [SychPL explicitly licensed their additions](https://github.com/tangency-labs/solidcraft/pull/5494#issuecomment-6375788360)
|
||||
under **MIT OR Apache-2.0**, at the recipient's option. The grant expressly covers
|
||||
redistribution and derived files, including `SELENE-functional.solidcraft`.
|
||||
The author media branch itself has no separate licence file; the linked public
|
||||
author declaration supplies the previously missing permission. The original
|
||||
rover and Ubuntu Font Licence notices above remain applicable and unchanged.
|
||||
|
||||
New procedural geometry, English documentation and command generators in this derivative are original contributions. Raspberry Pi references inform dimensions and component identity; manufacturer CAD, logos, PCB artwork, electrical netlists and photographs are not embedded. No commercial CAD assets or GPL geometry implementations are imported.
|
||||
|
||||
## Authoring runtime and format compatibility
|
||||
|
||||
The reconstruction workflow selects the official **SolidCraft v0.18.2 Linux x86_64 CLI**. Its [published release](https://github.com/tangency-labs/solidcraft/releases/tag/v0.18.2) identifies source commit `4927214976ff20758fde35af03bd6b2d6cf73e18`. The release archive SHA-256 is `9d0c922ac72204f34ad22ca7a171be78016ab002e304ace3c07d34d187d830ff`; the extracted CLI SHA-256 is `e50fe78292d569c36052b24f46f1732bc4e43d1ecdac6a64092aa1cee3b97086`. The executor is an external development dependency and is not bundled as a model asset.
|
||||
|
||||
This runtime writes **`solidcraft/28`**, which the personal render branch's format-29 reader can migrate. The unchanged source remains in format 23. The newer official v0.19.0 writes format 30, beyond that render branch's reader, so its isolated component fixtures remain development evidence rather than the authoritative final build. Final acceptance must name the actual executor and final model hash; success in a different runtime does not replace that run. No native format marker is rewritten by these tools.
|
||||
|
||||
## Reproducibility boundaries
|
||||
|
||||
- Keep the pinned source unchanged. Author geometry, appearances, components, joints and studies through SolidCraft commands into a separately named derivative.
|
||||
- Record the executor version and binary hash with each native build. A newer native format is not backwards compatible merely because geometry looks similar. Do not edit a file's format marker to bypass this restriction.
|
||||
- Bind exact evaluated body names and component identities. Feature declarations alone are not a body inventory.
|
||||
- Verify joint movement and followers against independent calculations. A successful command without actual movement is not a successful mechanism test.
|
||||
- Preserve execution failures and incomplete checks explicitly. Do not carry validation claims from a lost intermediate checkpoint into a newly rebuilt model.
|
||||
- A native model suitable for inspection and render preparation is not a certified manufacturing design, an electrical design, or a physically simulated lunar rover.
|
||||
|
||||
The prepared appearance catalog, scene specifications and future dynamics sequence have their own evidence status. Admitting this source does not automatically bind or validate those resources.
|
||||
@@ -0,0 +1,147 @@
|
||||
# SELENE native validation
|
||||
|
||||
This report distinguishes evaluation of the complete saved rover, independent checks of its motion, reduced geometry fixtures and actual image generation. A clean feature timeline alone does not establish mechanical clearance, and a reduced fixture does not establish a collision-free whole rover.
|
||||
|
||||
## Native artifact and executors
|
||||
|
||||
The saved derivative is [models/SELENE-functional.solidcraft](models/SELENE-functional.solidcraft), **439,883 bytes**, native format **`solidcraft/28`**. Its SHA-256 is:
|
||||
|
||||
```text
|
||||
3bd2bfa1c6336394c4a4208d30b52c80d06658a3bd7ea57cc93b774411d1bd68
|
||||
```
|
||||
|
||||
The unchanged source is `source/SELENE-showcase.solidcraft`, 314,452 bytes, SHA-256 `1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677`. It is byte-identical to SychPL's published improved showcase file; [SOURCE.md](SOURCE.md) pins its author commit and license evidence. Native evaluation of that source found 1,418 bodies and no feature errors or warnings. Its container has 3,378 history features, 47 components excluding root, 47 occurrences, 49 joints, nine motion links and one motion study.
|
||||
|
||||
The authoring and final acceptance executor is the official SolidCraft v0.18.2 Linux CLI, SHA-256 `e50fe78292d569c36052b24f46f1732bc4e43d1ecdac6a64092aa1cee3b97086`. It writes `solidcraft/28`. The personal render branch's format-29 reader accepts that format. The native container is only read for inspection and selector construction; all CAD changes are made through SolidCraft commands.
|
||||
|
||||
The personal fork at `10ada1b45a4eb285ce752ac72f9aaa968ff8b5c4` was also compiled successfully and used for bounded product-render checks. Its CLI SHA-256 is `2a5485f7c7832d29b6340988837316e247b94eeeb9d4f7333ee616cea38c6826`. This separately built executable is not substituted into the authoring checkpoint chain.
|
||||
|
||||
## Complete-model build and motion acceptance
|
||||
|
||||
The full native build passed **17 saved stages and 2,318 native commands**, including the explicit inventory and graph inspections. Its final timeline has **zero errors and zero warnings**; all live body names are unique. The final native joint graph reports no errors, conflicts or floating occurrences.
|
||||
|
||||
| Native inventory | Supplied source | Functional derivative |
|
||||
|---|---:|---:|
|
||||
| Evaluated bodies | 1,418 | 2,116 |
|
||||
| Components excluding root | 47 | 172 |
|
||||
| Occurrences | 47 | 172 |
|
||||
| History features | 3,378 | 5,484 |
|
||||
| Joints | 49 | 180 |
|
||||
| Motion links | 9 | 99 |
|
||||
| Motion studies | 1 | 8 |
|
||||
|
||||
The final joint inventory contains 135 revolutes, 11 sliders, 33 rigid joints and one cylindrical joint. The saved document also contains **121 browser groups, ten named views and ten render setup records**. The build history and final native inventory are in `target/selene/native-build/`.
|
||||
|
||||
Independent final-master acceptance **passed all 33 cases and 880 numerical comparisons** in a fresh official v0.18.2 process. The run completed on 2026-10-22, from 08:40:24 to 08:53:15 UTC, with exit code 0. It exercised 26 kinematic/neutral cases and seven selected neutral-pose interference pairs. Both the master and original source remained byte-for-byte unchanged. All 19 independent drivers were neutral on open and after the final reset; the tested graph inspections reported no errors, conflicts or floating occurrences.
|
||||
|
||||
| Kinematic case family | Cases | Accepted exercise |
|
||||
|---|---:|---|
|
||||
| Drivetrain | 1 | Six wheels follow the driver; a 90° turn gives −62.831853 mm demonstration-track travel at the 40 mm nominal radius. Independent wheel and track world-position checks pass. |
|
||||
| Solar deployment | 1 | The selected 20° deployment closes all four actuator loops and agrees with the independently calculated strokes. |
|
||||
| Independent pointing | 2 | Sensor and dish pointing are driven independently, with native follower and world-position checks. |
|
||||
| Gripper | 2 | Driver endpoints −15° and +18°, opposite follower values and jaw world positions. |
|
||||
| Sample cap | 2 | 360° and 1440° rotation produce 1.5 mm and 6 mm axial travel respectively. |
|
||||
| Suspension | 12 | Each of six carriers is driven to both −4° and +1.5°. Closed-loop strokes and carrier world centers of mass match independent calculations. |
|
||||
| Rolling-element bearings | 5 | Shoulder, elbow, wrist, tool tilt and sensor elevation drivers exercise all ten bearing cages and 80 ball-spin relations, with one orbital witness per bearing. |
|
||||
| Neutral reset | 1 | All 19 independent driver coordinates return to zero. |
|
||||
| **Kinematic total** | **26** | **All passed.** |
|
||||
|
||||
The 880 numerical comparisons include repeated neutral-coordinate readbacks between cases; they are not 880 distinct poses. Numerical agreement is a solver check, not a manufacturing tolerance claim.
|
||||
|
||||
| Numerical quantity | Comparisons | Maximum absolute error | Acceptance tolerance |
|
||||
|---|---:|---:|---:|
|
||||
| Joint angles | 756 | 7.106 × 10⁻¹⁵° | 10⁻⁶° |
|
||||
| Linear joint coordinates | 19 | 3.777 × 10⁻¹¹ mm | 10⁻⁵ mm |
|
||||
| Suspension strokes, included above | 12 | 3.927 × 10⁻¹² mm | 10⁻⁵ mm |
|
||||
| World center-of-mass coordinates | 105 | 4.443 × 10⁻⁵ mm | 0.002 mm |
|
||||
| Bearing orbit coordinates, included above | 30 | 1.318 × 10⁻⁵ mm | 0.002 mm |
|
||||
|
||||
The largest linear error was a solar actuator stroke; the largest world-coordinate error was the dish yaw mount's center-of-mass height.
|
||||
|
||||
| Selected neutral-pose pair | Completed method | Result |
|
||||
|---|---|---|
|
||||
| `Shoulder link -9` / `Elbow link -9` | Exact solid intersection | Clear |
|
||||
| `Elbow link -9` / `Distal wrist link -9` | Exact solid intersection | Clear |
|
||||
| `Tool wrist machined tongue` / `Tool tilt joint shaft` | Exact solid intersection | Clear |
|
||||
| `Gripper jaw -1` / `Gripper jaw 1` | Conservative broad-phase separation | Clear |
|
||||
| `Raspberry Pi 5 PCB` / `Pi5 USB2 mounting tab 1` | Exact solid intersection | Clear |
|
||||
| `Raspberry Pi 5 PCB` / `Pi5 USB3 mounting tab 2` | Exact solid intersection | Clear |
|
||||
| `Raspberry Pi 5 PCB` / `Pi5 GPIO pin 40` | Exact solid intersection | Clear |
|
||||
|
||||
These are **six exact intersection checks and one broad-phase clearance**, all with zero reported overlaps, unchecked or skipped pairs, no truncation and no exhausted budget. They are selected checks at neutral, not an exhaustive swept collision analysis.
|
||||
|
||||
The complete local machine-readable report is `target/selene/validation-final/validation.json`, schema `1.0.0`, 228,492 bytes, SHA-256 `0ccbf279f27885f6a4646a691a03915ca9ae22ae2f6bfef9574b856392474130`. It records every case, comparison, drive and interference result. The validator's SHA-256 is `b032962210e86a516193bd549d9137dcff93dbff4a3e038ca9a08de3493e1aac`. The repository's resource rules keep raw execution reports in ignored `target/`; the shipped validator and committed case selection reproduce them.
|
||||
|
||||
The reproducible builder saves every completed stage, validates complete native command and timing traces, rejects timeline errors or warnings, requires unique live body names and checks the native joint graph. Resume verifies source, executable, recipe, result and checkpoint hashes. The independent validator opens the final saved file in a new process and checks requested values, follower values and world-coordinate measurements against separate calculations. It does not save its test poses over the master.
|
||||
|
||||
The selected interference pairs in [motion/interference-pairs.json](motion/interference-pairs.json) are deliberately bounded. Any timeout, unchecked pair or failed command is incomplete evidence, not a clearance pass. They do not exhaust all body pairs or all simultaneous configurations.
|
||||
|
||||
## Reduced-fixture evidence
|
||||
|
||||
These checks were completed before integrating the corresponding production commands. Their scope remains local even when the same geometry is present in the full rover.
|
||||
|
||||
| Subject | Actual evidence | Result and scope |
|
||||
|---|---|---|
|
||||
| Rolling-element kinematics | An arm bearing and a sensor-head bearing each driven by 30°; all eight relative ball spins and one orbital position checked in each case. | Arm cage 12.679558011° and relative ball spin −94.643843725°; head cage 13.360248447° and relative ball spin −135.576157538°. Maximum world orbital error 1.474 × 10⁻¹⁰ mm. Ideal no-slip relations, without contact-force simulation. |
|
||||
| Bearing clearances | Eleven core arm/bearing pairs and four head-retention pairs: 14 completed exact Boolean checks and one bounding-box exclusion. Core fixture: 288 bodies, 736 features, 117 components, 115 joints and 90 links. | No overlap reported and no pair unresolved after retries. Both fixture inventories have zero feature errors/warnings. These official v0.19.0 fixtures precede the production arm set-screw tips' final 0.05 mm extension; the named local pairs do not establish all-body or all-pose clearance. |
|
||||
| Raspberry Pi 5 | Official v0.19.0 fixture: 748 commands, 492 bodies and 1,202 features. Two analytic volumes, all 40 GPIO centers, six exact Boolean pairs and a separate broad-phase check of 26 major package envelopes. | PCB volume error 0.000514094% against a 0.01% tolerance; maximum GPIO center error 1.422 × 10⁻¹⁴ mm. No reported overlaps, unchecked pairs or timeline errors/warnings. Component layout remains a visual reconstruction. |
|
||||
| Gripper | Native checks at −15°, 0° and +18°, plus a 661-point analytic sweep at 0.05° and a continuous vertex/stationary-point separation bound. | Minimum jaw-to-jaw gap 5.735342 mm; minimum pad-to-pad gap 6.360460 mm. The local jaw envelopes remain in opposite half-planes over the continuous driver interval. Pin/sleeve radial clearance is 0.05 mm. This is a local gripper proof. |
|
||||
| Suspension | Retained-source-label fixture: 71 commands, 15 bodies, 43 features; both −4° and +1.5° endpoints; 12 pair-pose checks over eight unique pairs, including six exact Boolean intersections. | No timeline errors/warnings or reported overlaps; no unchecked pairs. Maximum slider-equation error 3.927 × 10⁻¹² mm and world center-of-mass error 1.973 × 10⁻⁹ mm. |
|
||||
| Yaw journals | Official v0.18.2 fixture: 101 commands, 20 bodies, 67 features; six support-only rotation cases, 44 pair-pose checks over 26 unique pairs, including 29 exact Boolean intersections; nine volume checks and 12 seating/distance measurements. | All cases passed; no timeline errors/warnings, unchecked pairs or reported overlaps. Maximum analytic volume error 0.0155823%, within the 0.02% tolerance. |
|
||||
| Integral glass vials | Official v0.18.2 fixture: 55 commands, six cups, one component and 49 features. The 22-command production subrecipe matches the validated recipe exactly. | Maximum analytic volume error 0.0080213%, COM error 0.000108088 mm and bounding-box error 0.000155825 mm. Each cup has one kernel shell; names, ownership, Glass material and opacity 0.30 are preserved. |
|
||||
|
||||
The yaw fixture exposed an existing overlap of approximately 21.33 mm³ between each of four dish mounting screw heads and their stationary support. Four local reliefs remove those overlaps. The support-only fixture exercises arm/turret ±160° and dish ±150° to inspect the axisymmetric interfaces; the complete rover retains its narrower documented joint limits. Those local rotations do not expand the rover's accepted motion envelope.
|
||||
|
||||
The journal supports have nominal 0.1 mm radial journal clearance, 0.15 mm radial pin clearance and 0.1 mm axial retention play. Display-mesh distance measurements of the tiny retainer gaps were 0.0644–0.0826 mm. These are mesh approximations; the nominal analytic dimensions and completed solid-interference results are recorded separately.
|
||||
|
||||
The vial fixture also exported 57,264 native STL triangles. After coordinate welding at 10⁻⁶ mm, the mesh has six connected components and zero boundary, nonmanifold or inconsistent-winding edges, and zero degenerate triangles. Each vessel retains its 11.6 mm outside diameter and 27 mm height, with a 0.8 mm wall and 1 mm integral floor. Its fixture SHA-256 is `76f0cb4e25e7beb2f04a1ccd84619144441f9d580129f0325c29ef8d774ef2a6`; detailed evidence is in `target/selene/vial-repair/validation-report.json`. Mesh closure does not establish physical dielectric renderer support.
|
||||
|
||||
Two initial bearing checks exhausted their eight-second budgets. With 30-second budgets, the shoulder-clevis/outer-race check completed in 12.122 seconds and the ball/inner-race check in 10.382 seconds, both clear. The original timeout reports remain alongside the successful retries. Their initial zero-overlap counts were not accepted as passes.
|
||||
|
||||
The electronics and core bearing fixtures use official v0.19.0, format 30; they are development fixtures, not the distributed master. Their production commands were subsequently replayed in the complete rover with v0.18.2. The retained-label suspension fixture's SHA-256 is `1da6c92ba9ff2c421dc5b475f9971b458d3d43bbb048147df0cdeb70fefb9a11`; the yaw fixture's is `65ba6b033e301bd6cc4c91caa31d2ea67c69064d970355ff0597609adc62efcd`. The unchanged electronics generator is `67a69a7e613ad59dcf474dc6ecd9d9fb8439aa193e2e2ee458c282b65186fd9d`; its fixture is `578d9ba7b00738552ef9201c57489520fd86275c7fcfa23818adcdaed07aae04`.
|
||||
|
||||
Local report locations in a development checkout are `target/selene/bearings/compact-phase-report.json`, `target/selene/bearings/review-gripper-presentation.json`, `target/selene/electronics/validation-report.json`, `target/selene/suspension/retained-labels/validation-report.json` and `target/selene/yaw-support-audit/validation-report.json`. Detailed generated logs, fixture files and diagnostic images stay outside the production asset package.
|
||||
|
||||
## Image evidence
|
||||
|
||||
The compiled personal fork reopened the complete final master and generated three actual **1400 × 1000 native Design PNGs**. All three were visually reviewed and are shipped under `exports/`. The overview shows the neutral rover, the electronics view exposes the connector mouths and populated board, and the bearing view isolates its races, balls and cage. The capture opened all 2,116 bodies with a clean timeline and left the master hash unchanged.
|
||||
|
||||
| Shipped preview | Bytes | SHA-256 |
|
||||
|---|---:|---|
|
||||
| [SELENE-overview.png](exports/SELENE-overview.png) | 423,686 | `44d317ca9b0f77c3ac5d43409f0b6b281b9d6724d58a3c8edd8ca2db19a0bc63` |
|
||||
| [SELENE-electronics.png](exports/SELENE-electronics.png) | 225,933 | `cd8af0700ce6a4cc0aa00bdfa5d246e4b3ed491847795636c65d9a8ead45991e` |
|
||||
| [SELENE-bearing.png](exports/SELENE-bearing.png) | 284,094 | `ed3a3da01946019c9c380bf8515013eca3a05c7bf5161ff4bb98ee36eb5ef92b` |
|
||||
|
||||
The native capture metadata identifies the CPU rasterizer and its expected warning: surface-analysis colors, highlights and legends are not drawn. These previews do not claim physical PBR or transmission. Cameras, executor hash and capture metadata are recorded in `target/selene/final-previews/export-report.json`; [tools/export_views.py](tools/export_views.py) reproduces the three selections without saving transient visibility or camera changes over the master.
|
||||
|
||||
Two actual `cpu-product` renders from the compiled personal fork passed preflight and image generation with no warnings: a single bearing fixture (20 visible bodies, 93,654 triangles) and the Pi isolated from the integrated rover checkpoint (504 visible bodies, 103,004 triangles). Both outputs were 768 × 576 PNGs and were visually inspected. The bearing is a reduced fixture; the electronics image uses actual integrated geometry. See [RENDER.md](RENDER.md) for exact resource estimates, rendering scope and limitations.
|
||||
|
||||
The complete rover exceeds this revision's 262,144-triangle CPU product admission limit. The 64 arm-bearing balls alone contain 654,336 reference-mesh triangles. That code path has not produced a whole-rover PBR image. Native Design previews and bounded product renders are different evidence.
|
||||
|
||||
## Repository checks
|
||||
|
||||
The catalog and prepared-resource validators passed with the source status `pinned_native`. The wider scene catalog intentionally remains `runtime_ready: false`: the native model's completion does not bind every proposed stage, material role or future dynamics event.
|
||||
|
||||
The required repository-wide `cargo xtask ci` command was attempted with Rust 1.95.0 and the required socket permissions. Formatting, asset attribution, icon checks (17 tests), license checks, generated lists and dependency-layer checks (17 crates) passed. CI then stopped at a pre-existing `clippy::nonminimal_bool` diagnostic in `crates/geom/src/fill_general.rs:166`, under `-D warnings`. That application source is unchanged by this work. Later workspace tests and WebAssembly checks were not reached. The whole repository gate is therefore **not green**; the successful native CLI build and asset checks do not replace it.
|
||||
|
||||
The final `cargo xtask ci` attempt, after adding the shipped master and all three previews, reproduced that same baseline Clippy failure. Its exact output is retained locally in `target/selene/ci-final.log`. Its asset and icon gates passed. The catalog and prepared-resource validators also passed with zero errors, and the final whitespace check was clean. No application Rust source is changed by this package.
|
||||
|
||||
## Resource failures and recovered attempts
|
||||
|
||||
The working environment has an 8 GiB memory limit. Three earlier native attempts were killed for exceeding it: one overlapped a second cold full-model open; two involved late renames of original suspension bodies. Late original-body renames forced a long history rebuild while prior evaluated state remained resident. The production recipe retains those original labels and splits suspension geometry into smaller saved stages. Geometry, ownership and joint intent remain explicit.
|
||||
|
||||
Full-model native processes now run sequentially. The provided tools set two native worker threads and an allocator policy of `MALLOC_ARENA_MAX=1`, `MALLOC_MMAP_THRESHOLD_=65536` and `MALLOC_TRIM_THRESHOLD_=65536`. These are process-memory settings, not geometry simplifications. Failed attempts and their logs are retained under `target/selene/failed-attempts/`; they are not counted as successful validation.
|
||||
|
||||
Strict container inspection also rejected one intermediate suspension checkpoint because the inherited tour still referenced the original wheel joint ID after wheel reparenting. The builder now refreshes that study by exact joint names before saving the suspension checkpoint. The corrected stage completed with 172 components and 180 joints, and the rejected file remains diagnostic evidence only.
|
||||
|
||||
The first presentation attempt failed at the original touching vial-wall/bottom union and saved no presentation checkpoint. The validated replacement removes each split pair and creates an envelope with a blind bore, retaining the original wall name, external dimensions, component and appearance. Its base coordinates account for the source's already baked `Move9` translation. The failed union log remains under `target/selene/failed-attempts/vial-touching-union/`.
|
||||
|
||||
## Remaining physical and animation scope
|
||||
|
||||
The rover is an editable geometric and kinematic showcase. The rolling bearings use ideal linked revolutes; the suspension uses rigid links and a closed pin–slider–pin loop. Neither provides contact forces, spring dynamics, damping, backlash, stress, fatigue or a rated load capacity. Fasteners have nominal seats rather than fully modeled thread engagement.
|
||||
|
||||
The six rigid spring solids and twelve motor leads remain neutral-pose render details and must be hidden for suspension movement. The motion visibility profile handles this. Flexible hose display geometry and rigid decorative arm hydraulic cylinders are excluded from the relevant moving presentation.
|
||||
|
||||
The Pi is an original visual reconstruction based on cited public mechanical dimensions. It is not manufacturer CAD, a PCB netlist, exact component artwork or an electrical design. Opaque PBR parameters are authored appearances; nominal material density does not establish measured mass, thermal behavior or friction. Glass viewport opacity is not a physical transmission model.
|
||||
|
||||
The adapted legacy tour and seven focused studies are animation authoring resources. Their presence does not certify every frame, every combined pose, obstacle clearance or a future throw-and-catch sequence. Those checks belong to the specific animation shot and any physical simulator chosen later.
|
||||
@@ -0,0 +1,96 @@
|
||||
-------------------------------
|
||||
UBUNTU FONT LICENCE Version 1.0
|
||||
-------------------------------
|
||||
|
||||
PREAMBLE
|
||||
This licence allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely. The fonts, including any derivative works, can be
|
||||
bundled, embedded, and redistributed provided the terms of this licence
|
||||
are met. The fonts and derivatives, however, cannot be released under
|
||||
any other licence. The requirement for fonts to remain under this
|
||||
licence does not require any document created using the fonts or their
|
||||
derivatives to be published under this licence, as long as the primary
|
||||
purpose of the document is not to be a vehicle for the distribution of
|
||||
the fonts.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this licence and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Original Version" refers to the collection of Font Software components
|
||||
as received under this licence.
|
||||
|
||||
"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.
|
||||
|
||||
"Copyright Holder(s)" refers to all individuals and companies who have a
|
||||
copyright ownership of the Font Software.
|
||||
|
||||
"Substantially Changed" refers to Modified Versions which can be easily
|
||||
identified as dissimilar to the Font Software by users of the Font
|
||||
Software comparing the Original Version with the Modified Version.
|
||||
|
||||
To "Propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification and with or without charging
|
||||
a redistribution fee), making available to the public, and in some
|
||||
countries other activities as well.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
This licence does not grant any rights under trademark law and all such
|
||||
rights are reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of the Font Software, to propagate the Font Software, subject to
|
||||
the below conditions:
|
||||
|
||||
1) Each copy of the Font Software must contain the above copyright
|
||||
notice and this licence. 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.
|
||||
|
||||
2) The font name complies with the following:
|
||||
(a) The Original Version must retain its name, unmodified.
|
||||
(b) Modified Versions which are Substantially Changed must be renamed to
|
||||
avoid use of the name of the Original Version or similar names entirely.
|
||||
(c) Modified Versions which are not Substantially Changed must be
|
||||
renamed to both (i) retain the name of the Original Version and (ii) add
|
||||
additional naming elements to distinguish the Modified Version from the
|
||||
Original Version. The name of such Modified Versions must be the name of
|
||||
the Original Version, with "derivative X" where X represents the name of
|
||||
the new work, appended to that name.
|
||||
|
||||
3) The name(s) of the Copyright Holder(s) and any contributor to the
|
||||
Font Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except (i) as required by this licence, (ii) to
|
||||
acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with
|
||||
their explicit written permission.
|
||||
|
||||
4) The Font Software, modified or unmodified, in part or in whole, must
|
||||
be distributed entirely under this licence, and must not be distributed
|
||||
under any other licence. The requirement for fonts to remain under this
|
||||
licence does not affect any document created using the Font Software,
|
||||
except any version of the Font Software extracted from a document
|
||||
created using the Font Software may only be distributed under this
|
||||
licence.
|
||||
|
||||
TERMINATION
|
||||
This licence 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.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,151 @@
|
||||
# SELENE original appearance pack
|
||||
|
||||
Forty-eight original appearance recipes are prepared for the current opaque PBR command path. Every recipe has a directly copyable, model-independent baseline and a separate advanced target specification. The pack contains no measured material dataset, external artwork, engineering material properties or runtime implementation.
|
||||
|
||||
## Files and status
|
||||
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `appearance-pack.json` | Editable authority for 48 recipes, their opaque projections and future target requirements. This is authoring data, not a native portable library file. |
|
||||
| `appearance-swatches.json` | Prepared command script with 48 labeled box swatches and one neutral support base. It uses the existing `file.new`, `solid.box` and `appearance.assign` command shapes. |
|
||||
| `appearance-pack.md` | Contract, use, limitations and recipe index. |
|
||||
|
||||
The authoring step checked JSON structure, ID/name uniqueness, catalog and capability references, numeric admission bounds, exact runtime parameter keys, and every swatch assignment against the recipe authority. **No SolidCraft runtime was executed and no rendered image was visually reviewed during authoring.** The script is a prepared input whose execution and render admission must be verified on the selected build.
|
||||
|
||||
## Runtime projection contract
|
||||
|
||||
Copy `items[].baseline_projection.runtime_parameters`, then add an existing target selection before calling `appearance.assign`. The projection includes `appearance`, `color`, `opacity: 1` and exactly three PBR fields: `metallic`, `roughness` and `dielectric_ior`. Targets are deliberately absent because the improved SELENE source model must be pinned and inspected before binding.
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "appearance.assign",
|
||||
"params": {
|
||||
"bodies": [
|
||||
"Existing target body"
|
||||
],
|
||||
"appearance": "SELENE-AP-001 Neutral matte enclosure",
|
||||
"color": "#717882",
|
||||
"opacity": 1.0,
|
||||
"pbr": {
|
||||
"metallic": 0.0,
|
||||
"roughness": 0.68,
|
||||
"dielectric_ior": 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The body name in this example is a placeholder, not a ready-to-run model binding. The current command also accepts face points and components. An occurrence name supplied as a component target resolves to its component definition; do not assume an independent occurrence override. Face overrides take precedence over broader appearances. Assigning a look replaces it: omitting `pbr` later restores the scalar response instead of retaining these fields.
|
||||
|
||||
Current bounds are metallic 0 to 1, perceptual roughness 0.045 to 1, relative dielectric IOR 1 to 3, and opacity exactly 1 for PBR. Colors are sRGB8 hex values decoded by the existing renderer. All values here are original illustrative authoring choices. The common IOR control of 1.5 is not a measured value; it controls reflection of the nonmetal fraction and does not enable transmission. The metal recipes use metallic 1 and the dielectric recipes use metallic 0; no mechanical or electrical properties follow from either choice.
|
||||
|
||||
The pack JSON is **not** `solidcraft-library/1` and cannot be passed directly to `library.inspect` or `library.apply`. That scalar library format cannot preserve PBR. Use the prepared script, an explicit appearance overlay, or a native format-21 design. A future catalog importer needs its own versioned admission contract.
|
||||
|
||||
## Prepared swatch script
|
||||
|
||||
The 48 swatches are 12 x 12 x 8 mm boxes in 8 columns and 6 rows with an 18 mm pitch. Their lower corners run from x = -69 mm to 57 mm and y = -51 mm to 39 mm, starting at z = 1 mm. A 144 x 108 x 1 mm base sits below them. IDs ascend along x within each row, then along y. Body names carry the recipe ID and English name; there is no text geometry, font, decal or external asset.
|
||||
|
||||
The script contains 99 commands: one new design, 49 boxes, and 49 appearance assignments. Flat boxes intentionally bound tessellation demand; they are an inspection grid, not a complete optical validation target. A curved reference, an angular light sweep, and close-up geometry remain necessary for validating highlights, anisotropy and layered targets when those functions exist.
|
||||
|
||||
Prepared commands for a built native CLI, run from the repository root:
|
||||
|
||||
```sh
|
||||
mkdir -p target/selene-render
|
||||
solidcraft-cli run assets/render/selene/materials/appearance-swatches.json --save target/selene-render/appearance-swatches.solidcraft --results --json-out target/selene-render/appearance-swatches-results.json
|
||||
solidcraft-cli render target/selene-render/appearance-swatches.solidcraft --out target/selene-render/appearance-swatches.png --width 768 --height 576
|
||||
```
|
||||
|
||||
These commands have been prepared, not executed. The render CLI automatically fits a camera when none is supplied. Existing output is protected unless `--overwrite` is explicitly provided. Keep local render evidence under ignored `target/`; this pack does not bundle unreviewed preview exports.
|
||||
|
||||
To style a pinned SELENE design, prepare a separate overlay containing only `appearance.assign` commands with verified target names, then run:
|
||||
|
||||
```sh
|
||||
solidcraft-cli run target/selene-render/verified-appearance-overlay.json --in path/to/pinned-selene.solidcraft --save target/selene-render/selene-styled.solidcraft --results
|
||||
```
|
||||
|
||||
Both input paths above are placeholders until the model and overlay are prepared. The overlay must contain no `file.new`, geometry edits, physical-material edits, joint edits or pose changes. Native save is the preservation path. `timeline.export_script` currently omits appearance overrides and refuses component/joint assemblies; it is not an appearance or articulated-model round-trip mechanism. A multi-command script stops at the first error and is not a whole-script transaction, so verify targets before applying it to the review copy.
|
||||
|
||||
## What the baseline can show
|
||||
|
||||
The current Render consumer supports opaque direct-lit responses under three fixed neutral directional lights, with the existing preview tone mapping and PNG export. It does not implement the textured, layered, transmissive or emissive targets described here. Current consumers have no cast shadows, environment illumination, indirect bounces, surface coating, anisotropy, absorption or transmission. Saved nondefault environment/exposure intent is not executable by this baseline. These limits are documented in [`docs/render-opaque-pbr.md`](../../../../docs/render-opaque-pbr.md) and [`docs/render-jobs.md`](../../../../docs/render-jobs.md).
|
||||
|
||||
Advanced targets remain separate authoring data. Their numeric controls are illustrative texture or geometry settings in millimetres, radians or explicitly named dimensionless units. They are not manufacturing recommendations or measurements. Optical spectra, refractive data, layer thicknesses and scattering coefficients remain unspecified where the recipe lists missing inputs. CAP references link to requirements in [`capabilities.json`](../../../../docs/render-materials/capabilities.json), not to a claim of implementation.
|
||||
|
||||
## SELENE-specific fidelity boundaries
|
||||
|
||||
- The sample vial, optical window and diffuser recipes are explicitly opaque inspection surrogates (AP-029, AP-030 and AP-039). They do not show glass, refraction or light transmission. Transparent containers need closed wall geometry and correct interior/exterior medium handling before the advanced target can be represented.
|
||||
- The unpowered LED face (AP-038) emits no light. Active LEDs require a separate emission model; spectrally excited phosphor conversion additionally requires excitation, conversion and emission data. Ordinary RGB emission must not be labelled fluorescence.
|
||||
- The black and silver anodized recipes (AP-015 and AP-016) are simplified outer-response surrogates. Actual anodizing combines a dielectric or absorbing oxide with a metal substrate; a single metalness value is not that layer model.
|
||||
- Blanket folds (AP-018 and AP-019), honeycomb walls (AP-040), mesh-wheel openings (AP-044), serrations and threads require geometry. Color or roughness alone cannot provide their silhouettes, empty space or self-shadowing.
|
||||
- Lunar terrain and deposits (AP-041 to AP-043) are granular surfaces in vacuum. The dust-patch baseline belongs on separate deposit geometry or a deliberately bounded face. Applying it to an entire rover body does not reproduce sparse dust coverage. No terrestrial fog, wetness or aerial perspective is implied.
|
||||
- Appearance assignments do not define density, stiffness, friction, thermal emissivity, electrical performance, leak tightness, cleanliness, ESD behavior or flight readiness. They must leave the improved model geometry, articulation, joint limits and motion data intact.
|
||||
- The automotive rubber sidewall (AP-048) is a representative terrestrial material target. Do not substitute it for the SELENE open metal wheel (AP-044) merely because both are wheel-related.
|
||||
|
||||
## Recipe index
|
||||
|
||||
All entries use opacity 1 and the illustrative IOR control 1.5. M is metallic fraction; R is perceptual roughness. The catalog link is semantic traceability to the 600-recipe planning catalog, not an imported texture or measured asset.
|
||||
|
||||
| ID | Original recipe | Catalog source | sRGB color | M | R | Baseline role |
|
||||
| --- | --- | --- | --- | ---: | ---: | --- |
|
||||
| SELENE-AP-001 | Neutral matte enclosure | MAT-031 | `#717882` | 0 | 0.68 | opaque surface |
|
||||
| SELENE-AP-002 | White thermal-coating preview | MAT-491 | `#d9dde0` | 0 | 0.58 | opaque surface |
|
||||
| SELENE-AP-003 | Matte optical baffle | MAT-468 | `#141619` | 0 | 0.94 | opaque surface |
|
||||
| SELENE-AP-004 | Ceramic gripper contact pad | MAT-574 | `#d9d7cf` | 0 | 0.32 | opaque surface |
|
||||
| SELENE-AP-005 | Machined aluminium wheel rim | MAT-561 | `#b9c0c7` | 1 | 0.29 | opaque surface |
|
||||
| SELENE-AP-006 | Serrated metal gripper jaw | MAT-573 | `#a6adb5` | 1 | 0.40 | opaque surface |
|
||||
| SELENE-AP-007 | Linear-brushed stainless housing | MAT-002 | `#b8bdc2` | 1 | 0.34 | opaque surface |
|
||||
| SELENE-AP-008 | Polished stainless sample cup | MAT-593 | `#c9ced3` | 1 | 0.16 | opaque surface |
|
||||
| SELENE-AP-009 | Titanium wrist finish | MAT-572 | `#8b9098` | 1 | 0.43 | opaque surface |
|
||||
| SELENE-AP-010 | Exposed copper conductor | MAT-164 | `#b97850` | 1 | 0.27 | opaque surface |
|
||||
| SELENE-AP-011 | Machined brass printer nozzle | MAT-391 | `#b4a06b` | 1 | 0.30 | opaque surface |
|
||||
| SELENE-AP-012 | Solidified solder joint | MAT-165 | `#bec3c6` | 1 | 0.25 | opaque surface |
|
||||
| SELENE-AP-013 | Metal sampling scoop | MAT-575 | `#9ba4ad` | 1 | 0.44 | opaque surface |
|
||||
| SELENE-AP-014 | Gold-finished contact pad | MAT-163 | `#bf9c49` | 1 | 0.21 | opaque surface |
|
||||
| SELENE-AP-015 | Black anodized chassis surrogate | MAT-567 | `#252a30` | 0 | 0.56 | opaque surface |
|
||||
| SELENE-AP-016 | Silver anodized cover surrogate | MAT-015 | `#abb3ba` | 1 | 0.39 | opaque surface |
|
||||
| SELENE-AP-017 | Composite arm tube surrogate | MAT-571 | `#252a2e` | 0 | 0.42 | opaque surface |
|
||||
| SELENE-AP-018 | Aluminized blanket metal face | MAT-501 | `#c3c8cd` | 1 | 0.18 | opaque surface |
|
||||
| SELENE-AP-019 | Polyimide-facing blanket surrogate | MAT-502 | `#80602e` | 0 | 0.30 | opaque surface |
|
||||
| SELENE-AP-020 | Solar-cell opaque preview | MAT-511 | `#172b43` | 0 | 0.24 | opaque surface |
|
||||
| SELENE-AP-021 | Silicone cable jacket | MAT-333 | `#484d56` | 0 | 0.77 | opaque surface |
|
||||
| SELENE-AP-022 | Polyimide harness wrap | MAT-332 | `#9d713d` | 0 | 0.46 | opaque surface |
|
||||
| SELENE-AP-023 | Fluoropolymer sealing ring | MAT-598 | `#dbddd7` | 0 | 0.49 | opaque surface |
|
||||
| SELENE-AP-024 | Elastomer seal candidate | MAT-599 | `#26292b` | 0 | 0.86 | opaque surface |
|
||||
| SELENE-AP-025 | Opaque sample cassette body | MAT-595 | `#424a54` | 0 | 0.54 | opaque surface |
|
||||
| SELENE-AP-026 | Textured ABS instrument shell | MAT-042 | `#59616b` | 0 | 0.64 | opaque surface |
|
||||
| SELENE-AP-027 | Powder-printed polyamide preview | MAT-175 | `#abb0b1` | 0 | 0.87 | opaque surface |
|
||||
| SELENE-AP-028 | FDM top-skin preview | MAT-171, MAT-361 | `#aab5bd` | 0 | 0.46 | opaque surface |
|
||||
| SELENE-AP-029 | Sample vial opaque inspection surrogate | MAT-582 | `#91a2ae` | 0 | 0.35 | opaque inspection surrogate |
|
||||
| SELENE-AP-030 | Window opaque inspection surrogate | MAT-583 | `#537286` | 0 | 0.24 | opaque inspection surrogate |
|
||||
| SELENE-AP-031 | Matte ceramic sample insert | MAT-594 | `#c9c5bb` | 0 | 0.59 | opaque surface |
|
||||
| SELENE-AP-032 | Threaded metal closure cap | MAT-596 | `#b6bcc3` | 1 | 0.31 | opaque surface |
|
||||
| SELENE-AP-033 | Graphite thermal-sheet preview | MAT-349 | `#35383d` | 0 | 0.91 | opaque surface |
|
||||
| SELENE-AP-034 | Solder-mask board face | MAT-161 | `#32624b` | 0 | 0.42 | opaque surface |
|
||||
| SELENE-AP-035 | Exposed glass-epoxy board edge | MAT-162 | `#9b9270` | 0 | 0.77 | opaque surface |
|
||||
| SELENE-AP-036 | Molded epoxy component body | MAT-166 | `#252727` | 0 | 0.80 | opaque surface |
|
||||
| SELENE-AP-037 | Battery-can metal preview | MAT-341 | `#b3bbc3` | 1 | 0.35 | opaque surface |
|
||||
| SELENE-AP-038 | Unpowered LED phosphor face | MAT-441 | `#d6bd64` | 0 | 0.65 | opaque surface |
|
||||
| SELENE-AP-039 | Diffuser opaque inspection surrogate | MAT-451 | `#dadcdb` | 0 | 0.72 | opaque inspection surrogate |
|
||||
| SELENE-AP-040 | Aluminium honeycomb cut edge | MAT-481 | `#a5adb6` | 1 | 0.40 | opaque surface |
|
||||
| SELENE-AP-041 | Mare-style regolith surface | MAT-531 | `#5e5c58` | 0 | 0.96 | opaque surface |
|
||||
| SELENE-AP-042 | Highland-style regolith surface | MAT-546 | `#8b8881` | 0 | 0.96 | opaque surface |
|
||||
| SELENE-AP-043 | Tool-transferred dust patch | MAT-559 | `#7b766d` | 0 | 0.98 | opaque deposit geometry response |
|
||||
| SELENE-AP-044 | Woven-metal wheel mesh | MAT-565 | `#999fa7` | 1 | 0.38 | opaque surface |
|
||||
| SELENE-AP-045 | Oiled oak workshop surface | MAT-111 | `#a17a51` | 0 | 0.56 | opaque surface |
|
||||
| SELENE-AP-046 | Varnished walnut joinery | MAT-113 | `#6d4d37` | 0 | 0.30 | opaque surface |
|
||||
| SELENE-AP-047 | Automotive smooth clearcoat surrogate | MAT-034, MAT-204 | `#4e697e` | 0 | 0.21 | opaque surface |
|
||||
| SELENE-AP-048 | Embossed tyre-sidewall preview | MAT-237 | `#282a2c` | 0 | 0.83 | opaque surface |
|
||||
|
||||
## Source and contract references
|
||||
|
||||
- [`appearance.assign` implementation](../../../../crates/engine/src/cmd/inspect.rs): named custom colors, body/face/component targeting and exact PBR block admission.
|
||||
- [Persistable PBR parameters](../../../../crates/doc/src/pbr_appearance.rs): appearance-owned optical values and sRGB decoding.
|
||||
- [Opaque product surface contract](../../../../docs/render-opaque-pbr.md): current consumers, limits, native preservation and unsupported functions.
|
||||
- [Original opaque studio example](../../../../examples/render-opaque-studio.json): existing `solid.box` and appearance command shapes used for this prepared script.
|
||||
- [CLI render workflow](../../../../apps/solidcraft-cli/src/render.rs) and [product-image jobs](../../../../docs/render-jobs.md): bounded PNG admission, preflight/start/wait/export and overwrite behavior.
|
||||
- [Script executor](../../../../crates/engine/src/lib.rs) and [timeline export](../../../../crates/engine/src/cmd/script.rs): replay semantics and export omissions.
|
||||
- [Scalar catalog contract](../../../../crates/io/src/catalog.rs): version-1 scalar-only fields and PBR export refusal.
|
||||
|
||||
## Original provenance
|
||||
|
||||
Author: SolidCraft contributors. License: MIT OR Apache-2.0. The two JSON files are original clean-room resource data and analytic command inputs. No commercial material library, copied shader, third-party artwork, restricted CAD extraction or generated image texture is bundled. Their exact attribution rows belong in the repository root `ATTRIBUTION.md`; Markdown documentation is exempt from the non-Markdown asset gate.
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,128 @@
|
||||
# SELENE mechanism acceptance
|
||||
|
||||
This directory records the source-level acceptance contract for **`SELENE-showcase.solidcraft`**. The source is now pinned and its persisted assembly records have been inspected. The checklist binds exact source IDs and parameters; it makes no native runtime claim from that container inspection.
|
||||
|
||||
[The source lock](../source-lock.json) selects the unchanged file supplied by SychPL, matching the author's public commit byte for byte. [SOURCE.md](../SOURCE.md) records that evidence. The functional derivative has a separate mechanism contract in [MECHANISMS.md](../MECHANISMS.md) and an executable native validator in [validate_native.py](../tools/validate_native.py).
|
||||
|
||||
## Three evidence levels
|
||||
|
||||
Each item in [mechanism-acceptance.json](mechanism-acceptance.json) separates:
|
||||
|
||||
1. **Documentation evidence:** a published project description or author demonstration, linked through the source lock's references.
|
||||
2. **Native evidence:** exact identities, geometry, parentage, limits and mechanism relationships inspected in the admitted file.
|
||||
3. **Runtime evidence:** results produced by a recorded SolidCraft revision from explicit inputs and an approved starting pose.
|
||||
|
||||
Native evidence is `inspected_container_only`; source runtime evidence remains `not_executed` in this checklist. The bindings are tied to source SHA-256 `1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677`. Reading the native container confirms records, references and stored values. It does not evaluate geometry, solve a joint, drive a study or certify a derivative.
|
||||
|
||||
`required_for_native_admission` identifies the mechanisms that establish the selected combined showcase. The sampled collision demonstration and flexible-hose visibility treatment are additional review areas. Any differences in the delivered source need explicit explanation; an admission tool cannot infer identity from a count or automatically approve a substitute.
|
||||
|
||||
## Review areas
|
||||
|
||||
| ID | Review area | Native and runtime questions |
|
||||
|---|---|---|
|
||||
| MCA-001 | Grounded structure and static modules | Which occurrences anchor the turret, dish support and other fixed modules? Do intended subsystems move without shifting the chassis? |
|
||||
| MCA-002 | Four split solar actuators | Which bodies belong to each barrel and rod, including their eyes and pins? Do the pieces move together correctly? |
|
||||
| MCA-003 | Actuator loops and travel stops | Do root pin, stroke slider and wing pin remain connected? Does an infeasible tilt stop with a useful reason? |
|
||||
| MCA-004 | Mirrored solar tilt | Does the actual link preserve the documented opposing increments, with valid axes, offsets and limits? |
|
||||
| MCA-005 | Six-wheel link chain | Are all wheels correctly driven through the chain regardless of link serialization order? |
|
||||
| MCA-006 | Rack-driven helper track | Is the 38 mm coupling correctly bound and explicitly treated as demonstration geometry? |
|
||||
| MCA-007 | Turret/dish gear | What are the actual driver, follower, sign, ratio and offset of the documented 24:36 pair? |
|
||||
| MCA-008 | Vial-cap screw | Does the independent cap or helper follow its reported screw motion? What remains necessary for a releasable, sealed vial? |
|
||||
| MCA-009 | Arm reach and drag | Do reachable and unreachable targets produce bounded, correctly reported poses within limits? |
|
||||
| MCA-010 | Coordinated tour and traces | Which study keys drive the subsystems? Which traces are analysis geometry, and what defines physical time? |
|
||||
| MCA-011 | Motion analysis and interference | What was sampled, which pairs were checked, and were results truncated? |
|
||||
| MCA-012 | Flexible-hose visibility | Which rigid hose approximations or sketches were hidden, and how will their treatment be disclosed? |
|
||||
|
||||
The detailed checks cite the [mechanism reference](https://github.com/tangency-labs/solidcraft/blob/463cea0615a22be2f7d6c30512211f9eda97ff28/skills/solidcraft-mechanisms/reference.md), the [author's combined showcase](https://github.com/tangency-labs/solidcraft/pull/1540#issuecomment-6205857321), [motion export](https://github.com/tangency-labs/solidcraft/pull/1680), and [motion analysis](https://github.com/tangency-labs/solidcraft/pull/1712).
|
||||
|
||||
## Source bindings and deliberate derivative changes
|
||||
|
||||
The unchanged source contains 47 occurrences, 49 joints, nine links and one `SELENE tour` study. Structure occurrence `1930` is grounded. Rigid joints `30..47` attach 18 modules to it; the joint graph reaches every source occurrence except the independent rock sample `3458`. The four actuator loops use joint triples `18/19/20`, `21/22/23`, `24/25/26` and `27/28/29`. These are persisted source facts, not evaluated degrees of freedom or a solver result.
|
||||
|
||||
The original helper track has a 38 mm rack radius; the functional derivative specifies 40 mm to match the modeled wheel radius. The source's `7 → 16` link couples sensor and dish azimuth at `-24/36`; the derivative deliberately gives those pointing systems independent controls. The source cap keeps its 1.5 mm lead and 0–6 mm axial travel. Source facts remain in the checklist so that an intentional change is visible rather than silently relabeled as the original design.
|
||||
|
||||
The source tour has 120 steps and nine keyed joint coordinates. Its three rigid hydraulic-hose sweeps and six associated sketches are hidden. Hiding them avoids presenting a fixed sweep as a deforming hose; flexible routing remains separate work.
|
||||
|
||||
## Numeric planning checks
|
||||
|
||||
The four `analytic_candidate` records are original calculations from published values. They can be recomputed without a model. Passing them says nothing about the contents of a candidate native file.
|
||||
|
||||
Native lengths use millimeters and native angles use radians. The documented joint and study commands accept degrees or explicit angle expressions. A tool must convert once at the boundary; it must not pass a radian-valued native angle to a degree-valued command unchanged.
|
||||
|
||||
### Actuator length and stop
|
||||
|
||||
The public mechanism reference supplies rounded port-side coordinates. For a planar planning example, use the common actuator X coordinate as zero:
|
||||
|
||||
- Hinge: `H = (0, -140, 158) mm`.
|
||||
- Root pin: `R = (0, -91, 134) mm`.
|
||||
- Wing pin at zero angle: `T0 = (0, -180.41, 169.71) mm`.
|
||||
- Wing rotation: positive about X.
|
||||
|
||||
The candidate relation is:
|
||||
|
||||
```text
|
||||
T(theta) = H + Rx(theta) * (T0 - H)
|
||||
L(theta) = norm(T(theta) - R)
|
||||
stroke(theta) = L(theta) - L(0)
|
||||
```
|
||||
|
||||
These inputs give a zero-angle length of **96.277475 mm** and a stroke of **-2.865953 mm** at **0.3490658504 rad** (20 degrees). The first positive angle reaching **-6 mm** stroke is approximately **0.5625425647 rad** (32.231315 degrees).
|
||||
|
||||
The reference reports approximately -2.87 mm at 20 degrees and a stop near 32.23 degrees. The small rounding difference is expected from its published coordinate precision. These rounded points are not exact native geometry and do not define a native replay tolerance.
|
||||
|
||||
The source bindings now record the full-precision pin positions. They give a 20-degree stroke expectation of **-2.8662098186467375 mm**, used by the functional validator. Verify closure over the path, not just at the final pose. An endpoint that happens to close can hide an impossible intermediate motion.
|
||||
|
||||
### Rack-and-pinion displacement
|
||||
|
||||
For the author's reported **38 mm pitch radius**, the displacement magnitude is:
|
||||
|
||||
```text
|
||||
abs(delta_x_mm) = 38 * abs(delta_theta_rad)
|
||||
```
|
||||
|
||||
One full turn gives **238.761042 mm**. The direction and initial offset depend on the source's joint axes and coupling. The moving regolith track is a prescribed demonstration helper; this relation does not establish wheel traction, contact forces, slip or lunar-ground dynamics.
|
||||
|
||||
### Gear-pair magnitude
|
||||
|
||||
Under the candidate interpretation that the 24 side drives the 36 side:
|
||||
|
||||
```text
|
||||
abs(delta_follower_rad) = (24 / 36) * abs(delta_driver_rad)
|
||||
```
|
||||
|
||||
A driver increment of **1.5707963268 rad** gives a follower magnitude of **1.0471975512 rad**. Source inspection confirms turret azimuth drives dish azimuth with ratio `-2/3` and zero offset. This historic analytic example does not apply to the independent pointing controls of the functional derivative.
|
||||
|
||||
### Vial-cap screw
|
||||
|
||||
Interpreting the documented 1.5 mm screw as **1.5 mm axial lead per revolution** gives:
|
||||
|
||||
```text
|
||||
abs(delta_axial_mm) = 1.5 * abs(delta_angle_rad) / (2*pi)
|
||||
```
|
||||
|
||||
A full turn yields **1.5 mm** axial travel. Source joint `49` is cylindrical about +Z, with a screw link from angular coordinate `0` to axial coordinate `1` and travel limits of 0–6 mm. This is a kinematic screw relation; it does not prove thread contact, closure sealing or capture retention.
|
||||
|
||||
## Runtime evidence to record
|
||||
|
||||
Each executed acceptance case should retain the native-file SHA-256, SolidCraft code revision, exact command inputs, initial pose, selected joint IDs and axes, effective link values, solver tolerances, resolved poses and any stop or collision reports. The functional validator writes actual MCP request/response JSONL, hashes its inputs before and after, resets primary drivers before each case, and records numeric comparisons without saving its in-memory test poses to the master.
|
||||
|
||||
A published numerical residual is evidence of that demonstration only. The author's reported arm residual is not a guaranteed precision threshold for arbitrary poses. Select a useful tolerance for the actual model and solver, and report it with the result.
|
||||
|
||||
The cited inverse-kinematics work does not check contact sets during `joint.reach`; contact review is a separate operation. Likewise, a sampled interference run can miss motion between samples. Record spacing, work limits and any truncation; use stronger checking when the task requires continuous clearance.
|
||||
|
||||
The reported 121 exported tour frames are export metadata. They do not establish the native study's exact key count, duration or physically feasible actuator speeds. A time mapping must be explicit before deriving velocities or accelerations.
|
||||
|
||||
## Limits of this acceptance
|
||||
|
||||
These checks establish reviewed kinematic structure and behavior. They do not establish mass properties, actuator torque, controller bandwidth, thermal limits, regolith forces, cable deformation or a feasible lunar sample throw and catch.
|
||||
|
||||
A vial cap that unscrews is useful source evidence. A future sample-transfer scene still needs a reviewed independent vial body, contents and closure boundaries, grasp/release rules, collision proxies, physical properties and capture behavior. No flight or collection mechanism is inferred from the demonstration.
|
||||
|
||||
Retain the source's provenance and record deliberate changes as new derivatives. A new source digest invalidates bindings and motion evidence; rendering quality settings cannot repair or silently retime those changes.
|
||||
|
||||
|
||||
## Prepared inspection and future dynamics inputs
|
||||
|
||||
[preflight-commands.json](preflight-commands.json) is a read-only five-command inventory to run on the actual opened design. It does not create, drive or alter a joint. Save its output under ignored `target/`, with the source digest and executor revision.
|
||||
|
||||
[sample-sequence.json](sample-sequence.json) specifies eleven future dynamics states from approach and collection through closure, release, flight, capture and storage, including a failed-catch branch. It reuses the existing kinematic authoring foundation and adds the contact, mass/inertia, actuation and event evidence needed for a physically validated animation. It is not an executable `motion.study` or an approved bake.
|
||||
@@ -0,0 +1,9 @@
|
||||
[
|
||||
["Shoulder link -9", "Elbow link -9"],
|
||||
["Elbow link -9", "Distal wrist link -9"],
|
||||
["Tool wrist machined tongue", "Tool tilt joint shaft"],
|
||||
["Gripper jaw -1", "Gripper jaw 1"],
|
||||
["Raspberry Pi 5 PCB", "Pi5 USB2 mounting tab 1"],
|
||||
["Raspberry Pi 5 PCB", "Pi5 USB3 mounting tab 2"],
|
||||
["Raspberry Pi 5 PCB", "Pi5 GPIO pin 40"]
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "joint.list",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "motion.list",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "appearance.list",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "material.list",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "render.scene",
|
||||
"params": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"metadata": {
|
||||
"schema_version": "0.1.0",
|
||||
"language": "en",
|
||||
"status": "specified_unbound",
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"source_lock": "../source-lock.json"
|
||||
},
|
||||
"id": "SELENE-SEQUENCE-001",
|
||||
"name": "Lunar collection, sealed-vial throw, catch and storage",
|
||||
"kind": "future_dynamics_contract_not_executable_motion_study",
|
||||
"existing_motion_policy": "Preserve and reuse the improved model motion studies, IK, links, traces and loop constraints. They provide kinematic authoring; they do not supply dynamic mass, contact impulses or granular physics.",
|
||||
"units": {
|
||||
"document_distance": "mm",
|
||||
"document_angle": "rad",
|
||||
"joint_command_angle": "deg",
|
||||
"solver_distance": "m",
|
||||
"solver_time": "s",
|
||||
"solver_mass": "kg",
|
||||
"solver_up_axis": "+Z",
|
||||
"conversion_boundary": "Convert lengths, rates, forces, torques and inertia exactly once between the native document and the SI solver."
|
||||
},
|
||||
"local_physics": {
|
||||
"gravity_m_s2": [
|
||||
0,
|
||||
0,
|
||||
-1.62
|
||||
],
|
||||
"gravity_source_id": "SRC-MOON-FACTSHEET",
|
||||
"atmospheric_drag": false,
|
||||
"wind": false,
|
||||
"candidate_fixed_step_hz": 240,
|
||||
"step_status": "Initial convergence-test candidate, not established adequate accuracy.",
|
||||
"required_refinement_factors": [
|
||||
1,
|
||||
2,
|
||||
4
|
||||
],
|
||||
"contact_parameters_status": "Unbound; mass, inertia, friction, restitution and actuator limits need provenance.",
|
||||
"grain_model": "Begin with aggregate sealed contents; a separate validated granular level is required for collection, spill or visible rearrangement."
|
||||
},
|
||||
"analytic_fixture_ids": [
|
||||
"PHY-001",
|
||||
"PHY-002",
|
||||
"PHY-003",
|
||||
"PHY-004",
|
||||
"PHY-005",
|
||||
"PHY-006"
|
||||
],
|
||||
"trajectory_candidate": {
|
||||
"fixture_id": "PHY-002",
|
||||
"status": "synthetic_planning_candidate_not_reachable_motion",
|
||||
"apex_rise_m": 0.15,
|
||||
"equal_height_range_m": 0.04,
|
||||
"must_resolve": [
|
||||
"release and catch height",
|
||||
"arm reachable workspace",
|
||||
"collision clearances",
|
||||
"joint velocities and motor effort",
|
||||
"vial inertia and spin",
|
||||
"gripper aperture and capture tolerance"
|
||||
]
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"id": "approach",
|
||||
"action": "Move the validated tool toward the sample patch.",
|
||||
"gates": [
|
||||
"Admitted source and derivative; no unresolved closed loops.",
|
||||
"Joint-limited collision-aware path with actuator rates and torque requirements checked."
|
||||
],
|
||||
"exit_event": "tool_ready"
|
||||
},
|
||||
{
|
||||
"id": "collect",
|
||||
"action": "Collect a declared regolith mass with the reviewed tool.",
|
||||
"gates": [
|
||||
"Collection geometry exists and reaches the patch.",
|
||||
"Ground removal and container mass gain balance, including spill."
|
||||
],
|
||||
"exit_event": "sample_loaded"
|
||||
},
|
||||
{
|
||||
"id": "seal",
|
||||
"action": "Close and verify the vial before the acrobatic sequence.",
|
||||
"gates": [
|
||||
"Separate lid/seal state and a mechanically feasible closure action.",
|
||||
"Contents mass and inertia updated; seal confirmed."
|
||||
],
|
||||
"exit_event": "vial_sealed"
|
||||
},
|
||||
{
|
||||
"id": "withdraw",
|
||||
"action": "Move the sealed vial to a reachable launch pose.",
|
||||
"gates": [
|
||||
"Grasp contact is stable.",
|
||||
"No penetration of wings, rover, terrain or sample rack."
|
||||
],
|
||||
"exit_event": "launch_ready"
|
||||
},
|
||||
{
|
||||
"id": "release",
|
||||
"action": "Remove grasp constraint and inherit actual rigid-body velocities.",
|
||||
"gates": [
|
||||
"v_COM = v_grip + omega_grip cross r in a single SI frame.",
|
||||
"Record source pose, release time, linear/angular velocity and sample mass."
|
||||
],
|
||||
"exit_event": "free_flight"
|
||||
},
|
||||
{
|
||||
"id": "free_flight",
|
||||
"action": "Integrate translation and rotation in local lunar gravity.",
|
||||
"gates": [
|
||||
"No hidden parenting or attractor force.",
|
||||
"Continuous collision detection and solver-step convergence; vacuum baseline has no drag."
|
||||
],
|
||||
"exit_event": "capture_or_miss"
|
||||
},
|
||||
{
|
||||
"id": "capture",
|
||||
"action": "Establish contact with a reachable moving gripper.",
|
||||
"gates": [
|
||||
"Relative velocity, impulses and motor effort remain within reviewed bounds.",
|
||||
"The contact solution determines success; no snap to a desired pose."
|
||||
],
|
||||
"exit_event": "settling"
|
||||
},
|
||||
{
|
||||
"id": "settle",
|
||||
"action": "Resolve residual motion before rack insertion.",
|
||||
"gates": [
|
||||
"Stable grasp and contents retention.",
|
||||
"Momentum/energy accounting includes actuation and dissipated contact energy."
|
||||
],
|
||||
"exit_event": "storage_ready"
|
||||
},
|
||||
{
|
||||
"id": "store",
|
||||
"action": "Insert and retain the vial in the sample box.",
|
||||
"gates": [
|
||||
"Rack/grommets remain on rover; vial and lid remain correctly assembled.",
|
||||
"Retention contact verified before the gripper releases."
|
||||
],
|
||||
"exit_event": "stored"
|
||||
},
|
||||
{
|
||||
"id": "miss",
|
||||
"action": "Preserve a failed catch and its physical outcome.",
|
||||
"gates": [
|
||||
"No time rewind, teleport or success flag without contact.",
|
||||
"Keep the miss in diagnostics; recovery is a new planned action."
|
||||
],
|
||||
"exit_event": "recovery_required"
|
||||
},
|
||||
{
|
||||
"id": "complete",
|
||||
"action": "Approve an immutable simulation bake for rendering.",
|
||||
"gates": [
|
||||
"Events, transforms, particles and source/solver hashes are recorded.",
|
||||
"Frame-rate and render-quality changes do not alter the approved physics."
|
||||
],
|
||||
"exit_event": "approved_bake"
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"from": "approach",
|
||||
"to": "collect",
|
||||
"condition": "tool_ready"
|
||||
},
|
||||
{
|
||||
"from": "collect",
|
||||
"to": "seal",
|
||||
"condition": "sample_loaded"
|
||||
},
|
||||
{
|
||||
"from": "seal",
|
||||
"to": "withdraw",
|
||||
"condition": "vial_sealed"
|
||||
},
|
||||
{
|
||||
"from": "withdraw",
|
||||
"to": "release",
|
||||
"condition": "launch_ready"
|
||||
},
|
||||
{
|
||||
"from": "release",
|
||||
"to": "free_flight",
|
||||
"condition": "grasp_removed"
|
||||
},
|
||||
{
|
||||
"from": "free_flight",
|
||||
"to": "capture",
|
||||
"condition": "valid_contact"
|
||||
},
|
||||
{
|
||||
"from": "free_flight",
|
||||
"to": "miss",
|
||||
"condition": "catch_window_ended_without_valid_contact"
|
||||
},
|
||||
{
|
||||
"from": "capture",
|
||||
"to": "settle",
|
||||
"condition": "grasp_stable"
|
||||
},
|
||||
{
|
||||
"from": "settle",
|
||||
"to": "store",
|
||||
"condition": "storage_ready"
|
||||
},
|
||||
{
|
||||
"from": "store",
|
||||
"to": "complete",
|
||||
"condition": "retention_verified"
|
||||
},
|
||||
{
|
||||
"from": "capture",
|
||||
"to": "miss",
|
||||
"condition": "capture_failed"
|
||||
}
|
||||
],
|
||||
"bake_contract": {
|
||||
"status": "specified_unbound",
|
||||
"requires": [
|
||||
"source_native_sha256",
|
||||
"derivative_native_sha256",
|
||||
"binding_revision",
|
||||
"simulation_parameter_sha256",
|
||||
"solver_name_and_revision",
|
||||
"time_step_and_convergence_report",
|
||||
"deterministic_seed",
|
||||
"sample_mass_history",
|
||||
"contact_and_grasp_events",
|
||||
"position_orientation_velocity_samples",
|
||||
"particle_state_when_enabled",
|
||||
"collision_proxy_revision",
|
||||
"approved_time_interval",
|
||||
"review_record"
|
||||
],
|
||||
"render_sampling": "Interpolate validated states at actual shutter times; never extrapolate past the approved interval.",
|
||||
"invalidated_by": [
|
||||
"native geometry or hierarchy change",
|
||||
"binding or contact-proxy change",
|
||||
"physics parameter or solver change",
|
||||
"initial-state or event change"
|
||||
],
|
||||
"not_invalidated_by": [
|
||||
"resolution",
|
||||
"render samples",
|
||||
"denoising",
|
||||
"exposure",
|
||||
"output color transform"
|
||||
]
|
||||
},
|
||||
"preservation_rules": [
|
||||
"Do not overwrite the source showcase study.",
|
||||
"Use independent named derivative studies and simulation outputs.",
|
||||
"Do not infer friction, density or strength from an appearance recipe.",
|
||||
"Do not treat sampled kinematic interference checks as continuous dynamic collision detection."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
# Prepared SELENE demonstration scenes
|
||||
|
||||
This directory contains **12 shot specifications, 10 stages and 33 semantic roles** for the improved SELENE model. They are editable authoring inputs with status `specified_unbound`. The native source is now pinned in [source-lock.json](../source-lock.json); the complete catalog's semantic roles and renderer resources still require explicit binding. None of these specifications substitutes old rover component or feature IDs for a reviewed selection.
|
||||
|
||||
The files prepare composition, lighting ownership, material intent and review gates. They do not install a renderer, create native geometry, simulate a catch or demonstrate a finished image.
|
||||
|
||||
## Files and authorities
|
||||
|
||||
| File | Authority |
|
||||
|---|---|
|
||||
| [shots.json](shots.json) | Shot composition, camera/framing recipes, output intent, comparisons and presentation/planning sequences. |
|
||||
| [stages.json](stages.json) | Explicit stage overrides, Sun/ambient/background ownership, generated geometry roles and clearance rules. |
|
||||
| [roles.json](roles.json) | Semantic selection targets, candidate material concepts, scope limits and native opaque-proxy eligibility. |
|
||||
| [../source-lock.json](../source-lock.json) | Accepted source identity and admission review, owned by the model-preparation workflow. |
|
||||
|
||||
The existing [render/materials catalog](../../../../docs/render-materials/README.md) remains authoritative for `MAT`, `ENVSET`, `STU`, `Q` and `SCENE` concepts. Stage geometry resolves the referenced `environment-presets.json` record and then applies only its declared overrides. This directory does not maintain a second copy of every terrain or room parameter. Metadata records hashes of the catalog files used to author the recipes; update those locks deliberately after a reviewed catalog revision.
|
||||
|
||||
`reference_scene_id` records design lineage. It is **not** an instruction to apply an entire catalog scene and then apply this shot again. Effective composition comes from the shot's explicit quality, studio, stage, roles and source policies. Existing catalog and scene IDs remain unchanged.
|
||||
|
||||
## Source and native-body preparation
|
||||
|
||||
Run from the repository root, using the pinned improved native file:
|
||||
|
||||
```sh
|
||||
python3 assets/render/selene/tools/prepare.py inspect --model assets/render/selene/source/SELENE-showcase.solidcraft --out target/render-selene/inspection.json
|
||||
python3 assets/render/selene/tools/prepare.py template --model assets/render/selene/source/SELENE-showcase.solidcraft --out target/render-selene/bindings.json
|
||||
```
|
||||
|
||||
Inspection and template generation do not approve a model. Review the source identity, license/admission record and exact body selections. Preserve the unreviewed template and save the reviewed bindings separately. The source lock contains `active_source.status = "pinned_native"` and records the accepted file's SHA-256, byte size, format, units and Z-up frame. It must match the selected file exactly. Reviewed body bindings remain necessary before compilation.
|
||||
|
||||
After those checks, the prepared opaque-body subset can be compiled:
|
||||
|
||||
```sh
|
||||
python3 assets/render/selene/tools/prepare.py compile --model assets/render/selene/source/SELENE-showcase.solidcraft --bindings target/render-selene/bindings-reviewed.json --lock assets/render/selene/source-lock.json --out target/render-selene/opaque-overlay.json
|
||||
```
|
||||
|
||||
The tool does not overwrite outputs. Use a new output path for a new inspection, review or compilation. The compiled overlay is a reviewed native **BODY-only opaque diagnostic subset**. It does not apply these complete shot specifications, create terrain, reproduce layered materials or enable a future renderer.
|
||||
|
||||
Eligible roles satisfy all three conditions: `kind == "appearance"`, `owner == "subject"`, and `opaque_proxy_allowed == true`. Optics, emitters, dust layers, framing regions, interaction regions and generated stage geometry remain outside that compiler. A reviewed body must be appropriate for a uniform opaque proxy; face-level or multilayer targets cannot be silently converted to whole-body assignments. Preserve the source's engineering material and physical properties.
|
||||
|
||||
The current native BODY appearance command styles a shared body definition. An appearance selected through one occurrence can affect every copy, so the review must cover all affected occurrences. This subset does not provide independent per-occurrence styling. The compiler accepts feature-declared body names; generated viewport instance names are not automatic binding targets. Resolve conflicting role appearances explicitly before compiling a shared definition.
|
||||
|
||||
The prepared-package check is:
|
||||
|
||||
```sh
|
||||
python3 assets/render/selene/tools/validate_prepared.py --json
|
||||
```
|
||||
|
||||
The existing catalog check remains separate:
|
||||
|
||||
```sh
|
||||
python3 docs/render-materials/validate_catalog.py --json
|
||||
```
|
||||
|
||||
Data validation establishes reference and specification consistency. The source-inspection report, native evaluation, actual images and future simulation evidence are separate results. Keep generated reports, overlays, previews and caches under `target/render-selene/`; do not commit them as resource masters.
|
||||
|
||||
## Shot list
|
||||
|
||||
| Shot | Stage | Purpose | Quality / studio |
|
||||
|---|---|---|---|
|
||||
| `SELENE-SHOT-001` | `SELENE-STAGE-001` | Low-Sun hero with native scale and terrain contact. | `Q-006` / `STU-021` |
|
||||
| `SELENE-SHOT-002` | `SELENE-STAGE-002` | High-Sun comparison, sharing the first shot's terrain, camera, materials and exposure. | `Q-006` / `STU-023` |
|
||||
| `SELENE-SHOT-003` | `SELENE-STAGE-003` | Sampling tool and terrain contact macro. | `Q-007` / `STU-023` |
|
||||
| `SELENE-SHOT-004` | `SELENE-STAGE-004` | LED-off/LED-on diagnosis of a genuinely solar-shadowed work patch. | `Q-005` / `STU-023` |
|
||||
| `SELENE-SHOT-005` | `SELENE-STAGE-005` | Rover in a generic polar-ridge setting with grazing sunlight. | `Q-006` / `STU-021` |
|
||||
| `SELENE-SHOT-006` | `SELENE-STAGE-006` | Arm, container, storage and transfer-station coverage. | `Q-007` / `STU-023` |
|
||||
| `SELENE-SHOT-007` | `SELENE-STAGE-006` | Static release/capture planning poses, including a possible miss. | `Q-007` / `STU-023` |
|
||||
| `SELENE-SHOT-008` | `SELENE-STAGE-007` | Shadow-interval audit with hardware lights off. | `Q-006` / `STU-023` |
|
||||
| `SELENE-SHOT-009` | `SELENE-STAGE-008` | Neutral studio diagnosis of the reviewed rover finishes. | `Q-010` / `STU-002` |
|
||||
| `SELENE-SHOT-010` | `SELENE-STAGE-009` | Eight presentation angles on a fixed studio stage. | `Q-003` / `STU-002` |
|
||||
| `SELENE-SHOT-011` | `SELENE-STAGE-010` | Explicitly labeled editorial hero with one declared fill rig. | `Q-006` / `STU-024` |
|
||||
| `SELENE-SHOT-012` | `SELENE-STAGE-006` | Vial walls, lid, contents and closure detail. | `Q-007` / `STU-023` |
|
||||
|
||||
The quality IDs are future authoring targets. They are not settings objects accepted by the current native command interface. In particular, do not submit the large lunar-master resolutions as current baseline setup commands without an independently verified executor contract.
|
||||
|
||||
## Coordinates, framing and scale
|
||||
|
||||
Lengths use millimeters and angles use radians. +Z is up. The -Y front / +X right labels are an **authored presentation-stage convention**, not an observation of the improved rover's heading. Review and record its source-to-stage instance alignment before resolving a shot. Camera and Sun azimuths refer to that stage frame; they are not geographic east/north or a lunar site ephemeris.
|
||||
|
||||
Cameras specify a target role, a zero target offset, a viewing azimuth/elevation, vertical field of view and frame-fill fraction. A future adapter derives target coordinates, distance and clip planes from reviewed role bounds, output aspect and the complete scene. It fits once on explicit request, respects camera locks and never rescales the model. The files contain no claimed native camera transform.
|
||||
|
||||
The sampling macro fits the actual contact region, while retaining the rest of the rover for shadows and reflections. It must not squeeze the whole rover into a small macro patch. The low/high-Sun pair shares the low-Sun geometry reference and seed so that the comparison changes illumination rather than terrain. The turntable has explicitly authored stage dimensions; the entire rotating subject envelope must fit with clearance before use.
|
||||
|
||||
The eight-view turntable rotates render instances of the rover and platform about the reviewed platform axis. Camera, room and rig remain fixed; internal joint poses remain frozen. These are presentation stills, not a mechanical turntable simulation or a lunar vehicle maneuver. The recipe requests no motion blur and makes no dynamics claim.
|
||||
|
||||
## Sun, vacuum and source ownership
|
||||
|
||||
Lunar stages use one environment-owned Sun. It is a **finite-angular disk represented directionally at infinity for the local stage**: direction and angular diameter are explicit, while a local XYZ light position is inapplicable. The local directional approximation has no stage-distance attenuation. The disk shown to the camera, if visible, must represent that same source. Do not add a second solar disk in an environment map or a second directional light in the studio rig.
|
||||
|
||||
The inherited draft diameter is `0.009250245036` radians, approximately 0.53 degrees. It remains an authored approximation, not a calculated lunar ephemeris. For context, the [NASA Sun Fact Sheet](https://nssdc.gsfc.nasa.gov/planetary/factsheet/sunfact.html) gives an apparent diameter of 1,919 arcseconds at 1 AU and variation with observing distance. The table does not calibrate these particular lunar shots. The recipe's irradiance value `1.0` is a dimensionless reference; it is not watts, lux, lumens or a measured exposure.
|
||||
|
||||
Physical lunar stages have zero sky radiance and no atmospheric scattering, fog, clouds, rain or wind. This is the surface-rendering approximation described in the [SELENE plan](../../../../docs/render-materials/SELENE.md), not a claim that the Moon has literally no exosphere. Geometry and reflected light can still illuminate shadows. Earth and stars remain disabled until separately reviewed celestial placement, visibility, radiance and exposure are available. An arbitrary oversized Earth or dense star overlay cannot be added to a physical shot.
|
||||
|
||||
The LED work patch retains the Sun and uses terrain to block its direct illumination. It needs exactly one calibrated subject-owned `rover_task_led`. Its visible emitter, analytic sampling proxy and optic must share the intended source path without duplicated power. The shadow-interval audit also retains the Sun behind geometry, disables all hardware sources and accepts a nearly black image.
|
||||
|
||||
Editorial staging keeps the vacuum rules but deliberately permits `STU-024` fill and an editorial fidelity label. The stage explicitly overrides the base `ENVSET-024` ambient fill to zero so that this demonstration uses one declared fill rig. It must remain distinguishable from the physical lunar shots.
|
||||
|
||||
## Role decisions that need explicit review
|
||||
|
||||
- `lunar_rocks` is a generated geometry set; `lunar_highland_rock` assigns the existing `MAT-545` appearance to that set. Every generated rock has an owner and appearance even when a base environment omitted a material-role field.
|
||||
- `rover_dust_overlay` uses `MAT-551` as a bounded surface layer. Its host appearance remains intact. It is outside the native opaque compiler and does not create atmospheric dust or assign contact parameters.
|
||||
- `task_led_emitter` and `task_led_optic` are separate. The existing candidate `MAT-456` specifically describes a **scattering silicone light tube**. If the improved model uses a different optical construction, choose a matching concept through a recorded shot-level override; do not treat that ID as a generic lens.
|
||||
- `sample_scoop` requires an actual sampling tool or an approved derivative. A gripper alone does not fulfill a scoop/contact shot.
|
||||
- `sample_container` identifies a reviewed vial assembly. The retaining grommet remains with the rack. Free-flight work requires an independent container identity, explicit closure and suitable collision geometry.
|
||||
- A scene can record an absent or not-visible optional role. A required camera, tool, source or interaction role cannot resolve to absent. Unresolved roles must remain visible in the preparation report.
|
||||
|
||||
## Staged animation work
|
||||
|
||||
1. **Source and appearance diagnosis.** Verify the pinned native source, review semantic selections, compile the eligible opaque body subset and inspect native scale. No dynamics is involved.
|
||||
2. **Still-image reference.** Bind stage geometry, materials, the Sun and optional hardware source. Review the physical hero, macro, lighting comparison and shadow audit before using the scene as an animation reference.
|
||||
3. **Planning poses.** Use `SELENE-SHOT-007` to inspect release, candidate flight, capture/miss and storage coverage. Joint limits, clearances, closure and reach remain explicit checks. The file assigns no physical event times or launch velocities.
|
||||
4. **Independent physical validation.** Establish mass/inertia, contact, actuation, constraint transitions and the millimeter/SI boundary. Use [lunar-physics-fixtures.json](../../../../docs/render-materials/lunar-physics-fixtures.json) as analytic checks, not as a ready-made rover trajectory. Rendering roughness does not determine friction or restitution.
|
||||
5. **Approved bake and image sequence.** After the [36 simulation requirements](../../../../docs/render-materials/simulation-requirements.json) are satisfied for the chosen approximation, record an immutable bake and source/resource hashes. The future `SCENE-020`, `Q-008` and `Q-009` references define preview/final intent. Preserve misses and solver failures, and keep physics timing independent of output frame rate.
|
||||
|
||||
These catalog specifications prepare those stages. Source admission is recorded separately in the source lock; native derivative results and concrete showcase renders are reported by their own build and validation records. The catalog itself does not establish contact simulation, complete renderer binding or final images for all 12 shots.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,585 @@
|
||||
{
|
||||
"metadata": {
|
||||
"schema_version": "0.3.0",
|
||||
"language": "en",
|
||||
"status": "pinned_native",
|
||||
"name": "SELENE improved showcase source lock",
|
||||
"authorship": "Original SolidCraft source-admission metadata based on the supplied native file and public source history; the unchanged improved native source is retained.",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"provenance_id": "ORIGINAL-2026-10-CATALOG",
|
||||
"inspected_on": "2026-10-22"
|
||||
},
|
||||
"active_source": {
|
||||
"variant": "SELENE-showcase",
|
||||
"file_name": "SELENE-showcase.solidcraft",
|
||||
"status": "pinned_native",
|
||||
"repository": "SychPL/solidcraft",
|
||||
"commit": "32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9",
|
||||
"path": "SELENE-showcase.solidcraft",
|
||||
"download_url": "https://raw.githubusercontent.com/SychPL/solidcraft/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft",
|
||||
"sha256": "1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677",
|
||||
"size_bytes": 314452,
|
||||
"format": "solidcraft/23",
|
||||
"units": "mm",
|
||||
"up_axis": "+Z",
|
||||
"local_path": "source/SELENE-showcase.solidcraft",
|
||||
"git_blob": "a06fee2c8a839f5efccc75ae6de4e68f951cb266",
|
||||
"published_at": "2026-10-21T20:00:01Z"
|
||||
},
|
||||
"coordinate_contract": {
|
||||
"status": "inspected_native_mm_and_reference_z_up",
|
||||
"native_linear_units": "mm",
|
||||
"native_angle_units": "rad",
|
||||
"up_axis": "+Z",
|
||||
"command_angle_policy": "The documented joint and motion commands accept degrees or explicit angle expressions. Convert exactly once from the native radian representation at a command boundary.",
|
||||
"frame_policy": "Resolve joints and components from the pinned improved native file. Persisted angles are radians; commands use degrees. World points must come from the evaluated native assembly."
|
||||
},
|
||||
"license_review": {
|
||||
"status": "reviewed_retained_notices",
|
||||
"license_expression": "MIT OR Apache-2.0",
|
||||
"reviewer": "OpenAI assistant, for the repository owner",
|
||||
"reviewed_at": "2026-10-24",
|
||||
"evidence_urls": [
|
||||
"https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft",
|
||||
"https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/ATTRIBUTION.md",
|
||||
"https://github.com/SychPL/solidcraft/commit/df2e74230e6659409d65501b5d9396b55c6503d3",
|
||||
"https://github.com/tangency-labs/solidcraft/pull/5494#issuecomment-6375788360"
|
||||
],
|
||||
"notices": [
|
||||
{
|
||||
"scope": "Original rover geometry and SolidCraft emblem",
|
||||
"author": "0xlillith and SolidCraft contributors",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"source": "https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/ATTRIBUTION.md"
|
||||
},
|
||||
{
|
||||
"scope": "Modelled Ubuntu Light lettering",
|
||||
"author": "Canonical Ltd.",
|
||||
"license": "Ubuntu Font Licence 1.0",
|
||||
"retained_notice": "licenses/UFL.txt",
|
||||
"source": "https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/UFL.txt"
|
||||
},
|
||||
{
|
||||
"scope": "Showcase assembly and helper additions",
|
||||
"author": "SychPL (Mateusz Sych)",
|
||||
"source": "https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft",
|
||||
"note": "Explicit author permission covers redistribution and derivatives, including SELENE-functional.solidcraft.",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"license_grant_url": "https://github.com/tangency-labs/solidcraft/pull/5494#issuecomment-6375788360",
|
||||
"license_grant_created_at": "2026-10-23T22:13:37Z"
|
||||
}
|
||||
],
|
||||
"scope": "Original model and showcase additions are licensed MIT OR Apache-2.0. The explicit author grant covers redistribution and derivatives. The separate Ubuntu Font Licence 1.0 lettering notice remains retained. This is a licence record, not renewed native-model validation.",
|
||||
"author_grant_verified_utc": "2026-10-23T22:24:59.302974+00:00"
|
||||
},
|
||||
"admission_review": {
|
||||
"variant_identity_confirmed": true,
|
||||
"license_and_attribution_reviewed": true,
|
||||
"reviewer": "OpenAI assistant, for the repository owner",
|
||||
"evidence_url": "https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft",
|
||||
"review_date": "2026-10-22"
|
||||
},
|
||||
"legacy_sources": [
|
||||
{
|
||||
"variant": "Rover-v7",
|
||||
"file_name": "Rover-v7.solidcraft",
|
||||
"status": "historical_reference_only",
|
||||
"eligible_as_active_source": false,
|
||||
"repository": "0xlillith/solidcraft-rover",
|
||||
"commit": "b32437915372d32b71419dc8f5143fe22ff1e869",
|
||||
"path": "models/Rover-v7.solidcraft",
|
||||
"url": "https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/models/Rover-v7.solidcraft",
|
||||
"sha256": "fcb08540b1db08325f366fd0ff235f84f66d96406961482736bc097d7248c6d6",
|
||||
"size_bytes": 216036,
|
||||
"format": "solidcraft/15",
|
||||
"units": "mm",
|
||||
"up_axis": "+Z",
|
||||
"reason": "The user selected the improved Tangency showcase. This original file lacks its documented mechanism additions and must be rejected as the active source, even if renamed.",
|
||||
"known_original_inventory": {
|
||||
"component_definitions_excluding_root": 36,
|
||||
"occurrences": 36,
|
||||
"revolute_joints": 17,
|
||||
"history_entries": 3324
|
||||
},
|
||||
"inventory_scope": "Legacy comparison only; no improved-source IDs, counts or format version are inferred from these numbers."
|
||||
}
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"id": "SELENE-REF-001",
|
||||
"type": "pinned_document",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/blob/463cea0615a22be2f7d6c30512211f9eda97ff28/skills/solidcraft-mechanisms/reference.md",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"commit": "463cea0615a22be2f7d6c30512211f9eda97ff28",
|
||||
"path": "skills/solidcraft-mechanisms/reference.md",
|
||||
"scope": "Published SELENE actuator, anchoring, motion-link and visibility example; command units and limitations.",
|
||||
"evidence_level": "documentation"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-002",
|
||||
"type": "author_comment",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1540#issuecomment-6205857321",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"author": "SychPL",
|
||||
"comment_id": 6205857321,
|
||||
"inspected_on": "2026-10-21",
|
||||
"scope": "Author identifies the improved showcase and describes drivetrain, actuator loops, anchored modules, arm reach, traces and coordinated motion.",
|
||||
"immutability": "The comment body is mutable. The inspection date and separately pinned media identify the evidence examined.",
|
||||
"evidence_level": "author_description"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-003",
|
||||
"type": "merged_pull_request",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1540",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"author": "SychPL",
|
||||
"merged_at": "2026-10-16T03:58:34Z",
|
||||
"merge_commit": "4d862cd76ccfa3a171c66c48d9a184209a33a945",
|
||||
"head_commit": "fd7d51489030f9fd698f11d563b8ba226f58a434",
|
||||
"scope": "Inverse kinematics and jointed dragging. Published demonstrations are kinematic; contact sets are not checked by joint.reach.",
|
||||
"evidence_level": "published_software_change"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-004",
|
||||
"type": "merged_pull_request",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1680",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"author": "SychPL",
|
||||
"merged_at": "2026-10-16T11:26:15Z",
|
||||
"merge_commit": "2ae21143ee2cb8ffb3af916ee2ffadac956a9faa",
|
||||
"head_commit": "57349b71c7274f19aa37cd9770e6670dc0f19fb2",
|
||||
"scope": "Explicitly names SELENE-showcase.solidcraft as the file used for the exported SELENE tour and solar-wing demonstrations.",
|
||||
"evidence_level": "published_software_change"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-005",
|
||||
"type": "merged_pull_request",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1712",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"author": "SychPL",
|
||||
"merged_at": "2026-10-16T22:09:37Z",
|
||||
"merge_commit": "37496198bf2c99285de703899a67a5f87ac60b7a",
|
||||
"head_commit": "f96aaa2a9852f906d815a7bc6dcd4fda3531469b",
|
||||
"scope": "SELENE motion plots, actuator-follower measurements and sampled arm-versus-wing interference examples. The PR explicitly limits collision detection to sampled states.",
|
||||
"evidence_level": "published_software_change"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-006",
|
||||
"type": "pinned_media_manifest",
|
||||
"url": "https://github.com/SychPL/solidcraft/tree/df2e74230e6659409d65501b5d9396b55c6503d3",
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch_at_inspection": "media/selene-showcase",
|
||||
"commit": "df2e74230e6659409d65501b5d9396b55c6503d3",
|
||||
"files": [
|
||||
"selene2-drivetrain.gif",
|
||||
"selene2-loops.gif",
|
||||
"selene2-arm-tour.gif"
|
||||
],
|
||||
"scope": "Three showcase recordings linked by the author comment. The tree contains no native model or licensing document.",
|
||||
"evidence_level": "media_reference_only",
|
||||
"vendored": false
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-007",
|
||||
"type": "pinned_media_manifest",
|
||||
"url": "https://github.com/SychPL/solidcraft/tree/1e2ad6842a5ad5c3b2cedee3e6508a8e4e3eb3d4",
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch_at_inspection": "media/motion-animation",
|
||||
"commit": "1e2ad6842a5ad5c3b2cedee3e6508a8e4e3eb3d4",
|
||||
"files": [
|
||||
"selene-tour.gif",
|
||||
"selene-wings.gif",
|
||||
"dialog.png"
|
||||
],
|
||||
"scope": "Headless motion-export demonstrations cited by PR 1680; no native model in the tree.",
|
||||
"evidence_level": "media_reference_only",
|
||||
"vendored": false
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-008",
|
||||
"type": "pinned_media_manifest",
|
||||
"url": "https://github.com/SychPL/solidcraft/tree/6d79237923e80704a3afb4c092950804b64a5c0a",
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch_at_inspection": "media/motion-analysis",
|
||||
"commit": "6d79237923e80704a3afb4c092950804b64a5c0a",
|
||||
"files": [
|
||||
"motion-plot.gif",
|
||||
"motion-collisions.gif"
|
||||
],
|
||||
"scope": "Motion-analysis demonstrations cited by PR 1712; no native model in the tree.",
|
||||
"evidence_level": "media_reference_only",
|
||||
"vendored": false
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-009",
|
||||
"type": "pinned_document",
|
||||
"url": "https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/ATTRIBUTION.md",
|
||||
"repository": "0xlillith/solidcraft-rover",
|
||||
"commit": "b32437915372d32b71419dc8f5143fe22ff1e869",
|
||||
"path": "ATTRIBUTION.md",
|
||||
"scope": "Original v7 model provenance: MIT OR Apache-2.0; Ubuntu Light lettering has Ubuntu Font Licence 1.0 provenance. This does not establish an unavailable derivative file's complete inventory.",
|
||||
"evidence_level": "legacy_license_document"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-010",
|
||||
"type": "pinned_document",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/blob/463cea0615a22be2f7d6c30512211f9eda97ff28/ATTRIBUTION.md",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"commit": "463cea0615a22be2f7d6c30512211f9eda97ff28",
|
||||
"path": "ATTRIBUTION.md",
|
||||
"scope": "Credits docs/screenshots/rover-build.gif and rover-build.mp4 as construction replay of Rover-recorded.solidcraft. Those rows do not identify the improved showcase native file.",
|
||||
"evidence_level": "upstream_license_document"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-011",
|
||||
"type": "pinned_document",
|
||||
"url": "https://github.com/0xlillith/solidcraft-rover/blob/b32437915372d32b71419dc8f5143fe22ff1e869/README.md",
|
||||
"repository": "0xlillith/solidcraft-rover",
|
||||
"commit": "b32437915372d32b71419dc8f5143fe22ff1e869",
|
||||
"path": "README.md",
|
||||
"scope": "Historical v7 and reconstruction-recording variants; their statistics must not be transferred to the improved showcase.",
|
||||
"evidence_level": "legacy_documentation"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-012",
|
||||
"type": "pinned_document",
|
||||
"url": "https://github.com/tangency-labs/models/blob/57abdd6f71c4202fcda78d19dcfdb54dde80a7a9/README.md",
|
||||
"repository": "tangency-labs/models",
|
||||
"commit": "57abdd6f71c4202fcda78d19dcfdb54dde80a7a9",
|
||||
"path": "README.md",
|
||||
"scope": "Separate CC0 benchmark-model collection. At inspection its complete tree contained no models; its license does not relicense SELENE.",
|
||||
"evidence_level": "search_scope_document"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-NATIVE-001",
|
||||
"type": "pinned_native_model",
|
||||
"repository": "SychPL/solidcraft",
|
||||
"commit": "32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9",
|
||||
"path": "SELENE-showcase.solidcraft",
|
||||
"url": "https://github.com/SychPL/solidcraft/blob/32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9/SELENE-showcase.solidcraft",
|
||||
"scope": "Exact author-published improved native source supplied by the owner.",
|
||||
"evidence_level": "native_container_inspected"
|
||||
},
|
||||
{
|
||||
"id": "SELENE-REF-USER-CLUE",
|
||||
"type": "pinned_document",
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"commit": "ac1768e08b83ed33212459951f5b50aa7a57cddc",
|
||||
"path": "skills/solidcraft-mechanisms/reference.md",
|
||||
"url": "https://github.com/tangency-labs/solidcraft/blob/ac1768e08b83ed33212459951f5b50aa7a57cddc/skills/solidcraft-mechanisms/reference.md",
|
||||
"scope": "The exact reference supplied by the owner; command contracts and the earlier SELENE closed-loop example.",
|
||||
"evidence_level": "documentation"
|
||||
}
|
||||
],
|
||||
"public_search": {
|
||||
"inspected_on": "2026-10-21",
|
||||
"method": "Read-only GitHub repository, tree, release, pull-request and comment APIs. Only the SolidCraft project, its original rover repository and contributor fork were inspected.",
|
||||
"conclusion": "The improved filename and behavior are documented, but no improved native model or native ZIP attachment was found in the public locations listed below. This is a bounded search result, not proof that the file does not exist elsewhere.",
|
||||
"repositories": [
|
||||
{
|
||||
"repository": "tangency-labs/solidcraft",
|
||||
"scope": "Complete main tree observed during the search; relevant mechanism documentation and attribution; release assets; PRs 1540, 1680 and 1712.",
|
||||
"observed_tree_identifier": "4b37c046e43ac0177a9359bc69f925c26ab25944",
|
||||
"tree_truncated": false,
|
||||
"tree_entry_count": 2583,
|
||||
"releases_examined": 42,
|
||||
"result": "No improved SELENE native file in the examined tree or release asset inventories. Existing rover-build media depict the original construction replay."
|
||||
},
|
||||
{
|
||||
"repository": "tangency-labs/models",
|
||||
"commit": "57abdd6f71c4202fcda78d19dcfdb54dde80a7a9",
|
||||
"scope": "Complete recursive tree, README, LICENSE and complete four-commit setup history.",
|
||||
"tree_truncated": false,
|
||||
"commits_examined": 4,
|
||||
"result": "No model assets. Only documentation, templates, CI and authoring checks. Repository-wide CC0 applies to that separate collection."
|
||||
},
|
||||
{
|
||||
"repository": "0xlillith/solidcraft-rover",
|
||||
"commit": "b32437915372d32b71419dc8f5143fe22ff1e869",
|
||||
"scope": "Default README and ATTRIBUTION; branch inventory.",
|
||||
"branches_examined": 1,
|
||||
"result": "Only main; still identifies the legacy v7 and reconstruction-recording variants."
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"scope": "Complete 109-name branch inventory; four candidate source trees; six relevant media trees and complete histories; release asset inventory.",
|
||||
"branch_names_examined": 109,
|
||||
"releases_examined": 1,
|
||||
"result": "No improved SELENE native asset in the examined source/media trees or release inventory. Listing branch names does not claim that every branch tree was inspected."
|
||||
}
|
||||
],
|
||||
"candidate_source_trees": [
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "feat/motion-export-animation",
|
||||
"commit": "57349b71c7274f19aa37cd9770e6670dc0f19fb2",
|
||||
"truncated": false,
|
||||
"result": "No SELENE or rover native file."
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "feat/joint-reach",
|
||||
"commit": "fd7d51489030f9fd698f11d563b8ba226f58a434",
|
||||
"truncated": false,
|
||||
"result": "No SELENE or rover native file."
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "feat/usability-integration",
|
||||
"commit": "ab05b24deefb72aaac16a668af353bf1ed1563a3",
|
||||
"truncated": false,
|
||||
"result": "No SELENE or rover native file."
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "skill/mechanisms",
|
||||
"commit": "e5a2c41c62d70975c86d056cc3b02dda948ff5e4",
|
||||
"truncated": false,
|
||||
"result": "No SELENE or rover native file."
|
||||
}
|
||||
],
|
||||
"media_histories": [
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/joint-reach",
|
||||
"commit": "471b3805bbd66f0b97acc729d91ea1658799760c",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "selene-drag.gif",
|
||||
"git_blob_sha": "638294cadcdf1300e10ac0fc5eb5f347141a0891",
|
||||
"size_bytes": 1137022
|
||||
},
|
||||
{
|
||||
"path": "selene-reach.gif",
|
||||
"git_blob_sha": "3ca58b8ce8ca8087dbae39ae47dbd553797b9b73",
|
||||
"size_bytes": 1494105
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/motion-analysis",
|
||||
"commit": "6d79237923e80704a3afb4c092950804b64a5c0a",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "motion-collisions.gif",
|
||||
"git_blob_sha": "7ad5479160a79945d0095d3c7b2c1e4d14301e2b",
|
||||
"size_bytes": 470336
|
||||
},
|
||||
{
|
||||
"path": "motion-plot.gif",
|
||||
"git_blob_sha": "e3877b28eda557faab5f56830517bedc38d8b04a",
|
||||
"size_bytes": 1802419
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/motion-animation",
|
||||
"commit": "1e2ad6842a5ad5c3b2cedee3e6508a8e4e3eb3d4",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "dialog.png",
|
||||
"git_blob_sha": "a3aa5ded86d7e0cf9878005a3116e3b3e606009d",
|
||||
"size_bytes": 848311
|
||||
},
|
||||
{
|
||||
"path": "selene-tour.gif",
|
||||
"git_blob_sha": "acc03c1cbca6f989c6fbc8efde0907220a6abf00",
|
||||
"size_bytes": 2995491
|
||||
},
|
||||
{
|
||||
"path": "selene-wings.gif",
|
||||
"git_blob_sha": "8a1577237bede2a3c829448b1675cef404cc6712",
|
||||
"size_bytes": 857815
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/motion-traces",
|
||||
"commit": "328d3c4b4ff76573145a39180e74d513983a16b8",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "motion-trace.gif",
|
||||
"git_blob_sha": "c5b52644a1d705c7fff4d4001ddcf7151b7d0595",
|
||||
"size_bytes": 1092339
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/selene-demo",
|
||||
"commit": "cffe218d22cb90a125bc133b768f000d307a3de8",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "selene-tour.gif",
|
||||
"git_blob_sha": "9556f388a6d2df7114a8e54e65e4f7596a44fe00",
|
||||
"size_bytes": 1528923
|
||||
},
|
||||
{
|
||||
"path": "selene-wings.gif",
|
||||
"git_blob_sha": "44950f585d4c65433970ca320f5d2b1a1e42777b",
|
||||
"size_bytes": 356635
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
},
|
||||
{
|
||||
"repository": "SychPL/solidcraft",
|
||||
"branch": "media/selene-showcase",
|
||||
"commit": "df2e74230e6659409d65501b5d9396b55c6503d3",
|
||||
"commits_examined": 1,
|
||||
"parent_commits": [],
|
||||
"tree_truncated": false,
|
||||
"files": [
|
||||
{
|
||||
"path": "selene2-arm-tour.gif",
|
||||
"git_blob_sha": "3910c50df33aac951cb5bcf55c3b7a7a028daeb4",
|
||||
"size_bytes": 2201708
|
||||
},
|
||||
{
|
||||
"path": "selene2-drivetrain.gif",
|
||||
"git_blob_sha": "fba2787a61126b54c862b1542d853e8143e80eaa",
|
||||
"size_bytes": 2085167
|
||||
},
|
||||
{
|
||||
"path": "selene2-loops.gif",
|
||||
"git_blob_sha": "3edd30a7a851127a9d350b6cc63df81772035cab",
|
||||
"size_bytes": 487152
|
||||
}
|
||||
],
|
||||
"native_files_found": 0
|
||||
}
|
||||
],
|
||||
"pull_request_discussions": [
|
||||
{
|
||||
"number": 1540,
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1540",
|
||||
"combined_issue_review_and_submission_records": 3,
|
||||
"review_threads": 0,
|
||||
"native_or_zip_attachments_found": 0
|
||||
},
|
||||
{
|
||||
"number": 1680,
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1680",
|
||||
"combined_issue_review_and_submission_records": 1,
|
||||
"review_threads": 0,
|
||||
"native_or_zip_attachments_found": 0
|
||||
},
|
||||
{
|
||||
"number": 1712,
|
||||
"url": "https://github.com/tangency-labs/solidcraft/pull/1712",
|
||||
"combined_issue_review_and_submission_records": 0,
|
||||
"review_threads": 0,
|
||||
"native_or_zip_attachments_found": 0
|
||||
}
|
||||
],
|
||||
"exclusions": [
|
||||
"No commercial CAD systems, extracted assets or GPL/LGPL/AGPL implementation sources were accessed.",
|
||||
"No screenshots, GIFs, native model, guessed derivative or reconstructed model are included in this package."
|
||||
],
|
||||
"superseded_by": "source_arrival; the previously inspected media branch acquired its native file in commit 32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9 after the historical search."
|
||||
},
|
||||
"admission_requirements": [
|
||||
{
|
||||
"id": "SELENE-ADMIT-001",
|
||||
"check": "Acquire the actual improved native source.",
|
||||
"acceptance": "Record an HTTPS provenance source that identifies the candidate native file as the author's improved SELENE showcase. A filename, GIF, command list or matching feature count alone cannot establish identity."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-002",
|
||||
"check": "Pin and verify the source bytes.",
|
||||
"acceptance": "Record the real repository/path/commit when repository-backed, actual download URL, SHA-256, byte length and native format. Verify bytes against the reviewed source record; reject every legacy_sources hash marked ineligible."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-003",
|
||||
"check": "Complete a file-specific license review.",
|
||||
"acceptance": "Record license expression, reviewer, date, supporting HTTPS evidence and applicable notices for the original model and any derivative helper geometry. Preserve Ubuntu Light lettering provenance when that geometry remains."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-004",
|
||||
"check": "Inspect the assembly without guessing bindings.",
|
||||
"acceptance": "Record native component, occurrence, joint, motion-link and study identities, units, parentage, grounded roots, limits and any contact settings. Verify uniqueness and connectivity against the actual native file; leave ambiguous matches unresolved."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-005",
|
||||
"check": "Review the documented mechanism expectations.",
|
||||
"acceptance": "Complete the native review in motion/mechanism-acceptance.json. Explain legitimate differences from the demonstrations. Do not admit a renamed v7 or automatically admit an arbitrary file because its shape or counts look similar."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-006",
|
||||
"check": "Perform an explicit source-lock transition.",
|
||||
"acceptance": "A reviewer sets active_source.status to pinned_native only after identity, provenance, bytes, license and native bindings are approved. Pending source locks cannot compile source-dependent scene or motion resources. Never fall back to a legacy source."
|
||||
},
|
||||
{
|
||||
"id": "SELENE-ADMIT-007",
|
||||
"check": "Keep runtime evidence separate.",
|
||||
"acceptance": "A pinned source is not a replay or physics result. Runtime motion needs a recorded SolidCraft revision, command inputs, tolerances, source digest, solved poses, stop/contact reports and review. Changed source bytes invalidate dependent bindings and recordings."
|
||||
}
|
||||
],
|
||||
"native_inspection": {
|
||||
"status": "inspected_container_only",
|
||||
"sha256": "1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677",
|
||||
"counts": {
|
||||
"history_features": 3378,
|
||||
"components_excluding_root": 47,
|
||||
"occurrences": 47,
|
||||
"joints": 49,
|
||||
"motion_links": 9,
|
||||
"motion_studies": 1
|
||||
},
|
||||
"scope": "Read-only ZIP and document inspection of the supplied source. These counts do not prove geometry evaluation, closed-loop solvability, collision clearance or derivative validation."
|
||||
},
|
||||
"source_arrival": {
|
||||
"file_name": "SELENE-showcase.solidcraft",
|
||||
"verification": "The supplied bytes match the published Git blob and SHA-256. This supersedes the historical search outcome recorded below.",
|
||||
"author_commit": "32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9",
|
||||
"parent_media_commit": "df2e74230e6659409d65501b5d9396b55c6503d3",
|
||||
"verified_on": "2026-10-22"
|
||||
},
|
||||
"authoring_runtime": {
|
||||
"status": "derivative_native_acceptance_passed",
|
||||
"name": "Official SolidCraft CLI",
|
||||
"version": "0.18.2",
|
||||
"platform": "linux-x86_64",
|
||||
"release_url": "https://github.com/tangency-labs/solidcraft/releases/tag/v0.18.2",
|
||||
"source_commit": "4927214976ff20758fde35af03bd6b2d6cf73e18",
|
||||
"archive_sha256": "9d0c922ac72204f34ad22ca7a171be78016ab002e304ace3c07d34d187d830ff",
|
||||
"cli_sha256": "e50fe78292d569c36052b24f46f1732bc4e43d1ecdac6a64092aa1cee3b97086",
|
||||
"written_format": "solidcraft/28",
|
||||
"compatibility_reason": "The personal render branch at 10ada1b45a4eb285ce752ac72f9aaa968ff8b5c4 reads through format 29. This executor writes format 28; official 0.19.0 writes format 30 and cannot be its authoring input.",
|
||||
"fixture_policy": "Isolated 0.19.0 component fixtures are development evidence only. Final-model validation must record the executor and model hashes actually used.",
|
||||
"binary_bundled": false,
|
||||
"final_acceptance": {
|
||||
"status": "passed",
|
||||
"model_path": "assets/render/selene/models/SELENE-functional.solidcraft",
|
||||
"model_sha256": "3bd2bfa1c6336394c4a4208d30b52c80d06658a3bd7ea57cc93b774411d1bd68",
|
||||
"completed_utc": "2026-10-22T08:53:15.882960+00:00",
|
||||
"cases": 33,
|
||||
"numeric_comparisons": 880,
|
||||
"report_sha256": "0ccbf279f27885f6a4646a691a03915ca9ae22ae2f6bfef9574b856392474130",
|
||||
"documentation": "assets/render/selene/VALIDATION.md",
|
||||
"scope": "Final derivative: sampled ideal kinematics, independent world-coordinate measurements and seven selected neutral interference pairs. This does not promote the separate original-source checklist or wider unbound render catalog."
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,418 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Native SELENE bearing and arm-clearance authoring commands.
|
||||
|
||||
All geometry and assembly edits go through SolidCraft commands. The ten bearings
|
||||
are intentionally inspectable open bearings, not catalogue-certified parts. Their
|
||||
grooves have 0.02 mm geometric clearance and the rolling relation is an ideal
|
||||
zero-contact-angle, fixed-outer-ring relation; it does not simulate contact loads,
|
||||
lubrication, friction or slip. Distances are millimetres, command angles degrees.
|
||||
|
||||
``stages()`` supplies safe native save/reopen boundaries. Each stage activates the
|
||||
root or its first target component explicitly. Creating all 110 new components
|
||||
in one ``component.from_bodies`` operation avoids repeated global reevaluations.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
AXIS = [0, 1, 0]
|
||||
JOINTS = (
|
||||
("Shoulder", [177, 0, 165], "Arm turret", "Upper arm", "Shoulder articulation", 11.0),
|
||||
("Elbow", [242, 0, 281], "Upper arm", "Forearm", "Elbow articulation", 7.0),
|
||||
("Wrist", [350, 0, 249], "Forearm", "Distal arm", "Wrist articulation", 11.2),
|
||||
("Tool tilt", [410, 0, 267], "Distal arm", "Gripper tool", "Tool tilt articulation", 7.0),
|
||||
("Turret tilt", [-45, 0, 249], "Turret yaw", "Turret sensor head", "Turret elevation articulation", 50.0),
|
||||
)
|
||||
HYDRAULIC_SUFFIXES = (
|
||||
"gold cylinder", "chrome piston", "barrel eye", "barrel eye pin",
|
||||
"barrel eye fork", "rod eye", "rod eye pin", "rod eye fork",
|
||||
"flexible hose", "hose union A", "hose union B",
|
||||
)
|
||||
|
||||
|
||||
def cmd(command: str, **params) -> dict:
|
||||
return {"command": command, "params": params}
|
||||
|
||||
|
||||
def activate(name: str = "root") -> dict:
|
||||
return cmd("component.activate", component=name)
|
||||
|
||||
|
||||
def cylinder(name, base, radius, height, *, axis=AXIS, operation="new", targets=None):
|
||||
p = dict(base=base, radius=radius, height=height, axis=axis,
|
||||
operation=operation, name=name)
|
||||
if operation == "new":
|
||||
p["body_name"] = name
|
||||
if targets:
|
||||
p["targets"] = targets
|
||||
return cmd("solid.cylinder", **p)
|
||||
|
||||
|
||||
def box(name, corner, size, *, operation="new", targets=None):
|
||||
p = dict(corner=corner, length=size[0], width=size[1], height=size[2],
|
||||
operation=operation, name=name)
|
||||
if operation == "new":
|
||||
p["body_name"] = name
|
||||
if targets:
|
||||
p["targets"] = targets
|
||||
return cmd("solid.box", **p)
|
||||
|
||||
|
||||
def ring(name, center, y0, width, ro, ri):
|
||||
x, _, z = center
|
||||
return [cylinder(name, [x, y0, z], ro, width),
|
||||
cylinder(name + " bore", [x, y0-1, z], ri, width+2,
|
||||
operation="cut", targets=[name])]
|
||||
|
||||
|
||||
def style(names, material="Steel", color=(185, 193, 201), roughness=.26):
|
||||
return [cmd("material.assign", bodies=names, material=material),
|
||||
cmd("appearance.assign", bodies=names, color=list(color),
|
||||
pbr={"metallic": 1, "roughness": roughness, "dielectric_ior": 1.5})]
|
||||
|
||||
|
||||
def bearing_specs():
|
||||
"""The actual native names, frames and analytic ratios used by validation."""
|
||||
result = []
|
||||
for label, center, parent, child, driver, y in JOINTS:
|
||||
ro, r = (5.0, .44) if label == "Turret tilt" else (6.0, .70)
|
||||
pitch = (ro + 3.05) / 2
|
||||
for side, sign in (("port", -1), ("starboard", 1)):
|
||||
name = f"Bearing {label} {side}"
|
||||
result.append(dict(name=name, center=[center[0], sign*y, center[2]],
|
||||
parent=parent, child=child, driver=driver,
|
||||
outer_radius=ro, bore_radius=3.05, width=4.0,
|
||||
ball_radius=r, pitch_radius=pitch, balls=8,
|
||||
groove_clearance=.02,
|
||||
cage_joint=name + " cage orbit",
|
||||
cage_ratio=.5*(1-r/pitch),
|
||||
ball_relative_spin_ratio=-.5*(pitch/r-r/pitch)))
|
||||
return result
|
||||
|
||||
|
||||
def race(name, center, ri, ro, pitch, ball_r, inner):
|
||||
"""Revolve a fixed closed cross-section, including an exact circular groove."""
|
||||
chamfer, half, groove = .06, 2.0, ball_r+.02
|
||||
shoulder = .85*ball_r
|
||||
h = math.sqrt(groove*groove-shoulder*shoulder)
|
||||
land = pitch-shoulder if inner else pitch+shoulder
|
||||
if inner:
|
||||
first = [[ri+chamfer,-half], [land-chamfer,-half],
|
||||
[land,-half+chamfer], [land,-h]]
|
||||
after = ["a1.end", [land,half-chamfer], [land-chamfer,half],
|
||||
[ri+chamfer,half], [ri,half-chamfer], [ri,-half+chamfer],
|
||||
"l1.start"]
|
||||
arc = dict(start="l3.end", end=[land,h], through=[pitch-groove,0])
|
||||
else:
|
||||
first = [[land,-h], [land,-half+chamfer], [land+chamfer,-half],
|
||||
[ro-chamfer,-half], [ro,-half+chamfer], [ro,half-chamfer],
|
||||
[ro-chamfer,half], [land+chamfer,half], [land,half-chamfer],
|
||||
[land,h]]
|
||||
after = None
|
||||
arc = dict(start="l9.end", end="l1.start", through=[pitch+groove,0])
|
||||
out = [cmd("sketch.create", name=name + " section",
|
||||
plane={"origin":center, "x_dir":[1,0,0], "y_dir":[0,1,0]}),
|
||||
cmd("sketch.line", points=first, infer=False),
|
||||
cmd("sketch.arc.three_point", **arc)]
|
||||
if after:
|
||||
out.append(cmd("sketch.line", points=after, infer=False))
|
||||
out += [cmd("sketch.constraint.fix", entities=[f"l{i}" for i in range(1,10)]+["a1"], fixed=True),
|
||||
cmd("sketch.finish"),
|
||||
cmd("solid.revolve", sketch=name+" section", axis="y", angle=360,
|
||||
operation="new", name=name, body_name=name)]
|
||||
return out
|
||||
|
||||
|
||||
def bearing_geometry(spec):
|
||||
n, c = spec["name"], spec["center"]
|
||||
r, pitch, ro = spec["ball_radius"], spec["pitch_radius"], spec["outer_radius"]
|
||||
out = race(n+" inner race", c, 3.05, ro, pitch, r, True)
|
||||
out += race(n+" outer race", c, 3.05, ro, pitch, r, False)
|
||||
rail_inner = r+.10
|
||||
out += ring(n+" cage", c, c[1]-rail_inner-.15, .15, pitch+.10, pitch-.10)
|
||||
out += ring(n+" cage rail +1", c, c[1]+rail_inner, .15, pitch+.10, pitch-.10)
|
||||
cage = [n+" cage", n+" cage rail +1"]
|
||||
balls = []
|
||||
for i in range(8):
|
||||
a = i*math.tau/8
|
||||
b = a+math.pi/8
|
||||
name = n+f" ball {i+1:02d}"
|
||||
balls.append(name)
|
||||
out.append(cmd("solid.sphere", name=name, body_name=name, operation="new", radius=r,
|
||||
center=[c[0]+pitch*math.cos(a), c[1], c[2]+pitch*math.sin(a)]))
|
||||
bridge = n+f" cage bridge {i+1:02d}"
|
||||
cage.append(bridge)
|
||||
out.append(cylinder(bridge,
|
||||
[c[0]+pitch*math.cos(b),c[1]-rail_inner,c[2]+pitch*math.sin(b)], .15, 2*rail_inner))
|
||||
out += style([n+" inner race", n+" outer race"], roughness=.23)
|
||||
out += style(balls, color=(209,215,220), roughness=.14)
|
||||
out += style(cage, "Brass", (186,147,67), .35)
|
||||
return out
|
||||
|
||||
|
||||
def bearing_assembly(specs):
|
||||
out = [activate()]
|
||||
anchors = []
|
||||
for s in specs:
|
||||
n = s["name"]
|
||||
anchors += [n+" inner race", n+" outer race", n+" cage"]
|
||||
anchors += [n+f" ball {i+1:02d}" for i in range(8)]
|
||||
out.append(cmd("component.from_bodies", bodies=anchors))
|
||||
for s in specs:
|
||||
n, c = s["name"], s["center"]
|
||||
cage_parts = [n+" cage rail +1"]+[n+f" cage bridge {i+1:02d}" for i in range(8)]
|
||||
out.append(cmd("component.move_bodies", bodies=cage_parts, component=n+" cage"))
|
||||
for race_kind, parent in (("outer",s["parent"]),("inner",s["child"])):
|
||||
out.append(cmd("joint.as_built", type="rigid", a=parent, b=n+f" {race_kind} race",
|
||||
name=n+f" {race_kind} seat", quiet=True))
|
||||
out.append(cmd("joint.as_built", type="revolute", a=n+" outer race", b=n+" cage",
|
||||
at={"occurrence":n+" outer race","point":c,"z":AXIS},
|
||||
name=s["cage_joint"], quiet=True))
|
||||
out.append(cmd("joint.motion_link", a=s["driver"], b=s["cage_joint"],
|
||||
ratio=s["cage_ratio"], offset=0, quiet=True))
|
||||
for i in range(8):
|
||||
name = n+f" ball {i+1:02d}"
|
||||
a = i*math.tau/8
|
||||
p = [c[0]+s["pitch_radius"]*math.cos(a),c[1],c[2]+s["pitch_radius"]*math.sin(a)]
|
||||
out.append(cmd("joint.as_built", type="revolute", a=n+" cage", b=name,
|
||||
at={"occurrence":n+" cage","point":p,"z":AXIS},
|
||||
name=name+" spin", quiet=True))
|
||||
out.append(cmd("joint.motion_link", a=s["driver"], b=name+" spin",
|
||||
ratio=s["ball_relative_spin_ratio"], offset=0, quiet=True))
|
||||
return out
|
||||
|
||||
|
||||
def clamp_hub(name, center, plate_y, inward):
|
||||
"""Split adapter for a 12.2 mm link bore and a 6 mm driven shaft."""
|
||||
x, _, z = center
|
||||
# Revolve the stepped section in one operation. Joining two tangent annuli
|
||||
# instead makes a needlessly difficult coincident curved-face boolean.
|
||||
profile = ([[3.025,0],[6.075,0],[6.075,4],[7.2,4],[7.2,4.6],[3.025,4.6]]
|
||||
if inward == 1 else
|
||||
[[3.025,-.6],[7.2,-.6],[7.2,0],[6.075,0],[6.075,4],[3.025,4]])
|
||||
out = [cmd("sketch.create", name=name+" section",
|
||||
plane={"origin":[x,plate_y,z],"x_dir":[1,0,0],"y_dir":[0,1,0]}),
|
||||
cmd("sketch.line", points=profile, closed=True, infer=False),
|
||||
cmd("sketch.constraint.fix", entities=[f"l{i}" for i in range(1,7)], fixed=True),
|
||||
cmd("sketch.finish"),
|
||||
cmd("solid.revolve", sketch=name+" section", axis="y", angle=360,
|
||||
operation="new",name=name,body_name=name)]
|
||||
out.append(box(name+" split", [x+2.8,plate_y-1,z-.16], [6,6,.32],
|
||||
operation="cut", targets=[name]))
|
||||
# Mill the screw seating flat before drilling: avoids a curved counterbore.
|
||||
out.append(box(name+" pinch head seat", [x+3.2,plate_y+.65,z-6], [3.3,2.7,2.5],
|
||||
operation="cut", targets=[name]))
|
||||
out.append(cylinder(name+" pinch clearance", [x+4.7,plate_y+2,z-5], .65,10,
|
||||
axis=[0,0,1], operation="cut", targets=[name]))
|
||||
shank, head = name+" pinch screw", name+" pinch screw head"
|
||||
out.append(cylinder(shank, [x+4.7,plate_y+2,z-3.5], .6,7, axis=[0,0,1]))
|
||||
out.append(cylinder(head, [x+4.7,plate_y+2,z-4.6], 1.15,1.1, axis=[0,0,1]))
|
||||
out.append(cylinder(head+" socket", [x+4.7,plate_y+2,z-4.7], .52,.75,
|
||||
axis=[0,0,1], operation="cut", targets=[head]))
|
||||
out += style([name], "Aluminum", (170,181,191), .34)
|
||||
out += style([shank,head], color=(64,69,75), roughness=.37)
|
||||
return out, [name,shank,head]
|
||||
|
||||
|
||||
def arm_clearance_stages():
|
||||
out = [activate()]
|
||||
for _,_,_,_,driver,_ in JOINTS:
|
||||
out.append(cmd("joint.drive", joint=driver, value=0, quiet=True))
|
||||
# Remove decorative cylinders that cannot telescope with the electric joints.
|
||||
for label, component in (("Shoulder","Upper arm"),("Elbow","Forearm"),("Wrist","Distal arm")):
|
||||
out += [activate(component), cmd("solid.remove", bodies=[label+" hydraulic "+s for s in HYDRAULIC_SUFFIXES])]
|
||||
for label, center, parent, child, _, _ in JOINTS:
|
||||
out.append(activate(parent))
|
||||
old = ([f"Turret tilt bearing {y}" for y in (-52,48)] if label=="Turret tilt"
|
||||
else [f"{label} rolling bearing {y}" for y in (-9,5)])
|
||||
out.append(cmd("solid.remove", bodies=old))
|
||||
shaft = "Turret elevation shaft" if label=="Turret tilt" else label+" joint shaft"
|
||||
transfer = [shaft]
|
||||
if label != "Turret tilt":
|
||||
out.append(cmd("solid.scale", bodies=[shaft], factors=[1,37/34,1], origin=center))
|
||||
out.append(cmd("solid.move", bodies=[shaft], translate=[0,.5,0]))
|
||||
transfer += [label+" retaining cap -18", label+" retaining cap 17"]
|
||||
out.append(cmd("component.move_bodies", bodies=transfer, component=child))
|
||||
out += [activate("Forearm"),
|
||||
cmd("solid.move", bodies=["Elbow link -9"], translate=[0,-4.2,0]),
|
||||
cmd("solid.move", bodies=["Elbow link 5"], translate=[0,4.2,0])]
|
||||
for t in (.28,.68):
|
||||
out.append(cmd("solid.scale", bodies=[f"Forearm cross brace {t}"], factors=[1,1.84,1], origin=[0,0,0]))
|
||||
out.append(cmd("solid.scale", bodies=[f"Forearm brace screw {t} shank"], factors=[1,26.4/18,1], origin=[0,0,0]))
|
||||
out.append(cmd("solid.move", bodies=[f"Forearm brace screw {t} head"], translate=[0,-4.2,0]))
|
||||
p = [242+108*t, -15, 281-32*t]
|
||||
out.append(cylinder(f"Forearm brace {t} drilled clearance", p,1.6,30,
|
||||
operation="cut", targets=["Elbow link -9","Elbow link 5",f"Forearm cross brace {t}"]))
|
||||
out.append(activate("Arm turret"))
|
||||
out.append(cylinder("Shoulder clevis bearing seats", [177,-15,165],6.05,30,
|
||||
operation="cut", targets=["Shoulder clevis -13","Shoulder clevis 9"]))
|
||||
out.append(activate("Turret yaw"))
|
||||
out.append(cylinder("Sensor fork bearing seats", [-45,-55,249],5.05,110,
|
||||
operation="cut", targets=["Turret elevation fork -52","Turret elevation fork 48"]))
|
||||
# The original actuator ears intrude into adjacent moving plates.
|
||||
for label, c, parent, _,_,_ in JOINTS[:3]:
|
||||
face = {"Shoulder":-13.0,"Elbow":-13.4,"Wrist":-13.2}[label]
|
||||
out.append(activate(parent))
|
||||
for suffix, dx in ((-14,-12),(10,12)):
|
||||
ear = f"{label} actuator ear {suffix}"
|
||||
screw = f"{label} ear screw {suffix}"
|
||||
out.append(box(ear+" face relief", [c[0]+dx-3,face,c[2]-4], [6,4,8], operation="cut", targets=[ear]))
|
||||
out.append(cmd("solid.move", bodies=[screw], translate=[0,face+12,0]))
|
||||
out.append(cylinder(ear+" screw clearance", [c[0]+dx,-26,c[2]],1.6,15,
|
||||
operation="cut", targets=[ear]))
|
||||
out.append(activate("Gripper tool"))
|
||||
out.append(cmd("solid.remove", bodies=["Tool wrist"]))
|
||||
out += [cmd("sketch.create", name="Tool wrist tongue outline", plane={"origin":[0,-4.8,0],"x_dir":[1,0,0],"y_dir":[0,0,-1]}),
|
||||
cmd("sketch.slot.center_to_center", p0=[410,-267], p1=[435,-247], width=12),
|
||||
cmd("sketch.circle.center", center=[410,-267], radius=3.05),
|
||||
cmd("sketch.constraint.fix", entities=["l1","a1","l2","a2","c1"], fixed=True),
|
||||
cmd("sketch.finish"),
|
||||
cmd("solid.extrude", sketch="Tool wrist tongue outline", distance=9.6,
|
||||
operation="new", profiles=[{"point":[420,-260]}],
|
||||
name="Tool wrist machined tongue", body_name="Tool wrist machined tongue"),
|
||||
box("Tool wrist crosshead mating face", [425,-6,230], [25,12,17],
|
||||
operation="cut", targets=["Tool wrist machined tongue"])]
|
||||
out += style(["Tool wrist machined tongue"], "Aluminum", (175,184,193), .32)
|
||||
out.append(activate())
|
||||
|
||||
# New hubs are made in root and transferred after their geometry is complete.
|
||||
hubs = [activate()]
|
||||
transfers = []
|
||||
for label, c, _, child, _, _ in JOINTS[:3]:
|
||||
for side, y0, inward in (("port",-13.2 if label=="Elbow" else -9,1),
|
||||
("starboard",9.2 if label=="Elbow" else 5,-1)):
|
||||
if label == "Elbow":
|
||||
inward = -inward # Forearm plates lie outside the upper-arm bearings.
|
||||
name = f"{label} driven split hub {side}"
|
||||
part, bodies = clamp_hub(name,c,y0,inward)
|
||||
hubs += part
|
||||
transfers.append((child,bodies))
|
||||
for component,bodies in transfers:
|
||||
hubs.append(cmd("component.move_bodies", bodies=bodies, component=component))
|
||||
for label,c,_,child,_,_ in JOINTS[:4]:
|
||||
hubs.append(activate(child))
|
||||
collars = [label+" retaining cap -18",label+" retaining cap 17"]
|
||||
for cap,y in zip(collars,(-18,17)):
|
||||
hubs.append(cylinder(cap+" shaft clearance",[c[0],y-.5,c[2]],3.05,3,
|
||||
operation="cut",targets=[cap]))
|
||||
hubs.append(cylinder(cap+" radial locking bore",[c[0],y+1,c[2]+2.5],.65,3.5,
|
||||
axis=[0,0,1],operation="cut",targets=[cap]))
|
||||
screw=cap+" locking screw"
|
||||
hubs.append(cylinder(screw,[c[0],y+1,c[2]+3.0],.6,1.85,axis=[0,0,1]))
|
||||
hubs.append(cylinder(screw+" socket",[c[0],y+1,c[2]+4.4],.3,.6,
|
||||
axis=[0,0,1],operation="cut",targets=[screw]))
|
||||
hubs += style([screw],color=(66,70,76),roughness=.38)
|
||||
# Axial spacers touch only inner-ring/shaft shoulders, never the outer race.
|
||||
shoulder_y = {"Shoulder":13,"Elbow":13.8,"Wrist":13.2,"Tool tilt":9}[label]
|
||||
names=[]
|
||||
for side,ya,yb in (("port",-16,-shoulder_y),("starboard",shoulder_y,17)):
|
||||
name=f"{label} shaft spacer {side}"
|
||||
hubs += ring(name,c,ya,yb-ya,3.7,3.05)
|
||||
names.append(name)
|
||||
if label != "Shoulder":
|
||||
inner_y = 4.8 if label == "Tool tilt" else 9.0
|
||||
for side,ya in (("port",-inner_y-.2),("starboard",inner_y)):
|
||||
name=f"{label} inner ring thrust spacer {side}"
|
||||
hubs += ring(name,c,ya,.2,3.7,3.05)
|
||||
names.append(name)
|
||||
hubs += style(names,roughness=.31)
|
||||
hubs.append(activate())
|
||||
return [("arm-clearances",out),("driven-hubs",hubs)]
|
||||
|
||||
|
||||
def head_retention_commands():
|
||||
"""Bored sensor-head axle, lockable collars and inner-race-only spacers."""
|
||||
out = [activate("Turret sensor head")]
|
||||
center = [-45, 0, 249]
|
||||
screws, spacers = [], []
|
||||
for cap_y in (-56, 54):
|
||||
cap = f"Turret pivot cap {cap_y}"
|
||||
out += [cylinder(cap+" shaft clearance", [-45,cap_y-.5,249],3.05,3,
|
||||
operation="cut",targets=[cap]),
|
||||
cylinder(cap+" radial locking bore", [-45,cap_y+1,251.5],.65,3.5,
|
||||
axis=[0,0,1],operation="cut",targets=[cap])]
|
||||
screw = cap+" locking screw"
|
||||
out += [cylinder(screw,[-45,cap_y+1,252],.6,1.85,axis=[0,0,1]),
|
||||
cylinder(screw+" socket",[-45,cap_y+1,253.4],.3,.6,
|
||||
axis=[0,0,1],operation="cut",targets=[screw])]
|
||||
screws.append(screw)
|
||||
# The old solid crossbeam enclosed the shaft. A continuous clearance bore
|
||||
# and two radial set screws now describe an actual fastening arrangement.
|
||||
out.append(cylinder("Sensor crossbeam shaft clearance",[-45,-48,249],3.05,96,
|
||||
operation="cut",targets=["Unified sensor crossbeam"]))
|
||||
for y in (-44,44):
|
||||
screw = f"Sensor crossbeam shaft set screw {y}"
|
||||
out += [cylinder(screw+" clearance",[-45,y,251.95],.8,4.1,
|
||||
axis=[0,0,1],operation="cut",targets=["Unified sensor crossbeam"]),
|
||||
cylinder(screw,[-45,y,252],.75,3,axis=[0,0,1]),
|
||||
cylinder(screw+" socket",[-45,y,254.4],.35,.7,
|
||||
axis=[0,0,1],operation="cut",targets=[screw])]
|
||||
screws.append(screw)
|
||||
for side, outer_y, inner_y in (("port",-54,-48),("starboard",52,47)):
|
||||
for kind, y, width in (("shaft spacer",outer_y,2),
|
||||
("inner ring thrust spacer",inner_y,1)):
|
||||
name = f"Turret tilt {kind} {side}"
|
||||
out += ring(name,center,y,width,3.5,3.05)
|
||||
spacers.append(name)
|
||||
out += style(screws,color=(66,70,76),roughness=.38)
|
||||
out += style(spacers,roughness=.31)
|
||||
out.append(activate())
|
||||
return out
|
||||
|
||||
|
||||
def stages():
|
||||
"""Named command lists; each is safe to execute then save/reopen."""
|
||||
specs=bearing_specs()
|
||||
result=arm_clearance_stages()
|
||||
result.append(("head-retention",head_retention_commands()))
|
||||
for i in range(0,len(specs),4):
|
||||
commands=[activate()]
|
||||
for s in specs[i:i+4]:
|
||||
commands += bearing_geometry(s)
|
||||
commands.append(activate())
|
||||
result.append((f"bearing-geometry-{i//4+1}",commands))
|
||||
result.append(("bearing-assembly",bearing_assembly(specs)))
|
||||
return result
|
||||
|
||||
|
||||
def commands():
|
||||
return [c for _,block in stages() for c in block]
|
||||
|
||||
|
||||
def fixture_commands():
|
||||
"""Single compact bearing fixture for independent geometry and phase checks."""
|
||||
s=bearing_specs()[0]
|
||||
s=dict(s,name="Bearing test",center=[0,0,0],parent="Fixed support",child="Driven shaft",
|
||||
driver="Test shaft angle",cage_joint="Bearing test cage orbit")
|
||||
out=[cylinder("Fixed support",[0,-3,0],7,1),
|
||||
cylinder("Support clearance",[0,-4,0],3.1,3,operation="cut",targets=["Fixed support"]),
|
||||
cylinder("Driven shaft",[0,-4,0],3,8),
|
||||
cmd("component.from_bodies",bodies=["Fixed support","Driven shaft"]),
|
||||
cmd("occurrence.ground",occurrence="Fixed support:1",grounded=True),
|
||||
cmd("joint.as_built",type="revolute",a="Fixed support",b="Driven shaft",
|
||||
at={"occurrence":"Fixed support","point":[0,0,0],"z":AXIS},name="Test shaft angle"),
|
||||
activate()]
|
||||
out+=bearing_geometry(s)+bearing_assembly([s])
|
||||
out+=[cmd("joint.list"),cmd("document.inspect",measure=True,sketches=False)]
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--out",type=Path,required=True)
|
||||
parser.add_argument("--fixture",action="store_true")
|
||||
parser.add_argument("--stages",action="store_true")
|
||||
args=parser.parse_args()
|
||||
args.out.parent.mkdir(parents=True,exist_ok=True)
|
||||
data=({"stages":[{"name":n,"commands":cs} for n,cs in stages()],"bearings":bearing_specs()}
|
||||
if args.stages else {"commands":fixture_commands() if args.fixture else commands()})
|
||||
args.out.write_text(json.dumps(data,indent=2)+"\n",encoding="utf-8")
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
||||
@@ -0,0 +1,284 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the enhanced native SELENE through reproducible SolidCraft commands.
|
||||
|
||||
Each stage runs in a fresh native process and is saved before the next stage.
|
||||
This bounds undo-history memory on the large source model. Successful resume
|
||||
requires unchanged input, executable, command recipe and checkpoint hashes.
|
||||
The source archive is inspected read-only; only SolidCraft writes CAD state.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
import bearings
|
||||
import electronics
|
||||
import finishes
|
||||
import mechanisms
|
||||
import suspension
|
||||
import yaw_supports
|
||||
from prepare import inspect_native
|
||||
|
||||
PACKAGE = Path(__file__).resolve().parents[1]
|
||||
SOURCE = PACKAGE / "source/SELENE-showcase.solidcraft"
|
||||
|
||||
|
||||
def sha(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def json_digest(value: object) -> str:
|
||||
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":"), allow_nan=False).encode()).hexdigest()
|
||||
|
||||
|
||||
def write(path: Path, value: object) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = path.with_suffix(path.suffix + ".tmp")
|
||||
temporary.write_text(json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + "\n", encoding="utf-8")
|
||||
temporary.replace(path)
|
||||
|
||||
|
||||
def require(value: bool, message: str) -> None:
|
||||
if not value:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def document(path: Path) -> dict:
|
||||
inspect_native(path) # Bounded archive, path, count and relationship admission.
|
||||
with zipfile.ZipFile(path) as archive:
|
||||
return json.loads(archive.read("document.json"))
|
||||
|
||||
|
||||
def health(inventory: dict) -> None:
|
||||
errors = [f for f in inventory.get("timeline", []) if f.get("error") or f.get("warning")]
|
||||
require(not errors, f"Native timeline has errors or warnings: {errors[:3]}")
|
||||
require(inventory.get("bodies") and len({b["name"] for b in inventory["bodies"]}) == len(inventory["bodies"]),
|
||||
"Native inventory has no bodies or duplicate names.")
|
||||
|
||||
|
||||
def execute(cli: Path, arguments: list[str], log: Path, timeout: float) -> None:
|
||||
env = os.environ.copy()
|
||||
env.update(RAYON_NUM_THREADS="2", MALLOC_ARENA_MAX="1", SOLIDCRAFT_GPU="cpu",
|
||||
MALLOC_MMAP_THRESHOLD_="65536", MALLOC_TRIM_THRESHOLD_="65536")
|
||||
started = time.monotonic()
|
||||
with log.open("wb") as stream:
|
||||
process = subprocess.Popen([str(cli), *arguments], stdout=stream, stderr=subprocess.STDOUT, env=env)
|
||||
try:
|
||||
while process.poll() is None:
|
||||
elapsed = time.monotonic() - started
|
||||
if elapsed > timeout:
|
||||
process.terminate()
|
||||
try:
|
||||
process.wait(timeout=10)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
process.wait()
|
||||
raise TimeoutError(f"Native process exceeded {timeout:g}s; see {log}")
|
||||
if elapsed > 0 and int(elapsed) % 30 == 0:
|
||||
print(f" native process active: {elapsed:.0f}s", flush=True)
|
||||
time.sleep(1)
|
||||
except BaseException:
|
||||
if process.poll() is None:
|
||||
process.terminate()
|
||||
process.wait(timeout=10)
|
||||
raise
|
||||
require(process.returncode == 0, f"Native process exited {process.returncode}; see {log}")
|
||||
|
||||
|
||||
def expected_stages(inventory: dict, source: dict) -> list[tuple[str, list[dict]]]:
|
||||
result = [
|
||||
("01-finishes", finishes.commands(inventory, source)),
|
||||
("02-primary-mechanisms", mechanisms.primary_commands()),
|
||||
("03-electronics", electronics.commands()),
|
||||
]
|
||||
for index, steps in enumerate(bearings.stages(), 1):
|
||||
if isinstance(steps, tuple):
|
||||
steps = steps[-1]
|
||||
result.append((f"04-bearings-{index:02}", steps))
|
||||
suspension_stages = list(suspension.stages())
|
||||
for index, steps in enumerate(suspension_stages, 1):
|
||||
if isinstance(steps, tuple):
|
||||
steps = steps[-1]
|
||||
if index == len(suspension_stages):
|
||||
# Reparenting wheels recreates their joints. Rebind the inherited
|
||||
# study before this checkpoint, so it never retains deleted IDs.
|
||||
steps = [*steps, mechanisms.adapted_author_tour(source)]
|
||||
result.append((f"05-suspension-{index:02}", steps))
|
||||
for index, (_, steps) in enumerate(yaw_supports.stages(), 1):
|
||||
result.append((f"05b-yaw-supports-{index:02}", steps))
|
||||
return [(name, commands + [mechanisms.c("document.inspect", measure=False, sketches=False), mechanisms.c("joint.list")])
|
||||
for name, commands in result]
|
||||
|
||||
|
||||
def run_stage(cli: Path, current: Path, work: Path, name: str, commands: list[dict], timeout: float) -> tuple[Path, dict]:
|
||||
require(bool(commands) and all(isinstance(x, dict) and "command" in x for x in commands), f"Bad stage {name}")
|
||||
recipe, result_path, checkpoint = (work / (name + suffix) for suffix in (".commands.json", ".results.json", ".solidcraft"))
|
||||
require(not checkpoint.exists(), f"Refusing to replace an unrecorded checkpoint: {checkpoint}")
|
||||
write(recipe, {"commands": commands})
|
||||
start = time.monotonic()
|
||||
print(f"Starting {name}: {len(commands)} native commands", flush=True)
|
||||
execute(cli, ["run", str(recipe), "--in", str(current), "--save", str(checkpoint),
|
||||
"--quiet", "--results", "--timings", "--json-out", str(result_path)],
|
||||
work / (name + ".log"), timeout)
|
||||
result = json.loads(result_path.read_text(encoding="utf-8"))
|
||||
timing = result.get("timings", [])
|
||||
require(len(timing) == len(commands), f"{name}: incomplete native timing trace")
|
||||
require([t.get("index") for t in timing] == list(range(len(commands))), f"{name}: unordered native timing trace")
|
||||
require([t.get("command") for t in timing] == [c["command"] for c in commands], f"{name}: command trace mismatch")
|
||||
require(len(result.get("results", [])) == len(commands), f"{name}: missing native command results")
|
||||
inventory, graph = result["results"][-2:]
|
||||
health(inventory)
|
||||
for key in ("conflicts", "errors", "floating"):
|
||||
require(not graph.get(key), f"{name}: native joint graph has {key}: {graph[key]}")
|
||||
native = inspect_native(checkpoint)
|
||||
entry = {
|
||||
"name": name, "commands": len(commands), "recipe_sha256": json_digest(commands),
|
||||
"input_sha256": sha(current), "checkpoint": checkpoint.name, "checkpoint_sha256": sha(checkpoint),
|
||||
"result_file": result_path.name, "result_sha256": sha(result_path),
|
||||
"duration_seconds": round(time.monotonic() - start, 3), "format": native["format"],
|
||||
"counts": native["counts"], "native_exit_code": 0,
|
||||
"process_memory_policy": {"MALLOC_ARENA_MAX": "1", "MALLOC_MMAP_THRESHOLD_": "65536",
|
||||
"MALLOC_TRIM_THRESHOLD_": "65536", "RAYON_NUM_THREADS": "2"},
|
||||
}
|
||||
print(f"Saved {name}: {native['counts']['history_features']} features, {native['counts']['joints']} joints", flush=True)
|
||||
return checkpoint, entry
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--cli", type=Path, required=True)
|
||||
parser.add_argument("--source", type=Path, default=SOURCE)
|
||||
parser.add_argument("--work", type=Path, required=True)
|
||||
parser.add_argument("--resume", action="store_true")
|
||||
parser.add_argument("--until", help="Stop after a named native stage; preserves a resumable checkpoint.")
|
||||
parser.add_argument("--inventory", type=Path, help="Reuse an existing evaluated source inventory; only body names are used to generate finishes.")
|
||||
parser.add_argument("--stage-timeout", type=float, default=2400)
|
||||
parser.add_argument("--output", type=Path, default=PACKAGE / "models/SELENE-functional.solidcraft")
|
||||
args = parser.parse_args()
|
||||
cli, source, work = args.cli.resolve(), args.source.resolve(), args.work.resolve()
|
||||
require(cli.is_file(), "Native CLI is missing.")
|
||||
require(sha(source) == finishes.SOURCE_SHA256 and source.stat().st_size == 314452, "Source is not the pinned author-supplied file.")
|
||||
source_doc = document(source)
|
||||
version = subprocess.check_output([str(cli), "--version"], text=True).strip()
|
||||
work.mkdir(parents=True, exist_ok=True)
|
||||
history_file = work / "build-history.json"
|
||||
initial = {
|
||||
"schema_version": "1.0", "source_sha256": sha(source), "cli_sha256": sha(cli), "cli_version": version,
|
||||
"started_at": datetime.now(timezone.utc).isoformat(), "stages": [], "status": "in_progress",
|
||||
}
|
||||
if args.resume:
|
||||
history = json.loads(history_file.read_text(encoding="utf-8"))
|
||||
for key in ("source_sha256", "cli_sha256", "cli_version"):
|
||||
require(history[key] == initial[key], f"Resume fingerprint changed: {key}")
|
||||
else:
|
||||
require(not history_file.exists(), "Build history exists; use --resume or a new work directory.")
|
||||
history = initial
|
||||
write(history_file, history)
|
||||
baseline = work / "source-inventory.json"
|
||||
if not baseline.exists():
|
||||
if args.inventory:
|
||||
shutil.copyfile(args.inventory.resolve(), baseline)
|
||||
history["inventory_origin"] = "Supplied evaluated inventory; native stage replay still verifies the source geometry."
|
||||
else:
|
||||
execute(cli, ["eval", str(source), "--json-out", str(baseline)], work / "source-evaluation.log", args.stage_timeout)
|
||||
history["inventory_origin"] = "This executable evaluated the pinned source."
|
||||
write(history_file, history)
|
||||
inventory = json.loads(baseline.read_text(encoding="utf-8"))
|
||||
health(inventory)
|
||||
require(len(inventory["bodies"]) == 1418, "Unexpected source body inventory.")
|
||||
stages = expected_stages(inventory, source_doc)
|
||||
require(args.until is None or args.until in dict(stages) or args.until == "06-presentation", "Unknown --until stage.")
|
||||
current = source
|
||||
for number, (name, commands) in enumerate(stages):
|
||||
if number < len(history["stages"]):
|
||||
old = history["stages"][number]
|
||||
require(old["name"] == name and old["recipe_sha256"] == json_digest(commands), f"Completed recipe changed: {name}")
|
||||
require(old["input_sha256"] == sha(current), f"Checkpoint chain changed before {name}")
|
||||
current = work / old["checkpoint"]
|
||||
require(sha(current) == old["checkpoint_sha256"], f"Checkpoint changed: {name}")
|
||||
require(sha(work / old["result_file"]) == old["result_sha256"], f"Native results changed: {name}")
|
||||
else:
|
||||
try:
|
||||
current, entry = run_stage(cli, current, work, name, commands, args.stage_timeout)
|
||||
except (ValueError, OSError, subprocess.SubprocessError, TimeoutError) as error:
|
||||
history.setdefault("failed_attempts", []).append({
|
||||
"stage": name, "recipe_sha256": json_digest(commands),
|
||||
"input_sha256": sha(current), "error": str(error),
|
||||
"recorded_at": datetime.now(timezone.utc).isoformat(),
|
||||
})
|
||||
write(history_file, history)
|
||||
raise
|
||||
history["stages"].append(entry)
|
||||
write(history_file, history)
|
||||
if args.until == name:
|
||||
print(f"Stopped at requested checkpoint: {current}", flush=True)
|
||||
return 0
|
||||
# Assembly-dependent groups and studies are authored after final native IDs exist.
|
||||
import presentation
|
||||
input_doc = document(current)
|
||||
prior_results = json.loads((work / history["stages"][len(stages)-1]["result_file"]).read_text(encoding="utf-8"))
|
||||
presentation_commands = presentation.commands(input_doc, prior_results["results"][-2])
|
||||
presentation_commands.append(mechanisms.adapted_author_tour(source_doc))
|
||||
presentation_commands.extend(mechanisms.study_commands(include_suspension=True))
|
||||
presentation_commands.extend([
|
||||
mechanisms.c("document.inspect", measure=False, sketches=False),
|
||||
mechanisms.c("joint.list"),
|
||||
])
|
||||
name = "06-presentation"
|
||||
if len(history["stages"]) > len(stages):
|
||||
old = history["stages"][len(stages)]
|
||||
require(old["name"] == name and old["recipe_sha256"] == json_digest(presentation_commands), "Presentation recipe changed.")
|
||||
current = work / old["checkpoint"]
|
||||
require(sha(current) == old["checkpoint_sha256"], "Presentation checkpoint changed.")
|
||||
require(sha(work / old["result_file"]) == old["result_sha256"], "Presentation results changed.")
|
||||
else:
|
||||
try:
|
||||
current, entry = run_stage(cli, current, work, name, presentation_commands, args.stage_timeout)
|
||||
except (ValueError, OSError, subprocess.SubprocessError, TimeoutError) as error:
|
||||
history.setdefault("failed_attempts", []).append({
|
||||
"stage": name, "recipe_sha256": json_digest(presentation_commands),
|
||||
"input_sha256": sha(current), "error": str(error),
|
||||
"recorded_at": datetime.now(timezone.utc).isoformat(),
|
||||
})
|
||||
write(history_file, history)
|
||||
raise
|
||||
history["stages"].append(entry)
|
||||
write(history_file, history)
|
||||
final_results = json.loads((work / (name + ".results.json")).read_text(encoding="utf-8"))["results"]
|
||||
final_inventory, joints = final_results[-2:]
|
||||
health(final_inventory)
|
||||
for key in ("conflicts", "errors", "floating"):
|
||||
require(not joints.get(key), f"Final native joint graph has {key}: {joints[key]}")
|
||||
write(work / "final-inspect.json", final_inventory)
|
||||
write(work / "final-joints.json", joints)
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
if args.output.exists():
|
||||
require(sha(args.output) == sha(current), "Final output exists with another hash; choose a new --output.")
|
||||
else:
|
||||
shutil.copyfile(current, args.output)
|
||||
history.update(status="native_build_passed", final_sha256=sha(current),
|
||||
final_body_count=len(final_inventory["bodies"]), output=str(args.output),
|
||||
completed_at=datetime.now(timezone.utc).isoformat())
|
||||
write(history_file, history)
|
||||
print(f"Native master saved: {args.output} ({sha(current)})", flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
raise SystemExit(main())
|
||||
except (ValueError, OSError, subprocess.SubprocessError, TimeoutError) as error:
|
||||
print(f"SELENE build failed: {error}", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
@@ -0,0 +1,367 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Author SELENE's Raspberry Pi 5 visual componentry through native commands.
|
||||
|
||||
The board outline and mounting pattern are from Raspberry Pi's public mechanical
|
||||
drawing. Package envelopes and connector internals are an original, dimension-
|
||||
informed visual reconstruction, not a production BOM, electrical design, or a
|
||||
manufacturer CAD model. All coordinates are millimetres. No native document is
|
||||
patched: this module only emits ordinary SolidCraft commands.
|
||||
|
||||
``commands()`` extends the pinned SELENE source. ``standalone_commands()`` makes
|
||||
the same board fixture in a new, isolated document for inspection and testing.
|
||||
The source board already sits at world (22, -28, 120); its early timeline was
|
||||
translated twice. Components are therefore authored at the evaluated location.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
BOARD = "Raspberry Pi 5 PCB"
|
||||
COMPONENT = "Raspberry Pi 5 componentry"
|
||||
ORIGIN = (22.0, -28.0, 120.0)
|
||||
THICKNESS = 1.6
|
||||
CORNER_RADIUS = 3.0
|
||||
GPIO_PITCH = 2.54
|
||||
GPIO_FIRST = (7.5, 50.0)
|
||||
MOUNTING = ((3.5, 3.5), (61.5, 3.5), (3.5, 52.5), (61.5, 52.5))
|
||||
VIA_POSITIONS = ((16, 42), (19, 42), (35, 44), (38, 44), (42, 45), (45, 45),
|
||||
(4, 42), (7, 44), (10, 44), (51, 8), (52.5, 8), (57, 46))
|
||||
PLACEHOLDERS = ["CPU cooler base", *[f"CPU cooler fin {i}" for i in range(3)],
|
||||
*[f"Pi port envelope {i}" for i in range(3)], "GPIO envelope"]
|
||||
SEMICONDUCTOR = "SELENE Pi5 semiconductor package proxy"
|
||||
FR4 = "SELENE Pi5 FR4 proxy"
|
||||
|
||||
# Built-in physical materials are bulk proxies, independent of visual coatings.
|
||||
ROLES = {
|
||||
"package": ((32, 35, 39), 0.0, 0.61, SEMICONDUCTOR),
|
||||
"socket": ((22, 27, 30), 0.0, 0.46, "ABS Plastic"),
|
||||
"usb_blue": ((30, 78, 155), 0.0, 0.40, "ABS Plastic"),
|
||||
"ceramic": ((173, 144, 95), 0.0, 0.62, SEMICONDUCTOR),
|
||||
"ferrite": ((76, 79, 80), 0.0, 0.70, SEMICONDUCTOR),
|
||||
"shield": ((182, 190, 198), 1.0, 0.31, "Steel"),
|
||||
"aluminum": ((184, 192, 201), 1.0, 0.27, "Aluminum"),
|
||||
"solder": ((174, 179, 185), 1.0, 0.39, "Steel"),
|
||||
"gold": ((215, 175, 79), 1.0, 0.24, "Brass"),
|
||||
"white": ((213, 218, 209), 0.0, 0.55, "ABS Plastic"),
|
||||
"led_green": ((74, 173, 70), 0.0, 0.22, "ABS Plastic"),
|
||||
"led_amber": ((229, 145, 34), 0.0, 0.24, "ABS Plastic"),
|
||||
"mask": ((31, 90, 51), 0.0, 0.44, FR4),
|
||||
}
|
||||
|
||||
|
||||
def command(command_id: str, **params) -> dict:
|
||||
return {"command": command_id, "params": params}
|
||||
|
||||
|
||||
class BoardAuthor:
|
||||
"""Small deterministic native-command emitter with unique body names."""
|
||||
|
||||
def __init__(self):
|
||||
self.steps = []
|
||||
self.bodies = []
|
||||
self.roles = defaultdict(list)
|
||||
|
||||
def add(self, command_id: str, **params):
|
||||
self.steps.append(command(command_id, **params))
|
||||
|
||||
def point(self, x: float, y: float, z: float) -> list:
|
||||
return [round(ORIGIN[0] + x, 8), round(ORIGIN[1] + y, 8),
|
||||
round(ORIGIN[2] + THICKNESS + z, 8)]
|
||||
|
||||
def body(self, name: str, role: str) -> str:
|
||||
name = "Pi5 " + name
|
||||
if name in self.bodies:
|
||||
raise ValueError(f"Duplicate body: {name}")
|
||||
self.bodies.append(name)
|
||||
self.roles[role].append(name)
|
||||
return name
|
||||
|
||||
def box(self, name, xyz, size, role="socket"):
|
||||
name = self.body(name, role)
|
||||
self.add("solid.box", corner=self.point(*xyz), length=size[0],
|
||||
width=size[1], height=size[2], operation="new",
|
||||
name=name, body_name=name)
|
||||
return name
|
||||
|
||||
def cut_box(self, target, label, xyz, size):
|
||||
self.add("solid.box", corner=self.point(*xyz), length=size[0],
|
||||
width=size[1], height=size[2], operation="cut",
|
||||
targets=[target], name="Pi5 " + label)
|
||||
|
||||
def cylinder(self, name, xyz, radius, height, role="gold", axis=(0, 0, 1)):
|
||||
name = self.body(name, role)
|
||||
self.add("solid.cylinder", base=self.point(*xyz), radius=radius,
|
||||
height=height, axis=list(axis), operation="new",
|
||||
name=name, body_name=name)
|
||||
return name
|
||||
|
||||
def bore(self, target, label, xyz, radius, height):
|
||||
self.add("solid.cylinder", base=self.point(*xyz), radius=radius,
|
||||
height=height, axis=[0, 0, 1], operation="cut",
|
||||
targets=[target], name="Pi5 " + label)
|
||||
|
||||
def ring(self, name, xyz, outer, inner, height, role="solder"):
|
||||
n = self.cylinder(name, xyz, outer, height, role)
|
||||
self.bore(n, name + " bore", (xyz[0], xyz[1], xyz[2] - 0.1), inner, height + 0.2)
|
||||
return n
|
||||
|
||||
def rotated_box(self, name, center, size, angle, role="package"):
|
||||
xyz = (center[0] - size[0] / 2, center[1] - size[1] / 2, center[2])
|
||||
n = self.box(name, xyz, size, role)
|
||||
pivot = self.point(*center)
|
||||
self.add("solid.move", bodies=[n], translate=[-v for v in pivot], name=n + " origin")
|
||||
self.add("solid.move", bodies=[n], axis=[0, 0, 1], angle=angle, name=n + " rotation")
|
||||
self.add("solid.move", bodies=[n], translate=pivot, name=n + " placement")
|
||||
return n
|
||||
|
||||
|
||||
def _geometry(a: BoardAuthor):
|
||||
# The preserved source PCB is drilled explicitly; pins do not disappear into
|
||||
# an unperforated slab. Via and GPIO bore sizes are illustrative clearances.
|
||||
header = a.box("GPIO insulator", (6.23, 48.73, 0), (50.8, 5.08, 2.5))
|
||||
for col in range(20):
|
||||
for row in range(2):
|
||||
pin = col * 2 + row + 1
|
||||
x, y = GPIO_FIRST[0] + GPIO_PITCH * col, GPIO_FIRST[1] + GPIO_PITCH * row
|
||||
a.cut_box(header, f"GPIO insulator bore {pin:02}", (x - .36, y - .36, -.1), (.72, .72, 2.7))
|
||||
a.box(f"GPIO pin {pin:02}", (x - .32, y - .32, -2.4), (.64, .64, 10.0), "gold")
|
||||
a.ring(f"GPIO top solder {pin:02}", (x, y, .01), .82, .50, .14)
|
||||
a.ring(f"GPIO underside solder {pin:02}", (x, y, -1.75), .82, .50, .15)
|
||||
|
||||
for i, (x, y) in enumerate(MOUNTING, 1):
|
||||
a.ring(f"Mounting annular pad {i}", (x, y, .01), 2.55, 1.35, .055, "gold")
|
||||
|
||||
# Visible packages and leads. Dimensions outside the public board interface
|
||||
# are a clearly documented visual approximation, not component CAD imports.
|
||||
a.box("BCM2712 substrate", (25.4, 19.1, .06), (15.5, 15.5, .55), "package")
|
||||
a.box("BCM2712 heat spreader", (26.35, 20.05, .61), (13.6, 13.6, .95), "aluminum")
|
||||
a.box("LPDDR4X package", (43.4, 29.0, .08), (10.0, 14.4, 1.0), "package")
|
||||
a.box("RP1 controller", (45.3, 14.2, .08), (12.0, 12.0, 1.18), "package")
|
||||
a.box("DA9091 PMIC", (15.2, 21.0, .08), (6.0, 6.0, 1.0), "package")
|
||||
for i, (x, y) in enumerate(((15.2, 28.2), (19.5, 28.2), (15.2, 32.8), (19.5, 16.5)), 1):
|
||||
a.box(f"Power inductor {i}", (x, y, .05), (3.1, 3.1, 1.9), "ferrite")
|
||||
a.box(f"Power inductor {i} terminal A", (x - .15, y + .3, .01), (.35, 2.5, .4), "solder")
|
||||
a.box(f"Power inductor {i} terminal B", (x + 2.9, y + .3, .01), (.35, 2.5, .4), "solder")
|
||||
a.rotated_box("BCM54213 Ethernet PHY", (64.0, 24.0, .08), (7.2, 7.2, 1.0), 45)
|
||||
a.box("CYW43455 wireless package", (6.0, 31.0, .08), (5.8, 5.8, .8), "package")
|
||||
# Five sheet bodies form a hollow RF cover, retaining a genuine underside.
|
||||
a.box("RF shield roof", (4.5, 29.5, 2.05), (10.0, 10.0, .22), "shield")
|
||||
a.box("RF shield west", (4.5, 29.5, 0), (.22, 10.0, 2.05), "shield")
|
||||
a.box("RF shield east", (14.28, 29.5, 0), (.22, 10.0, 2.05), "shield")
|
||||
a.box("RF shield south", (4.72, 29.5, 0), (9.56, .22, 2.05), "shield")
|
||||
a.box("RF shield north", (4.72, 39.28, 0), (9.56, .22, 2.05), "shield")
|
||||
|
||||
# Stacked USB-A: open front cavities, two distinct tongues and their gold
|
||||
# contacts. The USB 3 additional contacts sit further back in each socket.
|
||||
for family, y, tongue_role in (("USB2", 37.8, "socket"), ("USB3", 19.8, "usb_blue")):
|
||||
shell = a.box(f"{family} stacked shell", (70.0, y, 0), (17.0, 14.2, 15.2), "shield")
|
||||
for level in range(2):
|
||||
z = .85 + level * 7.3
|
||||
a.cut_box(shell, f"{family} cavity {level + 1}", (71.0, y + .55, z), (16.4, 13.1, 5.75))
|
||||
a.box(f"{family} tongue {level + 1}", (72.1, y + 1.2, z + 2.45), (12.9, 11.8, 1.05), tongue_role)
|
||||
for pin in range(4):
|
||||
a.box(f"{family} level {level + 1} contact {pin + 1}",
|
||||
(76.0, y + 3.1 + pin * 2.5, z + 2.27), (8.1, .85, .18), "gold")
|
||||
if family == "USB3":
|
||||
for pin in range(5):
|
||||
a.box(f"{family} level {level + 1} SS contact {pin + 1}",
|
||||
(73.1, y + 2.3 + pin * 2.0, z + 3.50), (2.0, .65, .14), "gold")
|
||||
for sign, sy in (("L", y + 2.5), ("R", y + 10.0)):
|
||||
a.box(f"{family} retention spring {level + 1}{sign}",
|
||||
(82.0, sy, z + 5.38), (2.0, 1.15, .25), "shield")
|
||||
for t, yy in enumerate((y + .9, y + 12.5), 1):
|
||||
a.box(f"{family} mounting tab {t}", (71.1, yy, -1.9), (.65, .9, 2.0), "solder")
|
||||
|
||||
# RJ45 is Pi 5's bottom right connector. Its socket is hollow, with a latch
|
||||
# recess, 8 contacts and green/amber indicator lenses in separate pockets.
|
||||
shell = a.box("RJ45 metal shell", (65.8, .8, 0), (21.2, 16.0, 13.5), "shield")
|
||||
a.cut_box(shell, "RJ45 socket cavity", (72.4, 2.0, 1.7), (15.0, 13.6, 10.2))
|
||||
a.cut_box(shell, "RJ45 latch recess", (80.0, 6.6, .6), (7.5, 4.4, 2.0))
|
||||
a.box("RJ45 internal contact carrier", (73.0, 2.5, 2.1), (3.0, 12.6, 6.2), "socket")
|
||||
for pin in range(8):
|
||||
a.box(f"RJ45 gold spring contact {pin + 1}", (75.0, 4.0 + pin * 1.27, 7.65), (8.8, .48, .20), "gold")
|
||||
for label, y, role in (("link", 1.5, "led_green"), ("activity", 14.2, "led_amber")):
|
||||
a.cut_box(shell, f"RJ45 {label} pocket", (85.3, y, 10.5), (2.0, 1.2, 1.8))
|
||||
a.box(f"RJ45 {label} lens", (85.4, y + .1, 10.6), (1.4, 1.0, 1.6), role)
|
||||
|
||||
# USB-C and dual micro-HDMI face the -Y edge. Contact counts describe their
|
||||
# visible interfaces, and do not imply that every pin is electrically used.
|
||||
shell = a.box("USB-C shell", (6.5, -1.2, .05), (9.2, 7.6, 3.25), "shield")
|
||||
a.cut_box(shell, "USB-C opening", (6.9, -1.5, .47), (8.4, 6.6, 2.37))
|
||||
a.box("USB-C tongue", (7.35, -.75, 1.44), (7.5, 5.2, .55), "socket")
|
||||
for row, z in (("upper", 2.0), ("lower", 1.30)):
|
||||
for pin in range(12):
|
||||
a.box(f"USB-C {row} contact {pin + 1:02}", (8.25 + pin * .5, -.15, z), (.25, 3.2, .12), "gold")
|
||||
for port, x in enumerate((24.5, 38.0), 1):
|
||||
shell = a.box(f"micro-HDMI {port} shell", (x, -1.0, .05), (7.0, 6.9, 2.85), "shield")
|
||||
a.cut_box(shell, f"micro-HDMI {port} opening", (x + .35, -1.2, .42), (6.3, 5.5, 2.08))
|
||||
a.box(f"micro-HDMI {port} tongue", (x + .8, -.5, 1.13), (5.4, 4.8, .52), "socket")
|
||||
for pin in range(19):
|
||||
a.box(f"micro-HDMI {port} contact {pin + 1:02}",
|
||||
(x + 1.0 + (pin // 2) * .5, -.15, 1.66 if pin % 2 else 1.0),
|
||||
(.20, 2.6, .10), "gold")
|
||||
|
||||
# Two 22-position MIPI FFC sockets and a 16-position PCIe FFC socket.
|
||||
for port, x in enumerate((45.8, 54.0), 1):
|
||||
# The long contact rows run along Y, leaving the real two bottom-edge
|
||||
# connectors visually readable between HDMI and Ethernet.
|
||||
n = a.box(f"MIPI {port} housing", (x, .5, 0), (4.8, 12.6, 2.15), "socket")
|
||||
a.cut_box(n, f"MIPI {port} cable slot", (x + .85, .4, .8), (3.1, 12.2, .65))
|
||||
a.box(f"MIPI {port} latch", (x + 3.85, 1.0, 1.60), (.8, 11.6, .65), "white")
|
||||
for pin in range(22):
|
||||
a.box(f"MIPI {port} contact {pin + 1:02}", (x + .45, 1.55 + pin * .5, .83), (3.1, .20, .16), "gold")
|
||||
n = a.box("PCIe FFC housing", (.8, 13.3, 0), (4.7, 9.7, 2.15), "socket")
|
||||
a.cut_box(n, "PCIe FFC cable slot", (.7, 14.0, .8), (4.2, 8.3, .65))
|
||||
a.box("PCIe FFC latch", (.65, 13.8, 1.6), (.85, 8.7, .65), "white")
|
||||
for pin in range(16):
|
||||
a.box(f"PCIe contact {pin + 1:02}", (1.0, 14.4 + pin * .5, .83), (3.2, .20, .16), "gold")
|
||||
|
||||
# Small shrouded JST-style headers with separate pins, open at the top.
|
||||
for name, count, x, y, pitch in (("Fan", 4, 61.5, 41.0, 1.0),
|
||||
("UART", 3, 18.0, 4.4, 1.0),
|
||||
("RTC battery", 2, 10.4, 10.8, 1.0)):
|
||||
width = (count - 1) * pitch + 2.2
|
||||
n = a.box(name + " shroud", (x, y, 0), (width, 3.4, 3.1), "white")
|
||||
a.cut_box(n, name + " header well", (x + .48, y + .48, .7), (width - .96, 2.44, 2.7))
|
||||
for pin in range(count):
|
||||
a.box(f"{name} pin {pin + 1}", (x + 1.0 + pin * pitch, y + 1.5, .25), (.3, .3, 2.35), "gold")
|
||||
a.box(f"{name} solder toe {pin + 1}", (x + .9 + pin * pitch, y - .55, .01), (.5, .75, .12), "solder")
|
||||
a.box("PoE 2x2 insulator", (60.7, 33.8, 0), (5.08, 5.08, 2.5), "socket")
|
||||
for col in range(2):
|
||||
for row in range(2):
|
||||
a.box(f"PoE pin {col * 2 + row + 1}",
|
||||
(61.65 + col * 2.54, 34.75 + row * 2.54, 2.5), (.64, .64, 4.0), "gold")
|
||||
|
||||
# Underside microSD socket: open mouth, shell, insulating carrier and 8 pads.
|
||||
shell = a.box("microSD underside cage", (-.5, 21.0, -3.5), (14.8, 13.8, 1.75), "shield")
|
||||
a.cut_box(shell, "microSD cavity", (-.8, 21.45, -3.2), (14.2, 12.9, 1.15))
|
||||
a.box("microSD internal carrier", (9.3, 21.6, -3.18), (3.9, 12.6, .45), "socket")
|
||||
for pin in range(8):
|
||||
a.box(f"microSD contact {pin + 1}", (5.8, 23.0 + pin * 1.1, -2.68), (6.6, .55, .12), "gold")
|
||||
|
||||
a.box("Power button frame", (-.5, 7.0, .1), (3.8, 5.2, 2.6), "shield")
|
||||
a.box("Power button plunger", (-1.1, 8.2, .6), (.9, 2.8, 1.6), "socket")
|
||||
a.box("Status LED base", (1.0, 46.0, .02), (1.8, 1.0, .35), "white")
|
||||
a.box("Status LED lens", (1.25, 46.12, .37), (1.3, .76, .35), "led_green")
|
||||
for index, (x, y) in enumerate(((37.8, 36.6), (55.6, 42.0)), 1):
|
||||
a.box(f"Crystal {index} ceramic base", (x, y, .03), (3.2, 2.5, .2), "ceramic")
|
||||
a.box(f"Crystal {index} metal lid", (x + .1, y + .1, .23), (3.0, 2.3, .6), "shield")
|
||||
|
||||
# Small passives provide honest scale cues. These are representative package
|
||||
# positions, not an asserted electrical component map or hidden full netlist.
|
||||
passives = ((18.7, 34), (21.2, 34), (23.7, 34), (17, 37), (20, 37), (23, 37),
|
||||
(28, 37), (31, 37), (34, 37), (28, 40), (31, 40), (34, 40),
|
||||
(39, 16), (42, 16), (39, 12.5), (42, 12.5),
|
||||
(25, 8), (28, 8), (31, 8), (34, 8), (37, 8), (40, 8),
|
||||
(55.2, 28), (57.8, 30.5), (58, 32), (63, 30.5), (66, 30.5), (67, 34.5),
|
||||
(22, 43), (25, 43), (28, 43), (31, 43))
|
||||
for i, (x, y) in enumerate(passives, 1):
|
||||
a.box(f"Passive {i:02} ceramic", (x, y, .08), (1.2, .8, .52), "ceramic" if i % 3 else "package")
|
||||
a.box(f"Passive {i:02} termination A", (x - .25, y, .04), (.3, .8, .45), "solder")
|
||||
a.box(f"Passive {i:02} termination B", (x + 1.15, y, .04), (.3, .8, .45), "solder")
|
||||
|
||||
for i, (x, y) in enumerate(VIA_POSITIONS, 1):
|
||||
a.ring(f"Plated via {i:02}", (x, y, -1.65), .35, .225, 1.75, "gold")
|
||||
|
||||
|
||||
def commands(*, standalone: bool = False) -> list[dict]:
|
||||
"""Return all native commands; no file IO and no inferred session state."""
|
||||
a = BoardAuthor()
|
||||
a.add("component.activate", component="root")
|
||||
if standalone:
|
||||
a.add("solid.box", corner=list(ORIGIN), length=85, width=56, height=THICKNESS,
|
||||
operation="new", name=BOARD, body_name=BOARD)
|
||||
for i, (x, y) in enumerate(MOUNTING, 1):
|
||||
a.bore(BOARD, f"Fixture mounting bore {i}", (x, y, -1.8), 1.35, 2.0)
|
||||
a.add("component.create", name="Avionics", parent="root", activate=False)
|
||||
a.add("component.move_bodies", bodies=[BOARD], component="Avionics")
|
||||
a.add("occurrence.ground", occurrence="Avionics:1", grounded=True)
|
||||
else:
|
||||
a.add("solid.remove", bodies=PLACEHOLDERS, name="Pi5 retire block placeholders")
|
||||
|
||||
# Complete substrate machining in its own component before adding hundreds
|
||||
# of small parts. This also supports engines that scope cuts to the active
|
||||
# component even when the target body was explicitly named.
|
||||
a.add("component.activate", component="Avionics")
|
||||
a.add("solid.fillet", edges=[[ORIGIN[0] + x, ORIGIN[1] + y, ORIGIN[2] + THICKNESS / 2]
|
||||
for x, y in ((0, 0), (85, 0), (85, 56), (0, 56))],
|
||||
radius=CORNER_RADIUS, name="Pi5 PCB corner radii")
|
||||
for col in range(20):
|
||||
for row in range(2):
|
||||
pin = col * 2 + row + 1
|
||||
x, y = GPIO_FIRST[0] + GPIO_PITCH * col, GPIO_FIRST[1] + GPIO_PITCH * row
|
||||
a.bore(BOARD, f"GPIO substrate bore {pin:02}", (x, y, -1.8), .5, 2.0)
|
||||
for i, (x, y) in enumerate(VIA_POSITIONS, 1):
|
||||
a.bore(BOARD, f"Via substrate bore {i:02}", (x, y, -1.8), .35, 2.0)
|
||||
for family, y in (("USB2", 37.8), ("USB3", 19.8)):
|
||||
for tab, yy in enumerate((y + .9, y + 12.5), 1):
|
||||
a.cut_box(BOARD, f"{family} PCB anchor slot {tab}",
|
||||
(71.0, yy - .1, -1.8), (.85, 1.1, 2.0))
|
||||
a.add("component.activate", component="root")
|
||||
|
||||
a.add("material.create", name=SEMICONDUCTOR, density_g_cm3=2.33,
|
||||
color=[32, 35, 39])
|
||||
a.add("material.create", name=FR4, density_g_cm3=1.85, color=[31, 90, 51])
|
||||
_geometry(a)
|
||||
a.roles["mask"].append(BOARD)
|
||||
for role, bodies in a.roles.items():
|
||||
color, metallic, roughness, material = ROLES[role]
|
||||
a.add("material.assign", bodies=bodies, material=material)
|
||||
a.add("appearance.assign", bodies=bodies, color=list(color), opacity=1,
|
||||
pbr={"metallic": metallic, "roughness": roughness, "dielectric_ior": 1.5})
|
||||
a.add("component.create", name=COMPONENT, parent="root", activate=False)
|
||||
a.add("component.move_bodies", bodies=a.bodies, component=COMPONENT)
|
||||
a.add("joint.as_built", name="Pi5 componentry fixed to board", type="rigid",
|
||||
a="Avionics", b=COMPONENT, quiet=True)
|
||||
a.add("component.activate", component="root")
|
||||
return a.steps
|
||||
|
||||
|
||||
def standalone_commands() -> list[dict]:
|
||||
return commands(standalone=True)
|
||||
|
||||
|
||||
def manifest() -> dict:
|
||||
"""Return independent analytic interfaces and new-body inventory."""
|
||||
a = BoardAuthor()
|
||||
_geometry(a)
|
||||
board_volume = (85 * 56 - 4 * CORNER_RADIUS ** 2 * (1 - math.pi / 4)) * THICKNESS - math.pi * THICKNESS * (
|
||||
4 * 1.35 ** 2 + 40 * .5 ** 2 + 12 * .35 ** 2) - 4 * .85 * 1.1 * THICKNESS
|
||||
header_volume = 50.8 * 5.08 * 2.5 - 40 * .72 * .72 * 2.5
|
||||
return {
|
||||
"scope": "Original visual reconstruction; not a complete BOM or electrical design",
|
||||
"board": {"body": BOARD, "origin_mm": list(ORIGIN), "size_mm": [85, 56, THICKNESS],
|
||||
"corner_radius_mm": CORNER_RADIUS,
|
||||
"usb_anchor_slots": {"count": 4, "size_mm": [.85, 1.1]},
|
||||
"mounting_centres_local_mm": [list(p) for p in MOUNTING],
|
||||
"mounting_diameter_mm": 2.7, "fixture_volume_mm3": board_volume},
|
||||
"gpio": {"count": 40, "pitch_mm": GPIO_PITCH,
|
||||
"first_pin_local_mm": list(GPIO_FIRST), "pin_section_mm": [.64, .64],
|
||||
"substrate_bore_mm": 1.0, "insulator_bore_mm": .72,
|
||||
"insulator_volume_mm3": header_volume},
|
||||
"body_count": len(a.bodies), "body_names": a.bodies,
|
||||
"roles": dict(a.roles), "removed_placeholders": PLACEHOLDERS,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--out", type=Path, required=True)
|
||||
parser.add_argument("--standalone", action="store_true")
|
||||
parser.add_argument("--manifest", type=Path)
|
||||
args = parser.parse_args()
|
||||
args.out.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.out.write_text(json.dumps({"commands": commands(standalone=args.standalone)}, indent=2) + "\n")
|
||||
if args.manifest:
|
||||
args.manifest.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.manifest.write_text(json.dumps(manifest(), indent=2) + "\n")
|
||||
print(f"{len(commands(standalone=args.standalone))} commands; {manifest()['body_count']} new bodies")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export three actual native Design previews without saving over the master.
|
||||
|
||||
One bounded MCP process opens the complete model once, then changes only its
|
||||
transient visibility and camera. The product renderer is a separate workflow;
|
||||
these images deliberately document the Design renderer used in the response.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
import presentation
|
||||
from validate_native import NativeMcp, digest, require
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--cli", type=Path, required=True)
|
||||
parser.add_argument("--model", type=Path, required=True)
|
||||
parser.add_argument("--out", type=Path, required=True)
|
||||
parser.add_argument("--width", type=int, default=1400)
|
||||
parser.add_argument("--height", type=int, default=1000)
|
||||
args = parser.parse_args()
|
||||
require(320 <= args.width <= 2400 and 240 <= args.height <= 1800, "Preview dimensions out of bounds")
|
||||
cli, model, output = args.cli.resolve(), args.model.resolve(), args.out.resolve()
|
||||
require(cli.is_file() and model.is_file(), "Missing executable or native master")
|
||||
require(not output.exists(), "Use a fresh output directory; existing previews are never overwritten")
|
||||
output.mkdir(parents=True)
|
||||
before = digest(model)
|
||||
report = {
|
||||
"status": "in_progress", "source_model_sha256": before, "cli_sha256": digest(cli),
|
||||
"started_at": datetime.now(timezone.utc).isoformat(), "images": [],
|
||||
"scope": "Actual native Design previews. No product PBR, path tracing or physical optical claim.",
|
||||
}
|
||||
native = None
|
||||
try:
|
||||
print("Opening the complete native master once for three previews", flush=True)
|
||||
native = NativeMcp(cli, model, output, timeout=600, startup_timeout=1200)
|
||||
inventory = native.tool("inspect_design", {"measure": False, "sketches": False, "joints": False})
|
||||
issues = [f for f in inventory.get("timeline", []) if f.get("error") or f.get("warning")]
|
||||
require(not issues and inventory.get("bodies"), "Native model has no bodies or an unhealthy timeline")
|
||||
report["evaluated_bodies"] = len(inventory["bodies"])
|
||||
shots = [
|
||||
("whole", "SELENE-overview.png", presentation.camera("Whole rover")),
|
||||
("electronics", "SELENE-electronics.png", presentation.camera("Electronics")),
|
||||
("bearing", "SELENE-bearing.png", {
|
||||
"target": [242, -7, 281], "yaw": -.18, "pitch": .30, "distance": 27, "fov": 0,
|
||||
}),
|
||||
]
|
||||
for profile, filename, camera in shots:
|
||||
print(f"Rendering native Design preview: {profile}", flush=True)
|
||||
for command in presentation.visibility_commands(inventory, profile):
|
||||
native.tool("execute", {**command, "verbose": False})
|
||||
reply = native.request("tools/call", {"name": "screenshot", "arguments": {
|
||||
"source": "model", "width": args.width, "height": args.height,
|
||||
"camera": camera, "grid": False, "axes": False,
|
||||
}})
|
||||
texts = [item.get("text", "") for item in reply.get("content", []) if item.get("type") == "text"]
|
||||
require(not reply.get("isError"), "Native screenshot failed: " + " ".join(texts))
|
||||
pictures = [item for item in reply.get("content", []) if item.get("type") == "image"]
|
||||
require(len(pictures) == 1 and pictures[0].get("mimeType") == "image/png", "Expected one PNG")
|
||||
png = base64.b64decode(pictures[0]["data"], validate=True)
|
||||
require(png[:8] == b"\x89PNG\r\n\x1a\n" and len(png) > 33, "Invalid PNG header")
|
||||
dimensions = struct.unpack(">II", png[16:24])
|
||||
require(dimensions == (args.width, args.height), "Unexpected native preview dimensions")
|
||||
(output / filename).write_bytes(png)
|
||||
report["images"].append({
|
||||
"file": filename, "profile": profile, "camera": camera,
|
||||
"width": dimensions[0], "height": dimensions[1], "bytes": len(png),
|
||||
"sha256": hashlib.sha256(png).hexdigest(),
|
||||
"native_capture_metadata": [json.loads(t) for t in texts],
|
||||
})
|
||||
report["status"] = "passed"
|
||||
except (OSError, ValueError, KeyError, TypeError, RuntimeError, TimeoutError) as error:
|
||||
report["status"] = "failed"
|
||||
report["error"] = str(error)
|
||||
finally:
|
||||
if native is not None:
|
||||
native.close()
|
||||
report["source_model_unchanged"] = digest(model) == before
|
||||
if not report["source_model_unchanged"]:
|
||||
report["status"] = "failed"
|
||||
report["finished_at"] = datetime.now(timezone.utc).isoformat()
|
||||
(output / "export-report.json").write_text(json.dumps(report, indent=2, allow_nan=False) + "\n")
|
||||
print(json.dumps({"status": report["status"], "images": len(report["images"]),
|
||||
"model_unchanged": report["source_model_unchanged"], "report": str(output / "export-report.json")}), flush=True)
|
||||
return 0 if report["status"] == "passed" else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Assign physical proxies and opaque PBR finishes through native commands.
|
||||
|
||||
The author's palette is retained. Density describes an explicitly simplified
|
||||
part material, not a verified rover mass budget. Optical glass remains separate
|
||||
from the opaque PBR contract. No serialized design state is rewritten.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
SOURCE_SHA256 = "1b0df486f30da157db27a33e0b5ed67f13d527d4dfdc6c334717a1df4e5b8677"
|
||||
|
||||
|
||||
def command(command_id: str, **params: object) -> dict:
|
||||
return {"command": command_id, "params": params}
|
||||
|
||||
|
||||
CUSTOM_MATERIALS = {
|
||||
"SELENE elastomer proxy": (1.20, [30, 35, 41]),
|
||||
"SELENE FR4 proxy": (1.85, [39, 104, 72]),
|
||||
"SELENE silicon proxy": (2.33, [29, 66, 107]),
|
||||
"SELENE rock proxy": (2.80, [122, 118, 110]),
|
||||
}
|
||||
|
||||
|
||||
def material_for(name: str) -> str:
|
||||
n = name.lower()
|
||||
if any(s in n for s in ("glass sample", "glass vial", "lens glass", "searchlight glass")):
|
||||
return "Glass"
|
||||
if any(s in n for s in ("tpu wheel", "tread grouser", "flexible hose", "battery strap", "bumper")):
|
||||
return "SELENE elastomer proxy"
|
||||
if any(s in n for s in ("raspberry pi", "management pcb", "driver and power pcb")):
|
||||
return "SELENE FR4 proxy"
|
||||
if "photovoltaic tile" in n:
|
||||
return "SELENE silicon proxy"
|
||||
if any(s in n for s in ("basalt", "sample material", "track ")):
|
||||
return "SELENE rock proxy"
|
||||
if any(s in n for s in ("contact", "terminal", "rf connector", "retention sleeve")):
|
||||
return "Brass"
|
||||
if any(s in n for s in ("shank", "screw", "locknut", "washer", "shaft", "bearing", "spring", "pin ", "pin cap", "grub", "rod ", "piston", "whip")):
|
||||
return "Steel"
|
||||
if any(s in n for s in ("diffuser", "led lens", "led element", "led package", "envelope", "end cap", "cell wrapper", "cradle", "tray", "motor lead", "battery retainer", "light pipe")):
|
||||
return "ABS Plastic"
|
||||
return "Aluminum"
|
||||
|
||||
|
||||
def optical_for(name: str, material: str, original: dict) -> tuple:
|
||||
n = name.lower()
|
||||
rgb = tuple(original.get("color", [146, 159, 174]))
|
||||
opacity = 1.0
|
||||
if any(s in n for s in ("glass sample", "glass vial")):
|
||||
return rgb, 0.30, None
|
||||
if any(s in n for s in ("lens glass", "searchlight glass", "underbody led diffuser")):
|
||||
return rgb, 0.46, None
|
||||
metallic, roughness = 0.0, 0.48
|
||||
if material == "SELENE elastomer proxy":
|
||||
roughness = 0.79
|
||||
elif material == "SELENE rock proxy":
|
||||
roughness = 0.93
|
||||
elif material == "Steel":
|
||||
metallic, roughness = 1.0, 0.28
|
||||
elif material == "Brass":
|
||||
metallic, roughness = 1.0, 0.30
|
||||
elif material == "Aluminum":
|
||||
metallic, roughness = 1.0, 0.32
|
||||
elif material == "SELENE silicon proxy":
|
||||
metallic, roughness = 0.14, 0.22
|
||||
elif material == "SELENE FR4 proxy":
|
||||
roughness = 0.44
|
||||
if rgb == (233, 137, 53):
|
||||
metallic, roughness = 0.0, 0.39
|
||||
elif rgb == (38, 49, 61) and material in ("Aluminum", "Steel"):
|
||||
metallic, roughness = 0.22, 0.49
|
||||
if "led" in n or "lamp" in n:
|
||||
roughness = 0.25 if material == "ABS Plastic" else roughness
|
||||
return rgb, opacity, (metallic, roughness, 1.5)
|
||||
|
||||
|
||||
def commands(inventory: dict, source_document: dict) -> list[dict]:
|
||||
bodies = inventory["bodies"]
|
||||
names = [body["name"] for body in bodies]
|
||||
if len(names) != len(set(names)):
|
||||
raise ValueError("Evaluated body names must be unique.")
|
||||
original = source_document.get("appearances", {}).get("bodies", {})
|
||||
result = [command("component.activate", component="root")]
|
||||
for name, (density, color) in CUSTOM_MATERIALS.items():
|
||||
result.append(command("material.create", name=name, density_g_cm3=density, color=color))
|
||||
physical: dict[str, list[str]] = defaultdict(list)
|
||||
optical: dict[tuple, list[str]] = defaultdict(list)
|
||||
for name in names:
|
||||
material = material_for(name)
|
||||
physical[material].append(name)
|
||||
# Pattern copies inherit their seed's established tyre/grouser identity.
|
||||
look = original.get(name, {})
|
||||
if not look and name.startswith("Tread grouser"):
|
||||
look = {"color": [32, 41, 52]}
|
||||
optical[optical_for(name, material, look)].append(name)
|
||||
for material, targets in sorted(physical.items()):
|
||||
result.append(command("material.assign", bodies=targets, material=material))
|
||||
for (color, opacity, pbr), targets in optical.items():
|
||||
params = {"bodies": targets, "color": list(color), "opacity": opacity}
|
||||
if pbr is not None:
|
||||
params["pbr"] = dict(zip(("metallic", "roughness", "dielectric_ior"), pbr))
|
||||
result.append(command("appearance.assign", **params))
|
||||
hidden = [name for name in names if name.startswith("Track ") or "flexible hose" in name.lower()]
|
||||
result.append(command("browser.visibility", items=hidden, visible=False))
|
||||
for folder in ("sketches", "joints", "origin"):
|
||||
result.append(command("browser.visibility", folder=folder, visible=False))
|
||||
result.append(command("document.metadata.set", values={
|
||||
"project": "SELENE render and mechanism showcase",
|
||||
"part_number": "SELENE-FUNCTIONAL",
|
||||
"revision": "1.0",
|
||||
"description": "Enhanced native assembly based on the author-supplied SELENE showcase. See repository validation and scope notes.",
|
||||
"io.tangency.selene": {
|
||||
"source_sha256": SOURCE_SHA256,
|
||||
"source_commit": "32ec1720447e3fcc6bb6cc53a63fb5b39cfa21b9",
|
||||
"units": "mm", "up_axis": "+Z",
|
||||
"physical_scope": "Nominal material-density proxies; not a verified manufacturing BOM or mass budget.",
|
||||
"electronics_scope": "Visual mechanical reconstruction; not an electrically functional PCB.",
|
||||
},
|
||||
}))
|
||||
return result
|
||||
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Native SELENE joints, gripper geometry and inspection studies.
|
||||
|
||||
All public command angles are degrees and all lengths are millimetres. The
|
||||
author's native document remains the input; this module never edits its JSON.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
|
||||
def c(command: str, **params: object) -> dict:
|
||||
return {"command": command, "params": params}
|
||||
|
||||
|
||||
WHEEL_JOINTS = [f"Wheel axis {side}:{x}" for side in (-1, 1) for x in (-90, 0, 90)]
|
||||
DRIVERS = [
|
||||
WHEEL_JOINTS[0], "Port solar tilt articulation",
|
||||
"Turret azimuth articulation", "Turret elevation articulation",
|
||||
"Arm azimuth articulation", "Shoulder articulation", "Elbow articulation",
|
||||
"Wrist articulation", "Tool tilt articulation", "Dish azimuth articulation",
|
||||
"Dish elevation articulation", "Vial cap thread",
|
||||
]
|
||||
LIMITS = {
|
||||
"Turret azimuth articulation": (-135, 135),
|
||||
"Turret elevation articulation": (-25, 45),
|
||||
"Dish azimuth articulation": (-120, 120),
|
||||
"Dish elevation articulation": (-35, 40),
|
||||
"Arm azimuth articulation": (-45, 45),
|
||||
"Shoulder articulation": (-35, 15),
|
||||
"Elbow articulation": (-30, 55),
|
||||
"Wrist articulation": (-45, 45),
|
||||
"Tool tilt articulation": (-45, 45),
|
||||
"Port solar tilt articulation": (0, 30),
|
||||
"Starboard solar tilt articulation": (-30, 0),
|
||||
"Vial cap thread": (0, 1440),
|
||||
}
|
||||
GRIPPER_DRIVER = "SELENE gripper jaw -1 articulation"
|
||||
GRIPPER_FOLLOWER = "SELENE gripper jaw 1 articulation"
|
||||
|
||||
|
||||
def ring(name: str, point: list, axis: list, outer: float, inner: float, height: float) -> list[dict]:
|
||||
"""An annular profile avoids a nearly coincident post-extrusion bore."""
|
||||
if axis == [0, 0, 1]:
|
||||
xd, yd = [1, 0, 0], [0, 1, 0]
|
||||
elif axis == [0, 1, 0]:
|
||||
xd, yd = [1, 0, 0], [0, 0, -1]
|
||||
elif axis == [0, -1, 0]:
|
||||
xd, yd = [1, 0, 0], [0, 0, 1]
|
||||
else:
|
||||
raise ValueError("Only the fixture's axial directions are supported.")
|
||||
return [
|
||||
c("sketch.create", name=name + " profile", plane={"origin": point, "x_dir": xd, "y_dir": yd}),
|
||||
c("sketch.circle.center", center=[0, 0], radius=outer),
|
||||
c("sketch.circle.center", center=[0, 0], radius=inner),
|
||||
c("sketch.constraint.fix", entities=["c1", "c2"], fixed=True),
|
||||
c("sketch.finish"),
|
||||
c("solid.extrude", sketch=name + " profile", profiles=[{"point": [(inner + outer) / 2, 0]}],
|
||||
distance=height, operation="new", name=name + " extrusion", body_name=name),
|
||||
]
|
||||
|
||||
|
||||
def polygon(name: str, points: list, z: float, height: float) -> list[dict]:
|
||||
return [
|
||||
c("sketch.create", name=name + " profile", plane="XY", offset=z),
|
||||
c("sketch.line", points=points, closed=True, infer=False),
|
||||
c("sketch.constraint.fix", entities=[f"l{i+1}" for i in range(len(points))], fixed=True),
|
||||
c("sketch.finish"),
|
||||
c("solid.extrude", sketch=name + " profile", distance=height, operation="new",
|
||||
name=name + " extrusion", body_name=name),
|
||||
]
|
||||
|
||||
|
||||
def primary_commands() -> list[dict]:
|
||||
result = [c("component.activate", component="root")]
|
||||
for joint in DRIVERS:
|
||||
result.append(c("joint.drive", joint=joint, value=0, quiet=True))
|
||||
# Independent sensor pointing: the original tour's illustrative gear is not a drivetrain.
|
||||
result.append(c("joint.delete", link=7))
|
||||
result.append(c("joint.rack_pinion", a=WHEEL_JOINTS[0], b="Track slide", radius=40, reverse=True, link=6, quiet=True))
|
||||
for joint, (low, high) in LIMITS.items():
|
||||
result.append(c("joint.limits", joint=joint, min=low, max=high))
|
||||
# These solid pieces transmit wheel torque, so they belong to the rotating wheel.
|
||||
for side in (-1, 1):
|
||||
for x in (-90, 0, 90):
|
||||
suffix = f"{side}:{x}"
|
||||
result.append(c("component.move_bodies", component=f"Wheel {suffix}", bodies=[
|
||||
f"4mm D output shaft {suffix}", f"Clamping hub barrel {suffix}",
|
||||
f"Hub grub screw {suffix}", f"Hub flange {suffix}",
|
||||
]))
|
||||
# Each jaw becomes an actual moving component. The fixed M3 pins stay in the crosshead.
|
||||
result.append(c("component.from_bodies", bodies=["Gripper jaw -1", "Gripper jaw 1"]))
|
||||
for side in (-1, 1):
|
||||
component = f"Gripper jaw {side}"
|
||||
result.append(c("component.activate", component=component))
|
||||
sleeve = f"SELENE gripper plain sleeve {side}"
|
||||
result.extend(ring(sleeve, [443, side * 9, 247], [0, 0, 1], 1.70, 1.55, 5))
|
||||
# Rubber pad on the sloped inner gripping surface, inset one millimetre at each end.
|
||||
a, b = [459.0, 17 - 6 / 11], [468.0, 11 + 6 / 11]
|
||||
norm = math.hypot(11, 6)
|
||||
delta = [-0.75 * 6 / norm, -0.75 * 11 / norm]
|
||||
pts = [a, b, [b[0] + delta[0], b[1] + delta[1]], [a[0] + delta[0], a[1] + delta[1]]]
|
||||
pts = [[x, side * y] for x, y in pts]
|
||||
pad = f"SELENE gripper contact pad {side}"
|
||||
result.extend(polygon(pad, pts, 248, 3))
|
||||
result.extend([
|
||||
c("material.assign", bodies=[sleeve], material="Brass"),
|
||||
c("appearance.assign", bodies=[sleeve], color=[195, 157, 80], pbr={"metallic": 1, "roughness": .30, "dielectric_ior": 1.5}),
|
||||
c("material.assign", bodies=[pad], material="SELENE elastomer proxy"),
|
||||
c("appearance.assign", bodies=[pad], color=[26, 30, 35], pbr={"metallic": 0, "roughness": .78, "dielectric_ior": 1.5}),
|
||||
c("joint.as_built", type="revolute", a="Gripper tool", b=component,
|
||||
at={"occurrence": "Gripper tool", "point": [443, side * 9, 249.5], "z": [0, 0, 1]},
|
||||
name=f"SELENE gripper jaw {side} articulation", limits=[[-15, 18] if side == -1 else [-18, 15]], quiet=True),
|
||||
])
|
||||
result.extend([
|
||||
c("joint.motion_link", a=GRIPPER_DRIVER, b=GRIPPER_FOLLOWER, ratio=-1, offset=0, quiet=True),
|
||||
c("component.activate", component="root"),
|
||||
])
|
||||
return result
|
||||
|
||||
|
||||
def study_commands(include_suspension: bool = False) -> list[dict]:
|
||||
drivers = DRIVERS + [GRIPPER_DRIVER]
|
||||
hinges = [f"SELENE suspension hinge {side}:{x}" for side in (-1, 1) for x in (-90, 0, 90)]
|
||||
if include_suspension:
|
||||
drivers += hinges
|
||||
poses = {
|
||||
"Drivetrain inspection": {WHEEL_JOINTS[0]: 360},
|
||||
"Solar deployment": {"Port solar tilt articulation": 30},
|
||||
"Arm articulation": {"Arm azimuth articulation": 18, "Shoulder articulation": -18,
|
||||
"Elbow articulation": 30, "Wrist articulation": -10, "Tool tilt articulation": 15},
|
||||
"Gripper inspection": {GRIPPER_DRIVER: 18},
|
||||
"Independent sensor pointing": {"Turret azimuth articulation": 30, "Turret elevation articulation": 15,
|
||||
"Dish azimuth articulation": -25, "Dish elevation articulation": 20},
|
||||
"Sample cap inspection": {"Vial cap thread": 720},
|
||||
}
|
||||
if include_suspension:
|
||||
poses["Suspension travel inspection"] = {name: -4 for name in hinges}
|
||||
result = []
|
||||
for name, goals in poses.items():
|
||||
keys = [{"joint": joint, "points": [[0, 0], [30, 0], [80, goals.get(joint, 0)], [100, goals.get(joint, 0)], [120, 0]]}
|
||||
for joint in drivers]
|
||||
result.append(c("motion.study", name="SELENE - " + name, steps=120, keys=keys))
|
||||
return result
|
||||
|
||||
|
||||
def adapted_author_tour(source_document: dict) -> dict:
|
||||
study = source_document["assembly"]["studies"][0]
|
||||
joints = {j["id"]: j for j in source_document["assembly"]["joints"]}
|
||||
keys = []
|
||||
for key in study["keys"]:
|
||||
joint = joints[key["joint"]]
|
||||
angular = joint["kind"] in ("revolute", "cylindrical") and key.get("index", 0) == 0
|
||||
points = [[step, math.degrees(value) if angular else value] for step, value in key["points"]]
|
||||
if joint["name"] in LIMITS:
|
||||
low, high = LIMITS[joint["name"]]
|
||||
points = [[step, min(high, max(low, value))] for step, value in points]
|
||||
keys.append({"joint": joint["name"], "index": key.get("index", 0), "points": points})
|
||||
return c("motion.study", study=study["id"], name="SELENE - Legacy author tour (adapted limits)", steps=120, keys=keys)
|
||||
|
||||
|
||||
def suspension_stroke(angle_deg: float) -> float:
|
||||
t = math.radians(angle_deg)
|
||||
return math.hypot(35 * math.cos(t) - 20 * math.sin(t) - 35,
|
||||
-35 * math.sin(t) - 20 * math.cos(t) - 2) - 22
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user