feat(solver): Phase 1c — OndselAdapter implementation #294
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Wrap OndselSolver behind the IKCSolver interface. This is the largest piece of Phase 1 — it moves all MbD-specific code out of AssemblyObject and into a self-contained adapter.
Parent: #287 (Phase 1)
Depends on: #292 (1a — API types), #293 (1b — SolverRegistry)
Blocks: #295 (1d — AssemblyObject refactor)
Scope
Files
OndselAdapter class
Translation layer: SolveContext -> ASMTAssembly
This moves the following logic out of AssemblyObject.cpp into OndselAdapter:
makeMbdAssembly()build_assembly(ctx)— creates ASMTAssembly from SolveContextmakeMbdPart()ctx.placements, creates ASMTPart per partmakeMbdMarker()makeMbdJointOfType()create_joint(c)— maps BaseJointKind to ASMT* typesmakeMbdJointDistance()fixGroundedPart()ctx.grounded, creates ASMTFixedJoint per grounded partJoint type mapping: BaseJointKind -> ASMT*
Plus: limits (ASMTRotationLimit, ASMTTranslationLimit) and motions (ASMTRotationalMotion, ASMTTranslationalMotion, ASMTGeneralMotion) from Constraint params.
Result extraction: ASMTAssembly -> SolveResult
getMbdPlacement()extract_result()— reads position3D + quaternions from all ASMTPartsupdateSolveStatus()extract_diagnostics()— iteratesmbdSystem->jointsMotionsDo()to build ConstraintDiagnostic listvalidateNewPlacements()ExternalSystem decoupling
Break the bidirectional pointer:
externalSystem->freecadAssemblyObject = thisExternalSystem::preMbDrun()/updateFromMbD()callbacks that referencedfreecadAssemblyObjectwere already commented-out stubs — no functional changeexternalSystem->preMbDrun(), it routes throughasmtAssemblypath (which works today)Solver registration
In Assembly module init (or OndselAdapter static init):
Key complexity
The
Distancedecomposition — CurrentlymakeMbdJointDistance()is a 35-case switch onDistanceType. With decomposed BaseJointKind, this logic moves upstream into AssemblyObject's SolveContext builder (1d) which classifies geometry and emits the specific BaseJointKind. OndselAdapter receives the already-classified type.Marker coordinate frames — OndselSolver uses named markers on parts for joint attachment. The adapter must translate SolveContext constraint refs (part + geometry) into ASMTMarker placements. This is currently split across
handleOneSideOfJoint()andgetRackPinionMarkers()in AssemblyObject.Drag state —
pre_drag()must callrunPreDrag(),drag_step()must update ASMTPart positions and callrunDragStep(),post_drag()must callrunPostDrag(). The adapter holdsmbdAssembly_as internal state between these calls.Simulation state —
run_kinematic()callsrunKINEMATIC(), thennum_frames()andupdate_for_frame()query the stored simulation results.Acceptance criteria
#includes are in OndselAdapter.cpp, not AssemblyObjectmakeMbdJointOfType()+makeMbdJointDistance()casesextract_diagnostics()produces ConstraintDiagnostic list equivalent to currentupdateSolveStatus()parsingReferences
src/Mod/Assembly/App/AssemblyObject.cpp— current integration (2157 lines)src/3rdParty/OndselSolver/OndselSolver/ExternalSystem.h— bidirectional coupling to breaksrc/3rdParty/OndselSolver/OndselSolver/ASMTAssembly.h— OndselSolver API surfacedocs/INTER_SOLVER.md§5 (Layer 2: OndselSolver Adapter)