Repository navigation
fix(mates): solve mated components that do not reach the first part - #1385
Merged
Merged
Conversation
The mate solver grounds the first declared part and walked only that part's component. Mates in any other component were silently dropped: the child stayed at its authored pose. Both the lowered geometry (mateFk) and solveMates (swept collision, reviews) were affected. The kernelcad-kinematic cookbook 05-clamshell-hinge-swept declares an unmated `table` first. Its `lid` never swung: evaluate reported a 180000 mm3 base/lid overlap at hinge 90, and checkSweptCollision reported 31/31 poses colliding. Declaring `table` last gave 3/31. Now every mated component is walked from its first declared part, which stays where its `at` puts it, like the grounded part. solveMates solves disconnected components by default; `solveDisconnectedComponents: false` keeps the old grounded-only walk. The assembly-sequence-gearbox example relied on its shaft/gear mates being ignored; its seats did not sit at the gear centres. Put the seats at the modelled gear centres so the mates keep every part where it is drawn. The placement-ignored-by-mate-fk test now expects the note for the mated child of an unreached component. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: w1ne <41898282+w1ne@users.noreply.github.com>
Auto-committed by run-codex-lane.sh so a dying loop can never lose work again. Squash or amend before review. Signed-off-by: w1ne <41898282+w1ne@users.noreply.github.com>
This reverts commit 7aa52c6. Signed-off-by: w1ne <41898282+w1ne@users.noreply.github.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.
Summary
If the first declared part has no mates, the mate solver ignored every mate in every other component. Each child stayed at its authored pose and no diagnostic reported it. This affected the lowered geometry (
mateFk) andsolveMates, which swept collision and the reviews use. This PR walks every mated component from its first declared part. That part stays where itsatputs it, the same as the grounded part.Reproduction (develop
80f7542be)The
kernelcad-kinematicskill cookbook05-clamshell-hinge-swept.kcad.tsdeclares an unmatedtablebefore thebase–lidhinge. Agents get this file throughlookup_cookbook/execute_cookbook.evaluatecookbook 05 (solvedModel({ hinge: 90 }))ok:false,assembly.interference.overlap: base/lid 180000 mm³ near (0, 50, 3), which islidat its authored poseok:true, no diagnosticstabledeclared last (control)ok:trueok:truecheckSweptCollisionhinge -15..135 step 5,tablefirstbase|lidat every angle)Changes
src/modeling/mates/solver.tswalkResolvedMateTree(mateFk) now walks each mated component from its first declared part. Parts with no mates stay at identity, as before.solveMatesnow solves disconnected components by default.solveDisconnectedComponents: falsekeeps the old walk, which covers only the grounded component.examples/assemblies/assembly-sequence-gearbox.kcad.ts: this example depended on its shaft/gear mates being ignored ("it does not solve the mates in this example"), and its seat values were not at the gear centres. The seats are now at the modelled gear centres, so the mates keep every part where it is drawn. The planner result is unchanged (checkAssemblyPathgearbox test: 19 steps).tests/unit/kinematic/checkSweptCollisionForest.test.ts. The clamshell withtablefirst must give the same colliding angles as withtablelast.tests/integration/lowering/solvedAssemblyMateFk.test.ts. The mated pair after an unmated first part lowers to Z max 7.5, not 5.solver.test.ts: forest is the default, and the opt-out keeps the old result.placementIgnoredByMateFk.test.ts: an unreached component now gets the note for its mated child (b) only, not for its root (a).Both new tests fail on unfixed
solver.ts: Z max is 5 instead of 7.5, and the sweep reports 11 colliding angles instead of[-15].Results (local)
tests/integration: 271 files passed, 17 skipped; 1770 tests passed, 0 failed.tests/unit+src: 7960 tests passed. 7 failures inconnectorManifestExport.test.tsandexport.atomic.test.ts(--connector-manifest ancestry is u…) also fail on unfixed code. Their error message refers to the worktree path on this host, not to the solver.npm run typecheck: clean. ESLint on changed files: clean.npm run test:ratchet: 13/13 passed.Limits
aton that child is now ignored (reported asassembly.placement-ignored-by-mate-fk). This is the same rule that already applies in the grounded component.08-sweep-tolerance-clearance.kcad.tsfails its own assertion. The bisected interference boundary is -0.01007 mm and the assertion limit is 0.01 mm. That is a separate issue.🤖 Generated with Claude Code