Give cached bodies fresh originalIDs per call site - #84
Merged
Conversation
Two identical shapes at two call sites came back sharing one originalID, so a UI keying off it treated them as one thing: selecting either picked both. Reported against two identical cylinders; it affects any array of identical parts, which in CAD is most of them. A cache hit handed back the geometry AND the IDs of whichever call site first produced it. Those IDs are provenance -- which node made this -- not content, so they cannot be cached along with the shape. Each distinct run now gets a fresh ID on a hit, one per run rather than one per body. That matters: Manifold's own AsOriginal() collapses a multi-run body to a single ID, which would have made a cached subtree of several parts selectable only as a whole. Each new ID inherits the old one's node and colour, so parts keep pointing at the AST nodes that actually produced them. Measured on 200 identical spheres, where every one after the first is a hit: 170 ms cold, 128 ms warm. The re-stamp rebuilds each cached body from its mesh, and the cache still pays for itself comfortably. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two identical shapes at two call sites came back sharing one
originalID, so a UI keying off it treated them as one thing — selecting either picked both.A cache hit handed back the geometry and the IDs of whichever call site first produced it. Those IDs are provenance — which node made this — not content, so they cannot be cached along with the shape.
Reported against two identical cylinders. It affects any array of identical parts, which in CAD is most of them.
Per run, not per body
Each distinct run gets a fresh ID on a hit. That distinction matters: Manifold's own
AsOriginal()collapses a multi-run body into a single ID —— which would have made a cached subtree of several parts selectable only as a whole. Each new ID inherits the old one's node and colour, so parts keep pointing at the AST nodes that actually produced them. A cached two-part module used twice yields four distinct IDs, and that is asserted.
Cost
Measured on 200 identical spheres, where every one after the first is a cache hit:
The re-stamp rebuilds each cached body from its mesh, and the cache still pays for itself comfortably.
Verification
Two new tests: distinct IDs across call sites (with the node mapping intact for both), and one-ID-per-part for a reused multi-part subtree.
The first hung on its first version —
GetMeshGL()returns by value, and takingbegin()andend()from two separate calls walks between unrelated buffers. Held in locals now.803 C++ tests pass. Against a local build, BelfrySCAD's 653 tests and its GUI verifiers pass, and the two cylinders now report
original_ids=[1]and[2]in the live renderer.🤖 Generated with Claude Code