docs: propose extensible material, appearance and component libraries (#792)
This commit is contained in:
1 parent
a2c7396160
commit
09b5da3e9f
3 files changed
+203
No files matched your search
+10
@@ -59,6 +59,16 @@ PCB / Package, Render, Animation, Simulation, Manufacture/CAM, Drawings.
|
|||||||
| M14 | Configurations: a table of rows (parameter expressions and feature suppressions per row) switched with config.activate (undoable, all or nothing), kept through parameter renames and feature deletes (config.configure, config.table, config.column/row/activate). Per-row body materials and appearances (library looks, custom colour/opacity and clearing overrides), undoable activation and save/reopen: done. Ordered typed configuration rules, atomic validation and structured rule editing: done. Component appearance and certified semantic face style columns, atomic preview/apply and independent-copy remapping: done. Exact constructed sketch-side and immutable imported-face lineage now preserve legacy names and reject retargeting. Left: ambiguous shifted/two-sided caps | in progress | 4 |
|
| M14 | Configurations: a table of rows (parameter expressions and feature suppressions per row) switched with config.activate (undoable, all or nothing), kept through parameter renames and feature deletes (config.configure, config.table, config.column/row/activate). Per-row body materials and appearances (library looks, custom colour/opacity and clearing overrides), undoable activation and save/reopen: done. Ordered typed configuration rules, atomic validation and structured rule editing: done. Component appearance and certified semantic face style columns, atomic preview/apply and independent-copy remapping: done. Exact constructed sketch-side and immutable imported-face lineage now preserve legacy names and reject retargeting. Left: ambiguous shifted/two-sided caps | in progress | 4 |
|
||||||
| M13 | Never lose work: atomic saves (temporary file, flush, rename; a crash at any moment leaves the old file or the new one) with the replaced version kept as `<file>.bak`; autosave of unsaved changes to the recovery folder every 5 minutes (preference) and after big operations, only when something changed; "Recover unsaved design?" on the next launch (`doc.recovery_list`, `doc.recover`, `doc.recovery_discard`); a kill-mid-save test (process killed while saving a 0.5 MB design 25 times). File format: `"format": "solidcraft/12"`, older formats upgraded step by step (`doc::format`), newer ones refused with a message, out-of-range numbers and broken placements refused; a corpus of designs saved by M0, components-era, joints-era and current builds (apps/solidcraft-cli/tests/corpus) that must open and evaluate as saved; damaged and hostile variants (truncation, bit flips, hostile values, removed keys, repeated features, deep nesting) never panic | done | 6 |
|
| M13 | Never lose work: atomic saves (temporary file, flush, rename; a crash at any moment leaves the old file or the new one) with the replaced version kept as `<file>.bak`; autosave of unsaved changes to the recovery folder every 5 minutes (preference) and after big operations, only when something changed; "Recover unsaved design?" on the next launch (`doc.recovery_list`, `doc.recover`, `doc.recovery_discard`); a kill-mid-save test (process killed while saving a 0.5 MB design 25 times). File format: `"format": "solidcraft/12"`, older formats upgraded step by step (`doc::format`), newer ones refused with a message, out-of-range numbers and broken placements refused; a corpus of designs saved by M0, components-era, joints-era and current builds (apps/solidcraft-cli/tests/corpus) that must open and evaluate as saved; damaged and hostile variants (truncation, bit flips, hostile values, removed keys, repeated features, deep nesting) never panic | done | 6 |
|
||||||
|
|
||||||
|
## Library foundations (#785, #786, #787)
|
||||||
|
|
||||||
|
- Proposed phases cover offline bundled/project/user packs, physical materials and
|
||||||
|
appearances, editable wood mapping, and parameterized component/assembly families.
|
||||||
|
Stable identity/revision, copied design definitions, provenance and resource limits
|
||||||
|
apply from the first implementation. Existing material, appearance and standard-part
|
||||||
|
commands remain the application paths. See [the proposal](docs/book/src/dev/libraries.md)
|
||||||
|
for source/license review and acceptance gates. This is planning only: pack loading,
|
||||||
|
texture rendering and expanded component families are not implemented by this entry.
|
||||||
|
|
||||||
## Render foundation
|
## Render foundation
|
||||||
|
|
||||||
- A bounded cooperative Radiance RGBE input utility is available in L1 render;
|
- A bounded cooperative Radiance RGBE input utility is available in L1 render;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
- [Contributing](dev/contributing.md)
|
- [Contributing](dev/contributing.md)
|
||||||
- [Architecture](dev/architecture.md)
|
- [Architecture](dev/architecture.md)
|
||||||
|
- [Extensible library proposal](dev/libraries.md)
|
||||||
- [The command engine](dev/commands.md)
|
- [The command engine](dev/commands.md)
|
||||||
- [The kernel boundary and truck](dev/kernel.md)
|
- [The kernel boundary and truck](dev/kernel.md)
|
||||||
- [Persistent naming](dev/naming.md)
|
- [Persistent naming](dev/naming.md)
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
# Extensible libraries: materials, appearances and components
|
||||||
|
|
||||||
|
Proposal for [#785](https://github.com/bherbruck/solidcraft/issues/785),
|
||||||
|
[#786](https://github.com/bherbruck/solidcraft/issues/786) and
|
||||||
|
[#787](https://github.com/bherbruck/solidcraft/issues/787). This page describes planned
|
||||||
|
contracts and acceptance gates, not an implemented pack format or new commands. It does
|
||||||
|
not bring the deferred Simulation or Render workspaces into scope.
|
||||||
|
|
||||||
|
## Reuse the existing paths
|
||||||
|
|
||||||
|
Physical materials already have built-in densities and design-local definitions
|
||||||
|
(`material.create`, `material.edit`, `material.delete`, `material.list`, `material.assign`).
|
||||||
|
They drive `component.properties`, survive reopening and participate in configurations.
|
||||||
|
Appearances have a built-in color/opacity library and body, face and component overrides.
|
||||||
|
`parts.library`, `parts.insert` and `parts.resize` already generate seven families of
|
||||||
|
fasteners, pins and bearing envelopes as editable components.
|
||||||
|
|
||||||
|
Extend those routes. A shared catalog supplies identity, discovery and provenance;
|
||||||
|
each entry kind retains its own payload and application rules. A physical material is
|
||||||
|
not a texture, and a reusable component is not executable plugin code.
|
||||||
|
|
||||||
|
## Portable, independently extensible packs
|
||||||
|
|
||||||
|
Use one versioned, offline pack envelope for three kinds: physical material, appearance
|
||||||
|
and component family. Both project contributors and users can author packs without
|
||||||
|
rebuilding SolidCraft. Start with a directory and JSON manifest, not a new archive format
|
||||||
|
or an online marketplace. The exact schema belongs in the bounded-loader PR, accompanied
|
||||||
|
by machine-checked examples; the following are its design requirements:
|
||||||
|
|
||||||
|
| Record | Required meaning |
|
||||||
|
|---|---|
|
||||||
|
| Pack | Schema version, stable namespaced ID, immutable revision, display name, author, source and license metadata |
|
||||||
|
| Entry | ID scoped to its pack, immutable revision, kind, label, category/tags, typed payload and per-entry provenance |
|
||||||
|
| Resource | Relative path, content digest, byte count, media role, author, source, license and included license text where required |
|
||||||
|
| Dependency | Explicit entry/revision reference; bounded acyclic resolution within explicitly selected packs |
|
||||||
|
| Selection | Pack ID + entry ID + exact revision; labels and filesystem paths are not identities |
|
||||||
|
|
||||||
|
Pack revisions and schema versions are different: the former identifies content, the
|
||||||
|
latter describes how to read it. Changing content under an existing revision is an error.
|
||||||
|
Unknown schema versions, entry kinds and required capabilities produce a clear refusal;
|
||||||
|
they are never silently interpreted as an older format. Optional extensions need an
|
||||||
|
explicit namespace and preservation rules before being accepted.
|
||||||
|
|
||||||
|
Provide three independent scopes:
|
||||||
|
|
||||||
|
- **Bundled:** reviewed with SolidCraft and read-only in the library editor.
|
||||||
|
- **Project:** packs explicitly opened for the current project/team; never discovered
|
||||||
|
by silently executing or trusting files beside a design.
|
||||||
|
- **User:** local packs the user creates, imports, edits or exports. Native file access
|
||||||
|
belongs in the app; browser users import/export through the web storage/file workflow.
|
||||||
|
|
||||||
|
Discovery order is deterministic. Duplicate labels can coexist, with their source shown.
|
||||||
|
Duplicate qualified identities/revisions with different contents are errors, not overrides
|
||||||
|
chosen by scan order. Editing a bundled entry uses **Save a copy** into a user namespace.
|
||||||
|
Updating a pack is explicit and leaves existing design instances unchanged.
|
||||||
|
|
||||||
|
## Designs own their selected definitions
|
||||||
|
|
||||||
|
On assignment/insertion, copy the definition, chosen revision, parameters, provenance and
|
||||||
|
required resource bytes into the design's existing container/resource mechanism. Keep the
|
||||||
|
source identity for inspection and an eventual explicit Update action. A saved design must
|
||||||
|
open, rebuild and render the supported appearance without the original pack, network or
|
||||||
|
another user's home directory. Installing a pack never changes a design or undo history.
|
||||||
|
|
||||||
|
Assignment/insertion/update is a normal engine command, atomic and undoable. Preview is
|
||||||
|
non-mutating. A failed import, unresolved dependency, name collision or unsupported recipe
|
||||||
|
leaves the document and undo/redo stacks intact. Existing material names and appearance
|
||||||
|
precedence retain their legacy meaning; introduce stable IDs through a documented migration
|
||||||
|
rather than reinterpret old name-based assignments. Design-format changes need their own
|
||||||
|
version/migration and reopen tests, separate from the pack schema version.
|
||||||
|
|
||||||
|
## Physical properties (#785)
|
||||||
|
|
||||||
|
Keep physical material and appearance selection independent, with an optional default look.
|
||||||
|
Convert imported density units explicitly to the existing g/cm³ representation; geometry
|
||||||
|
continues to use millimetres and radians. Never infer units from magnitudes. Properties
|
||||||
|
need source, edition/date, grade, processing condition and applicable temperature/moisture
|
||||||
|
when relevant. Unknown properties stay unknown, not zero or guessed values.
|
||||||
|
|
||||||
|
Start with density and mass integration through the existing commands. Reserve typed
|
||||||
|
extensions for elastic constants, yield/ultimate strength, thermal properties and
|
||||||
|
orthotropic axes, but do not expose these as FEA-ready until their model, units and
|
||||||
|
validation are implemented. A generic wood density is not an engineering material grade.
|
||||||
|
User-measured data can be stored with its own provenance and edited without changing the
|
||||||
|
bundled library.
|
||||||
|
|
||||||
|
## Wood and sheet appearances (#786)
|
||||||
|
|
||||||
|
Begin with body-local mapping, an explicit physical repeat size and a user-editable grain
|
||||||
|
frame. Suggest the longest **local** body-bound axis once, with X/Y/Z order for equal
|
||||||
|
extents; store the chosen frame rather than recompute it on every resize. Manual rotation
|
||||||
|
and scale survive parameter rebuilds, instance placement, undo and reopening. Shared
|
||||||
|
component instances transform the same definition-local mapping with their placement.
|
||||||
|
Non-finite or degenerate frames refuse; automatic choice remains a suggestion.
|
||||||
|
|
||||||
|
Visual grain does not rotate the body, its geometric bounding box or a manufacturing
|
||||||
|
stock frame. Structural grain direction and grain-aware nesting/cut lists are distinct
|
||||||
|
features, coordinated with [#137](https://github.com/bherbruck/solidcraft/issues/137).
|
||||||
|
An anisotropic shading effect also does not imply mechanical anisotropy.
|
||||||
|
|
||||||
|
After basic wood mapping, add sheet-specific top/bottom/edge looks: MDF, chipboard,
|
||||||
|
plywood and compact laminate, then melamine, laminate, linoleum and veneer finishes.
|
||||||
|
Appearance layers initially describe presentation only. Physical finish thickness or
|
||||||
|
mass must be explicit modelling/material inputs, never an invisible side effect of paint.
|
||||||
|
Face/edge assignments require durable identities and must refuse a lost association
|
||||||
|
rather than paint a nearby replacement face.
|
||||||
|
|
||||||
|
Keep texture role, color space, normal-map convention and physical scale explicit.
|
||||||
|
Coordinate with the [render capability contract](https://github.com/bherbruck/solidcraft/blob/main/docs/render-backends.md):
|
||||||
|
the existing color/opacity viewport is not proof of PBR or texture support. A renderer
|
||||||
|
must report what it supports; unavailable maps use a documented preview fallback with
|
||||||
|
a visible notice. Export either preserves supported mapping/resources or reports loss.
|
||||||
|
|
||||||
|
## Standard and user component families (#787)
|
||||||
|
|
||||||
|
Keep the existing fastener insertion/resize path. Add original parameterized BAR, SHS,
|
||||||
|
RHS and CHS recipes first, with explicit length units, parameter bounds, section frames
|
||||||
|
and insertion/connection frames. Validate wall thickness against the outer size and
|
||||||
|
state whether corners are sharp or rounded. Do not label approximate geometry as a
|
||||||
|
certified standard section. UB/UC need actual flange/web radii and tapers; identifying a
|
||||||
|
standard does not grant redistribution rights to its published size tables.
|
||||||
|
|
||||||
|
A family revision defines a bounded parameter schema, permitted recipe and optional
|
||||||
|
reviewed size table. A size designation identifies a row, not an arbitrary filename.
|
||||||
|
Changing size rebuilds the same component identity and preserves supported connections.
|
||||||
|
Initial recipes must use a small allowlist of ordinary modelling operations. No embedded
|
||||||
|
native code, shell commands, scripts, arbitrary command IDs or network hooks. Reject
|
||||||
|
cycles, excessive expansion and unsupported operations before mutating the design.
|
||||||
|
|
||||||
|
Custom assemblies follow single components: bounded dependencies, named connection
|
||||||
|
frames, explicit shared/independent instance semantics and one-step insertion undo.
|
||||||
|
Store selected parameters and definition snapshots so missing or changed catalogs cannot
|
||||||
|
silently substitute another part. Geometric envelope models, including existing bearing
|
||||||
|
envelopes, must remain distinguishable from detailed/manufacturing-ready models.
|
||||||
|
|
||||||
|
## Sources and licensing
|
||||||
|
|
||||||
|
SolidCraft is MIT OR Apache-2.0. Code and generated recipes must follow the clean-room
|
||||||
|
rules; never copy commercial CAD materials, templates, geometry, icons or catalogs.
|
||||||
|
Third-party assets retain their own licenses. Every bundled resource needs its author,
|
||||||
|
source, license and `ATTRIBUTION.md` row, even if attribution is optional under CC0.
|
||||||
|
Record hashes and retrieval dates when admitting actual files. A manifest's claimed
|
||||||
|
license is provenance to review, not automatic evidence of permission.
|
||||||
|
|
||||||
|
Sources checked on 2026-10-13; no external assets or datasets are bundled by this proposal:
|
||||||
|
|
||||||
|
| Source | Suitable use / admission condition |
|
||||||
|
|---|---|
|
||||||
|
| [ambientCG license](https://docs.ambientcg.com/license/) | Downloadable assets and material preview renders are CC0. Candidate wood/sheet texture source; choose and attribute individual files. |
|
||||||
|
| [Poly Haven license](https://polyhaven.com/license) | Assets are CC0. Site text, logos and other site content have separate rights; API access has separate terms. Do not copy provider implementation code. |
|
||||||
|
| [Wikidata structured-data license](https://www.wikidata.org/wiki/Wikidata:Copyright) | Structured entity/property data are CC0; other page text has different terms. Candidate for individual referenced quantities and identifiers, not unverified engineering-grade defaults. Preserve the underlying measurement references, qualifiers and units. |
|
||||||
|
| [USDA Wood Handbook, revised 2021](https://research.fs.usda.gov/fpl/wood-handbook) | Reference for moisture, physical and mechanical wood properties. Verify the specific table's rights, species, units and conditions before importing data; no wholesale dataset approval is implied. |
|
||||||
|
| [NIST data/publication rights](https://www.nist.gov/open/copyright-fair-use-and-licensing-statements-srd-data-software-and-technical-series-publications) and [repository terms](https://materialsdata.nist.gov/terms/) | Candidate property references only. Uploaded data use provider-selected terms; public availability is not a blanket redistribution license. Review each dataset. |
|
||||||
|
| [Khronos PBR overview](https://www.khronos.org/gltf/pbr) | Public rendering conventions for texture roles and shading properties; a design reference, not a source of CAD material data. |
|
||||||
|
| Original SolidCraft recipes / user measurements | Preferred initial component recipes and illustrative procedural previews; preserve authorship and label illustrative versus measured values. |
|
||||||
|
|
||||||
|
Prefer CC0 resources for the starter texture pack and original recipes for the starter
|
||||||
|
component pack. Defer uncertain or restrictive data rather than scrape supplier sites,
|
||||||
|
copy standards publications or assume a downloadable CAD file can be redistributed.
|
||||||
|
|
||||||
|
## Phases and acceptance gates
|
||||||
|
|
||||||
|
Each implementation PR references these issues without closing them prematurely.
|
||||||
|
|
||||||
|
| Phase | Deliverable | Required evidence before calling it complete |
|
||||||
|
|---|---|---|
|
||||||
|
| 0 | This proposal, source review and roadmap | Maintainer-reviewable contract; distinguish existing functions from planned ones; no runtime or format changes. |
|
||||||
|
| 1 | Shared bounded manifest parser, resolver and pack validation/import/export | Project and user manifests use the same schema; deterministic conflicts, invalid versions/IDs, missing resources/dependencies, cycles, path traversal and budget exhaustion fail atomically; native + wasm pass. |
|
||||||
|
| 2 | Material and appearance catalog integration and browser UI | Create/copy/edit/import/export from the UI; existing commands used; analytic box mass before/after assignment; configurations, undo and offline cold reopening; actual screenshots. |
|
||||||
|
| 3 | Wood mapping and a small reviewed starter pack | Rotate/scale grain on a public-safe block and placed instance; no flip on resize; reopen without pack; rendering capability/fallback tests and screenshots; attribution for each shipped asset. |
|
||||||
|
| 4 | Parameterized section families and reviewed standard size data | BAR: area = width × height; sharp RHS/SHS: outer area minus inner area; CHS: π(outer_diameter² − inner_diameter²)/4. Check volume = area × length, hollow membership, insertion frame, resize, connections, undo and offline reopening; screenshots. |
|
||||||
|
| 5 | Custom assemblies, sheet face/edge layers and expanded catalogs | Bounded nested insertion, shared/independent semantics, durable face associations, explicit updates and loss reporting; measured tests and screenshots for each workflow. |
|
||||||
|
|
||||||
|
After phase 1, material/appearance integration and section-family work can advance
|
||||||
|
independently. Wood mapping depends on actual renderer support, not on section families.
|
||||||
|
Phase 5 is several separate PRs, each following its relevant earlier workflow, rather
|
||||||
|
than one change coupling assembly insertion to face painting.
|
||||||
|
|
||||||
|
Keep parsing/resource I/O in `io`, durable selected definitions in `doc`, application
|
||||||
|
and validation commands in `engine`, renderer-specific interpretation in `render`/its
|
||||||
|
adapters, and discovery/editing UI in `ui-egui`. Lower layers do not depend on the UI
|
||||||
|
or platform file dialogs. Reuse container resource deduplication; avoid a second blob store.
|
||||||
|
|
||||||
|
Before allocating/decoding, enforce manifest byte/entry/string/dependency limits, total
|
||||||
|
resource bytes, image dimensions/decoded bytes and recipe expansion bounds. Paths must be
|
||||||
|
relative, normalized and confined to the selected pack, including symlink handling. Phase 1
|
||||||
|
must publish exact limits and test their boundaries. Do not auto-fetch missing files or
|
||||||
|
install executable extensions. Explicit import/export is enough for the first delivery.
|
||||||
|
|
||||||
|
Run `cargo xtask ci` for each implementation arc and check remote PR results. Geometry
|
||||||
|
tests use analytic values; UI and observable CAD changes include actual app evidence.
|
||||||
|
The three issues remain open until their individual workflows pass these gates.
|
||||||
Reference in new issue
Block a user