brepjs 18.72.0 → 18.73.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/dist/brepjs.cjs CHANGED
@@ -2208,6 +2208,17 @@ function quatFromTo(from, to) {
2208
2208
  c[2] / len
2209
2209
  ];
2210
2210
  }
2211
+ /** Hamilton product `a ⊗ b` — the rotation that applies `b` first, then `a`. */
2212
+ function quatMultiply(a, b) {
2213
+ const [aw, ax, ay, az] = a;
2214
+ const [bw, bx, by, bz] = b;
2215
+ return [
2216
+ aw * bw - ax * bx - ay * by - az * bz,
2217
+ aw * bx + ax * bw + ay * bz - az * by,
2218
+ aw * by - ax * bz + ay * bw + az * bx,
2219
+ aw * bz + ax * by - ay * bx + az * bw
2220
+ ];
2221
+ }
2211
2222
  //#endregion
2212
2223
  //#region src/kernel/solverAdapter.ts
2213
2224
  /**
@@ -2697,6 +2708,95 @@ function addJoint(assembly, joint) {
2697
2708
  joints: [...existing, joint]
2698
2709
  };
2699
2710
  }
2711
+ var IDENTITY_POSE = {
2712
+ position: [
2713
+ 0,
2714
+ 0,
2715
+ 0
2716
+ ],
2717
+ rotation: [
2718
+ 1,
2719
+ 0,
2720
+ 0,
2721
+ 0
2722
+ ]
2723
+ };
2724
+ /** Compose two poses: the result applies `b` in `a`'s frame (`a ∘ b`). */
2725
+ function composePose(a, b) {
2726
+ const rb = quatRotate(a.rotation, b.position);
2727
+ return {
2728
+ position: [
2729
+ a.position[0] + rb[0],
2730
+ a.position[1] + rb[1],
2731
+ a.position[2] + rb[2]
2732
+ ],
2733
+ rotation: quatMultiply(a.rotation, b.rotation)
2734
+ };
2735
+ }
2736
+ /** Collect every joint attached anywhere in the assembly tree. */
2737
+ function collectJoints(assembly) {
2738
+ const joints = [];
2739
+ require_historyFns.walkAssembly(assembly, (node) => {
2740
+ if (node.joints) joints.push(...node.joints);
2741
+ });
2742
+ return joints;
2743
+ }
2744
+ /**
2745
+ * Forward kinematics: set joint values and propagate world poses down the
2746
+ * kinematic chain. Each joint's axis is interpreted in its **parent's** frame,
2747
+ * so a child's world pose is `parentWorld ∘ jointTransform(joint, value)`.
2748
+ *
2749
+ * Bodies not driven by a joint (chain roots) start at the origin. `jointValues`
2750
+ * overrides a joint's stored value, keyed by the **child** node name; omitted
2751
+ * joints use `joint.value`. Resolution is topological (reuses the Phase-0
2752
+ * ordering), so chains of any depth compose. Returns a world pose for every node.
2753
+ */
2754
+ function forwardKinematics(assembly, jointValues = {}) {
2755
+ const joints = [];
2756
+ const names = /* @__PURE__ */ new Set();
2757
+ require_historyFns.walkAssembly(assembly, (node) => {
2758
+ names.add(node.name);
2759
+ if (node.joints) joints.push(...node.joints);
2760
+ });
2761
+ const byChild = /* @__PURE__ */ new Map();
2762
+ for (const j of joints) {
2763
+ byChild.set(j.child, j);
2764
+ names.add(j.parent);
2765
+ names.add(j.child);
2766
+ }
2767
+ const poses = /* @__PURE__ */ new Map();
2768
+ for (const name of names) if (!byChild.has(name)) poses.set(name, IDENTITY_POSE);
2769
+ const pending = [...joints];
2770
+ let progress = true;
2771
+ while (progress && pending.length > 0) {
2772
+ progress = false;
2773
+ for (let i = pending.length - 1; i >= 0; i--) {
2774
+ const j = pending[i];
2775
+ if (!j) continue;
2776
+ const parentPose = poses.get(j.parent);
2777
+ if (!parentPose) continue;
2778
+ pending.splice(i, 1);
2779
+ progress = true;
2780
+ if (poses.has(j.child)) continue;
2781
+ const value = jointValues[j.child] ?? j.value;
2782
+ poses.set(j.child, composePose(parentPose, jointTransform(j, value)));
2783
+ }
2784
+ }
2785
+ for (const j of pending) if (!poses.has(j.child)) poses.set(j.child, IDENTITY_POSE);
2786
+ return poses;
2787
+ }
2788
+ var JOINT_FREEDOM = {
2789
+ revolute: 1,
2790
+ prismatic: 1
2791
+ };
2792
+ /**
2793
+ * Open-chain mobility — the number of independent degrees of freedom. Each
2794
+ * revolute/prismatic joint contributes 1, so for a serial chain this equals the
2795
+ * joint count. (Closed-loop Grübler/Kutzbach analysis is future work.)
2796
+ */
2797
+ function mechanismDOF(assembly) {
2798
+ return collectJoints(assembly).reduce((sum, j) => sum + JOINT_FREEDOM[j.type], 0);
2799
+ }
2700
2800
  //#endregion
2701
2801
  //#region src/measurement/interferenceFns.ts
2702
2802
  /**
@@ -6692,6 +6792,7 @@ exports.flatten = require_errors.flatten;
6692
6792
  exports.flipFaceOrientation = require_faceFns.flipFaceOrientation;
6693
6793
  exports.flipOrientation = require_curveFns.flipOrientation;
6694
6794
  exports.fontMetrics = require_textMetrics.fontMetrics;
6795
+ exports.forwardKinematics = forwardKinematics;
6695
6796
  exports.fromBREP = fromBREP$1;
6696
6797
  exports.fromKernelDir = fromKernelDir;
6697
6798
  exports.fromKernelPnt = fromKernelPnt;
@@ -6853,6 +6954,7 @@ Object.defineProperty(exports, "measurement", {
6853
6954
  return measurement_exports;
6854
6955
  }
6855
6956
  });
6957
+ exports.mechanismDOF = mechanismDOF;
6856
6958
  exports.mesh = mesh;
6857
6959
  exports.meshEdges = meshEdges;
6858
6960
  exports.meshMultiLOD = require_meshFns.meshMultiLOD;
package/dist/brepjs.js CHANGED
@@ -2219,6 +2219,17 @@ function quatFromTo(from, to) {
2219
2219
  c[2] / len
2220
2220
  ];
2221
2221
  }
2222
+ /** Hamilton product `a ⊗ b` — the rotation that applies `b` first, then `a`. */
2223
+ function quatMultiply(a, b) {
2224
+ const [aw, ax, ay, az] = a;
2225
+ const [bw, bx, by, bz] = b;
2226
+ return [
2227
+ aw * bw - ax * bx - ay * by - az * bz,
2228
+ aw * bx + ax * bw + ay * bz - az * by,
2229
+ aw * by - ax * bz + ay * bw + az * bx,
2230
+ aw * bz + ax * by - ay * bx + az * bw
2231
+ ];
2232
+ }
2222
2233
  //#endregion
2223
2234
  //#region src/kernel/solverAdapter.ts
2224
2235
  /**
@@ -2708,6 +2719,95 @@ function addJoint(assembly, joint) {
2708
2719
  joints: [...existing, joint]
2709
2720
  };
2710
2721
  }
2722
+ var IDENTITY_POSE = {
2723
+ position: [
2724
+ 0,
2725
+ 0,
2726
+ 0
2727
+ ],
2728
+ rotation: [
2729
+ 1,
2730
+ 0,
2731
+ 0,
2732
+ 0
2733
+ ]
2734
+ };
2735
+ /** Compose two poses: the result applies `b` in `a`'s frame (`a ∘ b`). */
2736
+ function composePose(a, b) {
2737
+ const rb = quatRotate(a.rotation, b.position);
2738
+ return {
2739
+ position: [
2740
+ a.position[0] + rb[0],
2741
+ a.position[1] + rb[1],
2742
+ a.position[2] + rb[2]
2743
+ ],
2744
+ rotation: quatMultiply(a.rotation, b.rotation)
2745
+ };
2746
+ }
2747
+ /** Collect every joint attached anywhere in the assembly tree. */
2748
+ function collectJoints(assembly) {
2749
+ const joints = [];
2750
+ walkAssembly(assembly, (node) => {
2751
+ if (node.joints) joints.push(...node.joints);
2752
+ });
2753
+ return joints;
2754
+ }
2755
+ /**
2756
+ * Forward kinematics: set joint values and propagate world poses down the
2757
+ * kinematic chain. Each joint's axis is interpreted in its **parent's** frame,
2758
+ * so a child's world pose is `parentWorld ∘ jointTransform(joint, value)`.
2759
+ *
2760
+ * Bodies not driven by a joint (chain roots) start at the origin. `jointValues`
2761
+ * overrides a joint's stored value, keyed by the **child** node name; omitted
2762
+ * joints use `joint.value`. Resolution is topological (reuses the Phase-0
2763
+ * ordering), so chains of any depth compose. Returns a world pose for every node.
2764
+ */
2765
+ function forwardKinematics(assembly, jointValues = {}) {
2766
+ const joints = [];
2767
+ const names = /* @__PURE__ */ new Set();
2768
+ walkAssembly(assembly, (node) => {
2769
+ names.add(node.name);
2770
+ if (node.joints) joints.push(...node.joints);
2771
+ });
2772
+ const byChild = /* @__PURE__ */ new Map();
2773
+ for (const j of joints) {
2774
+ byChild.set(j.child, j);
2775
+ names.add(j.parent);
2776
+ names.add(j.child);
2777
+ }
2778
+ const poses = /* @__PURE__ */ new Map();
2779
+ for (const name of names) if (!byChild.has(name)) poses.set(name, IDENTITY_POSE);
2780
+ const pending = [...joints];
2781
+ let progress = true;
2782
+ while (progress && pending.length > 0) {
2783
+ progress = false;
2784
+ for (let i = pending.length - 1; i >= 0; i--) {
2785
+ const j = pending[i];
2786
+ if (!j) continue;
2787
+ const parentPose = poses.get(j.parent);
2788
+ if (!parentPose) continue;
2789
+ pending.splice(i, 1);
2790
+ progress = true;
2791
+ if (poses.has(j.child)) continue;
2792
+ const value = jointValues[j.child] ?? j.value;
2793
+ poses.set(j.child, composePose(parentPose, jointTransform(j, value)));
2794
+ }
2795
+ }
2796
+ for (const j of pending) if (!poses.has(j.child)) poses.set(j.child, IDENTITY_POSE);
2797
+ return poses;
2798
+ }
2799
+ var JOINT_FREEDOM = {
2800
+ revolute: 1,
2801
+ prismatic: 1
2802
+ };
2803
+ /**
2804
+ * Open-chain mobility — the number of independent degrees of freedom. Each
2805
+ * revolute/prismatic joint contributes 1, so for a serial chain this equals the
2806
+ * joint count. (Closed-loop Grübler/Kutzbach analysis is future work.)
2807
+ */
2808
+ function mechanismDOF(assembly) {
2809
+ return collectJoints(assembly).reduce((sum, j) => sum + JOINT_FREEDOM[j.type], 0);
2810
+ }
2711
2811
  //#endregion
2712
2812
  //#region src/measurement/interferenceFns.ts
2713
2813
  /**
@@ -6478,4 +6578,4 @@ var csg_exports = /* @__PURE__ */ __exportAll({
6478
6578
  withEvaluator: () => withEvaluator
6479
6579
  });
6480
6580
  //#endregion
6481
- export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, init, initFromManifold, initFromOC, initVoxel, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTransform, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
6581
+ export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, forwardKinematics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, init, initFromManifold, initFromOC, initVoxel, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTransform, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mechanismDOF, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
package/dist/index.d.ts CHANGED
@@ -121,7 +121,7 @@ export { exportAssemblySTEP, type ShapeOptions, type SupportedUnit, } from './op
121
121
  export { linearPattern, circularPattern } from './operations/patternFns.js';
122
122
  export { createAssemblyNode, addChild, removeChild, updateNode, findNode, walkAssembly, countNodes, collectShapes, type AssemblyNode, type AssemblyNodeOptions, } from './operations/assemblyFns.js';
123
123
  export { addMate, solveAssembly, type MateConstraint, type MateEntity, type AssemblySolveResult, } from './operations/mateFns.js';
124
- export { revoluteJoint, prismaticJoint, setJointValue, jointTransform, addJoint, type Joint, type JointAxis, type JointType, type JointPose, type JointOptions, } from './operations/jointFns.js';
124
+ export { revoluteJoint, prismaticJoint, setJointValue, jointTransform, addJoint, forwardKinematics, mechanismDOF, type Joint, type JointAxis, type JointType, type JointPose, type JointOptions, } from './operations/jointFns.js';
125
125
  export { createHistory, addStep, undoLast, findStep, getShape as getHistoryShape, stepCount, stepsFrom, registerShape, createRegistry, registerOperation, replayHistory, replayFrom, modifyStep, serializeHistory, deserializeHistory, type OperationStep, type ModelHistory, type SerializedHistory, type OperationFn, type OperationRegistry as HistoryOperationRegistry, } from './operations/historyFns.js';
126
126
  export { measureVolume, measureArea, measureLength, measureDistance, measureDistanceProps, createDistanceQuery, measureVolumeProps, measureSurfaceProps, measureLinearProps, type PhysicalProps, type VolumeProps, type SurfaceProps, type LinearProps, type DistanceProps, measureCurvatureAt, measureCurvatureAtMid, type CurvatureResult, } from './measurement/measureFns.js';
127
127
  export { checkInterference, checkAllInterferences, type InterferenceResult, type InterferencePair, } from './measurement/interferenceFns.js';
@@ -53,3 +53,20 @@ export declare function setJointValue(joint: Joint, value: number): Joint;
53
53
  export declare function jointTransform(joint: Joint, value?: number): JointPose;
54
54
  /** Attach a joint to an assembly node. Returns a new node (immutable). */
55
55
  export declare function addJoint(assembly: AssemblyNode, joint: Joint): AssemblyNode;
56
+ /**
57
+ * Forward kinematics: set joint values and propagate world poses down the
58
+ * kinematic chain. Each joint's axis is interpreted in its **parent's** frame,
59
+ * so a child's world pose is `parentWorld ∘ jointTransform(joint, value)`.
60
+ *
61
+ * Bodies not driven by a joint (chain roots) start at the origin. `jointValues`
62
+ * overrides a joint's stored value, keyed by the **child** node name; omitted
63
+ * joints use `joint.value`. Resolution is topological (reuses the Phase-0
64
+ * ordering), so chains of any depth compose. Returns a world pose for every node.
65
+ */
66
+ export declare function forwardKinematics(assembly: AssemblyNode, jointValues?: Readonly<Record<string, number>>): Map<string, JointPose>;
67
+ /**
68
+ * Open-chain mobility — the number of independent degrees of freedom. Each
69
+ * revolute/prismatic joint contributes 1, so for a serial chain this equals the
70
+ * joint count. (Closed-loop Grübler/Kutzbach analysis is future work.)
71
+ */
72
+ export declare function mechanismDOF(assembly: AssemblyNode): number;
@@ -13,3 +13,5 @@ export declare function quatRotate(q: Quat, v: Vec3): [number, number, number];
13
13
  export declare function quatFromAxisAngle(axis: Vec3, angle: number): [number, number, number, number];
14
14
  /** Shortest-arc quaternion rotating unit vector `from` onto unit vector `to`. */
15
15
  export declare function quatFromTo(from: Vec3, to: Vec3): [number, number, number, number];
16
+ /** Hamilton product `a ⊗ b` — the rotation that applies `b` first, then `a`. */
17
+ export declare function quatMultiply(a: Quat, b: Quat): [number, number, number, number];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brepjs",
3
- "version": "18.72.0",
3
+ "version": "18.73.0",
4
4
  "description": "Web CAD library with pluggable geometry kernel",
5
5
  "keywords": [
6
6
  "cad",