Add bounded portable Home thumbnails to design files (#518)

A save with cache: true also stores a small bounded PNG thumbnail (240 × 150, at most 256 KiB, keyed to the exact document) made from cached meshes only. Home uses it when its local picture is missing, without rebuilding the design; ordinary saves and downloads still omit it. Closes #303.

Co-authored-by: lillith <[email protected]>
This commit is contained in:
selune authored and GitHub committed 2026-10-13 05:20:47 -04:00
1 parent 24974e6f37
commit bcbfa50eac
10 files changed
+431 -5

No files matched your search

+4
View File
@@ -52,6 +52,10 @@ cache with `cache: true` on warm saves; saving never rebuilds cold geometry just
create one. Ordinary saves and browser downloads default to `cache: false`. An additional display-mesh cache remains opt-in
with `preview: true`. Unsupported or mismatched caches are ignored. Browser opening
still rebuilds synchronously.
Warm saves with explicit `cache: true` can also include a small PNG thumbnail. It travels with the file, so
Home can show the recent design without reconstructing it when no local picture
is available. Missing or incompatible pictures use the usual thumbnail generation.
The default `cache: false` omits the portable thumbnail too.
The repository's `docs/design-container.md` describes limits and encoding details.
Current designs use format 16, including physical materials defined in the design, the font of sketch text, sheet metal corner relief shapes, sketch face anchors on cylinder caps, sketch axis
+31
View File
@@ -185,3 +185,34 @@ existing preview remains opt-in. GPU tessellation is independent work. Continue
using format/application constants rather than source-tree hashing build scripts,
retain JSON Save As/MCP/script compatibility and the documented legacy shims, and
run standalone wasm validation on each published code revision.
## Portable thumbnail
A warm save with `cache: true` may add `cache/thumbnail.png` and its small
`cache/thumbnail.json` key. The picture is a 240 x 150 PNG, bounded to 256 KiB,
keyed by `solidcraft-thumbnail/1`, application version, exact document SHA-256 and
PNG SHA-256. It contains an isometric view of visible solid bodies with their
appearances. It is display-only and independent of the producing geometry kernel.
Saving uses only already placed bodies and cached meshes, at most 1,024 bodies,
100,000 triangles and 100,000 vertices. A preflight also caps projected pixel-box
work at four million supersampled pixels and face-color lookups at one million,
so overlapping triangles cannot make a small picture arbitrarily expensive.
It never evaluates or tessellates a cold
model for a picture. Active edits, pending moves, model errors, absent warm
geometry or exceeded limits omit the picture. Ordinary saves and browser downloads
default to `cache: false` and omit the PNG; `cache: true` explicitly opts in. Plain JSON
never contains the PNG. The same writer is used by desktop and browser saves.
The seekable thumbnail reader checks the small key, retained document metadata,
PNG size/header and hashes without resolving source blobs. The Home/Recent Files
reader tries its local picture cache, then this portable picture, then its existing
background reconstruction. PNG decoding also has dimension and allocation limits.
Missing, mismatched, truncated or malformed pictures are misses and never prevent
authoritative document opening. Embedding a PNG does not install an operating-system
file-browser thumbnail provider.
Desktop thumbnail reads seek within the file. The browser VFS supplies a bounded
in-memory buffer instead; it avoids geometry reconstruction but does not provide
range-based OPFS reads. IO checks the PNG header and hashes, while the consuming
UI performs the full bounded PNG decode.
+47
View File
@@ -536,3 +536,50 @@ eliminated. A live frame's held solve was already cheap: the seed places the str
returns at once. Of a live strip frame, the seed reads the constraints in about 0.15 ms, so a
per-gesture cache of that reading is not worth its invalidation (its signs depend on the
reference positions, which change every step).
## Portable thumbnail save cost (#303)
Portable thumbnail generation requires explicit `cache: true`. Ordinary saves and
browser downloads default to `cache: false`, so they incur none of the thumbnail
work or added bytes measured below.
Measured 2026-10-13 on the same Windows machine and `ci` profile as above, but
with **SolidCraft 0.7.0** on both sides: `d3d215b` before the thumbnail change and
thumbnail revision `e180cdc` after it. These measurements precede the integration
of upstream `9f88537`; later geometry changes are not included in these timings.
A preserved executable of the baseline
and the new executable ran the existing `benchmark_native_cache_save` on the same
STEP and sensor documents. Three paired batches alternated before/after order;
each batch performed nine alternating atomic saves per encoding. The values below
are medians of the three batch medians, not a percentile of all individual saves.
No compilation, test suite or desktop model was running during these measurements.
| 512-cube STEP encoding | Before PNG (ms) | After PNG (ms) | Container bytes before → after |
|---|---:|---:|---:|
| Plain JSON | 10.334 | 9.676 | 1,998,826 → 1,998,826 |
| Container, `cache: false` | 8.850 | 9.013 | 1,950,084 → 1,950,084 |
| Native cache, fast | 45.323 | 53.473 | 4,694,035 → 4,720,385 |
| Native cache, compact | 42.739 | 48.643 | 837,067 → 863,417 |
The PNG itself is 25,916 bytes; its key and ZIP records bring the increase to
26,350 bytes. Fast-cache batch medians ranged from 41.585–47.779 ms before and
53.212–56.556 ms after. Compact ranged from 36.672–43.040 ms before and
47.688–51.724 ms after. The approximately 8 ms fast-save increase is a measured
cost on this example, not a general latency bound. JSON bytes and document/source
blob bytes were compared across both implementations and remained identical.
The sensor enclosure deliberately receives **no portable PNG**: its projected
triangle boxes total 4,293,457 supersampled pixels, above the four-million work
budget. The native fast container remains 379,099 bytes. Its save batch medians
are 14.714 ms before (12.187–14.956) and 13.728 ms after (13.439–14.648); these
vary within the observed run ranges and do not establish a speedup. Home retains
its existing thumbnail-generation fallback for this case. A small triangle count
alone does not guarantee eligibility, because large overlapping faces cost more.
Actual desktop check: copy the STEP container to a new public temporary path,
start SolidCraft 0.7.0 with that path in Recent and an empty local thumbnail cache,
and show Home without opening the design. The portable picture was ready in one
observed 47.6 ms check; no local PNG was created and the active document remained
empty. The screenshot shows the transferred file's picture while built-in sample
pictures are still loading. This is one functional visual check, not a first-frame
benchmark. The separate counting-reader regression proves source-blob deferral.