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:
1 parent
24974e6f37
commit
bcbfa50eac
10 files changed
+431
-5
No files matched your search
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in new issue
Block a user