@faicad/faijs 0.16.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -5
- package/NOTICE +5 -6
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +19 -1
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/assembly/entities.d.ts +1 -1
- package/dist/api/assembly/entities.d.ts.map +1 -1
- package/dist/api/assembly/entities.js.map +1 -1
- package/dist/api/assembly/joints.d.ts +2 -2
- package/dist/api/assembly/joints.d.ts.map +1 -1
- package/dist/api/assembly/joints.js +2 -2
- package/dist/api/assembly/joints.js.map +1 -1
- package/dist/api/assembly/lower.d.ts +1 -1
- package/dist/api/assembly/lower.d.ts.map +1 -1
- package/dist/api/assembly/lower.js.map +1 -1
- package/dist/api/assembly/pose.d.ts +3 -3
- package/dist/api/assembly/pose.d.ts.map +1 -1
- package/dist/api/assembly/pose.js +1 -1
- package/dist/api/assembly/pose.js.map +1 -1
- package/dist/api/assembly/preview.d.ts +1 -1
- package/dist/api/assembly/preview.d.ts.map +1 -1
- package/dist/api/assembly/preview.js +1 -1
- package/dist/api/assembly/preview.js.map +1 -1
- package/dist/api/assembly/solve.d.ts.map +1 -1
- package/dist/api/assembly/solve.js +3 -3
- package/dist/api/assembly/solve.js.map +1 -1
- package/dist/api/assembly/solvers/assembly-tree.d.ts +98 -0
- package/dist/api/assembly/solvers/assembly-tree.d.ts.map +1 -0
- package/dist/api/assembly/solvers/assembly-tree.js +130 -0
- package/dist/api/assembly/solvers/assembly-tree.js.map +1 -0
- package/dist/api/assembly/solvers/chain-solver.d.ts +27 -0
- package/dist/api/assembly/solvers/chain-solver.d.ts.map +1 -0
- package/dist/api/assembly/solvers/chain-solver.js +330 -0
- package/dist/api/assembly/solvers/chain-solver.js.map +1 -0
- package/dist/api/assembly/solvers/global-solver.js +2 -2
- package/dist/api/assembly/solvers/global-solver.js.map +1 -1
- package/dist/api/assembly/solvers/joints-kinematics.d.ts +308 -0
- package/dist/api/assembly/solvers/joints-kinematics.d.ts.map +1 -0
- package/dist/api/assembly/solvers/joints-kinematics.js +643 -0
- package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -0
- package/dist/api/assembly/solvers/quat.d.ts +35 -0
- package/dist/api/assembly/solvers/quat.d.ts.map +1 -0
- package/dist/api/assembly/solvers/quat.js +84 -0
- package/dist/api/assembly/solvers/quat.js.map +1 -0
- package/dist/api/assembly/solvers/types.d.ts +33 -0
- package/dist/api/assembly/solvers/types.d.ts.map +1 -1
- package/dist/api/assembly/solvers/types.js.map +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +3 -4
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/brep-mirror/booleanFns.d.ts +40 -0
- package/dist/api/brep-mirror/booleanFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/booleanFns.js +99 -0
- package/dist/api/brep-mirror/booleanFns.js.map +1 -0
- package/dist/api/brep-mirror/brepHelpers.d.ts +55 -0
- package/dist/api/brep-mirror/brepHelpers.d.ts.map +1 -0
- package/dist/api/brep-mirror/brepHelpers.js +131 -0
- package/dist/api/brep-mirror/brepHelpers.js.map +1 -0
- package/dist/api/brep-mirror/compoundFns.d.ts +47 -0
- package/dist/api/brep-mirror/compoundFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/compoundFns.js +300 -0
- package/dist/api/brep-mirror/compoundFns.js.map +1 -0
- package/dist/api/brep-mirror/healingFns.d.ts +78 -0
- package/dist/api/brep-mirror/healingFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/healingFns.js +294 -0
- package/dist/api/brep-mirror/healingFns.js.map +1 -0
- package/dist/api/brep-mirror/hullFns.d.ts +20 -0
- package/dist/api/brep-mirror/hullFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/hullFns.js +46 -0
- package/dist/api/brep-mirror/hullFns.js.map +1 -0
- package/dist/api/brep-mirror/patternFns.d.ts +43 -0
- package/dist/api/brep-mirror/patternFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/patternFns.js +178 -0
- package/dist/api/brep-mirror/patternFns.js.map +1 -0
- package/dist/api/brep-mirror/primitiveFns.d.ts +42 -0
- package/dist/api/brep-mirror/primitiveFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/primitiveFns.js +104 -0
- package/dist/api/brep-mirror/primitiveFns.js.map +1 -0
- package/dist/api/brep-mirror/roofFns.d.ts +24 -0
- package/dist/api/brep-mirror/roofFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/roofFns.js +229 -0
- package/dist/api/brep-mirror/roofFns.js.map +1 -0
- package/dist/api/brep-mirror/straightSkeleton.d.ts +36 -0
- package/dist/api/brep-mirror/straightSkeleton.d.ts.map +1 -0
- package/dist/api/brep-mirror/straightSkeleton.js +443 -0
- package/dist/api/brep-mirror/straightSkeleton.js.map +1 -0
- package/dist/api/brep-mirror/sweepFns.d.ts +55 -0
- package/dist/api/brep-mirror/sweepFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/sweepFns.js +200 -0
- package/dist/api/brep-mirror/sweepFns.js.map +1 -0
- package/dist/api/brep-mirror/threadFns.d.ts +15 -0
- package/dist/api/brep-mirror/threadFns.d.ts.map +1 -1
- package/dist/api/brep-mirror/threadFns.js +37 -2
- package/dist/api/brep-mirror/threadFns.js.map +1 -1
- package/dist/api/brep-mirror/topologyFns.d.ts +74 -0
- package/dist/api/brep-mirror/topologyFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/topologyFns.js +273 -0
- package/dist/api/brep-mirror/topologyFns.js.map +1 -0
- package/dist/api/brep-topology.d.ts +190 -0
- package/dist/api/brep-topology.d.ts.map +1 -0
- package/dist/api/brep-topology.js +337 -0
- package/dist/api/brep-topology.js.map +1 -0
- package/dist/api/brepjs-compat/constants.d.ts +11 -0
- package/dist/api/brepjs-compat/constants.d.ts.map +1 -0
- package/dist/api/brepjs-compat/constants.js +11 -0
- package/dist/api/brepjs-compat/constants.js.map +1 -0
- package/dist/api/brepjs-compat/index.d.ts +19 -232
- package/dist/api/brepjs-compat/index.d.ts.map +1 -1
- package/dist/api/brepjs-compat/index.js +19 -286
- package/dist/api/brepjs-compat/index.js.map +1 -1
- package/dist/api/brepjs-compat/planeOps.d.ts +98 -0
- package/dist/api/brepjs-compat/planeOps.d.ts.map +1 -0
- package/dist/api/brepjs-compat/planeOps.js +170 -0
- package/dist/api/brepjs-compat/planeOps.js.map +1 -0
- package/dist/api/brepjs-compat/planeTypes.d.ts +24 -0
- package/dist/api/brepjs-compat/planeTypes.d.ts.map +1 -0
- package/dist/api/brepjs-compat/planeTypes.js +8 -0
- package/dist/api/brepjs-compat/planeTypes.js.map +1 -0
- package/dist/api/brepjs-compat/types.d.ts +64 -0
- package/dist/api/brepjs-compat/types.d.ts.map +1 -0
- package/dist/api/brepjs-compat/types.js +48 -0
- package/dist/api/brepjs-compat/types.js.map +1 -0
- package/dist/api/brepjs-compat/vecOps.d.ts +124 -0
- package/dist/api/brepjs-compat/vecOps.d.ts.map +1 -0
- package/dist/api/brepjs-compat/vecOps.js +202 -0
- package/dist/api/brepjs-compat/vecOps.js.map +1 -0
- package/dist/api/chamfer.d.ts +5 -0
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +13 -8
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts.map +1 -1
- package/dist/api/compound-geom.js +8 -2
- package/dist/api/compound-geom.js.map +1 -1
- package/dist/api/draft.d.ts +69 -0
- package/dist/api/draft.d.ts.map +1 -0
- package/dist/api/draft.js +109 -0
- package/dist/api/draft.js.map +1 -0
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +2 -2
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts.map +1 -1
- package/dist/api/engrave.js +2 -3
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +28 -13
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts.map +1 -1
- package/dist/api/face-ref.js +2 -2
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +137 -0
- package/dist/api/feature-repair.d.ts.map +1 -0
- package/dist/api/feature-repair.js +221 -0
- package/dist/api/feature-repair.js.map +1 -0
- package/dist/api/fillet-variable.d.ts +35 -0
- package/dist/api/fillet-variable.d.ts.map +1 -0
- package/dist/api/fillet-variable.js +71 -0
- package/dist/api/fillet-variable.js.map +1 -0
- package/dist/api/fillet.d.ts +3 -0
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +7 -4
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/2d.d.ts +1 -13
- package/dist/api/generated/2d.d.ts.map +1 -1
- package/dist/api/generated/2d.js +6 -1
- package/dist/api/generated/2d.js.map +1 -1
- package/dist/api/generated/brepjs/index.d.ts +298 -298
- package/dist/api/generated/brepjs/index.d.ts.map +1 -1
- package/dist/api/generated/brepjs/index.js +183 -183
- package/dist/api/generated/brepjs/index.js.map +1 -1
- package/dist/api/generated/core.d.ts +3 -123
- package/dist/api/generated/core.d.ts.map +1 -1
- package/dist/api/generated/core.js +2 -81
- package/dist/api/generated/core.js.map +1 -1
- package/dist/api/generated/gear.d.ts +1 -15
- package/dist/api/generated/gear.d.ts.map +1 -1
- package/dist/api/generated/gear.js +6 -3
- package/dist/api/generated/gear.js.map +1 -1
- package/dist/api/generated/io.d.ts +1 -13
- package/dist/api/generated/io.d.ts.map +1 -1
- package/dist/api/generated/io.js +6 -1
- package/dist/api/generated/io.js.map +1 -1
- package/dist/api/generated/kernel.d.ts +1 -39
- package/dist/api/generated/kernel.d.ts.map +1 -1
- package/dist/api/generated/kernel.js +6 -4
- package/dist/api/generated/kernel.js.map +1 -1
- package/dist/api/generated/measurement.d.ts +53 -97
- package/dist/api/generated/measurement.d.ts.map +1 -1
- package/dist/api/generated/measurement.js +48 -143
- package/dist/api/generated/measurement.js.map +1 -1
- package/dist/api/generated/ns.d.ts +1 -10
- package/dist/api/generated/ns.d.ts.map +1 -1
- package/dist/api/generated/ns.js +2 -10
- package/dist/api/generated/ns.js.map +1 -1
- package/dist/api/generated/operations.d.ts +65 -110
- package/dist/api/generated/operations.d.ts.map +1 -1
- package/dist/api/generated/operations.js +132 -80
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/projection.d.ts +1 -8
- package/dist/api/generated/projection.d.ts.map +1 -1
- package/dist/api/generated/projection.js +6 -4
- package/dist/api/generated/projection.js.map +1 -1
- package/dist/api/generated/query.d.ts +1 -9
- package/dist/api/generated/query.d.ts.map +1 -1
- package/dist/api/generated/query.js +6 -1
- package/dist/api/generated/query.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts +2 -0
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js +34 -22
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/script-face.d.ts +52 -27
- package/dist/api/generated/script-face.d.ts.map +1 -1
- package/dist/api/generated/script-face.js +18 -4
- package/dist/api/generated/script-face.js.map +1 -1
- package/dist/api/generated/sketching.d.ts +4 -7
- package/dist/api/generated/sketching.d.ts.map +1 -1
- package/dist/api/generated/sketching.js +10 -8
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/text.d.ts +1 -6
- package/dist/api/generated/text.d.ts.map +1 -1
- package/dist/api/generated/text.js +6 -3
- package/dist/api/generated/text.js.map +1 -1
- package/dist/api/generated/topology.d.ts +77 -175
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +172 -131
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/geom.d.ts.map +1 -1
- package/dist/api/geom.js +2 -2
- package/dist/api/geom.js.map +1 -1
- package/dist/api/helix.d.ts +51 -0
- package/dist/api/helix.d.ts.map +1 -0
- package/dist/api/helix.js +63 -0
- package/dist/api/helix.js.map +1 -0
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +6 -2
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.d.ts +18 -5
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +29 -12
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.d.ts +10 -0
- package/dist/api/internal/compat-op.d.ts.map +1 -1
- package/dist/api/internal/compat-op.js +9 -3
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/internal/compat-projection.d.ts +4 -4
- package/dist/api/internal/compat-projection.js +7 -7
- package/dist/api/internal/compat-projection.js.map +1 -1
- package/dist/api/internal/l3-bridge.d.ts +75 -42
- package/dist/api/internal/l3-bridge.d.ts.map +1 -1
- package/dist/api/internal/l3-bridge.js +105 -50
- package/dist/api/internal/l3-bridge.js.map +1 -1
- package/dist/api/internal/profile-wire.d.ts +31 -0
- package/dist/api/internal/profile-wire.d.ts.map +1 -0
- package/dist/api/internal/profile-wire.js +37 -0
- package/dist/api/internal/profile-wire.js.map +1 -0
- package/dist/api/internal/replica-role-table.js +2 -2
- package/dist/api/internal/replica-role-table.js.map +1 -1
- package/dist/api/loft.d.ts +66 -0
- package/dist/api/loft.d.ts.map +1 -0
- package/dist/api/loft.js +111 -0
- package/dist/api/loft.js.map +1 -0
- package/dist/api/measurement/index.d.ts +51 -0
- package/dist/api/measurement/index.d.ts.map +1 -0
- package/dist/api/measurement/index.js +71 -0
- package/dist/api/measurement/index.js.map +1 -0
- package/dist/api/occt-kernel-bridge.d.ts +5 -8
- package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
- package/dist/api/occt-kernel-bridge.js +18 -14
- package/dist/api/occt-kernel-bridge.js.map +1 -1
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +3 -4
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/place.d.ts.map +1 -1
- package/dist/api/place.js +2 -4
- package/dist/api/place.js.map +1 -1
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +3 -4
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/replicate.d.ts +28 -1
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +29 -19
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/result.d.ts +6 -11
- package/dist/api/result.d.ts.map +1 -1
- package/dist/api/result.js +6 -11
- package/dist/api/result.js.map +1 -1
- package/dist/api/revolve.d.ts.map +1 -1
- package/dist/api/revolve.js +15 -14
- package/dist/api/revolve.js.map +1 -1
- package/dist/api/screw.d.ts +3 -0
- package/dist/api/screw.d.ts.map +1 -1
- package/dist/api/screw.js +9 -4
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts +1 -1
- package/dist/api/section-by-plane.d.ts +42 -0
- package/dist/api/section-by-plane.d.ts.map +1 -0
- package/dist/api/section-by-plane.js +61 -0
- package/dist/api/section-by-plane.js.map +1 -0
- package/dist/api/shell.d.ts +45 -0
- package/dist/api/shell.d.ts.map +1 -0
- package/dist/api/shell.js +73 -0
- package/dist/api/shell.js.map +1 -0
- package/dist/api/sketch.d.ts +8 -1
- package/dist/api/sketch.d.ts.map +1 -1
- package/dist/api/sketch.js +12 -7
- package/dist/api/sketch.js.map +1 -1
- package/dist/api/split-by-plane.d.ts +41 -0
- package/dist/api/split-by-plane.d.ts.map +1 -0
- package/dist/api/split-by-plane.js +60 -0
- package/dist/api/split-by-plane.js.map +1 -0
- package/dist/api/split.d.ts +6 -1
- package/dist/api/split.d.ts.map +1 -1
- package/dist/api/split.js +23 -9
- package/dist/api/split.js.map +1 -1
- package/dist/api/surface/arg-spec.d.ts +22 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +723 -476
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/sweep.d.ts +55 -0
- package/dist/api/sweep.d.ts.map +1 -0
- package/dist/api/sweep.js +86 -0
- package/dist/api/sweep.js.map +1 -0
- package/dist/api/thicken.d.ts +36 -0
- package/dist/api/thicken.d.ts.map +1 -0
- package/dist/api/thicken.js +55 -0
- package/dist/api/thicken.js.map +1 -0
- package/dist/api/transform.d.ts +8 -0
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +15 -4
- package/dist/api/transform.js.map +1 -1
- package/dist/api/view/cameraFns.d.ts +48 -0
- package/dist/api/view/cameraFns.d.ts.map +1 -0
- package/dist/api/view/cameraFns.js +75 -0
- package/dist/api/view/cameraFns.js.map +1 -0
- package/dist/api/view/projectionPlanes.d.ts +25 -0
- package/dist/api/view/projectionPlanes.d.ts.map +1 -0
- package/dist/api/view/projectionPlanes.js +30 -0
- package/dist/api/view/projectionPlanes.js.map +1 -0
- package/dist/api/view/view-camera.d.ts +2 -2
- package/dist/api/view/view-camera.d.ts.map +1 -1
- package/dist/api/view/view-camera.js +3 -3
- package/dist/api/view/view-camera.js.map +1 -1
- package/dist/api/view/view-projection.d.ts +9 -6
- package/dist/api/view/view-projection.d.ts.map +1 -1
- package/dist/api/view/view-projection.js +132 -65
- package/dist/api/view/view-projection.js.map +1 -1
- package/dist/api/wire.d.ts +45 -0
- package/dist/api/wire.d.ts.map +1 -0
- package/dist/api/wire.js +96 -0
- package/dist/api/wire.js.map +1 -0
- package/dist/boolean/creased-normals.d.ts +50 -0
- package/dist/boolean/creased-normals.d.ts.map +1 -0
- package/dist/boolean/creased-normals.js +114 -0
- package/dist/boolean/creased-normals.js.map +1 -0
- package/dist/boolean/deriveNormals.d.ts +4 -1
- package/dist/boolean/deriveNormals.d.ts.map +1 -1
- package/dist/boolean/deriveNormals.js +5 -2
- package/dist/boolean/deriveNormals.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +6 -0
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +11 -2
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts +4 -0
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +4 -0
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +79 -59
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +7 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +15 -7
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +52 -167
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +93 -130
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js +9 -7
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/types.d.ts +14 -1
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js +11 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/step.d.ts +3 -0
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +7 -1
- package/dist/brep/export/step.js.map +1 -1
- package/dist/brep/face-evolution.d.ts +8 -0
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +15 -3
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +20 -2
- package/dist/brep/handle-bridge.d.ts.map +1 -1
- package/dist/brep/handle-bridge.js +25 -2
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +25 -5
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +336 -144
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +6 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +5 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +9 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +32 -2
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +8 -2
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +3 -0
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +3 -1
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +18 -2
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +29 -1
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +3 -0
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +7 -0
- package/dist/env-agnostic.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +28 -0
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +29 -1
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
- package/dist/occt-kernel/highLevelApi.js +6 -3
- package/dist/occt-kernel/highLevelApi.js.map +1 -1
- package/dist/occt-kernel/hullGeometry.d.ts +31 -0
- package/dist/occt-kernel/hullGeometry.d.ts.map +1 -0
- package/dist/occt-kernel/hullGeometry.js +319 -0
- package/dist/occt-kernel/hullGeometry.js.map +1 -0
- package/dist/occt-kernel/hullOps.d.ts +24 -0
- package/dist/occt-kernel/hullOps.d.ts.map +1 -0
- package/dist/occt-kernel/hullOps.js +52 -0
- package/dist/occt-kernel/hullOps.js.map +1 -0
- package/dist/occt-kernel/occt-primitives.d.ts +14 -0
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -0
- package/dist/occt-kernel/occt-primitives.js +351 -0
- package/dist/occt-kernel/occt-primitives.js.map +1 -0
- package/dist/occt-kernel/occtKernel.d.ts +14 -6
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +11 -3
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/topologyExt.js +2 -2
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/primitives/brep-primitives.d.ts +4 -0
- package/dist/primitives/brep-primitives.d.ts.map +1 -1
- package/dist/primitives/brep-primitives.js +4 -0
- package/dist/primitives/brep-primitives.js.map +1 -1
- package/dist/result/bug.d.ts +22 -0
- package/dist/result/bug.d.ts.map +1 -0
- package/dist/result/bug.js +28 -0
- package/dist/result/bug.js.map +1 -0
- package/dist/result/errors.d.ts +270 -0
- package/dist/result/errors.d.ts.map +1 -0
- package/dist/result/errors.js +317 -0
- package/dist/result/errors.js.map +1 -0
- package/dist/result/kernelErrorTranslation.d.ts +21 -0
- package/dist/result/kernelErrorTranslation.d.ts.map +1 -0
- package/dist/result/kernelErrorTranslation.js +102 -0
- package/dist/result/kernelErrorTranslation.js.map +1 -0
- package/dist/result/result.d.ts +213 -0
- package/dist/result/result.d.ts.map +1 -0
- package/dist/result/result.js +336 -0
- package/dist/result/result.js.map +1 -0
- package/dist/result/vec3.d.ts +12 -0
- package/dist/result/vec3.d.ts.map +1 -0
- package/dist/result/vec3.js +14 -0
- package/dist/result/vec3.js.map +1 -0
- package/dist/runtime-state.d.ts +9 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +3 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +2 -1
- package/dist/sdk.js.map +1 -1
- package/dist/shape.d.ts +43 -1
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +57 -1
- package/dist/shape.js.map +1 -1
- package/dist/topology/naming/geom-hint.js +1 -1
- package/dist/topology/naming/geom-hint.js.map +1 -1
- package/dist/topology/naming/score.js +1 -1
- package/dist/topology/naming/score.js.map +1 -1
- package/package.json +6 -16
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { quatRotate, quatFromAxisAngle, quatFromTo } from './quat.js';
|
|
2
|
+
/**
|
|
3
|
+
* Degrees of freedom each constraint leaves unresolved when it can't be applied
|
|
4
|
+
* (entity-type mismatch or an unreachable reference). All four types now solve
|
|
5
|
+
* for well-typed inputs; these counts only feed the diagnostic `dof` for the
|
|
6
|
+
* unsupported cases.
|
|
7
|
+
* coincident: 3 translational · concentric: 2 rotational + 2 translational = 4
|
|
8
|
+
* distance: 1 translational · angle: 1 rotational
|
|
9
|
+
*/
|
|
10
|
+
const UNSUPPORTED_DOF = {
|
|
11
|
+
coincident: 3,
|
|
12
|
+
concentric: 4,
|
|
13
|
+
distance: 1,
|
|
14
|
+
angle: 1,
|
|
15
|
+
};
|
|
16
|
+
const IDENTITY_ROTATION = [1, 0, 0, 0];
|
|
17
|
+
function add(a, b) {
|
|
18
|
+
return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
|
|
19
|
+
}
|
|
20
|
+
function sub(a, b) {
|
|
21
|
+
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
|
|
22
|
+
}
|
|
23
|
+
function dot(a, b) {
|
|
24
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
25
|
+
}
|
|
26
|
+
function cross(a, b) {
|
|
27
|
+
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
|
|
28
|
+
}
|
|
29
|
+
function scale(a, s) {
|
|
30
|
+
return [a[0] * s, a[1] * s, a[2] * s];
|
|
31
|
+
}
|
|
32
|
+
function normalize(a) {
|
|
33
|
+
const l = Math.hypot(a[0], a[1], a[2]) || 1;
|
|
34
|
+
return [a[0] / l, a[1] / l, a[2] / l];
|
|
35
|
+
}
|
|
36
|
+
/** A unit vector perpendicular to `v` (for the parallel-normals degenerate case). */
|
|
37
|
+
function anyPerpendicular(v) {
|
|
38
|
+
const ref = Math.abs(v[0]) < 0.9 ? [1, 0, 0] : [0, 1, 0];
|
|
39
|
+
return normalize(cross(v, ref));
|
|
40
|
+
}
|
|
41
|
+
/** Apply a pose (rotate then translate) to an entity's origin and any directions. */
|
|
42
|
+
function transformEntity(e, pose) {
|
|
43
|
+
const origin = add(quatRotate(pose.rotation, e.origin), pose.position);
|
|
44
|
+
return {
|
|
45
|
+
type: e.type,
|
|
46
|
+
origin,
|
|
47
|
+
...(e.normal ? { normal: quatRotate(pose.rotation, e.normal) } : {}),
|
|
48
|
+
...(e.direction ? { direction: quatRotate(pose.rotation, e.direction) } : {}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Position a dependent plane against an already-placed reference plane.
|
|
53
|
+
*
|
|
54
|
+
* `ref` is the reference entity already in world space. The dependent is at the
|
|
55
|
+
* origin (a node is only solved once, while unplaced), so the returned position
|
|
56
|
+
* is its absolute translation along the reference normal. `extra` is the gap for
|
|
57
|
+
* a distance mate (0 for coincident). Plane mates don't reorient the dependent.
|
|
58
|
+
*/
|
|
59
|
+
function solvePlanePair(ref, dep, extra) {
|
|
60
|
+
const n = ref.normal ?? [0, 0, 1];
|
|
61
|
+
const offset = dot(n, sub(ref.origin, dep.origin)) + extra;
|
|
62
|
+
return { position: scale(n, offset), rotation: IDENTITY_ROTATION };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Concentric (axis-axis) mate: rotate the dependent so its axis is parallel to
|
|
66
|
+
* the reference axis, then translate so the two axes are collinear (the
|
|
67
|
+
* dependent's axis point is placed on the reference axis). `ref` is in world
|
|
68
|
+
* space; the dependent is at the origin.
|
|
69
|
+
*/
|
|
70
|
+
function solveConcentric(ref, dep) {
|
|
71
|
+
const dRef = ref.direction ?? [0, 0, 1];
|
|
72
|
+
const dDep = dep.direction ?? [0, 0, 1];
|
|
73
|
+
const rotation = quatFromTo(dDep, dRef);
|
|
74
|
+
const rotatedOrigin = quatRotate(rotation, dep.origin);
|
|
75
|
+
return { position: sub(ref.origin, rotatedOrigin), rotation };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Angle mate: rotate the dependent so the angle between its (plane) normal and
|
|
79
|
+
* the reference normal equals `angleRad`. Orientation-only — position is left at
|
|
80
|
+
* the origin. `ref` is in world space; the dependent is at the origin.
|
|
81
|
+
*/
|
|
82
|
+
function solveAngle(ref, dep, angleRad) {
|
|
83
|
+
const nRef = normalize(ref.normal ?? [0, 0, 1]);
|
|
84
|
+
const nDep = normalize(dep.normal ?? [0, 0, 1]);
|
|
85
|
+
const phi = Math.acos(Math.max(-1, Math.min(1, dot(nDep, nRef))));
|
|
86
|
+
const c = cross(nDep, nRef);
|
|
87
|
+
const axis = Math.hypot(c[0], c[1], c[2]) < 1e-9 ? anyPerpendicular(nDep) : c;
|
|
88
|
+
// Rotating nDep about (nDep×nRef) by +phi aligns it with nRef; rotate by
|
|
89
|
+
// (phi − angle) to leave exactly `angleRad` between them.
|
|
90
|
+
return { position: [0, 0, 0], rotation: quatFromAxisAngle(axis, phi - angleRad) };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Point-point coincident/distance: place the dependent point on the reference
|
|
94
|
+
* point (`extra` = 0) or at `extra` along the original separation direction.
|
|
95
|
+
* If the points already coincide the direction is arbitrary (+X).
|
|
96
|
+
*/
|
|
97
|
+
function solvePointPair(refOrigin, depOrigin, extra) {
|
|
98
|
+
const sep = sub(depOrigin, refOrigin);
|
|
99
|
+
const len = Math.hypot(sep[0], sep[1], sep[2]);
|
|
100
|
+
const dir = len < 1e-9 ? [1, 0, 0] : scale(sep, 1 / len);
|
|
101
|
+
const target = add(refOrigin, scale(dir, extra));
|
|
102
|
+
return { position: sub(target, depOrigin), rotation: IDENTITY_ROTATION };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Move the dependent plane (normal `depNormal`, at the origin) so its signed
|
|
106
|
+
* distance from the reference point equals `extra` (the mirror of `solvePlanePair`
|
|
107
|
+
* for a point reference and a plane dependent).
|
|
108
|
+
*/
|
|
109
|
+
function solvePlaneToPoint(depNormal, refOrigin, depOrigin, extra) {
|
|
110
|
+
const n = normalize(depNormal);
|
|
111
|
+
const t = dot(n, sub(refOrigin, depOrigin)) - extra;
|
|
112
|
+
return { position: scale(n, t), rotation: IDENTITY_ROTATION };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Reference axis, dependent point: drop the point onto the axis line
|
|
116
|
+
* (`extra` = 0) or place it at radial distance `extra` from the line, keeping
|
|
117
|
+
* its along-axis position. A point already on the axis gets an arbitrary radial.
|
|
118
|
+
*/
|
|
119
|
+
function solveAxisToPoint(ref, depOrigin, extra) {
|
|
120
|
+
const d = normalize(ref.direction ?? [0, 0, 1]);
|
|
121
|
+
const foot = add(ref.origin, scale(d, dot(d, sub(depOrigin, ref.origin))));
|
|
122
|
+
if (extra === 0)
|
|
123
|
+
return { position: sub(foot, depOrigin), rotation: IDENTITY_ROTATION };
|
|
124
|
+
const radial = sub(depOrigin, foot);
|
|
125
|
+
const rlen = Math.hypot(radial[0], radial[1], radial[2]);
|
|
126
|
+
const rdir = rlen < 1e-9 ? anyPerpendicular(d) : scale(radial, 1 / rlen);
|
|
127
|
+
return { position: sub(add(foot, scale(rdir, extra)), depOrigin), rotation: IDENTITY_ROTATION };
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Reference point, dependent axis: translate the axis line so it passes through
|
|
131
|
+
* the point (`extra` = 0) or lies at perpendicular distance `extra` from it.
|
|
132
|
+
* Translation is purely perpendicular to the axis, so the line's direction and
|
|
133
|
+
* along-axis parameterization are preserved.
|
|
134
|
+
*/
|
|
135
|
+
function solvePointToAxis(refOrigin, dep, extra) {
|
|
136
|
+
const d = normalize(dep.direction ?? [0, 0, 1]);
|
|
137
|
+
const w = sub(dep.origin, refOrigin);
|
|
138
|
+
const perp = sub(w, scale(d, dot(d, w)));
|
|
139
|
+
const plen = Math.hypot(perp[0], perp[1], perp[2]);
|
|
140
|
+
if (extra === 0)
|
|
141
|
+
return { position: scale(perp, -1), rotation: IDENTITY_ROTATION };
|
|
142
|
+
const pdir = plen < 1e-9 ? anyPerpendicular(d) : scale(perp, 1 / plen);
|
|
143
|
+
return { position: sub(scale(pdir, extra), perp), rotation: IDENTITY_ROTATION };
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Axis-axis distance: align the dependent axis parallel to the reference, then
|
|
147
|
+
* offset it to perpendicular distance `extra` (parallel pin-and-spacer). With
|
|
148
|
+
* `extra` = 0 the axes become collinear, matching `concentric`.
|
|
149
|
+
*/
|
|
150
|
+
function solveAxisAxisDistance(ref, dep, extra) {
|
|
151
|
+
const dRef = normalize(ref.direction ?? [0, 0, 1]);
|
|
152
|
+
const dDep = normalize(dep.direction ?? [0, 0, 1]);
|
|
153
|
+
const rotation = quatFromTo(dDep, dRef);
|
|
154
|
+
const depO = quatRotate(rotation, dep.origin);
|
|
155
|
+
const w = sub(depO, ref.origin);
|
|
156
|
+
const perp = sub(w, scale(dRef, dot(dRef, w)));
|
|
157
|
+
const plen = Math.hypot(perp[0], perp[1], perp[2]);
|
|
158
|
+
const pdir = plen < 1e-9 ? anyPerpendicular(dRef) : scale(perp, 1 / plen);
|
|
159
|
+
return { position: sub(scale(pdir, extra), perp), rotation };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Supported entity-type pairs for the translational mates (`coincident` /
|
|
163
|
+
* `distance`), keyed `${entityA}-${entityB}`. Both orders are listed where the
|
|
164
|
+
* solver handles them, so a user need not pre-order the entities.
|
|
165
|
+
*/
|
|
166
|
+
const TRANSLATIONAL_PAIRS = new Set([
|
|
167
|
+
'plane-plane',
|
|
168
|
+
'plane-point',
|
|
169
|
+
'point-plane',
|
|
170
|
+
'point-point',
|
|
171
|
+
'axis-axis',
|
|
172
|
+
'axis-point',
|
|
173
|
+
'point-axis',
|
|
174
|
+
]);
|
|
175
|
+
/** Entity types the orientation/axis mates require of (entityA, entityB). */
|
|
176
|
+
const REQUIRED_ENTITIES = {
|
|
177
|
+
angle: 'plane',
|
|
178
|
+
concentric: 'axis',
|
|
179
|
+
};
|
|
180
|
+
const POSITIONING_TYPES = new Set(['coincident', 'distance', 'angle', 'concentric']);
|
|
181
|
+
/** Whether a positioning mate's entity pair is solvable. */
|
|
182
|
+
function isSupportedPair(type, a, b) {
|
|
183
|
+
const required = REQUIRED_ENTITIES[type];
|
|
184
|
+
if (required)
|
|
185
|
+
return a === required && b === required;
|
|
186
|
+
// coincident / distance: dispatch by entity-type pair.
|
|
187
|
+
return TRANSLATIONAL_PAIRS.has(`${a}-${b}`);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Solve a `coincident` (extra = 0) or `distance` (extra = value) mate for any
|
|
191
|
+
* supported entity-type pair. `ref` is already in world space; the dependent is
|
|
192
|
+
* at the origin. Returns null only for an unsupported pair (filtered out
|
|
193
|
+
* upstream by `isSupportedPair`).
|
|
194
|
+
*/
|
|
195
|
+
function solveTranslational(ref, dep, extra) {
|
|
196
|
+
const key = `${ref.type}-${dep.type}`;
|
|
197
|
+
switch (key) {
|
|
198
|
+
case 'plane-plane':
|
|
199
|
+
case 'plane-point':
|
|
200
|
+
// Both use the reference plane normal; a point dependent has no normal.
|
|
201
|
+
return solvePlanePair(ref, dep, extra);
|
|
202
|
+
case 'point-plane':
|
|
203
|
+
return solvePlaneToPoint(dep.normal ?? [0, 0, 1], ref.origin, dep.origin, extra);
|
|
204
|
+
case 'point-point':
|
|
205
|
+
return solvePointPair(ref.origin, dep.origin, extra);
|
|
206
|
+
case 'axis-axis':
|
|
207
|
+
return extra === 0 ? solveConcentric(ref, dep) : solveAxisAxisDistance(ref, dep, extra);
|
|
208
|
+
case 'axis-point':
|
|
209
|
+
return solveAxisToPoint(ref, dep.origin, extra);
|
|
210
|
+
case 'point-axis':
|
|
211
|
+
return solvePointToAxis(ref.origin, dep, extra);
|
|
212
|
+
default:
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** Dispatch a positioning mate to its solver. `ref` is already in world space. */
|
|
217
|
+
function solveMate(c, ref, dep) {
|
|
218
|
+
switch (c.type) {
|
|
219
|
+
case 'concentric':
|
|
220
|
+
return solveConcentric(ref, dep);
|
|
221
|
+
case 'angle':
|
|
222
|
+
return solveAngle(ref, dep, ((c.value ?? 0) * Math.PI) / 180);
|
|
223
|
+
default: {
|
|
224
|
+
// coincident (extra = 0) / distance (extra = value). isSupportedPair has
|
|
225
|
+
// already filtered out unsupported pairs upstream, so a null here means
|
|
226
|
+
// TRANSLATIONAL_PAIRS and solveTranslational drifted out of sync — surface
|
|
227
|
+
// that invariant violation loudly rather than guessing with plane logic.
|
|
228
|
+
const extra = c.type === 'distance' ? (c.value ?? 0) : 0;
|
|
229
|
+
const pose = solveTranslational(ref, dep, extra);
|
|
230
|
+
if (!pose) {
|
|
231
|
+
throw new Error(`solveMate: unsupported entity pair escaped filter: ${ref.type}-${dep.type}`);
|
|
232
|
+
}
|
|
233
|
+
return pose;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Solve assembly constraints analytically.
|
|
239
|
+
*
|
|
240
|
+
* Handles: fixed, concentric (axis-axis), angle (plane-plane orientation), and
|
|
241
|
+
* coincident/distance for any supported entity-type pair (plane-plane,
|
|
242
|
+
* plane-point, point-point, axis-axis, axis-point, and both point orders — see
|
|
243
|
+
* `TRANSLATIONAL_PAIRS`). For a positioning mate, entityA is the reference and
|
|
244
|
+
* entityB the dependent. Chain roots (nodes never positioned by a
|
|
245
|
+
* mate) and explicit `fixed` nodes anchor at the origin; constraints then resolve
|
|
246
|
+
* in topological order — each places its dependent against the reference's solved
|
|
247
|
+
* pose (rotation included), so multi-body chains compose. Returns
|
|
248
|
+
* `converged: false` with details for entity-type mismatches and any constraint
|
|
249
|
+
* whose reference never resolves.
|
|
250
|
+
* @param nodes - Names of the nodes participating in the assembly.
|
|
251
|
+
* @param constraints - Constraints to solve.
|
|
252
|
+
* @returns The solver result with per-node transforms, DOF count, and convergence info.
|
|
253
|
+
*/
|
|
254
|
+
export function solveConstraints(nodes, constraints) {
|
|
255
|
+
const transforms = new Map();
|
|
256
|
+
// Initialize all nodes at origin
|
|
257
|
+
for (const node of nodes) {
|
|
258
|
+
transforms.set(node, { position: [0, 0, 0], rotation: IDENTITY_ROTATION });
|
|
259
|
+
}
|
|
260
|
+
const unsupported = [];
|
|
261
|
+
// For positioning mates, entityA is the reference and entityB the dependent.
|
|
262
|
+
const positioning = constraints.filter((c) => POSITIONING_TYPES.has(c.type) && c.entityA && c.entityB);
|
|
263
|
+
const dependents = new Set();
|
|
264
|
+
for (const c of positioning)
|
|
265
|
+
if (c.entityB)
|
|
266
|
+
dependents.add(c.entityB.node);
|
|
267
|
+
// Anchors are placed at the origin: any node never positioned by a mate (a
|
|
268
|
+
// chain root), plus any explicit `fixed` node.
|
|
269
|
+
const placed = new Set();
|
|
270
|
+
for (const node of nodes)
|
|
271
|
+
if (!dependents.has(node))
|
|
272
|
+
placed.add(node);
|
|
273
|
+
for (const c of constraints)
|
|
274
|
+
if (c.type === 'fixed' && c.entityA)
|
|
275
|
+
placed.add(c.entityA.node);
|
|
276
|
+
// Entity-type mismatches are unsupported regardless of order; report them
|
|
277
|
+
// eagerly and keep only well-typed mates for topological resolution. A node
|
|
278
|
+
// left unplaced by such a mate (it's a dependent, so not a root) will cause
|
|
279
|
+
// any downstream mate that references it to end up `(unanchored)` — intended:
|
|
280
|
+
// an unsolved reference can't compose, so the chain doesn't converge.
|
|
281
|
+
const pending = [];
|
|
282
|
+
for (const c of positioning) {
|
|
283
|
+
if (!c.entityA || !c.entityB)
|
|
284
|
+
continue;
|
|
285
|
+
const a = c.entityA.entity.type;
|
|
286
|
+
const b = c.entityB.entity.type;
|
|
287
|
+
if (!isSupportedPair(c.type, a, b)) {
|
|
288
|
+
unsupported.push(`${c.type}(${a}-${b})`);
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
pending.push(c);
|
|
292
|
+
}
|
|
293
|
+
// Resolve in topological rounds: a mate solves once its reference (entityA) is
|
|
294
|
+
// placed, positioning the dependent (entityB) against the reference's solved
|
|
295
|
+
// world-space pose so multi-body chains compose.
|
|
296
|
+
let progress = true;
|
|
297
|
+
while (progress && pending.length > 0) {
|
|
298
|
+
progress = false;
|
|
299
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
300
|
+
const c = pending[i];
|
|
301
|
+
if (!c?.entityA || !c.entityB)
|
|
302
|
+
continue;
|
|
303
|
+
const ref = c.entityA;
|
|
304
|
+
const dep = c.entityB;
|
|
305
|
+
if (!placed.has(ref.node))
|
|
306
|
+
continue; // reference not solved yet — defer
|
|
307
|
+
pending.splice(i, 1);
|
|
308
|
+
progress = true;
|
|
309
|
+
if (placed.has(dep.node))
|
|
310
|
+
continue; // dependent already anchored (fixed) — redundant
|
|
311
|
+
const refPose = transforms.get(ref.node) ?? {
|
|
312
|
+
position: [0, 0, 0],
|
|
313
|
+
rotation: IDENTITY_ROTATION,
|
|
314
|
+
};
|
|
315
|
+
const refWorld = transformEntity(ref.entity, refPose);
|
|
316
|
+
transforms.set(dep.node, solveMate(c, refWorld, dep.entity));
|
|
317
|
+
placed.add(dep.node);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Anything still pending has a reference that never resolved (e.g. a cycle).
|
|
321
|
+
for (const c of pending)
|
|
322
|
+
unsupported.push(`${c.type}(unanchored)`);
|
|
323
|
+
const dof = unsupported.reduce((sum, type) => {
|
|
324
|
+
// Look up by exact key first, then by base type (before parenthesis)
|
|
325
|
+
const baseDof = UNSUPPORTED_DOF[type] ?? UNSUPPORTED_DOF[type.split('(')[0] ?? ''] ?? 0;
|
|
326
|
+
return sum + baseDof;
|
|
327
|
+
}, 0);
|
|
328
|
+
return { transforms, dof, converged: unsupported.length === 0, unsupported };
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=chain-solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain-solver.js","sourceRoot":"","sources":["../../../../src/api/assembly/solvers/chain-solver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Constraint solver (chain) — core 自有实现(§5.6 移植:vendored solverAdapter 逐字对齐)。\n *\n * 移植来源:packages/brepjs/src/kernel/solverAdapter.ts(Phase 5 随 brepjs 包删除前\n * 已做 parity 对拍——本文件与 vendored 行为逐项一致,无重新设计)。\n * 类型 SolverEntity/SolverConstraint/SolverResult 迁入 ./types(§5.6.1,消费方共用)。\n */\nimport type { SolverEntity, SolverConstraint, SolverResult } from './types'\n\nimport { quatRotate, quatFromAxisAngle, quatFromTo } from './quat'\n\n/** 3D vector (local alias to avoid cross-layer import). */\ntype Vec3 = readonly [number, number, number];\n\n/**\n * Degrees of freedom each constraint leaves unresolved when it can't be applied\n * (entity-type mismatch or an unreachable reference). All four types now solve\n * for well-typed inputs; these counts only feed the diagnostic `dof` for the\n * unsupported cases.\n * coincident: 3 translational · concentric: 2 rotational + 2 translational = 4\n * distance: 1 translational · angle: 1 rotational\n */\nconst UNSUPPORTED_DOF: Readonly<Record<string, number>> = {\n coincident: 3,\n concentric: 4,\n distance: 1,\n angle: 1,\n};\n\ntype Quat = [number, number, number, number];\ntype Pose = { position: Vec3; rotation: Quat };\n\nconst IDENTITY_ROTATION: Quat = [1, 0, 0, 0];\n\nfunction add(a: Vec3, b: Vec3): Vec3 {\n return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];\n}\n\nfunction sub(a: Vec3, b: Vec3): Vec3 {\n return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];\n}\n\nfunction dot(a: Vec3, b: Vec3): number {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cross(a: Vec3, b: Vec3): Vec3 {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\nfunction scale(a: Vec3, s: number): Vec3 {\n return [a[0] * s, a[1] * s, a[2] * s];\n}\n\nfunction normalize(a: Vec3): Vec3 {\n const l = Math.hypot(a[0], a[1], a[2]) || 1;\n return [a[0] / l, a[1] / l, a[2] / l];\n}\n\n/** A unit vector perpendicular to `v` (for the parallel-normals degenerate case). */\nfunction anyPerpendicular(v: Vec3): Vec3 {\n const ref: Vec3 = Math.abs(v[0]) < 0.9 ? [1, 0, 0] : [0, 1, 0];\n return normalize(cross(v, ref));\n}\n\n/** Apply a pose (rotate then translate) to an entity's origin and any directions. */\nfunction transformEntity(e: SolverEntity, pose: Pose): SolverEntity {\n const origin = add(quatRotate(pose.rotation, e.origin), pose.position);\n return {\n type: e.type,\n origin,\n ...(e.normal ? { normal: quatRotate(pose.rotation, e.normal) } : {}),\n ...(e.direction ? { direction: quatRotate(pose.rotation, e.direction) } : {}),\n };\n}\n\n/**\n * Position a dependent plane against an already-placed reference plane.\n *\n * `ref` is the reference entity already in world space. The dependent is at the\n * origin (a node is only solved once, while unplaced), so the returned position\n * is its absolute translation along the reference normal. `extra` is the gap for\n * a distance mate (0 for coincident). Plane mates don't reorient the dependent.\n */\nfunction solvePlanePair(ref: SolverEntity, dep: SolverEntity, extra: number): Pose {\n const n = ref.normal ?? [0, 0, 1];\n const offset = dot(n, sub(ref.origin, dep.origin)) + extra;\n return { position: scale(n, offset), rotation: IDENTITY_ROTATION };\n}\n\n/**\n * Concentric (axis-axis) mate: rotate the dependent so its axis is parallel to\n * the reference axis, then translate so the two axes are collinear (the\n * dependent's axis point is placed on the reference axis). `ref` is in world\n * space; the dependent is at the origin.\n */\nfunction solveConcentric(ref: SolverEntity, dep: SolverEntity): Pose {\n const dRef = ref.direction ?? [0, 0, 1];\n const dDep = dep.direction ?? [0, 0, 1];\n const rotation = quatFromTo(dDep, dRef);\n const rotatedOrigin = quatRotate(rotation, dep.origin);\n return { position: sub(ref.origin, rotatedOrigin), rotation };\n}\n\n/**\n * Angle mate: rotate the dependent so the angle between its (plane) normal and\n * the reference normal equals `angleRad`. Orientation-only — position is left at\n * the origin. `ref` is in world space; the dependent is at the origin.\n */\nfunction solveAngle(ref: SolverEntity, dep: SolverEntity, angleRad: number): Pose {\n const nRef = normalize(ref.normal ?? [0, 0, 1]);\n const nDep = normalize(dep.normal ?? [0, 0, 1]);\n const phi = Math.acos(Math.max(-1, Math.min(1, dot(nDep, nRef))));\n const c = cross(nDep, nRef);\n const axis = Math.hypot(c[0], c[1], c[2]) < 1e-9 ? anyPerpendicular(nDep) : c;\n // Rotating nDep about (nDep×nRef) by +phi aligns it with nRef; rotate by\n // (phi − angle) to leave exactly `angleRad` between them.\n return { position: [0, 0, 0], rotation: quatFromAxisAngle(axis, phi - angleRad) };\n}\n\n/**\n * Point-point coincident/distance: place the dependent point on the reference\n * point (`extra` = 0) or at `extra` along the original separation direction.\n * If the points already coincide the direction is arbitrary (+X).\n */\nfunction solvePointPair(refOrigin: Vec3, depOrigin: Vec3, extra: number): Pose {\n const sep = sub(depOrigin, refOrigin);\n const len = Math.hypot(sep[0], sep[1], sep[2]);\n const dir: Vec3 = len < 1e-9 ? [1, 0, 0] : scale(sep, 1 / len);\n const target = add(refOrigin, scale(dir, extra));\n return { position: sub(target, depOrigin), rotation: IDENTITY_ROTATION };\n}\n\n/**\n * Move the dependent plane (normal `depNormal`, at the origin) so its signed\n * distance from the reference point equals `extra` (the mirror of `solvePlanePair`\n * for a point reference and a plane dependent).\n */\nfunction solvePlaneToPoint(depNormal: Vec3, refOrigin: Vec3, depOrigin: Vec3, extra: number): Pose {\n const n = normalize(depNormal);\n const t = dot(n, sub(refOrigin, depOrigin)) - extra;\n return { position: scale(n, t), rotation: IDENTITY_ROTATION };\n}\n\n/**\n * Reference axis, dependent point: drop the point onto the axis line\n * (`extra` = 0) or place it at radial distance `extra` from the line, keeping\n * its along-axis position. A point already on the axis gets an arbitrary radial.\n */\nfunction solveAxisToPoint(ref: SolverEntity, depOrigin: Vec3, extra: number): Pose {\n const d = normalize(ref.direction ?? [0, 0, 1]);\n const foot = add(ref.origin, scale(d, dot(d, sub(depOrigin, ref.origin))));\n if (extra === 0) return { position: sub(foot, depOrigin), rotation: IDENTITY_ROTATION };\n const radial = sub(depOrigin, foot);\n const rlen = Math.hypot(radial[0], radial[1], radial[2]);\n const rdir = rlen < 1e-9 ? anyPerpendicular(d) : scale(radial, 1 / rlen);\n return { position: sub(add(foot, scale(rdir, extra)), depOrigin), rotation: IDENTITY_ROTATION };\n}\n\n/**\n * Reference point, dependent axis: translate the axis line so it passes through\n * the point (`extra` = 0) or lies at perpendicular distance `extra` from it.\n * Translation is purely perpendicular to the axis, so the line's direction and\n * along-axis parameterization are preserved.\n */\nfunction solvePointToAxis(refOrigin: Vec3, dep: SolverEntity, extra: number): Pose {\n const d = normalize(dep.direction ?? [0, 0, 1]);\n const w = sub(dep.origin, refOrigin);\n const perp = sub(w, scale(d, dot(d, w)));\n const plen = Math.hypot(perp[0], perp[1], perp[2]);\n if (extra === 0) return { position: scale(perp, -1), rotation: IDENTITY_ROTATION };\n const pdir = plen < 1e-9 ? anyPerpendicular(d) : scale(perp, 1 / plen);\n return { position: sub(scale(pdir, extra), perp), rotation: IDENTITY_ROTATION };\n}\n\n/**\n * Axis-axis distance: align the dependent axis parallel to the reference, then\n * offset it to perpendicular distance `extra` (parallel pin-and-spacer). With\n * `extra` = 0 the axes become collinear, matching `concentric`.\n */\nfunction solveAxisAxisDistance(ref: SolverEntity, dep: SolverEntity, extra: number): Pose {\n const dRef = normalize(ref.direction ?? [0, 0, 1]);\n const dDep = normalize(dep.direction ?? [0, 0, 1]);\n const rotation = quatFromTo(dDep, dRef);\n const depO = quatRotate(rotation, dep.origin);\n const w = sub(depO, ref.origin);\n const perp = sub(w, scale(dRef, dot(dRef, w)));\n const plen = Math.hypot(perp[0], perp[1], perp[2]);\n const pdir = plen < 1e-9 ? anyPerpendicular(dRef) : scale(perp, 1 / plen);\n return { position: sub(scale(pdir, extra), perp), rotation };\n}\n\n/**\n * Supported entity-type pairs for the translational mates (`coincident` /\n * `distance`), keyed `${entityA}-${entityB}`. Both orders are listed where the\n * solver handles them, so a user need not pre-order the entities.\n */\nconst TRANSLATIONAL_PAIRS = new Set([\n 'plane-plane',\n 'plane-point',\n 'point-plane',\n 'point-point',\n 'axis-axis',\n 'axis-point',\n 'point-axis',\n]);\n\n/** Entity types the orientation/axis mates require of (entityA, entityB). */\nconst REQUIRED_ENTITIES: Readonly<Record<string, SolverEntity['type']>> = {\n angle: 'plane',\n concentric: 'axis',\n};\n\nconst POSITIONING_TYPES = new Set(['coincident', 'distance', 'angle', 'concentric']);\n\n/** Whether a positioning mate's entity pair is solvable. */\nfunction isSupportedPair(type: string, a: SolverEntity['type'], b: SolverEntity['type']): boolean {\n const required = REQUIRED_ENTITIES[type];\n if (required) return a === required && b === required;\n // coincident / distance: dispatch by entity-type pair.\n return TRANSLATIONAL_PAIRS.has(`${a}-${b}`);\n}\n\n/**\n * Solve a `coincident` (extra = 0) or `distance` (extra = value) mate for any\n * supported entity-type pair. `ref` is already in world space; the dependent is\n * at the origin. Returns null only for an unsupported pair (filtered out\n * upstream by `isSupportedPair`).\n */\nfunction solveTranslational(ref: SolverEntity, dep: SolverEntity, extra: number): Pose | null {\n const key = `${ref.type}-${dep.type}`;\n switch (key) {\n case 'plane-plane':\n case 'plane-point':\n // Both use the reference plane normal; a point dependent has no normal.\n return solvePlanePair(ref, dep, extra);\n case 'point-plane':\n return solvePlaneToPoint(dep.normal ?? [0, 0, 1], ref.origin, dep.origin, extra);\n case 'point-point':\n return solvePointPair(ref.origin, dep.origin, extra);\n case 'axis-axis':\n return extra === 0 ? solveConcentric(ref, dep) : solveAxisAxisDistance(ref, dep, extra);\n case 'axis-point':\n return solveAxisToPoint(ref, dep.origin, extra);\n case 'point-axis':\n return solvePointToAxis(ref.origin, dep, extra);\n default:\n return null;\n }\n}\n\n/** Dispatch a positioning mate to its solver. `ref` is already in world space. */\nfunction solveMate(c: SolverConstraint, ref: SolverEntity, dep: SolverEntity): Pose {\n switch (c.type) {\n case 'concentric':\n return solveConcentric(ref, dep);\n case 'angle':\n return solveAngle(ref, dep, ((c.value ?? 0) * Math.PI) / 180);\n default: {\n // coincident (extra = 0) / distance (extra = value). isSupportedPair has\n // already filtered out unsupported pairs upstream, so a null here means\n // TRANSLATIONAL_PAIRS and solveTranslational drifted out of sync — surface\n // that invariant violation loudly rather than guessing with plane logic.\n const extra = c.type === 'distance' ? (c.value ?? 0) : 0;\n const pose = solveTranslational(ref, dep, extra);\n if (!pose) {\n throw new Error(\n `solveMate: unsupported entity pair escaped filter: ${ref.type}-${dep.type}`\n );\n }\n return pose;\n }\n }\n}\n\n/**\n * Solve assembly constraints analytically.\n *\n * Handles: fixed, concentric (axis-axis), angle (plane-plane orientation), and\n * coincident/distance for any supported entity-type pair (plane-plane,\n * plane-point, point-point, axis-axis, axis-point, and both point orders — see\n * `TRANSLATIONAL_PAIRS`). For a positioning mate, entityA is the reference and\n * entityB the dependent. Chain roots (nodes never positioned by a\n * mate) and explicit `fixed` nodes anchor at the origin; constraints then resolve\n * in topological order — each places its dependent against the reference's solved\n * pose (rotation included), so multi-body chains compose. Returns\n * `converged: false` with details for entity-type mismatches and any constraint\n * whose reference never resolves.\n * @param nodes - Names of the nodes participating in the assembly.\n * @param constraints - Constraints to solve.\n * @returns The solver result with per-node transforms, DOF count, and convergence info.\n */\nexport function solveConstraints(nodes: string[], constraints: SolverConstraint[]): SolverResult {\n const transforms = new Map<string, Pose>();\n\n // Initialize all nodes at origin\n for (const node of nodes) {\n transforms.set(node, { position: [0, 0, 0], rotation: IDENTITY_ROTATION });\n }\n\n const unsupported: string[] = [];\n\n // For positioning mates, entityA is the reference and entityB the dependent.\n const positioning = constraints.filter(\n (c) => POSITIONING_TYPES.has(c.type) && c.entityA && c.entityB\n );\n const dependents = new Set<string>();\n for (const c of positioning) if (c.entityB) dependents.add(c.entityB.node);\n\n // Anchors are placed at the origin: any node never positioned by a mate (a\n // chain root), plus any explicit `fixed` node.\n const placed = new Set<string>();\n for (const node of nodes) if (!dependents.has(node)) placed.add(node);\n for (const c of constraints) if (c.type === 'fixed' && c.entityA) placed.add(c.entityA.node);\n\n // Entity-type mismatches are unsupported regardless of order; report them\n // eagerly and keep only well-typed mates for topological resolution. A node\n // left unplaced by such a mate (it's a dependent, so not a root) will cause\n // any downstream mate that references it to end up `(unanchored)` — intended:\n // an unsolved reference can't compose, so the chain doesn't converge.\n const pending: SolverConstraint[] = [];\n for (const c of positioning) {\n if (!c.entityA || !c.entityB) continue;\n const a = c.entityA.entity.type;\n const b = c.entityB.entity.type;\n if (!isSupportedPair(c.type, a, b)) {\n unsupported.push(`${c.type}(${a}-${b})`);\n continue;\n }\n pending.push(c);\n }\n\n // Resolve in topological rounds: a mate solves once its reference (entityA) is\n // placed, positioning the dependent (entityB) against the reference's solved\n // world-space pose so multi-body chains compose.\n let progress = true;\n while (progress && pending.length > 0) {\n progress = false;\n for (let i = pending.length - 1; i >= 0; i--) {\n const c = pending[i];\n if (!c?.entityA || !c.entityB) continue;\n const ref = c.entityA;\n const dep = c.entityB;\n if (!placed.has(ref.node)) continue; // reference not solved yet — defer\n\n pending.splice(i, 1);\n progress = true;\n if (placed.has(dep.node)) continue; // dependent already anchored (fixed) — redundant\n\n const refPose = transforms.get(ref.node) ?? {\n position: [0, 0, 0],\n rotation: IDENTITY_ROTATION,\n };\n const refWorld = transformEntity(ref.entity, refPose);\n transforms.set(dep.node, solveMate(c, refWorld, dep.entity));\n placed.add(dep.node);\n }\n }\n\n // Anything still pending has a reference that never resolved (e.g. a cycle).\n for (const c of pending) unsupported.push(`${c.type}(unanchored)`);\n\n const dof = unsupported.reduce((sum, type) => {\n // Look up by exact key first, then by base type (before parenthesis)\n const baseDof = UNSUPPORTED_DOF[type] ?? UNSUPPORTED_DOF[type.split('(')[0] ?? ''] ?? 0;\n return sum + baseDof;\n }, 0);\n\n return { transforms, dof, converged: unsupported.length === 0, unsupported };\n}\n"]}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* 失败模式(§4.6):唯一抛错路径 = 约束类型无法映射为代价;其余以 warnings 透明化,
|
|
19
19
|
* 不抛错(LM 终止即 converged=true)。
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
21
|
+
import { getBrepApi } from '../../../brep/handle-bridge.js';
|
|
22
22
|
import { normalizeConstraint } from '../normalize.js';
|
|
23
23
|
import { poseToAssemblyTransform } from '../pose.js';
|
|
24
24
|
import { resolveFaceGeometryOfRef, resolveSolverEntity, } from '../entities.js';
|
|
@@ -142,7 +142,7 @@ export function solveGlobal(members, memberNames, constraints, opts) {
|
|
|
142
142
|
});
|
|
143
143
|
let kernel = null;
|
|
144
144
|
try {
|
|
145
|
-
kernel =
|
|
145
|
+
kernel = getBrepApi();
|
|
146
146
|
}
|
|
147
147
|
catch {
|
|
148
148
|
/* mesh/primitive 行快照路径:快照引用仍可解 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-solver.js","sourceRoot":"","sources":["../../../../src/api/assembly/solvers/global-solver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/assembly/solvers/global-solver — 纯 TS global 装配求解器(P1)\n *\n * 复刻 CadQuery `cadquery/occ_impl/solver.py` 的**语义**(全局 NLP、模长参数化旋转、\n * 9 类代价、Axis 缺省反平行、Plane=Axis(π)+Point(0)、包围盒对角长缩放),\n * 以 Levenberg-Marquardt 替代 IPOPT,**零原生/WASM 依赖**(裁定 1–6,详见\n * `docs/plans/2026-09-08-assembly-dual-solver.md`)。\n *\n * 关键裁定(写进代码,不在别处手算):\n * - 裁定 1/2:faijs Shape 不携带 placement → 初值 T0=R0=0,world 系==本地系;\n * 两侧 marker 经 `resolveFaceGeometryOfRef`/`resolveSolverEntity` 直接取本地系,无不对称。\n * - 裁定 3:残差取 CQ 代价的「平方前内层量」(非对代价开方)。\n * - 裁定 4:线性求解自实现(linalg.ts)。\n * - 裁定 5:旋转 pivot 恒 [0,0,0](CQ 的 Rotate(v,R)+T 绕世界原点)。\n * - 裁定 6:锚定用 CQ B4(assembly.py:455-490):Fixed / name==self.name 锁定;\n * 否则第一个不在 unary 里的 binary object;否则实体 0。锁定成员冻结为 identity。\n *\n * 失败模式(§4.6):唯一抛错路径 = 约束类型无法映射为代价;其余以 warnings 透明化,\n * 不抛错(LM 终止即 converged=true)。\n */\n\nimport type { Shape } from '../../../mesh/types'\nimport type { BrepEngineApi } from '../../../brep/engine/primitives'\nimport { getBackends } from '../../../runtime-state'\nimport type { AssemblyTransform } from '../../../runtime-state'\nimport type { AssemblyConstraint, EntityRef } from '../types'\nimport { normalizeConstraint } from '../normalize'\nimport { poseToAssemblyTransform, type SolverPose } from '../pose'\nimport {\n resolveFaceGeometryOfRef,\n resolveSolverEntity,\n type EntityResolutionEnv,\n} from '../entities'\nimport { type SolveOptions, type GlobalMarker, type GlobalSolveResult } from './types'\nimport {\n type Vec3,\n vadd,\n vsub,\n vdot,\n vscale,\n vnormalize,\n vsumsqr,\n ata,\n atb,\n solveDampedNormal,\n} from './linalg'\nimport { rotateByR, quatFromR } from './pose-from-delta'\n\nconst DEG2RAD = Math.PI / 180\nconst R_INIT = 1e-2 // B3\nconst LM_LAMBDA0 = 1e-3\nconst LM_MAXITER = 2000\nconst LM_TOL_OBJ = 1e-12\nconst LM_TOL_STEP = 1e-10\nconst PENALTY = 1e-16 // B1,等价 sqrt = 1e-8\nconst RESIDUAL_WARN = 1e-6 // §4.6 阈值系数\n\ntype CostFn = 'point' | 'axis' | 'point_in_plane' | 'point_on_line'\n\ninterface CostTerm {\n cid: number\n fn: CostFn\n /** 点侧成员下标(point_in_plane/point_on_line 的点;axis 的 dir 侧)。 */\n ia: number\n ma: GlobalMarker\n /** 平面/线侧成员下标(point_in_plane/point_on_line 的平面/线;axis 的 dir 侧)。 */\n ib: number\n mb: GlobalMarker\n /** point=距离(mm);axis=夹角(rad);point_in_plane/point_on_line=val。 */\n val: number\n /** 是否除以 scale(CQ scaling 字典:point 类 true,axis 类 false)。 */\n scaleFlag: boolean\n}\n\n/** 把一条 EntityRef 解析为本地系 GlobalMarker(无坐标系不对称)。 */\nfunction resolveMarker(ref: EntityRef, env: EntityResolutionEnv): GlobalMarker {\n if ('point' in ref) {\n return { type: 'point', p: [ref.point[0], ref.point[1], ref.point[2]] }\n }\n if ('face' in ref) {\n const geom = resolveFaceGeometryOfRef(ref, env)\n const normal = vnormalize([geom.normal[0], geom.normal[1], geom.normal[2]])\n return {\n type: 'plane',\n center: [geom.center[0], geom.center[1], geom.center[2]],\n normal,\n }\n }\n // edge / faceIndex → 走 resolveSolverEntity(统一抽取)\n const se = resolveSolverEntity(ref, env)\n if (se.type === 'axis') {\n return {\n type: 'axis',\n origin: [se.origin[0], se.origin[1], se.origin[2]],\n // `direction` is optional in the vendored SolverEntity type but always present for the\n // axis branch produced by resolveSolverEntity (cylinder/cone face, or edge axis snapshot).\n dir: vnormalize([se.direction![0], se.direction![1], se.direction![2]]),\n }\n }\n if (se.type === 'plane') {\n return {\n type: 'plane',\n center: [se.origin[0], se.origin[1], se.origin[2]],\n // `normal` is optional in the vendored SolverEntity type but always present for the plane branch.\n normal: vnormalize([se.normal![0], se.normal![1], se.normal![2]]),\n }\n }\n return { type: 'point', p: [se.origin[0], se.origin[1], se.origin[2]] }\n}\n\nfunction markerPoint(m: GlobalMarker, R: Vec3, T: Vec3): Vec3 {\n const base = m.type === 'point' ? m.p : m.type === 'axis' ? m.origin : m.center\n return vadd(rotateByR(base, R), T)\n}\nfunction markerDir(m: GlobalMarker, R: Vec3): Vec3 {\n // point markers never reach here (axis cost / plane normal / line direction only);\n // narrow to axis/plane and fall back to the point for type-completeness.\n const base = m.type === 'axis' ? m.dir : m.type === 'plane' ? m.normal : m.p\n return rotateByR(base, R)\n}\n\n/** 计算单条代价项的残差向量(平方前内层量,裁定 3)。 */\nfunction termResidual(t: CostTerm, sa: { T: Vec3; R: Vec3 }, sb: { T: Vec3; R: Vec3 }, scale: number): number[] {\n const inv = t.scaleFlag ? 1 / scale : 1\n switch (t.fn) {\n case 'point': {\n const pa = markerPoint(t.ma, sa.R, sa.T)\n const pb = markerPoint(t.mb, sb.R, sb.T)\n const d = vscale(vsub(pa, pb), inv)\n if (Math.abs(t.val) < 1e-12) return d // 3-vec,val=0\n return [vsumsqr(d) - (t.val / scale) ** 2] // 1-vec,val≠0\n }\n case 'axis': {\n const d1 = markerDir(t.ma, sa.R)\n const d2 = markerDir(t.mb, sb.R)\n if (Math.abs(t.val) < 1e-12) return vsub(d1, d2) // 3-vec,val=0\n if (Math.abs(t.val - Math.PI) < 1e-12) return vadd(d1, d2) // 3-vec,val=π\n return [vdot(d1, d2) - Math.cos(t.val)] // 1-vec,其他\n }\n case 'point_in_plane': {\n const p1 = markerPoint(t.ma, sa.R, sa.T) // 点\n const n = markerDir(t.mb, sb.R) // 平面法向\n let c = markerPoint(t.mb, sb.R, sb.T) // 平面上一点\n if (Math.abs(t.val) > 1e-12) c = vadd(c, vscale(n, t.val)) // 沿法向平移 val(CQ m2_pnt 偏移)\n const d = vdot(n, vsub(c, p1)) * inv\n return [d] // 1-vec\n }\n case 'point_on_line': {\n const p1 = markerPoint(t.ma, sa.R, sa.T) // 点\n const o = markerPoint(t.mb, sb.R, sb.T) // 线上一点\n const dln = markerDir(t.mb, sb.R) // 线方向\n const delta = vsub(p1, o)\n const perp = vscale(vsub(delta, vscale(dln, vdot(delta, dln))), inv)\n if (Math.abs(t.val) < 1e-12) return perp // 3-vec,val=0\n return [vsumsqr(perp) - t.val] // 1-vec,val≠0(注意 val 不缩放)\n }\n }\n}\n\n/**\n * 纯 TS global 求解器入口。\n *\n * @param members - member shapes(与 memberNames 对齐)。\n * @param memberNames - 成员变量名(约束以名引用,空名会抛错)。\n * @param constraints - 规范化前的原始约束。\n * @param opts - 求解选项(solver 已在外层判定为 'global',此处 name 用于 B4 锚定)。\n * @returns 与 `AssemblySolveResult` 对齐的结果。\n */\nexport function solveGlobal(\n members: Shape[],\n memberNames: string[],\n constraints: AssemblyConstraint[],\n opts?: SolveOptions,\n): GlobalSolveResult {\n memberNames.forEach((name, i) => {\n if (!name) {\n throw new Error(`[assembly:global] member at index ${i} has an empty name`)\n }\n })\n\n const memberMap = new Map<string, Shape>()\n members.forEach((m, i) => {\n const name = memberNames[i]\n if (name && !memberMap.has(name)) memberMap.set(name, m)\n })\n\n let kernel: BrepEngineApi | null = null\n try {\n kernel = getBackends().kernel.brep as BrepEngineApi | null\n } catch {\n /* mesh/primitive 行快照路径:快照引用仍可解 */\n }\n const env: EntityResolutionEnv = { kernel, memberOf: (p: string) => memberMap.get(p) }\n\n // ── 建立代价项、锁定集、尺度点 ──\n const terms: CostTerm[] = []\n const unsupported: string[] = []\n const lockedSet = new Set<number>()\n const order: string[] = []\n const binaryOrder: string[] = []\n const unarySet = new Set<string>()\n const scalePts: Vec3[] = []\n\n constraints.forEach((raw, cid) => {\n const c = normalizeConstraint(raw)\n const register = (p: string) => {\n if (!order.includes(p)) order.push(p)\n }\n if (c.type === 'fixed') {\n register(c.part)\n unarySet.add(c.part)\n const idx = memberNames.indexOf(c.part)\n if (idx >= 0) lockedSet.add(idx)\n return\n }\n const ia = memberNames.indexOf(c.a.part)\n const ib = memberNames.indexOf(c.b.part)\n if (ia < 0 || ib < 0) {\n unsupported.push(`constraint references unknown part: ${ia < 0 ? c.a.part : c.b.part}`)\n return\n }\n if (!binaryOrder.includes(c.a.part)) binaryOrder.push(c.a.part)\n register(c.a.part)\n register(c.b.part)\n if (c.a.part === opts?.name) lockedSet.add(ia)\n if (c.b.part === opts?.name) lockedSet.add(ib)\n\n const mA = resolveMarker(c.a, env)\n const mB = resolveMarker(c.b, env)\n scalePts.push(markerPoint(mA, [0, 0, 0], [0, 0, 0]))\n scalePts.push(markerPoint(mB, [0, 0, 0], [0, 0, 0]))\n\n switch (c.type) {\n case 'mate':\n case 'align': {\n if (mA.type !== 'plane' || mB.type !== 'plane') {\n unsupported.push(`${c.type} requires plane entities on both sides`)\n return\n }\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: c.type === 'mate' ? Math.PI : 0, scaleFlag: false })\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n break\n }\n case 'coincident': {\n pushCoincident(terms, cid, ia, mA, ib, mB)\n break\n }\n case 'concentric': {\n if (mA.type !== 'axis' || mB.type !== 'axis') {\n unsupported.push('concentric requires axis entities on both sides')\n return\n }\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val: 0, scaleFlag: true })\n break\n }\n case 'distance': {\n pushDistance(terms, cid, ia, mA, ib, mB, c.value, unsupported)\n break\n }\n case 'angle': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: c.value * DEG2RAD, scaleFlag: false })\n break\n }\n case 'parallel': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n break\n }\n case 'perpendicular': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: Math.PI / 2, scaleFlag: false })\n break\n }\n default:\n unsupported.push(`unsupported constraint type: ${(c as { type?: string }).type}`)\n }\n })\n\n // ── B4 锚定 ──\n if (lockedSet.size === 0) {\n for (const b of binaryOrder) {\n if (!unarySet.has(b)) {\n const idx = memberNames.indexOf(b)\n if (idx >= 0) {\n lockedSet.add(idx)\n break\n }\n }\n }\n }\n if (lockedSet.size === 0 && order.length > 0) {\n const idx = memberNames.indexOf(order[0])\n if (idx >= 0) lockedSet.add(idx)\n }\n\n // ── scale = 所有 marker 点的包围盒对角长(CQ B5;marker 近似几何 bbox) ──\n const scale = computeScale(scalePts)\n\n // ── 自由成员与变量 ──\n const freeIdx: number[] = []\n const blockMap = new Map<number, number>()\n memberNames.forEach((_, i) => {\n if (!lockedSet.has(i)) {\n blockMap.set(i, freeIdx.length)\n freeIdx.push(i)\n }\n })\n const n = freeIdx.length * 6\n const x = new Array(n).fill(0)\n for (let k = 0; k < freeIdx.length; k++) {\n x[6 * k + 3] = R_INIT\n x[6 * k + 4] = R_INIT\n x[6 * k + 5] = R_INIT\n }\n\n const stateOf = (xx: number[], i: number): { T: Vec3; R: Vec3 } => {\n if (lockedSet.has(i)) return { T: [0, 0, 0], R: [0, 0, 0] }\n const k = blockMap.get(i)!\n return {\n T: [xx[6 * k], xx[6 * k + 1], xx[6 * k + 2]],\n R: [xx[6 * k + 3], xx[6 * k + 4], xx[6 * k + 5]],\n }\n }\n\n const residual = (xx: number[]): number[] => {\n const r: number[] = []\n for (const t of terms) {\n const e = termResidual(t, stateOf(xx, t.ia), stateOf(xx, t.ib), scale)\n for (const v of e) r.push(v)\n }\n // penalty 1e-16(B1):sqrt 后 1e-8,T/scale 缩小、R 直接\n for (let k = 0; k < freeIdx.length; k++) {\n r.push(PENALTY ** 0.5 * (xx[6 * k] / scale))\n r.push(PENALTY ** 0.5 * (xx[6 * k + 1] / scale))\n r.push(PENALTY ** 0.5 * (xx[6 * k + 2] / scale))\n r.push(PENALTY ** 0.5 * xx[6 * k + 3])\n r.push(PENALTY ** 0.5 * xx[6 * k + 4])\n r.push(PENALTY ** 0.5 * xx[6 * k + 5])\n }\n return r\n }\n\n // ── LM 迭代 ──\n let lambda = LM_LAMBDA0\n let current = residual(x)\n let obj = 0.5 * dot(current, current)\n\n for (let iter = 0; iter < LM_MAXITER; iter++) {\n const m = current.length\n const J = new Array(m * n).fill(0)\n for (let col = 0; col < n; col++) {\n const h = col % 6 < 3 ? 1e-7 * scale : 1e-7\n const xp = x.slice()\n const xm = x.slice()\n xp[col] += h\n xm[col] -= h\n const rp = residual(xp)\n const rm = residual(xm)\n for (let row = 0; row < m; row++) J[row * n + col] = (rp[row] - rm[row]) / (2 * h)\n }\n const JtJ = ata(J, m, n)\n const Jtr = atb(J, current, m, n)\n\n // 梯度范数收敛(与步长早停互补,避免 λ 放大时误判收敛)\n if (maxAbs(Jtr) < 1e-8) {\n break\n }\n\n const negJtr = Jtr.map((v) => -v)\n const objBefore = obj\n let improved = false\n let acceptedStep: number[] | null = null\n for (let attempt = 0; attempt < 12 && !improved; attempt++) {\n const step = solveDampedNormal(JtJ, negJtr, n, lambda)\n if (!step) break\n const xTry = x.slice()\n for (let j = 0; j < n; j++) xTry[j] += step[j]\n const rTry = residual(xTry)\n const objTry = 0.5 * dot(rTry, rTry)\n if (objTry <= obj) {\n for (let j = 0; j < n; j++) x[j] = xTry[j]\n current = rTry\n obj = objTry\n improved = true\n acceptedStep = step\n lambda = Math.max(lambda / 3, 1e-15)\n } else {\n lambda *= 2\n }\n }\n if (!improved) break\n\n // 步长收敛仅在信任域健康(λ 小)时认定——λ 大时的微小步长只是阻尼,非真收敛\n if (acceptedStep && maxAbs(acceptedStep) < LM_TOL_STEP && lambda < 1e-2) {\n break\n }\n if (Math.abs(objBefore - obj) < LM_TOL_OBJ * Math.max(1, Math.abs(objBefore))) {\n break\n }\n }\n\n // ── 组装结果 ──\n const transforms: AssemblyTransform[] = []\n for (let k = 0; k < freeIdx.length; k++) {\n const i = freeIdx[k]\n const T: Vec3 = [x[6 * k], x[6 * k + 1], x[6 * k + 2]]\n const R: Vec3 = [x[6 * k + 3], x[6 * k + 4], x[6 * k + 5]]\n const pose: SolverPose = { position: T, rotation: quatFromR(R[0], R[1], R[2]) }\n transforms.push(poseToAssemblyTransform(pose, [0, 0, 0], i))\n }\n\n // 逐约束残差(诊断)\n const residuals: number[] = []\n const warnings: string[] = []\n const byCid = new Map<number, number>()\n for (const t of terms) {\n const e = termResidual(t, stateOf(x, t.ia), stateOf(x, t.ib), scale)\n const s = e.reduce((acc, v) => acc + v * v, 0)\n byCid.set(t.cid, (byCid.get(t.cid) ?? 0) + s)\n }\n constraints.forEach((_, cid) => {\n const r = byCid.get(cid) ?? 0\n residuals.push(r)\n if (r > RESIDUAL_WARN * scale) warnings.push(`constraint #${cid} residual=${r.toExponential(3)} (> ${RESIDUAL_WARN * scale})`)\n })\n\n return {\n transforms,\n dof: 0,\n converged: true,\n unsupported,\n residuals,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n\nfunction pushCoincident(terms: CostTerm[], cid: number, ia: number, mA: GlobalMarker, ib: number, mB: GlobalMarker): void {\n if (mA.type === 'point' && mB.type === 'point') {\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'plane' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_in_plane', ia: ib, ma: mB, ib: ia, mb: mA, val: 0, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'plane') {\n terms.push({ cid, fn: 'point_in_plane', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'axis') {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_on_line', ia: ib, ma: mB, ib, mb: mA, val: 0, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'axis') {\n terms.push({ cid, fn: 'point_on_line', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else {\n // 两面 coincident:按 align 语义(平行 + 中心重合)\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n }\n}\n\nfunction pushDistance(\n terms: CostTerm[],\n cid: number,\n ia: number,\n mA: GlobalMarker,\n ib: number,\n mB: GlobalMarker,\n val: number,\n unsupported: string[],\n): void {\n if (mA.type === 'point' && mB.type === 'point') {\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val, scaleFlag: true })\n } else if (mA.type === 'plane' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_in_plane', ia: ib, ma: mB, ib: ia, mb: mA, val, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'plane') {\n terms.push({ cid, fn: 'point_in_plane', ia, ma: mA, ib, mb: mB, val, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'axis') {\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val, scaleFlag: true })\n } else {\n unsupported.push(`distance requires point-point / plane-point / axis-axis entities, got ${mA.type}-${mB.type}`)\n }\n}\n\nfunction computeScale(pts: Vec3[]): number {\n if (pts.length === 0) return 1\n const min: Vec3 = [Infinity, Infinity, Infinity]\n const max: Vec3 = [-Infinity, -Infinity, -Infinity]\n for (const p of pts) {\n for (let i = 0; i < 3; i++) {\n if (p[i] < min[i]) min[i] = p[i]\n if (p[i] > max[i]) max[i] = p[i]\n }\n }\n const diag = Math.hypot(max[0] - min[0], max[1] - min[1], max[2] - min[2])\n return Math.max(diag, 1e-6)\n}\n\nfunction dot(a: number[], b: number[]): number {\n let s = 0\n for (let i = 0; i < a.length; i++) s += a[i] * b[i]\n return s\n}\nfunction maxAbs(a: number[]): number {\n let m = 0\n for (const v of a) m = Math.max(m, Math.abs(v))\n return m\n}\n"]}
|
|
1
|
+
{"version":3,"file":"global-solver.js","sourceRoot":"","sources":["../../../../src/api/assembly/solvers/global-solver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/assembly/solvers/global-solver — 纯 TS global 装配求解器(P1)\n *\n * 复刻 CadQuery `cadquery/occ_impl/solver.py` 的**语义**(全局 NLP、模长参数化旋转、\n * 9 类代价、Axis 缺省反平行、Plane=Axis(π)+Point(0)、包围盒对角长缩放),\n * 以 Levenberg-Marquardt 替代 IPOPT,**零原生/WASM 依赖**(裁定 1–6,详见\n * `docs/plans/2026-09-08-assembly-dual-solver.md`)。\n *\n * 关键裁定(写进代码,不在别处手算):\n * - 裁定 1/2:faijs Shape 不携带 placement → 初值 T0=R0=0,world 系==本地系;\n * 两侧 marker 经 `resolveFaceGeometryOfRef`/`resolveSolverEntity` 直接取本地系,无不对称。\n * - 裁定 3:残差取 CQ 代价的「平方前内层量」(非对代价开方)。\n * - 裁定 4:线性求解自实现(linalg.ts)。\n * - 裁定 5:旋转 pivot 恒 [0,0,0](CQ 的 Rotate(v,R)+T 绕世界原点)。\n * - 裁定 6:锚定用 CQ B4(assembly.py:455-490):Fixed / name==self.name 锁定;\n * 否则第一个不在 unary 里的 binary object;否则实体 0。锁定成员冻结为 identity。\n *\n * 失败模式(§4.6):唯一抛错路径 = 约束类型无法映射为代价;其余以 warnings 透明化,\n * 不抛错(LM 终止即 converged=true)。\n */\n\nimport type { Shape } from '../../../mesh/types'\nimport type { BrepEngineApi } from '../../../brep/engine/primitives'\nimport { getBrepApi } from '../../../brep/handle-bridge'\nimport type { AssemblyTransform } from '../../../runtime-state'\nimport type { AssemblyConstraint, EntityRef } from '../types'\nimport { normalizeConstraint } from '../normalize'\nimport { poseToAssemblyTransform, type SolverPose } from '../pose'\nimport {\n resolveFaceGeometryOfRef,\n resolveSolverEntity,\n type EntityResolutionEnv,\n} from '../entities'\nimport { type SolveOptions, type GlobalMarker, type GlobalSolveResult } from './types'\nimport {\n type Vec3,\n vadd,\n vsub,\n vdot,\n vscale,\n vnormalize,\n vsumsqr,\n ata,\n atb,\n solveDampedNormal,\n} from './linalg'\nimport { rotateByR, quatFromR } from './pose-from-delta'\n\nconst DEG2RAD = Math.PI / 180\nconst R_INIT = 1e-2 // B3\nconst LM_LAMBDA0 = 1e-3\nconst LM_MAXITER = 2000\nconst LM_TOL_OBJ = 1e-12\nconst LM_TOL_STEP = 1e-10\nconst PENALTY = 1e-16 // B1,等价 sqrt = 1e-8\nconst RESIDUAL_WARN = 1e-6 // §4.6 阈值系数\n\ntype CostFn = 'point' | 'axis' | 'point_in_plane' | 'point_on_line'\n\ninterface CostTerm {\n cid: number\n fn: CostFn\n /** 点侧成员下标(point_in_plane/point_on_line 的点;axis 的 dir 侧)。 */\n ia: number\n ma: GlobalMarker\n /** 平面/线侧成员下标(point_in_plane/point_on_line 的平面/线;axis 的 dir 侧)。 */\n ib: number\n mb: GlobalMarker\n /** point=距离(mm);axis=夹角(rad);point_in_plane/point_on_line=val。 */\n val: number\n /** 是否除以 scale(CQ scaling 字典:point 类 true,axis 类 false)。 */\n scaleFlag: boolean\n}\n\n/** 把一条 EntityRef 解析为本地系 GlobalMarker(无坐标系不对称)。 */\nfunction resolveMarker(ref: EntityRef, env: EntityResolutionEnv): GlobalMarker {\n if ('point' in ref) {\n return { type: 'point', p: [ref.point[0], ref.point[1], ref.point[2]] }\n }\n if ('face' in ref) {\n const geom = resolveFaceGeometryOfRef(ref, env)\n const normal = vnormalize([geom.normal[0], geom.normal[1], geom.normal[2]])\n return {\n type: 'plane',\n center: [geom.center[0], geom.center[1], geom.center[2]],\n normal,\n }\n }\n // edge / faceIndex → 走 resolveSolverEntity(统一抽取)\n const se = resolveSolverEntity(ref, env)\n if (se.type === 'axis') {\n return {\n type: 'axis',\n origin: [se.origin[0], se.origin[1], se.origin[2]],\n // `direction` is optional in the vendored SolverEntity type but always present for the\n // axis branch produced by resolveSolverEntity (cylinder/cone face, or edge axis snapshot).\n dir: vnormalize([se.direction![0], se.direction![1], se.direction![2]]),\n }\n }\n if (se.type === 'plane') {\n return {\n type: 'plane',\n center: [se.origin[0], se.origin[1], se.origin[2]],\n // `normal` is optional in the vendored SolverEntity type but always present for the plane branch.\n normal: vnormalize([se.normal![0], se.normal![1], se.normal![2]]),\n }\n }\n return { type: 'point', p: [se.origin[0], se.origin[1], se.origin[2]] }\n}\n\nfunction markerPoint(m: GlobalMarker, R: Vec3, T: Vec3): Vec3 {\n const base = m.type === 'point' ? m.p : m.type === 'axis' ? m.origin : m.center\n return vadd(rotateByR(base, R), T)\n}\nfunction markerDir(m: GlobalMarker, R: Vec3): Vec3 {\n // point markers never reach here (axis cost / plane normal / line direction only);\n // narrow to axis/plane and fall back to the point for type-completeness.\n const base = m.type === 'axis' ? m.dir : m.type === 'plane' ? m.normal : m.p\n return rotateByR(base, R)\n}\n\n/** 计算单条代价项的残差向量(平方前内层量,裁定 3)。 */\nfunction termResidual(t: CostTerm, sa: { T: Vec3; R: Vec3 }, sb: { T: Vec3; R: Vec3 }, scale: number): number[] {\n const inv = t.scaleFlag ? 1 / scale : 1\n switch (t.fn) {\n case 'point': {\n const pa = markerPoint(t.ma, sa.R, sa.T)\n const pb = markerPoint(t.mb, sb.R, sb.T)\n const d = vscale(vsub(pa, pb), inv)\n if (Math.abs(t.val) < 1e-12) return d // 3-vec,val=0\n return [vsumsqr(d) - (t.val / scale) ** 2] // 1-vec,val≠0\n }\n case 'axis': {\n const d1 = markerDir(t.ma, sa.R)\n const d2 = markerDir(t.mb, sb.R)\n if (Math.abs(t.val) < 1e-12) return vsub(d1, d2) // 3-vec,val=0\n if (Math.abs(t.val - Math.PI) < 1e-12) return vadd(d1, d2) // 3-vec,val=π\n return [vdot(d1, d2) - Math.cos(t.val)] // 1-vec,其他\n }\n case 'point_in_plane': {\n const p1 = markerPoint(t.ma, sa.R, sa.T) // 点\n const n = markerDir(t.mb, sb.R) // 平面法向\n let c = markerPoint(t.mb, sb.R, sb.T) // 平面上一点\n if (Math.abs(t.val) > 1e-12) c = vadd(c, vscale(n, t.val)) // 沿法向平移 val(CQ m2_pnt 偏移)\n const d = vdot(n, vsub(c, p1)) * inv\n return [d] // 1-vec\n }\n case 'point_on_line': {\n const p1 = markerPoint(t.ma, sa.R, sa.T) // 点\n const o = markerPoint(t.mb, sb.R, sb.T) // 线上一点\n const dln = markerDir(t.mb, sb.R) // 线方向\n const delta = vsub(p1, o)\n const perp = vscale(vsub(delta, vscale(dln, vdot(delta, dln))), inv)\n if (Math.abs(t.val) < 1e-12) return perp // 3-vec,val=0\n return [vsumsqr(perp) - t.val] // 1-vec,val≠0(注意 val 不缩放)\n }\n }\n}\n\n/**\n * 纯 TS global 求解器入口。\n *\n * @param members - member shapes(与 memberNames 对齐)。\n * @param memberNames - 成员变量名(约束以名引用,空名会抛错)。\n * @param constraints - 规范化前的原始约束。\n * @param opts - 求解选项(solver 已在外层判定为 'global',此处 name 用于 B4 锚定)。\n * @returns 与 `AssemblySolveResult` 对齐的结果。\n */\nexport function solveGlobal(\n members: Shape[],\n memberNames: string[],\n constraints: AssemblyConstraint[],\n opts?: SolveOptions,\n): GlobalSolveResult {\n memberNames.forEach((name, i) => {\n if (!name) {\n throw new Error(`[assembly:global] member at index ${i} has an empty name`)\n }\n })\n\n const memberMap = new Map<string, Shape>()\n members.forEach((m, i) => {\n const name = memberNames[i]\n if (name && !memberMap.has(name)) memberMap.set(name, m)\n })\n\n let kernel: BrepEngineApi | null = null\n try {\n kernel = getBrepApi()\n } catch {\n /* mesh/primitive 行快照路径:快照引用仍可解 */\n }\n const env: EntityResolutionEnv = { kernel, memberOf: (p: string) => memberMap.get(p) }\n\n // ── 建立代价项、锁定集、尺度点 ──\n const terms: CostTerm[] = []\n const unsupported: string[] = []\n const lockedSet = new Set<number>()\n const order: string[] = []\n const binaryOrder: string[] = []\n const unarySet = new Set<string>()\n const scalePts: Vec3[] = []\n\n constraints.forEach((raw, cid) => {\n const c = normalizeConstraint(raw)\n const register = (p: string) => {\n if (!order.includes(p)) order.push(p)\n }\n if (c.type === 'fixed') {\n register(c.part)\n unarySet.add(c.part)\n const idx = memberNames.indexOf(c.part)\n if (idx >= 0) lockedSet.add(idx)\n return\n }\n const ia = memberNames.indexOf(c.a.part)\n const ib = memberNames.indexOf(c.b.part)\n if (ia < 0 || ib < 0) {\n unsupported.push(`constraint references unknown part: ${ia < 0 ? c.a.part : c.b.part}`)\n return\n }\n if (!binaryOrder.includes(c.a.part)) binaryOrder.push(c.a.part)\n register(c.a.part)\n register(c.b.part)\n if (c.a.part === opts?.name) lockedSet.add(ia)\n if (c.b.part === opts?.name) lockedSet.add(ib)\n\n const mA = resolveMarker(c.a, env)\n const mB = resolveMarker(c.b, env)\n scalePts.push(markerPoint(mA, [0, 0, 0], [0, 0, 0]))\n scalePts.push(markerPoint(mB, [0, 0, 0], [0, 0, 0]))\n\n switch (c.type) {\n case 'mate':\n case 'align': {\n if (mA.type !== 'plane' || mB.type !== 'plane') {\n unsupported.push(`${c.type} requires plane entities on both sides`)\n return\n }\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: c.type === 'mate' ? Math.PI : 0, scaleFlag: false })\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n break\n }\n case 'coincident': {\n pushCoincident(terms, cid, ia, mA, ib, mB)\n break\n }\n case 'concentric': {\n if (mA.type !== 'axis' || mB.type !== 'axis') {\n unsupported.push('concentric requires axis entities on both sides')\n return\n }\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val: 0, scaleFlag: true })\n break\n }\n case 'distance': {\n pushDistance(terms, cid, ia, mA, ib, mB, c.value, unsupported)\n break\n }\n case 'angle': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: c.value * DEG2RAD, scaleFlag: false })\n break\n }\n case 'parallel': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n break\n }\n case 'perpendicular': {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: Math.PI / 2, scaleFlag: false })\n break\n }\n default:\n unsupported.push(`unsupported constraint type: ${(c as { type?: string }).type}`)\n }\n })\n\n // ── B4 锚定 ──\n if (lockedSet.size === 0) {\n for (const b of binaryOrder) {\n if (!unarySet.has(b)) {\n const idx = memberNames.indexOf(b)\n if (idx >= 0) {\n lockedSet.add(idx)\n break\n }\n }\n }\n }\n if (lockedSet.size === 0 && order.length > 0) {\n const idx = memberNames.indexOf(order[0])\n if (idx >= 0) lockedSet.add(idx)\n }\n\n // ── scale = 所有 marker 点的包围盒对角长(CQ B5;marker 近似几何 bbox) ──\n const scale = computeScale(scalePts)\n\n // ── 自由成员与变量 ──\n const freeIdx: number[] = []\n const blockMap = new Map<number, number>()\n memberNames.forEach((_, i) => {\n if (!lockedSet.has(i)) {\n blockMap.set(i, freeIdx.length)\n freeIdx.push(i)\n }\n })\n const n = freeIdx.length * 6\n const x = new Array(n).fill(0)\n for (let k = 0; k < freeIdx.length; k++) {\n x[6 * k + 3] = R_INIT\n x[6 * k + 4] = R_INIT\n x[6 * k + 5] = R_INIT\n }\n\n const stateOf = (xx: number[], i: number): { T: Vec3; R: Vec3 } => {\n if (lockedSet.has(i)) return { T: [0, 0, 0], R: [0, 0, 0] }\n const k = blockMap.get(i)!\n return {\n T: [xx[6 * k], xx[6 * k + 1], xx[6 * k + 2]],\n R: [xx[6 * k + 3], xx[6 * k + 4], xx[6 * k + 5]],\n }\n }\n\n const residual = (xx: number[]): number[] => {\n const r: number[] = []\n for (const t of terms) {\n const e = termResidual(t, stateOf(xx, t.ia), stateOf(xx, t.ib), scale)\n for (const v of e) r.push(v)\n }\n // penalty 1e-16(B1):sqrt 后 1e-8,T/scale 缩小、R 直接\n for (let k = 0; k < freeIdx.length; k++) {\n r.push(PENALTY ** 0.5 * (xx[6 * k] / scale))\n r.push(PENALTY ** 0.5 * (xx[6 * k + 1] / scale))\n r.push(PENALTY ** 0.5 * (xx[6 * k + 2] / scale))\n r.push(PENALTY ** 0.5 * xx[6 * k + 3])\n r.push(PENALTY ** 0.5 * xx[6 * k + 4])\n r.push(PENALTY ** 0.5 * xx[6 * k + 5])\n }\n return r\n }\n\n // ── LM 迭代 ──\n let lambda = LM_LAMBDA0\n let current = residual(x)\n let obj = 0.5 * dot(current, current)\n\n for (let iter = 0; iter < LM_MAXITER; iter++) {\n const m = current.length\n const J = new Array(m * n).fill(0)\n for (let col = 0; col < n; col++) {\n const h = col % 6 < 3 ? 1e-7 * scale : 1e-7\n const xp = x.slice()\n const xm = x.slice()\n xp[col] += h\n xm[col] -= h\n const rp = residual(xp)\n const rm = residual(xm)\n for (let row = 0; row < m; row++) J[row * n + col] = (rp[row] - rm[row]) / (2 * h)\n }\n const JtJ = ata(J, m, n)\n const Jtr = atb(J, current, m, n)\n\n // 梯度范数收敛(与步长早停互补,避免 λ 放大时误判收敛)\n if (maxAbs(Jtr) < 1e-8) {\n break\n }\n\n const negJtr = Jtr.map((v) => -v)\n const objBefore = obj\n let improved = false\n let acceptedStep: number[] | null = null\n for (let attempt = 0; attempt < 12 && !improved; attempt++) {\n const step = solveDampedNormal(JtJ, negJtr, n, lambda)\n if (!step) break\n const xTry = x.slice()\n for (let j = 0; j < n; j++) xTry[j] += step[j]\n const rTry = residual(xTry)\n const objTry = 0.5 * dot(rTry, rTry)\n if (objTry <= obj) {\n for (let j = 0; j < n; j++) x[j] = xTry[j]\n current = rTry\n obj = objTry\n improved = true\n acceptedStep = step\n lambda = Math.max(lambda / 3, 1e-15)\n } else {\n lambda *= 2\n }\n }\n if (!improved) break\n\n // 步长收敛仅在信任域健康(λ 小)时认定——λ 大时的微小步长只是阻尼,非真收敛\n if (acceptedStep && maxAbs(acceptedStep) < LM_TOL_STEP && lambda < 1e-2) {\n break\n }\n if (Math.abs(objBefore - obj) < LM_TOL_OBJ * Math.max(1, Math.abs(objBefore))) {\n break\n }\n }\n\n // ── 组装结果 ──\n const transforms: AssemblyTransform[] = []\n for (let k = 0; k < freeIdx.length; k++) {\n const i = freeIdx[k]\n const T: Vec3 = [x[6 * k], x[6 * k + 1], x[6 * k + 2]]\n const R: Vec3 = [x[6 * k + 3], x[6 * k + 4], x[6 * k + 5]]\n const pose: SolverPose = { position: T, rotation: quatFromR(R[0], R[1], R[2]) }\n transforms.push(poseToAssemblyTransform(pose, [0, 0, 0], i))\n }\n\n // 逐约束残差(诊断)\n const residuals: number[] = []\n const warnings: string[] = []\n const byCid = new Map<number, number>()\n for (const t of terms) {\n const e = termResidual(t, stateOf(x, t.ia), stateOf(x, t.ib), scale)\n const s = e.reduce((acc, v) => acc + v * v, 0)\n byCid.set(t.cid, (byCid.get(t.cid) ?? 0) + s)\n }\n constraints.forEach((_, cid) => {\n const r = byCid.get(cid) ?? 0\n residuals.push(r)\n if (r > RESIDUAL_WARN * scale) warnings.push(`constraint #${cid} residual=${r.toExponential(3)} (> ${RESIDUAL_WARN * scale})`)\n })\n\n return {\n transforms,\n dof: 0,\n converged: true,\n unsupported,\n residuals,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n\nfunction pushCoincident(terms: CostTerm[], cid: number, ia: number, mA: GlobalMarker, ib: number, mB: GlobalMarker): void {\n if (mA.type === 'point' && mB.type === 'point') {\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'plane' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_in_plane', ia: ib, ma: mB, ib: ia, mb: mA, val: 0, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'plane') {\n terms.push({ cid, fn: 'point_in_plane', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'axis') {\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val: 0, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_on_line', ia: ib, ma: mB, ib, mb: mA, val: 0, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'axis') {\n terms.push({ cid, fn: 'point_on_line', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n } else {\n // 两面 coincident:按 align 语义(平行 + 中心重合)\n terms.push({ cid, fn: 'axis', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: false })\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val: 0, scaleFlag: true })\n }\n}\n\nfunction pushDistance(\n terms: CostTerm[],\n cid: number,\n ia: number,\n mA: GlobalMarker,\n ib: number,\n mB: GlobalMarker,\n val: number,\n unsupported: string[],\n): void {\n if (mA.type === 'point' && mB.type === 'point') {\n terms.push({ cid, fn: 'point', ia, ma: mA, ib, mb: mB, val, scaleFlag: true })\n } else if (mA.type === 'plane' && mB.type === 'point') {\n terms.push({ cid, fn: 'point_in_plane', ia: ib, ma: mB, ib: ia, mb: mA, val, scaleFlag: true })\n } else if (mA.type === 'point' && mB.type === 'plane') {\n terms.push({ cid, fn: 'point_in_plane', ia, ma: mA, ib, mb: mB, val, scaleFlag: true })\n } else if (mA.type === 'axis' && mB.type === 'axis') {\n terms.push({ cid, fn: 'point_on_line', ia, ma: { type: 'point', p: mA.origin }, ib, mb: mB, val, scaleFlag: true })\n } else {\n unsupported.push(`distance requires point-point / plane-point / axis-axis entities, got ${mA.type}-${mB.type}`)\n }\n}\n\nfunction computeScale(pts: Vec3[]): number {\n if (pts.length === 0) return 1\n const min: Vec3 = [Infinity, Infinity, Infinity]\n const max: Vec3 = [-Infinity, -Infinity, -Infinity]\n for (const p of pts) {\n for (let i = 0; i < 3; i++) {\n if (p[i] < min[i]) min[i] = p[i]\n if (p[i] > max[i]) max[i] = p[i]\n }\n }\n const diag = Math.hypot(max[0] - min[0], max[1] - min[1], max[2] - min[2])\n return Math.max(diag, 1e-6)\n}\n\nfunction dot(a: number[], b: number[]): number {\n let s = 0\n for (let i = 0; i < a.length; i++) s += a[i] * b[i]\n return s\n}\nfunction maxAbs(a: number[]): number {\n let m = 0\n for (const v of a) m = Math.max(m, Math.abs(v))\n return m\n}\n"]}
|