cam/model: the seeded island floats 1 mm above its pocket floor — the property parts test a detached solid (#964)

Closed
#969 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
55/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
threejs, typescript

Research direction

Read casemaker-app/tests/tools/randomParts.ts, especially buildRandomPart and the plate pocket and island construction. Make the island reach the pocket floor, then regenerate the three golden pins with CASEMAKER_UPDATE_GOLDEN=1 and rerun opsProperty959, sequenceProperty961, linkProperty962, and modelGoldenPins. Done when plate trees have no unreachable entries and the scoped assertion in randomPartsKinds.spec.ts requires an empty list for every kind.

Written by the indexing model from the issue text.

Description

bug fabrication triaged

Where. casemaker-app/tests/tools/randomParts.ts, buildRandomPart, the rectilinear/filleted plate kinds (the first-wave parts used by the property tests and the golden pins).

The defect. The pocket void is cut depth + 1 deep, so its floor is at −(depth + 1):

const pocket = topBox(tl, w, d, depth + 1, cx, cy);

but the island added back into that pocket is only depth tall:

solid = solid.add(topBox(tl, 2.5, 2.5, depth, cx, cy));

so the island's underside sits at −depth — 1 mm above the pocket floor. Manifold.add keeps it as a detached solid, and the feature recognition lists its underside in tree.unreachable as a zero-height 'undercut': that entry, which every plate-kind tree carries, is this artifact — not a recognition result.

Smallest reproduction.

const part = buildRandomPart(1, 'rectilinear', tl);
part.tree.unreachable;
// [{ footprint: [[[-8.75,-11.25],[-8.75,-8.75],[-11.25,-8.75],[-11.25,-11.25]]],
//    zRange: [-3.082, -3.082], reason: 'undercut' }]

The footprint is exactly the 2.5 × 2.5 island; the single Z is its underside (the seed's pocket depth). Seeds 2 and 3 give the same shape at their own depths (−2.356, −2.869).

Why it matters. The file's own header and the property tests' comments claim "pockets, an island" and "one island in the first pocket, standing from the floor to the stock top". The tests are actually exercising a floating solid, so the island case proves nothing about standing material in a pocket — the one thing it was added for. It also leaves the misleading zero-height undercut in every plate tree (a real undercut has height).

Fix. One line — make the island as deep as the pocket void:

solid = solid.add(topBox(tl, 2.5, 2.5, depth + 1, cx, cy));

Ripple (why it is not folded into the widening branch). This changes every plate-kind mesh, so the three golden pins — synth-rect-a (rectilinear seed 1), synth-rect-b (rectilinear seed 3), synth-fillet-a (filleted seed 2) — change their meshSha256 and their program hashes. The fix wants CASEMAKER_UPDATE_GOLDEN=1 regeneration with a landing note naming the artefact, then opsProperty959, sequenceProperty961, linkProperty962 and modelGoldenPins re-run. After it, the plate kinds' tree.unreachable should be empty, and randomPartsKinds.spec.ts's scoped assertion (currently tolerating the zero-height entry with a pointer to #964) can be tightened to require an empty list for every kind.

Recorded while widening the generator; the original note is on #964 (comment 6641069834). Fix is tests-only — no app behaviour changes.

Edits from the maintainer's review, 2026-11-05 (docs/reviews/2026-11-05-engine-rebuild-review.md §5)

  • Land, then close.
Dominant language
TypeScript
Stars
2
Forks
0
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from SlyWombat/CaseMaker

All issues in SlyWombat/CaseMaker

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.