brepjs 18.81.1 → 18.82.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 +4 -1
- package/dist/brepjs.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/operations/dhFns.d.ts +34 -0
- package/dist/operations/jointFns.d.ts +7 -0
- package/dist/operations/urdfFns.d.ts +33 -0
- package/dist/operations.cjs +4 -1
- package/dist/operations.d.ts +2 -0
- package/dist/operations.js +2 -2
- package/dist/{threadFns-YzJhd0Kz.js → threadFns-D0TPhxRK.js} +260 -5
- package/dist/{threadFns-By0Gy2f9.cjs → threadFns-DOAHxp0G.cjs} +276 -3
- package/package.json +1 -1
package/dist/brepjs.cjs
CHANGED
|
@@ -17,7 +17,7 @@ const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
|
|
|
17
17
|
const require_surfaceBuilders = require("./surfaceBuilders-B8aVZamB.cjs");
|
|
18
18
|
const require_primitiveFns = require("./primitiveFns-DEBQdEkG.cjs");
|
|
19
19
|
const require_healingFns = require("./healingFns--PtL9j2K.cjs");
|
|
20
|
-
const require_threadFns = require("./threadFns-
|
|
20
|
+
const require_threadFns = require("./threadFns-DOAHxp0G.cjs");
|
|
21
21
|
const require_blueprintSketcher = require("./blueprintSketcher-BJPBKhF3.cjs");
|
|
22
22
|
const require_helpers = require("./helpers-B8mE35Fm.cjs");
|
|
23
23
|
const require_drawFns = require("./drawFns-DTpCthM5.cjs");
|
|
@@ -6645,6 +6645,7 @@ exports.exportSTEP = require_meshFns.exportSTEP;
|
|
|
6645
6645
|
exports.exportSTEPConfigured = require_importFns.exportSTEPConfigured;
|
|
6646
6646
|
exports.exportSTL = require_meshFns.exportSTL;
|
|
6647
6647
|
exports.exportThreeMF = require_importFns.exportThreeMF;
|
|
6648
|
+
exports.exportURDF = require_threadFns.exportURDF;
|
|
6648
6649
|
exports.extrude = extrude;
|
|
6649
6650
|
exports.extrudeAll = require_loftFns.extrudeAll;
|
|
6650
6651
|
exports.face = require_primitiveFns.face;
|
|
@@ -6734,6 +6735,7 @@ exports.importSTL = require_importFns.importSTL;
|
|
|
6734
6735
|
exports.importSVG = require_importFns.importSVG;
|
|
6735
6736
|
exports.importSVGPathD = require_importFns.importSVGPathD;
|
|
6736
6737
|
exports.importThreeMF = importThreeMF;
|
|
6738
|
+
exports.importURDF = require_threadFns.importURDF;
|
|
6737
6739
|
exports.init = require_shapeTypes.init;
|
|
6738
6740
|
exports.initFromManifold = require_shapeTypes.initFromManifold;
|
|
6739
6741
|
exports.initFromOC = require_shapeTypes.initFromOC;
|
|
@@ -6799,6 +6801,7 @@ exports.iterVertices = require_topologyQueryFns.iterVertices;
|
|
|
6799
6801
|
exports.iterWires = require_topologyQueryFns.iterWires;
|
|
6800
6802
|
exports.jointTrajectory = require_threadFns.jointTrajectory;
|
|
6801
6803
|
exports.jointTransform = require_threadFns.jointTransform;
|
|
6804
|
+
exports.jointsFromDH = require_threadFns.jointsFromDH;
|
|
6802
6805
|
exports.kernelCall = require_topologyQueryFns.kernelCall;
|
|
6803
6806
|
exports.kernelCallRaw = require_topologyQueryFns.kernelCallRaw;
|
|
6804
6807
|
exports.kernelCallScoped = require_topologyQueryFns.kernelCallScoped;
|
package/dist/brepjs.js
CHANGED
|
@@ -15,7 +15,7 @@ import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayA
|
|
|
15
15
|
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, r as makeFace, s as assembleWire } from "./surfaceBuilders-hTXdNCYm.js";
|
|
16
16
|
import { A as cutAll, C as threePointArc, D as wireLoop, E as wire, F as sectionToFace$1, I as slice$1, L as split$1, M as fuseAll, N as intersect$2, O as booleanPipeline, P as section$1, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere$1, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, j as fuse$2, k as cut$2, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus$1, x as subFace, y as solid } from "./primitiveFns-BSKbI4Kl.js";
|
|
17
17
|
import { A as edgesOfFace, C as shellWithEvolution, D as getNurbsCurveData, E as fuseAllBisect, F as chamferDistAngle, I as toBufferGeometryData, L as toGroupedBufferGeometryData, M as sharedEdges, N as verticesOfEdge, O as getNurbsSurfaceData, P as wiresOfFace, R as toLODGeometryData, S as intersectWithEvolution, T as cutAllBisect, _ as positionOnCurve, a as healFace, b as filletWithEvolution, c as isValid$1, d as draft$1, f as fillet$1, g as variableFillet, h as thicken$1, i as heal$1, j as facesOfEdge, k as adjacentFaces, l as solidFromShell, m as shell$1, n as fixSelfIntersection, o as healSolid, p as offset$1, r as fixShape, s as healWire, t as autoHeal, u as chamfer$1, v as chamferWithEvolution, w as checkBoolean, x as fuseWithEvolution, y as cutWithEvolution, z as toLineGeometryData } from "./healingFns-Bm-NdBj_.js";
|
|
18
|
-
import { A as
|
|
18
|
+
import { A as setJointValue, B as findNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as quatRotate, H as updateNode, I as addChild, J as createAssembly, K as linearPattern, L as collectShapes, M as sphericalJoint, N as quatFromAxisAngle, O as prismaticJoint, P as quatFromTo, R as countNodes, S as addJoint, T as jointTransform, U as walkAssembly, V as removeChild, W as circularPattern, _ as exportURDF, a as deserializeHistory, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, p as serializeHistory, q as exportAssemblySTEP, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as createAssemblyNode } from "./threadFns-D0TPhxRK.js";
|
|
19
19
|
import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-EYqKWQh0.js";
|
|
20
20
|
import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-CD8EMZ5l.js";
|
|
21
21
|
import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-D_LwehLr.js";
|
|
@@ -6457,4 +6457,4 @@ var csg_exports = /* @__PURE__ */ __exportAll({
|
|
|
6457
6457
|
withEvaluator: () => withEvaluator
|
|
6458
6458
|
});
|
|
6459
6459
|
//#endregion
|
|
6460
|
-
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, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, 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, inverseKinematics, 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, jointTrajectory, 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, planarJoint, 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, setJointValues, 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, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, 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 };
|
|
6460
|
+
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, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, 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, exportURDF, 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, importURDF, init, initFromManifold, initFromOC, initVoxel, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, inverseKinematics, 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, jointTrajectory, jointTransform, jointsFromDH, 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, planarJoint, 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, setJointValues, 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, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, 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
|
@@ -123,6 +123,8 @@ export { createAssemblyNode, addChild, removeChild, updateNode, findNode, walkAs
|
|
|
123
123
|
export { addMate, solveAssembly, type MateConstraint, type MateEntity, type AssemblySolveResult, } from './operations/mateFns.js';
|
|
124
124
|
export { revoluteJoint, prismaticJoint, cylindricalJoint, planarJoint, sphericalJoint, setJointValue, setJointValues, jointTransform, addJoint, forwardKinematics, mechanismDOF, type Joint, type JointDOF, type JointAxis, type JointType, type JointPose, type JointOptions, type CylindricalOptions, type PlanarOptions, type SphericalOptions, } from './operations/jointFns.js';
|
|
125
125
|
export { inverseKinematics, jointTrajectory, type IKTarget, type IKOptions, type IKResult, type TrajectorySample, } from './operations/ikFns.js';
|
|
126
|
+
export { jointsFromDH, type DHRow, type DHOptions } from './operations/dhFns.js';
|
|
127
|
+
export { exportURDF, importURDF, type UrdfExportOptions, type UrdfDocument, } from './operations/urdfFns.js';
|
|
126
128
|
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';
|
|
127
129
|
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';
|
|
128
130
|
export { checkInterference, checkAllInterferences, type InterferenceResult, type InterferencePair, } from './measurement/interferenceFns.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Joint } from './jointFns.js';
|
|
2
|
+
/** One row of a Denavit-Hartenberg table (angles in degrees). */
|
|
3
|
+
export interface DHRow {
|
|
4
|
+
/** Link length: translation along the (rotated) x axis. */
|
|
5
|
+
readonly a: number;
|
|
6
|
+
/** Link twist: rotation about the x axis, in degrees. */
|
|
7
|
+
readonly alpha: number;
|
|
8
|
+
/** Link offset: translation along the z axis. For prismatic, the home offset. */
|
|
9
|
+
readonly d: number;
|
|
10
|
+
/** Joint angle about z, in degrees. For revolute, the home angle. */
|
|
11
|
+
readonly theta: number;
|
|
12
|
+
/** Which parameter is the joint variable. Default `'revolute'` (θ varies). */
|
|
13
|
+
readonly type?: 'revolute' | 'prismatic';
|
|
14
|
+
/** Joint range lower bound (degrees for revolute, length for prismatic). */
|
|
15
|
+
readonly min?: number;
|
|
16
|
+
/** Joint range upper bound. */
|
|
17
|
+
readonly max?: number;
|
|
18
|
+
/** Initial joint value (clamped to range). Default 0. */
|
|
19
|
+
readonly value?: number;
|
|
20
|
+
/** Child link name produced by this row. Default `link{i+1}`. */
|
|
21
|
+
readonly name?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DHOptions {
|
|
24
|
+
/** Name of the base (root) link. Default `'base'`. */
|
|
25
|
+
base?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a serial revolute/prismatic joint chain from a DH table. Joint `i`
|
|
29
|
+
* connects the previous link to row `i`'s link; its motion is the variable
|
|
30
|
+
* parameter (θ for revolute, d for prismatic) about/along +z, and its fixed
|
|
31
|
+
* link geometry is carried on `Joint.offset`. The result drives correctly
|
|
32
|
+
* through `forwardKinematics` and reports `rows.length` DOF via `mechanismDOF`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function jointsFromDH(rows: readonly DHRow[], options?: DHOptions): Joint[];
|
|
@@ -32,6 +32,13 @@ export interface Joint {
|
|
|
32
32
|
readonly value: number;
|
|
33
33
|
/** All drivable degrees of freedom, in composition order. */
|
|
34
34
|
readonly dofs: readonly JointDOF[];
|
|
35
|
+
/**
|
|
36
|
+
* Optional fixed transform applied to the child frame *after* the joint
|
|
37
|
+
* motion (`childWorld = parentWorld ∘ jointTransform ∘ offset`). Lets a single
|
|
38
|
+
* joint carry a static link offset (e.g. a Denavit-Hartenberg link geometry)
|
|
39
|
+
* without an extra body. Defaults to identity. See `jointsFromDH`.
|
|
40
|
+
*/
|
|
41
|
+
readonly offset?: JointPose;
|
|
35
42
|
}
|
|
36
43
|
/** A rigid transform: translation + quaternion rotation `[w, x, y, z]`. */
|
|
37
44
|
export interface JointPose {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Result } from '../core/result.js';
|
|
2
|
+
import { AssemblyNode } from './assemblyFns.js';
|
|
3
|
+
import { Joint } from './jointFns.js';
|
|
4
|
+
export interface UrdfExportOptions {
|
|
5
|
+
/** `<robot name="...">`. Default `'robot'`. */
|
|
6
|
+
name?: string;
|
|
7
|
+
/** Default `effort` limit emitted for every joint. Default 0. */
|
|
8
|
+
effort?: number;
|
|
9
|
+
/** Default `velocity` limit emitted for every joint. Default 0. */
|
|
10
|
+
velocity?: number;
|
|
11
|
+
/** Per-link mesh filename for a `<visual>` reference, keyed by node name. */
|
|
12
|
+
meshes?: Readonly<Record<string, string>>;
|
|
13
|
+
}
|
|
14
|
+
export interface UrdfDocument {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly links: string[];
|
|
17
|
+
readonly joints: Joint[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Serialize an assembly's links and revolute/prismatic joints to a URDF string.
|
|
21
|
+
* Returns an error if any joint is multi-DOF or carries a fixed `offset`, since
|
|
22
|
+
* URDF cannot represent those as a single joint.
|
|
23
|
+
*/
|
|
24
|
+
export declare function exportURDF(assembly: AssemblyNode, options?: UrdfExportOptions): Result<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a URDF document into its robot name, link names, and revolute/prismatic
|
|
27
|
+
* joints. `continuous` joints become revolute with a full -180..180 range;
|
|
28
|
+
* `fixed`/`floating`/`planar` joints are skipped (their links are still listed).
|
|
29
|
+
* A non-zero `<origin rpy>` is folded into the joint axis direction; its
|
|
30
|
+
* residual frame rotation is not represented (URDF's pre-motion frame offset has
|
|
31
|
+
* no single-joint brepjs equivalent).
|
|
32
|
+
*/
|
|
33
|
+
export declare function importURDF(xml: string): Result<UrdfDocument>;
|
package/dist/operations.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_threadFns = require("./threadFns-
|
|
2
|
+
const require_threadFns = require("./threadFns-DOAHxp0G.cjs");
|
|
3
3
|
const require_loftFns = require("./loftFns-DiSsI2PM.cjs");
|
|
4
4
|
exports.addChild = require_threadFns.addChild;
|
|
5
5
|
exports.addJoint = require_threadFns.addJoint;
|
|
@@ -14,14 +14,17 @@ exports.createHistory = require_threadFns.createHistory;
|
|
|
14
14
|
exports.createRegistry = require_threadFns.createRegistry;
|
|
15
15
|
exports.cylindricalJoint = require_threadFns.cylindricalJoint;
|
|
16
16
|
exports.exportAssemblySTEP = require_threadFns.exportAssemblySTEP;
|
|
17
|
+
exports.exportURDF = require_threadFns.exportURDF;
|
|
17
18
|
exports.findNode = require_threadFns.findNode;
|
|
18
19
|
exports.findStep = require_threadFns.findStep;
|
|
19
20
|
exports.forwardKinematics = require_threadFns.forwardKinematics;
|
|
20
21
|
exports.getHistoryShape = require_threadFns.getShape;
|
|
21
22
|
exports.gridPattern = require_threadFns.gridPattern;
|
|
23
|
+
exports.importURDF = require_threadFns.importURDF;
|
|
22
24
|
exports.inverseKinematics = require_threadFns.inverseKinematics;
|
|
23
25
|
exports.jointTrajectory = require_threadFns.jointTrajectory;
|
|
24
26
|
exports.jointTransform = require_threadFns.jointTransform;
|
|
27
|
+
exports.jointsFromDH = require_threadFns.jointsFromDH;
|
|
25
28
|
exports.linearPattern = require_threadFns.linearPattern;
|
|
26
29
|
exports.mechanismDOF = require_threadFns.mechanismDOF;
|
|
27
30
|
exports.modifyStep = require_threadFns.modifyStep;
|
package/dist/operations.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export { linearPattern, circularPattern, gridPattern } from './operations/patter
|
|
|
12
12
|
export { createAssemblyNode, addChild, removeChild, updateNode, findNode, walkAssembly, countNodes, collectShapes, type AssemblyNode, type AssemblyNodeOptions, } from './operations/assemblyFns.js';
|
|
13
13
|
export { revoluteJoint, prismaticJoint, cylindricalJoint, planarJoint, sphericalJoint, setJointValue, setJointValues, jointTransform, addJoint, forwardKinematics, mechanismDOF, type Joint, type JointDOF, type JointAxis, type JointType, type JointPose, type JointOptions, type CylindricalOptions, type PlanarOptions, type SphericalOptions, } from './operations/jointFns.js';
|
|
14
14
|
export { inverseKinematics, jointTrajectory, type IKTarget, type IKOptions, type IKResult, type TrajectorySample, } from './operations/ikFns.js';
|
|
15
|
+
export { jointsFromDH, type DHRow, type DHOptions } from './operations/dhFns.js';
|
|
16
|
+
export { exportURDF, importURDF, type UrdfExportOptions, type UrdfDocument, } from './operations/urdfFns.js';
|
|
15
17
|
export { exportAssemblySTEP, type ShapeOptions, type SupportedUnit, } from './operations/exporterFns.js';
|
|
16
18
|
export { createHistory, addStep, undoLast, findStep, getShape as getHistoryShape, stepCount, stepsFrom, registerShape, createRegistry, registerOperation, replayHistory, replayFrom, modifyStep, type OperationStep, type ModelHistory, type OperationFn, type OperationRegistry as HistoryOperationRegistry, } from './operations/historyFns.js';
|
|
17
19
|
export { type AssemblyExporter, createAssembly } from './operations/exporters.js';
|
package/dist/operations.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { B as
|
|
1
|
+
import { A as setJointValue, B as findNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, G as gridPattern, H as updateNode, I as addChild, J as createAssembly, K as linearPattern, L as collectShapes, M as sphericalJoint, O as prismaticJoint, R as countNodes, S as addJoint, T as jointTransform, U as walkAssembly, V as removeChild, W as circularPattern, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, q as exportAssemblySTEP, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as createAssemblyNode } from "./threadFns-D0TPhxRK.js";
|
|
2
2
|
import { d as twistExtrude, l as supportExtrude, o as complexExtrude, u as sweep } from "./loftFns-CsHOwded.js";
|
|
3
|
-
export { addChild, addJoint, addStep, circularPattern, collectShapes, complexExtrude, countNodes, createAssembly, createAssemblyNode, createHistory, createRegistry, cylindricalJoint, exportAssemblySTEP, findNode, findStep, forwardKinematics, getShape as getHistoryShape, gridPattern, inverseKinematics, jointTrajectory, jointTransform, linearPattern, mechanismDOF, modifyStep, planarJoint, prismaticJoint, registerOperation, registerShape, removeChild, replayFrom, replayHistory, revoluteJoint, setJointValue, setJointValues, sphericalJoint, stepCount, stepsFrom, supportExtrude, sweep, thread, twistExtrude, undoLast, updateNode, walkAssembly };
|
|
3
|
+
export { addChild, addJoint, addStep, circularPattern, collectShapes, complexExtrude, countNodes, createAssembly, createAssemblyNode, createHistory, createRegistry, cylindricalJoint, exportAssemblySTEP, exportURDF, findNode, findStep, forwardKinematics, getShape as getHistoryShape, gridPattern, importURDF, inverseKinematics, jointTrajectory, jointTransform, jointsFromDH, linearPattern, mechanismDOF, modifyStep, planarJoint, prismaticJoint, registerOperation, registerShape, removeChild, replayFrom, replayHistory, revoluteJoint, setJointValue, setJointValues, sphericalJoint, stepCount, stepsFrom, supportExtrude, sweep, thread, twistExtrude, undoLast, updateNode, walkAssembly };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { B as createKernelHandle, R as DisposalScope, Y as _usingCtx, Z as getKernel, t as castShape } from "./shapeTypes-DfQi9Kvk.js";
|
|
2
|
-
import { A as ok, T as isOk, b as err, d as validationError, n as computationError, r as ioError } from "./errors-DNWJsfVU.js";
|
|
2
|
+
import { A as ok, T as isOk, b as err, d as validationError, n as computationError, r as ioError, t as BrepErrorCode } from "./errors-DNWJsfVU.js";
|
|
3
3
|
import { d as vecNormalize, s as vecIsZero } from "./vecOps-SKPRvPH-.js";
|
|
4
4
|
import { y as fromBREP } from "./faceFns-Cuxdy-7R.js";
|
|
5
5
|
import { s as toBREP } from "./shapeFns-BzlBMNRO.js";
|
|
@@ -344,7 +344,7 @@ function quatMultiply(a, b) {
|
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
346
|
//#region src/operations/jointFns.ts
|
|
347
|
-
var DEG2RAD = Math.PI / 180;
|
|
347
|
+
var DEG2RAD$2 = Math.PI / 180;
|
|
348
348
|
function clamp(value, min, max) {
|
|
349
349
|
return Math.min(max, Math.max(min, value));
|
|
350
350
|
}
|
|
@@ -539,7 +539,7 @@ function dofPose(origin, dof, value) {
|
|
|
539
539
|
0
|
|
540
540
|
]
|
|
541
541
|
};
|
|
542
|
-
const rotation = quatFromAxisAngle(dof.axis, value * DEG2RAD);
|
|
542
|
+
const rotation = quatFromAxisAngle(dof.axis, value * DEG2RAD$2);
|
|
543
543
|
const ro = quatRotate(rotation, origin);
|
|
544
544
|
return {
|
|
545
545
|
position: [
|
|
@@ -653,7 +653,8 @@ function forwardKinematics(assembly, jointValues = {}) {
|
|
|
653
653
|
progress = true;
|
|
654
654
|
if (poses.has(j.child)) continue;
|
|
655
655
|
const value = jointValues[j.child] ?? j.value;
|
|
656
|
-
|
|
656
|
+
const local = j.offset ? composePose(jointTransform(j, value), j.offset) : jointTransform(j, value);
|
|
657
|
+
poses.set(j.child, composePose(parentPose, local));
|
|
657
658
|
}
|
|
658
659
|
}
|
|
659
660
|
for (const j of pending) if (!poses.has(j.child)) poses.set(j.child, IDENTITY_POSE$1);
|
|
@@ -969,6 +970,260 @@ function jointTrajectory(assembly, from, to, steps) {
|
|
|
969
970
|
return samples;
|
|
970
971
|
}
|
|
971
972
|
//#endregion
|
|
973
|
+
//#region src/operations/dhFns.ts
|
|
974
|
+
/**
|
|
975
|
+
* Denavit-Hartenberg interchange: build a brepjs joint chain from a standard
|
|
976
|
+
* (distal) DH parameter table.
|
|
977
|
+
*
|
|
978
|
+
* Each DH row maps the previous link frame to the next via
|
|
979
|
+
* `Rz(θ) · Tz(d) · Tx(a) · Rx(α)`, with one parameter the joint variable
|
|
980
|
+
* (θ for revolute, d for prismatic) and the rest fixed link geometry. A row
|
|
981
|
+
* becomes a single revolute/prismatic joint whose motion is the variable part
|
|
982
|
+
* and whose fixed link geometry rides on the joint's post-motion `offset`
|
|
983
|
+
* (see `Joint.offset`), so the chain composes correctly through
|
|
984
|
+
* `forwardKinematics` and each row contributes exactly one DOF.
|
|
985
|
+
*/
|
|
986
|
+
var DEG2RAD$1 = Math.PI / 180;
|
|
987
|
+
/**
|
|
988
|
+
* The fixed DH link transform `Rz(θ) · Tz(d) · Tx(a) · Rx(α)` as a pose.
|
|
989
|
+
* Carries the constant link geometry that rides on the joint's `offset`.
|
|
990
|
+
*/
|
|
991
|
+
function linkOffset(thetaDeg, d, a, alphaDeg) {
|
|
992
|
+
const theta = thetaDeg * DEG2RAD$1;
|
|
993
|
+
const alpha = alphaDeg * DEG2RAD$1;
|
|
994
|
+
const rotation = quatMultiply(quatFromAxisAngle([
|
|
995
|
+
0,
|
|
996
|
+
0,
|
|
997
|
+
1
|
|
998
|
+
], theta), quatFromAxisAngle([
|
|
999
|
+
1,
|
|
1000
|
+
0,
|
|
1001
|
+
0
|
|
1002
|
+
], alpha));
|
|
1003
|
+
return {
|
|
1004
|
+
position: [
|
|
1005
|
+
a * Math.cos(theta),
|
|
1006
|
+
a * Math.sin(theta),
|
|
1007
|
+
d
|
|
1008
|
+
],
|
|
1009
|
+
rotation
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Build a serial revolute/prismatic joint chain from a DH table. Joint `i`
|
|
1014
|
+
* connects the previous link to row `i`'s link; its motion is the variable
|
|
1015
|
+
* parameter (θ for revolute, d for prismatic) about/along +z, and its fixed
|
|
1016
|
+
* link geometry is carried on `Joint.offset`. The result drives correctly
|
|
1017
|
+
* through `forwardKinematics` and reports `rows.length` DOF via `mechanismDOF`.
|
|
1018
|
+
*/
|
|
1019
|
+
function jointsFromDH(rows, options = {}) {
|
|
1020
|
+
const base = options.base ?? "base";
|
|
1021
|
+
const names = rows.map((r, i) => r.name ?? `link${i + 1}`);
|
|
1022
|
+
return rows.map((row, i) => {
|
|
1023
|
+
const parent = i === 0 ? base : names[i - 1] ?? `link${i}`;
|
|
1024
|
+
const child = names[i] ?? `link${i + 1}`;
|
|
1025
|
+
const offset = linkOffset(row.theta, row.d, row.a, row.alpha);
|
|
1026
|
+
const axis = {
|
|
1027
|
+
origin: [
|
|
1028
|
+
0,
|
|
1029
|
+
0,
|
|
1030
|
+
0
|
|
1031
|
+
],
|
|
1032
|
+
direction: [
|
|
1033
|
+
0,
|
|
1034
|
+
0,
|
|
1035
|
+
1
|
|
1036
|
+
]
|
|
1037
|
+
};
|
|
1038
|
+
const opts = {
|
|
1039
|
+
...row.min !== void 0 ? { min: row.min } : {},
|
|
1040
|
+
...row.max !== void 0 ? { max: row.max } : {},
|
|
1041
|
+
...row.value !== void 0 ? { value: row.value } : {}
|
|
1042
|
+
};
|
|
1043
|
+
return {
|
|
1044
|
+
...row.type === "prismatic" ? prismaticJoint(parent, child, axis, opts) : revoluteJoint(parent, child, axis, opts),
|
|
1045
|
+
offset
|
|
1046
|
+
};
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region src/operations/urdfFns.ts
|
|
1051
|
+
/**
|
|
1052
|
+
* URDF interchange: export a brepjs assembly + its joints to URDF, and import a
|
|
1053
|
+
* URDF document back into links and joints.
|
|
1054
|
+
*
|
|
1055
|
+
* URDF natively models single-DOF joints, so `revolute` and `prismatic` joints
|
|
1056
|
+
* round-trip (parents, axes, and limits preserved). Multi-DOF joints
|
|
1057
|
+
* (cylindrical/planar/spherical) and joints carrying a fixed `offset` (e.g.
|
|
1058
|
+
* Denavit-Hartenberg links) have no faithful single-joint URDF representation
|
|
1059
|
+
* and are reported as an error on export.
|
|
1060
|
+
*
|
|
1061
|
+
* Revolute limits are radians in URDF and degrees in brepjs, so they are
|
|
1062
|
+
* converted on the boundary. The XML is parsed with a small URDF-shaped reader
|
|
1063
|
+
* (no XML dependency); it handles the standard `<robot>/<link>/<joint>` subset.
|
|
1064
|
+
*/
|
|
1065
|
+
var DEG2RAD = Math.PI / 180;
|
|
1066
|
+
var RAD2DEG = 180 / Math.PI;
|
|
1067
|
+
function escapeXml(s) {
|
|
1068
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1069
|
+
}
|
|
1070
|
+
/** Format a number for XML, normalizing -0 to 0. */
|
|
1071
|
+
function fmt(n) {
|
|
1072
|
+
return String(n === 0 ? 0 : n);
|
|
1073
|
+
}
|
|
1074
|
+
function vec(v) {
|
|
1075
|
+
return `${fmt(v[0])} ${fmt(v[1])} ${fmt(v[2])}`;
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Serialize an assembly's links and revolute/prismatic joints to a URDF string.
|
|
1079
|
+
* Returns an error if any joint is multi-DOF or carries a fixed `offset`, since
|
|
1080
|
+
* URDF cannot represent those as a single joint.
|
|
1081
|
+
*/
|
|
1082
|
+
function exportURDF(assembly, options = {}) {
|
|
1083
|
+
const robot = options.name ?? "robot";
|
|
1084
|
+
const effort = options.effort ?? 0;
|
|
1085
|
+
const velocity = options.velocity ?? 0;
|
|
1086
|
+
const meshes = options.meshes ?? {};
|
|
1087
|
+
const links = [];
|
|
1088
|
+
const joints = [];
|
|
1089
|
+
walkAssembly(assembly, (n) => {
|
|
1090
|
+
links.push(n.name);
|
|
1091
|
+
if (n.joints) joints.push(...n.joints);
|
|
1092
|
+
});
|
|
1093
|
+
for (const j of joints) {
|
|
1094
|
+
if (j.type !== "revolute" && j.type !== "prismatic") return err(validationError(BrepErrorCode.VALIDATION_FAILED, `exportURDF: joint '${j.parent}->${j.child}' is '${j.type}'; URDF supports only revolute and prismatic joints`));
|
|
1095
|
+
if (j.offset) return err(validationError(BrepErrorCode.VALIDATION_FAILED, `exportURDF: joint '${j.parent}->${j.child}' carries a fixed offset (e.g. a DH link) that URDF cannot represent as a single joint`));
|
|
1096
|
+
}
|
|
1097
|
+
const lines = ["<?xml version=\"1.0\"?>", `<robot name="${escapeXml(robot)}">`];
|
|
1098
|
+
for (const link of links) {
|
|
1099
|
+
const mesh = meshes[link];
|
|
1100
|
+
if (mesh) lines.push(` <link name="${escapeXml(link)}">`, ` <visual><geometry><mesh filename="${escapeXml(mesh)}"/></geometry></visual>`, ` </link>`);
|
|
1101
|
+
else lines.push(` <link name="${escapeXml(link)}"/>`);
|
|
1102
|
+
}
|
|
1103
|
+
for (const j of joints) {
|
|
1104
|
+
const toRad = j.type === "revolute";
|
|
1105
|
+
const lower = toRad ? j.min * DEG2RAD : j.min;
|
|
1106
|
+
const upper = toRad ? j.max * DEG2RAD : j.max;
|
|
1107
|
+
const origin = j.type === "prismatic" ? [
|
|
1108
|
+
0,
|
|
1109
|
+
0,
|
|
1110
|
+
0
|
|
1111
|
+
] : j.axis.origin;
|
|
1112
|
+
lines.push(` <joint name="${escapeXml(`${j.parent}_to_${j.child}`)}" type="${j.type}">`, ` <parent link="${escapeXml(j.parent)}"/>`, ` <child link="${escapeXml(j.child)}"/>`, ` <origin xyz="${vec(origin)}" rpy="0 0 0"/>`, ` <axis xyz="${vec(j.axis.direction)}"/>`, ` <limit lower="${fmt(lower)}" upper="${fmt(upper)}" effort="${fmt(effort)}" velocity="${fmt(velocity)}"/>`, ` </joint>`);
|
|
1113
|
+
}
|
|
1114
|
+
lines.push("</robot>", "");
|
|
1115
|
+
return ok(lines.join("\n"));
|
|
1116
|
+
}
|
|
1117
|
+
/** Read a string attribute from a tag's attribute text. */
|
|
1118
|
+
function attr(text, name) {
|
|
1119
|
+
return new RegExp(`\\b${name}\\s*=\\s*"([^"]*)"`).exec(text)?.[1];
|
|
1120
|
+
}
|
|
1121
|
+
/** Parse a whitespace-separated numeric triple, defaulting missing components to 0. */
|
|
1122
|
+
function triple(s, fallback) {
|
|
1123
|
+
if (!s) return fallback;
|
|
1124
|
+
const parts = s.trim().split(/\s+/).map(Number);
|
|
1125
|
+
return [
|
|
1126
|
+
parts[0] ?? 0,
|
|
1127
|
+
parts[1] ?? 0,
|
|
1128
|
+
parts[2] ?? 0
|
|
1129
|
+
];
|
|
1130
|
+
}
|
|
1131
|
+
/** Rotate an axis by a URDF roll-pitch-yaw (fixed-axis XYZ) triple in radians. */
|
|
1132
|
+
function applyRpy(axis, rpy) {
|
|
1133
|
+
return quatRotate(quatMultiply(quatMultiply(quatFromAxisAngle([
|
|
1134
|
+
0,
|
|
1135
|
+
0,
|
|
1136
|
+
1
|
|
1137
|
+
], rpy[2]), quatFromAxisAngle([
|
|
1138
|
+
0,
|
|
1139
|
+
1,
|
|
1140
|
+
0
|
|
1141
|
+
], rpy[1])), quatFromAxisAngle([
|
|
1142
|
+
1,
|
|
1143
|
+
0,
|
|
1144
|
+
0
|
|
1145
|
+
], rpy[0])), axis);
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Parse a URDF document into its robot name, link names, and revolute/prismatic
|
|
1149
|
+
* joints. `continuous` joints become revolute with a full -180..180 range;
|
|
1150
|
+
* `fixed`/`floating`/`planar` joints are skipped (their links are still listed).
|
|
1151
|
+
* A non-zero `<origin rpy>` is folded into the joint axis direction; its
|
|
1152
|
+
* residual frame rotation is not represented (URDF's pre-motion frame offset has
|
|
1153
|
+
* no single-joint brepjs equivalent).
|
|
1154
|
+
*/
|
|
1155
|
+
function importURDF(xml) {
|
|
1156
|
+
const robotMatch = /<robot\b([^>]*)>/.exec(xml);
|
|
1157
|
+
if (!robotMatch) return err(validationError(BrepErrorCode.VALIDATION_FAILED, "importURDF: no <robot> element found"));
|
|
1158
|
+
const name = attr(robotMatch[1] ?? "", "name") ?? "robot";
|
|
1159
|
+
const links = [];
|
|
1160
|
+
const linkRe = /<link\b([^>]*?)(?:\/>|>)/g;
|
|
1161
|
+
for (let m = linkRe.exec(xml); m; m = linkRe.exec(xml)) {
|
|
1162
|
+
const n = attr(m[1] ?? "", "name");
|
|
1163
|
+
if (n) links.push(n);
|
|
1164
|
+
}
|
|
1165
|
+
const joints = [];
|
|
1166
|
+
const jointRe = /<joint\b([^>]*)>([\s\S]*?)<\/joint>/g;
|
|
1167
|
+
for (let m = jointRe.exec(xml); m; m = jointRe.exec(xml)) {
|
|
1168
|
+
const head = m[1] ?? "";
|
|
1169
|
+
const body = m[2] ?? "";
|
|
1170
|
+
const type = attr(head, "type") ?? "fixed";
|
|
1171
|
+
if (type === "fixed" || type === "floating" || type === "planar") continue;
|
|
1172
|
+
const parentTag = /<parent\b([^>]*?)\/?>/.exec(body);
|
|
1173
|
+
const childTag = /<child\b([^>]*?)\/?>/.exec(body);
|
|
1174
|
+
const parent = attr(parentTag?.[1] ?? "", "link");
|
|
1175
|
+
const child = attr(childTag?.[1] ?? "", "link");
|
|
1176
|
+
if (!parent || !child) return err(validationError(BrepErrorCode.VALIDATION_FAILED, `importURDF: joint missing parent/child link (${attr(head, "name") ?? "unnamed"})`));
|
|
1177
|
+
const originTag = /<origin\b([^>]*?)\/?>/.exec(body);
|
|
1178
|
+
const axisTag = /<axis\b([^>]*?)\/?>/.exec(body);
|
|
1179
|
+
const limitTag = /<limit\b([^>]*?)\/?>/.exec(body);
|
|
1180
|
+
const origin = triple(attr(originTag?.[1] ?? "", "xyz"), [
|
|
1181
|
+
0,
|
|
1182
|
+
0,
|
|
1183
|
+
0
|
|
1184
|
+
]);
|
|
1185
|
+
const rpy = triple(attr(originTag?.[1] ?? "", "rpy"), [
|
|
1186
|
+
0,
|
|
1187
|
+
0,
|
|
1188
|
+
0
|
|
1189
|
+
]);
|
|
1190
|
+
const direction = applyRpy(triple(attr(axisTag?.[1] ?? "", "xyz"), [
|
|
1191
|
+
1,
|
|
1192
|
+
0,
|
|
1193
|
+
0
|
|
1194
|
+
]), rpy);
|
|
1195
|
+
const lowerRaw = Number(attr(limitTag?.[1] ?? "", "lower") ?? NaN);
|
|
1196
|
+
const upperRaw = Number(attr(limitTag?.[1] ?? "", "upper") ?? NaN);
|
|
1197
|
+
if (type === "prismatic") {
|
|
1198
|
+
const opts = Number.isFinite(lowerRaw) && Number.isFinite(upperRaw) ? {
|
|
1199
|
+
min: lowerRaw,
|
|
1200
|
+
max: upperRaw
|
|
1201
|
+
} : {};
|
|
1202
|
+
joints.push(prismaticJoint(parent, child, {
|
|
1203
|
+
origin,
|
|
1204
|
+
direction
|
|
1205
|
+
}, opts));
|
|
1206
|
+
} else if (type === "revolute" || type === "continuous") {
|
|
1207
|
+
const opts = type === "continuous" || !Number.isFinite(lowerRaw) || !Number.isFinite(upperRaw) ? {
|
|
1208
|
+
min: -180,
|
|
1209
|
+
max: 180
|
|
1210
|
+
} : {
|
|
1211
|
+
min: lowerRaw * RAD2DEG,
|
|
1212
|
+
max: upperRaw * RAD2DEG
|
|
1213
|
+
};
|
|
1214
|
+
joints.push(revoluteJoint(parent, child, {
|
|
1215
|
+
origin,
|
|
1216
|
+
direction
|
|
1217
|
+
}, opts));
|
|
1218
|
+
} else return err(validationError(BrepErrorCode.VALIDATION_FAILED, `importURDF: joint '${attr(head, "name") ?? "unnamed"}' has unrecognized type '${type}'`));
|
|
1219
|
+
}
|
|
1220
|
+
return ok({
|
|
1221
|
+
name,
|
|
1222
|
+
links,
|
|
1223
|
+
joints
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
//#endregion
|
|
972
1227
|
//#region src/operations/historyFns.ts
|
|
973
1228
|
/** Create a new empty history. */
|
|
974
1229
|
function createHistory() {
|
|
@@ -1236,4 +1491,4 @@ function thread(options) {
|
|
|
1236
1491
|
}
|
|
1237
1492
|
}
|
|
1238
1493
|
//#endregion
|
|
1239
|
-
export {
|
|
1494
|
+
export { setJointValue as A, findNode as B, cylindricalJoint as C, planarJoint as D, mechanismDOF as E, quatRotate as F, gridPattern as G, updateNode as H, addChild as I, createAssembly as J, linearPattern as K, collectShapes as L, sphericalJoint as M, quatFromAxisAngle as N, prismaticJoint as O, quatFromTo as P, countNodes as R, addJoint as S, jointTransform as T, walkAssembly as U, removeChild as V, circularPattern as W, exportURDF as _, deserializeHistory as a, inverseKinematics as b, modifyStep as c, replayFrom as d, replayHistory as f, undoLast as g, stepsFrom as h, createRegistry as i, setJointValues as j, revoluteJoint as k, registerOperation as l, stepCount as m, addStep as n, findStep as o, serializeHistory as p, exportAssemblySTEP as q, createHistory as r, getShape as s, thread as t, registerShape as u, importURDF as v, forwardKinematics as w, jointTrajectory as x, jointsFromDH as y, createAssemblyNode as z };
|
|
@@ -344,7 +344,7 @@ function quatMultiply(a, b) {
|
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
346
|
//#region src/operations/jointFns.ts
|
|
347
|
-
var DEG2RAD = Math.PI / 180;
|
|
347
|
+
var DEG2RAD$2 = Math.PI / 180;
|
|
348
348
|
function clamp(value, min, max) {
|
|
349
349
|
return Math.min(max, Math.max(min, value));
|
|
350
350
|
}
|
|
@@ -539,7 +539,7 @@ function dofPose(origin, dof, value) {
|
|
|
539
539
|
0
|
|
540
540
|
]
|
|
541
541
|
};
|
|
542
|
-
const rotation = quatFromAxisAngle(dof.axis, value * DEG2RAD);
|
|
542
|
+
const rotation = quatFromAxisAngle(dof.axis, value * DEG2RAD$2);
|
|
543
543
|
const ro = quatRotate(rotation, origin);
|
|
544
544
|
return {
|
|
545
545
|
position: [
|
|
@@ -653,7 +653,8 @@ function forwardKinematics(assembly, jointValues = {}) {
|
|
|
653
653
|
progress = true;
|
|
654
654
|
if (poses.has(j.child)) continue;
|
|
655
655
|
const value = jointValues[j.child] ?? j.value;
|
|
656
|
-
|
|
656
|
+
const local = j.offset ? composePose(jointTransform(j, value), j.offset) : jointTransform(j, value);
|
|
657
|
+
poses.set(j.child, composePose(parentPose, local));
|
|
657
658
|
}
|
|
658
659
|
}
|
|
659
660
|
for (const j of pending) if (!poses.has(j.child)) poses.set(j.child, IDENTITY_POSE$1);
|
|
@@ -969,6 +970,260 @@ function jointTrajectory(assembly, from, to, steps) {
|
|
|
969
970
|
return samples;
|
|
970
971
|
}
|
|
971
972
|
//#endregion
|
|
973
|
+
//#region src/operations/dhFns.ts
|
|
974
|
+
/**
|
|
975
|
+
* Denavit-Hartenberg interchange: build a brepjs joint chain from a standard
|
|
976
|
+
* (distal) DH parameter table.
|
|
977
|
+
*
|
|
978
|
+
* Each DH row maps the previous link frame to the next via
|
|
979
|
+
* `Rz(θ) · Tz(d) · Tx(a) · Rx(α)`, with one parameter the joint variable
|
|
980
|
+
* (θ for revolute, d for prismatic) and the rest fixed link geometry. A row
|
|
981
|
+
* becomes a single revolute/prismatic joint whose motion is the variable part
|
|
982
|
+
* and whose fixed link geometry rides on the joint's post-motion `offset`
|
|
983
|
+
* (see `Joint.offset`), so the chain composes correctly through
|
|
984
|
+
* `forwardKinematics` and each row contributes exactly one DOF.
|
|
985
|
+
*/
|
|
986
|
+
var DEG2RAD$1 = Math.PI / 180;
|
|
987
|
+
/**
|
|
988
|
+
* The fixed DH link transform `Rz(θ) · Tz(d) · Tx(a) · Rx(α)` as a pose.
|
|
989
|
+
* Carries the constant link geometry that rides on the joint's `offset`.
|
|
990
|
+
*/
|
|
991
|
+
function linkOffset(thetaDeg, d, a, alphaDeg) {
|
|
992
|
+
const theta = thetaDeg * DEG2RAD$1;
|
|
993
|
+
const alpha = alphaDeg * DEG2RAD$1;
|
|
994
|
+
const rotation = quatMultiply(quatFromAxisAngle([
|
|
995
|
+
0,
|
|
996
|
+
0,
|
|
997
|
+
1
|
|
998
|
+
], theta), quatFromAxisAngle([
|
|
999
|
+
1,
|
|
1000
|
+
0,
|
|
1001
|
+
0
|
|
1002
|
+
], alpha));
|
|
1003
|
+
return {
|
|
1004
|
+
position: [
|
|
1005
|
+
a * Math.cos(theta),
|
|
1006
|
+
a * Math.sin(theta),
|
|
1007
|
+
d
|
|
1008
|
+
],
|
|
1009
|
+
rotation
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Build a serial revolute/prismatic joint chain from a DH table. Joint `i`
|
|
1014
|
+
* connects the previous link to row `i`'s link; its motion is the variable
|
|
1015
|
+
* parameter (θ for revolute, d for prismatic) about/along +z, and its fixed
|
|
1016
|
+
* link geometry is carried on `Joint.offset`. The result drives correctly
|
|
1017
|
+
* through `forwardKinematics` and reports `rows.length` DOF via `mechanismDOF`.
|
|
1018
|
+
*/
|
|
1019
|
+
function jointsFromDH(rows, options = {}) {
|
|
1020
|
+
const base = options.base ?? "base";
|
|
1021
|
+
const names = rows.map((r, i) => r.name ?? `link${i + 1}`);
|
|
1022
|
+
return rows.map((row, i) => {
|
|
1023
|
+
const parent = i === 0 ? base : names[i - 1] ?? `link${i}`;
|
|
1024
|
+
const child = names[i] ?? `link${i + 1}`;
|
|
1025
|
+
const offset = linkOffset(row.theta, row.d, row.a, row.alpha);
|
|
1026
|
+
const axis = {
|
|
1027
|
+
origin: [
|
|
1028
|
+
0,
|
|
1029
|
+
0,
|
|
1030
|
+
0
|
|
1031
|
+
],
|
|
1032
|
+
direction: [
|
|
1033
|
+
0,
|
|
1034
|
+
0,
|
|
1035
|
+
1
|
|
1036
|
+
]
|
|
1037
|
+
};
|
|
1038
|
+
const opts = {
|
|
1039
|
+
...row.min !== void 0 ? { min: row.min } : {},
|
|
1040
|
+
...row.max !== void 0 ? { max: row.max } : {},
|
|
1041
|
+
...row.value !== void 0 ? { value: row.value } : {}
|
|
1042
|
+
};
|
|
1043
|
+
return {
|
|
1044
|
+
...row.type === "prismatic" ? prismaticJoint(parent, child, axis, opts) : revoluteJoint(parent, child, axis, opts),
|
|
1045
|
+
offset
|
|
1046
|
+
};
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region src/operations/urdfFns.ts
|
|
1051
|
+
/**
|
|
1052
|
+
* URDF interchange: export a brepjs assembly + its joints to URDF, and import a
|
|
1053
|
+
* URDF document back into links and joints.
|
|
1054
|
+
*
|
|
1055
|
+
* URDF natively models single-DOF joints, so `revolute` and `prismatic` joints
|
|
1056
|
+
* round-trip (parents, axes, and limits preserved). Multi-DOF joints
|
|
1057
|
+
* (cylindrical/planar/spherical) and joints carrying a fixed `offset` (e.g.
|
|
1058
|
+
* Denavit-Hartenberg links) have no faithful single-joint URDF representation
|
|
1059
|
+
* and are reported as an error on export.
|
|
1060
|
+
*
|
|
1061
|
+
* Revolute limits are radians in URDF and degrees in brepjs, so they are
|
|
1062
|
+
* converted on the boundary. The XML is parsed with a small URDF-shaped reader
|
|
1063
|
+
* (no XML dependency); it handles the standard `<robot>/<link>/<joint>` subset.
|
|
1064
|
+
*/
|
|
1065
|
+
var DEG2RAD = Math.PI / 180;
|
|
1066
|
+
var RAD2DEG = 180 / Math.PI;
|
|
1067
|
+
function escapeXml(s) {
|
|
1068
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1069
|
+
}
|
|
1070
|
+
/** Format a number for XML, normalizing -0 to 0. */
|
|
1071
|
+
function fmt(n) {
|
|
1072
|
+
return String(n === 0 ? 0 : n);
|
|
1073
|
+
}
|
|
1074
|
+
function vec(v) {
|
|
1075
|
+
return `${fmt(v[0])} ${fmt(v[1])} ${fmt(v[2])}`;
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Serialize an assembly's links and revolute/prismatic joints to a URDF string.
|
|
1079
|
+
* Returns an error if any joint is multi-DOF or carries a fixed `offset`, since
|
|
1080
|
+
* URDF cannot represent those as a single joint.
|
|
1081
|
+
*/
|
|
1082
|
+
function exportURDF(assembly, options = {}) {
|
|
1083
|
+
const robot = options.name ?? "robot";
|
|
1084
|
+
const effort = options.effort ?? 0;
|
|
1085
|
+
const velocity = options.velocity ?? 0;
|
|
1086
|
+
const meshes = options.meshes ?? {};
|
|
1087
|
+
const links = [];
|
|
1088
|
+
const joints = [];
|
|
1089
|
+
walkAssembly(assembly, (n) => {
|
|
1090
|
+
links.push(n.name);
|
|
1091
|
+
if (n.joints) joints.push(...n.joints);
|
|
1092
|
+
});
|
|
1093
|
+
for (const j of joints) {
|
|
1094
|
+
if (j.type !== "revolute" && j.type !== "prismatic") return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, `exportURDF: joint '${j.parent}->${j.child}' is '${j.type}'; URDF supports only revolute and prismatic joints`));
|
|
1095
|
+
if (j.offset) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, `exportURDF: joint '${j.parent}->${j.child}' carries a fixed offset (e.g. a DH link) that URDF cannot represent as a single joint`));
|
|
1096
|
+
}
|
|
1097
|
+
const lines = ["<?xml version=\"1.0\"?>", `<robot name="${escapeXml(robot)}">`];
|
|
1098
|
+
for (const link of links) {
|
|
1099
|
+
const mesh = meshes[link];
|
|
1100
|
+
if (mesh) lines.push(` <link name="${escapeXml(link)}">`, ` <visual><geometry><mesh filename="${escapeXml(mesh)}"/></geometry></visual>`, ` </link>`);
|
|
1101
|
+
else lines.push(` <link name="${escapeXml(link)}"/>`);
|
|
1102
|
+
}
|
|
1103
|
+
for (const j of joints) {
|
|
1104
|
+
const toRad = j.type === "revolute";
|
|
1105
|
+
const lower = toRad ? j.min * DEG2RAD : j.min;
|
|
1106
|
+
const upper = toRad ? j.max * DEG2RAD : j.max;
|
|
1107
|
+
const origin = j.type === "prismatic" ? [
|
|
1108
|
+
0,
|
|
1109
|
+
0,
|
|
1110
|
+
0
|
|
1111
|
+
] : j.axis.origin;
|
|
1112
|
+
lines.push(` <joint name="${escapeXml(`${j.parent}_to_${j.child}`)}" type="${j.type}">`, ` <parent link="${escapeXml(j.parent)}"/>`, ` <child link="${escapeXml(j.child)}"/>`, ` <origin xyz="${vec(origin)}" rpy="0 0 0"/>`, ` <axis xyz="${vec(j.axis.direction)}"/>`, ` <limit lower="${fmt(lower)}" upper="${fmt(upper)}" effort="${fmt(effort)}" velocity="${fmt(velocity)}"/>`, ` </joint>`);
|
|
1113
|
+
}
|
|
1114
|
+
lines.push("</robot>", "");
|
|
1115
|
+
return require_errors.ok(lines.join("\n"));
|
|
1116
|
+
}
|
|
1117
|
+
/** Read a string attribute from a tag's attribute text. */
|
|
1118
|
+
function attr(text, name) {
|
|
1119
|
+
return new RegExp(`\\b${name}\\s*=\\s*"([^"]*)"`).exec(text)?.[1];
|
|
1120
|
+
}
|
|
1121
|
+
/** Parse a whitespace-separated numeric triple, defaulting missing components to 0. */
|
|
1122
|
+
function triple(s, fallback) {
|
|
1123
|
+
if (!s) return fallback;
|
|
1124
|
+
const parts = s.trim().split(/\s+/).map(Number);
|
|
1125
|
+
return [
|
|
1126
|
+
parts[0] ?? 0,
|
|
1127
|
+
parts[1] ?? 0,
|
|
1128
|
+
parts[2] ?? 0
|
|
1129
|
+
];
|
|
1130
|
+
}
|
|
1131
|
+
/** Rotate an axis by a URDF roll-pitch-yaw (fixed-axis XYZ) triple in radians. */
|
|
1132
|
+
function applyRpy(axis, rpy) {
|
|
1133
|
+
return quatRotate(quatMultiply(quatMultiply(quatFromAxisAngle([
|
|
1134
|
+
0,
|
|
1135
|
+
0,
|
|
1136
|
+
1
|
|
1137
|
+
], rpy[2]), quatFromAxisAngle([
|
|
1138
|
+
0,
|
|
1139
|
+
1,
|
|
1140
|
+
0
|
|
1141
|
+
], rpy[1])), quatFromAxisAngle([
|
|
1142
|
+
1,
|
|
1143
|
+
0,
|
|
1144
|
+
0
|
|
1145
|
+
], rpy[0])), axis);
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Parse a URDF document into its robot name, link names, and revolute/prismatic
|
|
1149
|
+
* joints. `continuous` joints become revolute with a full -180..180 range;
|
|
1150
|
+
* `fixed`/`floating`/`planar` joints are skipped (their links are still listed).
|
|
1151
|
+
* A non-zero `<origin rpy>` is folded into the joint axis direction; its
|
|
1152
|
+
* residual frame rotation is not represented (URDF's pre-motion frame offset has
|
|
1153
|
+
* no single-joint brepjs equivalent).
|
|
1154
|
+
*/
|
|
1155
|
+
function importURDF(xml) {
|
|
1156
|
+
const robotMatch = /<robot\b([^>]*)>/.exec(xml);
|
|
1157
|
+
if (!robotMatch) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, "importURDF: no <robot> element found"));
|
|
1158
|
+
const name = attr(robotMatch[1] ?? "", "name") ?? "robot";
|
|
1159
|
+
const links = [];
|
|
1160
|
+
const linkRe = /<link\b([^>]*?)(?:\/>|>)/g;
|
|
1161
|
+
for (let m = linkRe.exec(xml); m; m = linkRe.exec(xml)) {
|
|
1162
|
+
const n = attr(m[1] ?? "", "name");
|
|
1163
|
+
if (n) links.push(n);
|
|
1164
|
+
}
|
|
1165
|
+
const joints = [];
|
|
1166
|
+
const jointRe = /<joint\b([^>]*)>([\s\S]*?)<\/joint>/g;
|
|
1167
|
+
for (let m = jointRe.exec(xml); m; m = jointRe.exec(xml)) {
|
|
1168
|
+
const head = m[1] ?? "";
|
|
1169
|
+
const body = m[2] ?? "";
|
|
1170
|
+
const type = attr(head, "type") ?? "fixed";
|
|
1171
|
+
if (type === "fixed" || type === "floating" || type === "planar") continue;
|
|
1172
|
+
const parentTag = /<parent\b([^>]*?)\/?>/.exec(body);
|
|
1173
|
+
const childTag = /<child\b([^>]*?)\/?>/.exec(body);
|
|
1174
|
+
const parent = attr(parentTag?.[1] ?? "", "link");
|
|
1175
|
+
const child = attr(childTag?.[1] ?? "", "link");
|
|
1176
|
+
if (!parent || !child) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, `importURDF: joint missing parent/child link (${attr(head, "name") ?? "unnamed"})`));
|
|
1177
|
+
const originTag = /<origin\b([^>]*?)\/?>/.exec(body);
|
|
1178
|
+
const axisTag = /<axis\b([^>]*?)\/?>/.exec(body);
|
|
1179
|
+
const limitTag = /<limit\b([^>]*?)\/?>/.exec(body);
|
|
1180
|
+
const origin = triple(attr(originTag?.[1] ?? "", "xyz"), [
|
|
1181
|
+
0,
|
|
1182
|
+
0,
|
|
1183
|
+
0
|
|
1184
|
+
]);
|
|
1185
|
+
const rpy = triple(attr(originTag?.[1] ?? "", "rpy"), [
|
|
1186
|
+
0,
|
|
1187
|
+
0,
|
|
1188
|
+
0
|
|
1189
|
+
]);
|
|
1190
|
+
const direction = applyRpy(triple(attr(axisTag?.[1] ?? "", "xyz"), [
|
|
1191
|
+
1,
|
|
1192
|
+
0,
|
|
1193
|
+
0
|
|
1194
|
+
]), rpy);
|
|
1195
|
+
const lowerRaw = Number(attr(limitTag?.[1] ?? "", "lower") ?? NaN);
|
|
1196
|
+
const upperRaw = Number(attr(limitTag?.[1] ?? "", "upper") ?? NaN);
|
|
1197
|
+
if (type === "prismatic") {
|
|
1198
|
+
const opts = Number.isFinite(lowerRaw) && Number.isFinite(upperRaw) ? {
|
|
1199
|
+
min: lowerRaw,
|
|
1200
|
+
max: upperRaw
|
|
1201
|
+
} : {};
|
|
1202
|
+
joints.push(prismaticJoint(parent, child, {
|
|
1203
|
+
origin,
|
|
1204
|
+
direction
|
|
1205
|
+
}, opts));
|
|
1206
|
+
} else if (type === "revolute" || type === "continuous") {
|
|
1207
|
+
const opts = type === "continuous" || !Number.isFinite(lowerRaw) || !Number.isFinite(upperRaw) ? {
|
|
1208
|
+
min: -180,
|
|
1209
|
+
max: 180
|
|
1210
|
+
} : {
|
|
1211
|
+
min: lowerRaw * RAD2DEG,
|
|
1212
|
+
max: upperRaw * RAD2DEG
|
|
1213
|
+
};
|
|
1214
|
+
joints.push(revoluteJoint(parent, child, {
|
|
1215
|
+
origin,
|
|
1216
|
+
direction
|
|
1217
|
+
}, opts));
|
|
1218
|
+
} else return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, `importURDF: joint '${attr(head, "name") ?? "unnamed"}' has unrecognized type '${type}'`));
|
|
1219
|
+
}
|
|
1220
|
+
return require_errors.ok({
|
|
1221
|
+
name,
|
|
1222
|
+
links,
|
|
1223
|
+
joints
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
//#endregion
|
|
972
1227
|
//#region src/operations/historyFns.ts
|
|
973
1228
|
/** Create a new empty history. */
|
|
974
1229
|
function createHistory() {
|
|
@@ -1314,6 +1569,12 @@ Object.defineProperty(exports, "exportAssemblySTEP", {
|
|
|
1314
1569
|
return exportAssemblySTEP;
|
|
1315
1570
|
}
|
|
1316
1571
|
});
|
|
1572
|
+
Object.defineProperty(exports, "exportURDF", {
|
|
1573
|
+
enumerable: true,
|
|
1574
|
+
get: function() {
|
|
1575
|
+
return exportURDF;
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1317
1578
|
Object.defineProperty(exports, "findNode", {
|
|
1318
1579
|
enumerable: true,
|
|
1319
1580
|
get: function() {
|
|
@@ -1344,6 +1605,12 @@ Object.defineProperty(exports, "gridPattern", {
|
|
|
1344
1605
|
return gridPattern;
|
|
1345
1606
|
}
|
|
1346
1607
|
});
|
|
1608
|
+
Object.defineProperty(exports, "importURDF", {
|
|
1609
|
+
enumerable: true,
|
|
1610
|
+
get: function() {
|
|
1611
|
+
return importURDF;
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1347
1614
|
Object.defineProperty(exports, "inverseKinematics", {
|
|
1348
1615
|
enumerable: true,
|
|
1349
1616
|
get: function() {
|
|
@@ -1362,6 +1629,12 @@ Object.defineProperty(exports, "jointTransform", {
|
|
|
1362
1629
|
return jointTransform;
|
|
1363
1630
|
}
|
|
1364
1631
|
});
|
|
1632
|
+
Object.defineProperty(exports, "jointsFromDH", {
|
|
1633
|
+
enumerable: true,
|
|
1634
|
+
get: function() {
|
|
1635
|
+
return jointsFromDH;
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1365
1638
|
Object.defineProperty(exports, "linearPattern", {
|
|
1366
1639
|
enumerable: true,
|
|
1367
1640
|
get: function() {
|