@faicad/sheetmetal 0.13.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.
Files changed (113) hide show
  1. package/dist/allowanceFns.d.ts +42 -0
  2. package/dist/allowanceFns.d.ts.map +1 -0
  3. package/dist/allowanceFns.js +63 -0
  4. package/dist/allowanceFns.js.map +1 -0
  5. package/dist/api.d.ts +312 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +367 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/authorFns.d.ts +118 -0
  10. package/dist/authorFns.d.ts.map +1 -0
  11. package/dist/authorFns.js +562 -0
  12. package/dist/authorFns.js.map +1 -0
  13. package/dist/bendTableFns.d.ts +87 -0
  14. package/dist/bendTableFns.d.ts.map +1 -0
  15. package/dist/bendTableFns.js +345 -0
  16. package/dist/bendTableFns.js.map +1 -0
  17. package/dist/compat.d.ts +90 -0
  18. package/dist/compat.d.ts.map +1 -0
  19. package/dist/compat.js +99 -0
  20. package/dist/compat.js.map +1 -0
  21. package/dist/contourFlangeFns.d.ts +122 -0
  22. package/dist/contourFlangeFns.d.ts.map +1 -0
  23. package/dist/contourFlangeFns.js +403 -0
  24. package/dist/contourFlangeFns.js.map +1 -0
  25. package/dist/cutoutFns.d.ts +95 -0
  26. package/dist/cutoutFns.d.ts.map +1 -0
  27. package/dist/cutoutFns.js +300 -0
  28. package/dist/cutoutFns.js.map +1 -0
  29. package/dist/dxfFns.d.ts +48 -0
  30. package/dist/dxfFns.d.ts.map +1 -0
  31. package/dist/dxfFns.js +236 -0
  32. package/dist/dxfFns.js.map +1 -0
  33. package/dist/facade.d.ts +449 -0
  34. package/dist/facade.d.ts.map +1 -0
  35. package/dist/facade.js +535 -0
  36. package/dist/facade.js.map +1 -0
  37. package/dist/featureTreeFns.d.ts +76 -0
  38. package/dist/featureTreeFns.d.ts.map +1 -0
  39. package/dist/featureTreeFns.js +190 -0
  40. package/dist/featureTreeFns.js.map +1 -0
  41. package/dist/foldFns.d.ts +83 -0
  42. package/dist/foldFns.d.ts.map +1 -0
  43. package/dist/foldFns.js +744 -0
  44. package/dist/foldFns.js.map +1 -0
  45. package/dist/foreignUnfoldFns.d.ts +62 -0
  46. package/dist/foreignUnfoldFns.d.ts.map +1 -0
  47. package/dist/foreignUnfoldFns.js +854 -0
  48. package/dist/foreignUnfoldFns.js.map +1 -0
  49. package/dist/formFns.d.ts +58 -0
  50. package/dist/formFns.d.ts.map +1 -0
  51. package/dist/formFns.js +300 -0
  52. package/dist/formFns.js.map +1 -0
  53. package/dist/hemFns.d.ts +17 -0
  54. package/dist/hemFns.d.ts.map +1 -0
  55. package/dist/hemFns.js +212 -0
  56. package/dist/hemFns.js.map +1 -0
  57. package/dist/index.d.ts +43 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +32 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/internal.d.ts +27 -0
  62. package/dist/internal.d.ts.map +1 -0
  63. package/dist/internal.js +38 -0
  64. package/dist/internal.js.map +1 -0
  65. package/dist/jogFns.d.ts +18 -0
  66. package/dist/jogFns.d.ts.map +1 -0
  67. package/dist/jogFns.js +180 -0
  68. package/dist/jogFns.js.map +1 -0
  69. package/dist/loftedFlangeFns.d.ts +23 -0
  70. package/dist/loftedFlangeFns.d.ts.map +1 -0
  71. package/dist/loftedFlangeFns.js +306 -0
  72. package/dist/loftedFlangeFns.js.map +1 -0
  73. package/dist/materials.d.ts +16 -0
  74. package/dist/materials.d.ts.map +1 -0
  75. package/dist/materials.js +44 -0
  76. package/dist/materials.js.map +1 -0
  77. package/dist/miterFns.d.ts +31 -0
  78. package/dist/miterFns.d.ts.map +1 -0
  79. package/dist/miterFns.js +128 -0
  80. package/dist/miterFns.js.map +1 -0
  81. package/dist/nestFns.d.ts +116 -0
  82. package/dist/nestFns.d.ts.map +1 -0
  83. package/dist/nestFns.js +517 -0
  84. package/dist/nestFns.js.map +1 -0
  85. package/dist/polygonFns.d.ts +144 -0
  86. package/dist/polygonFns.d.ts.map +1 -0
  87. package/dist/polygonFns.js +324 -0
  88. package/dist/polygonFns.js.map +1 -0
  89. package/dist/reliefFns.d.ts +44 -0
  90. package/dist/reliefFns.d.ts.map +1 -0
  91. package/dist/reliefFns.js +367 -0
  92. package/dist/reliefFns.js.map +1 -0
  93. package/dist/reportFns.d.ts +33 -0
  94. package/dist/reportFns.d.ts.map +1 -0
  95. package/dist/reportFns.js +71 -0
  96. package/dist/reportFns.js.map +1 -0
  97. package/dist/tabFns.d.ts +43 -0
  98. package/dist/tabFns.d.ts.map +1 -0
  99. package/dist/tabFns.js +179 -0
  100. package/dist/tabFns.js.map +1 -0
  101. package/dist/types.d.ts +629 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +2 -0
  104. package/dist/types.js.map +1 -0
  105. package/dist/unfoldFns.d.ts +120 -0
  106. package/dist/unfoldFns.d.ts.map +1 -0
  107. package/dist/unfoldFns.js +766 -0
  108. package/dist/unfoldFns.js.map +1 -0
  109. package/dist/validateFns.d.ts +18 -0
  110. package/dist/validateFns.d.ts.map +1 -0
  111. package/dist/validateFns.js +196 -0
  112. package/dist/validateFns.js.map +1 -0
  113. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorFns.js","sourceRoot":"","sources":["../src/authorFns.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type Result,\n type Vec3,\n type Bounds3D,\n type Solid,\n type ValidSolid,\n ok,\n err,\n validationError,\n box,\n cylinder,\n fuse,\n cut,\n intersect,\n rotate,\n translate,\n vecAdd,\n vecSub,\n vecScale,\n vecDot,\n vecCross,\n vecNormalize,\n} from '@faicad/faijs/brepjs-compat';\nimport type {\n BendFeature,\n BendRule,\n FlangeFeature,\n EdgeRef,\n FlatSide,\n MaterialSpec,\n MiterSpec,\n SheetMetalPart,\n} from './types.js';\nimport { normalizeSolid } from './internal.js';\nimport { ROOT_FLAT_ID, featureTree, type FeatureTree } from './featureTreeFns.js';\n\n/** Authoring options for the base flat the flanges attach to. */\nexport interface BaseFlatSpec {\n /** Extent along the run (+X) axis. */\n length: number;\n /** Extent along the width (+Y) axis. */\n width: number;\n}\n\n/** Which edge a flange folds off (of the base, or of its parent flange). */\nexport type FlangeSide = FlatSide;\n\n/** A single flange to author off an edge of its parent flat. */\nexport interface FlangeSpec {\n id: string;\n /** Flat length measured from the end of the bend along the flange plane. */\n length: number;\n /** Signed fold angle in degrees. */\n angleDeg: number;\n rule: BendRule;\n /** Parent edge to attach to. Default `'xmax'` (the leading +X edge). */\n side?: FlangeSide | undefined;\n /** Fold direction relative to the parent face normal. Default `'up'`. */\n direction?: 'up' | 'down' | undefined;\n /** Id of another flange this flange folds off (its distal edge). Default = base flat. */\n parent?: string | undefined;\n /** Start position along the parent edge. Default `0`. */\n offset?: number | undefined;\n /** Extent along the parent edge. Default = full parent-edge length. */\n width?: number | undefined;\n miter?: MiterSpec | undefined;\n}\n\n/**\n * A seam: a bend connecting two already-authored flats that is intentionally left\n * unfolded (a free edge). Closing the last wall of a box/tube back onto an earlier\n * flat produces a cyclic feature graph; the feature tree turns this edge into a\n * SEAM_CUT, and the unfold leaves the flats connected through the spanning tree.\n */\nexport interface SeamSpec {\n /** Flat id the seam folds from (an authored flange, or `'root'`/`'face-0'` for the base). */\n parent: string;\n /** Flat id the seam meets (must already be authored; `'root'`/`'face-0'` = base). */\n child: string;\n angleDeg: number;\n rule: BendRule;\n}\n\n/** Inputs for {@link authorPart}. */\nexport interface AuthorSpec {\n thickness: number;\n base: BaseFlatSpec;\n flanges: FlangeSpec[];\n material?: MaterialSpec | undefined;\n /** Optional seams that close a profile into a tube/box (left unfolded). */\n seams?: SeamSpec[] | undefined;\n}\n\n/**\n * Stable edge reference for flange attachment. The base flat is `face-0`; every\n * flange face is `face-<n+1>` in authoring order. The leading edge of a flat is\n * `edgeIndex 0`. The reference also carries `parentId`/`side`/`offset`/`extent`\n * so the feature tree and recursive unfold can resolve the exact parent edge a\n * flange folds from without reading topology back out of the B-rep.\n *\n * @param faceIndex - the face index of the flat: `0` for the base, `n+1` for the\n * flange authored in the `n`-th position.\n * @returns an {@link EdgeRef} pointing at the flat's leading edge (`edgeIndex 0`).\n */\nexport function baseEdgeRef(faceIndex: number): EdgeRef {\n return { kind: 'index', faceIndex, edgeIndex: 0 };\n}\n\n/**\n * A flat in the part: the base, or a placed flange face. Each carries the world\n * frame (origin + orthonormal axes) of its top surface so a child flange can be\n * built directly off any of its four edges, at any fold direction.\n */\nexport interface FlatFrame {\n id: string;\n /** Near corner of the flat on its −normal (bottom) surface; the flat spans\n * `thickness` along +n. Local `(x, y)` maps to `origin + x·u + y·v`. */\n origin: Vec3;\n /** In-plane direction; the flat spans `[0, uLen]` along it. */\n u: Vec3;\n /** In-plane direction; the flat spans `[0, vLen]` along it. */\n v: Vec3;\n /** Outward face normal of the top surface (n = u × v). */\n n: Vec3;\n uLen: number;\n vLen: number;\n}\n\n/**\n * Author a sheet-metal part: a base flat plus an arbitrary tree of flanges. Each\n * flange folds off one of the four edges of its parent flat (the base by default,\n * or another flange via `parent`), in the requested direction (up/down), over an\n * optional sub-span of that edge (`offset`/`width`). Returns a {@link SheetMetalPart}\n * carrying the folded 3D solid and the recorded bend feature tree the unfold\n * consumes. All construction stays on the public, OCCT-WASM-safe API.\n *\n * @param spec - the authoring spec: sheet thickness, base flat dimensions, the\n * flange list, optional material, and optional closing seams.\n * @returns a `Result<SheetMetalPart>` — `ok` with the folded part on success, or\n * `err` with a `validationError` for an invalid thickness / base / flange /\n * seam specification.\n */\nexport function authorPart(spec: AuthorSpec): Result<SheetMetalPart> {\n const { thickness } = spec;\n if (!Number.isFinite(thickness) || thickness <= 0) {\n return err(validationError('INVALID_THICKNESS', `thickness must be positive, got ${thickness}`));\n }\n const { length: baseLen, width } = spec.base;\n if (!Number.isFinite(baseLen) || baseLen <= 0) {\n return err(validationError('INVALID_BASE_LENGTH', `base.length must be positive, got ${baseLen}`));\n }\n if (!Number.isFinite(width) || width <= 0) {\n return err(validationError('INVALID_BASE_WIDTH', `base.width must be positive, got ${width}`));\n }\n\n const seen = new Set<string>();\n for (const flange of spec.flanges) {\n // `::` is reserved as the seam-bend id delimiter (`seam::<parent>::<child>`);\n // allowing it in a flange id would make the seam parent/child ambiguous to parse.\n // `root`/`face-0` are reserved sentinels for the base flat — a flange reusing\n // either would silently overwrite the base frame and fold off wrong geometry.\n if (flange.id === '' || flange.id.includes('::') || flange.id === ROOT_FLAT_ID || flange.id === 'face-0') {\n return err(\n validationError('INVALID_FLANGE_ID', `flange id must be non-empty, must not contain '::', and must not reuse the reserved ids 'root'/'face-0', got '${flange.id}'`)\n );\n }\n if (seen.has(flange.id)) {\n return err(validationError('DUPLICATE_FLANGE', `duplicate flange id '${flange.id}'`));\n }\n seen.add(flange.id);\n }\n\n // Two flanges on the same parent edge must not overlap along that edge.\n const overlap = checkEdgeOverlaps(spec.flanges, baseLen, width);\n if (!overlap.ok) return overlap;\n\n const ROOT = ROOT_FLAT_ID;\n const frames = new Map<string, FlatFrame>();\n // Frame origin sits on the sheet's −normal (bottom) surface; the flat spans\n // `thickness` along +n. This matches the canonical assembly, whose z=0 plane is\n // the sheet bottom and whose bend cylinder sits at z = T+r (up) / −r (down).\n frames.set(ROOT, {\n id: ROOT,\n origin: [0, 0, 0],\n u: [1, 0, 0],\n v: [0, 1, 0],\n n: [0, 0, 1],\n uLen: baseLen,\n vLen: width,\n });\n\n let solid: Solid = box(baseLen, width, thickness);\n const flanges: FlangeFeature[] = [];\n const bends: BendFeature[] = [];\n\n // Author in spec order; a chained flange must follow its parent. Resolve the\n // parent frame by flange id (or the base for a root flange).\n for (const flange of spec.flanges) {\n const parentId = flange.parent ?? ROOT;\n const parentFrame = frames.get(parentId);\n if (parentFrame === undefined) {\n return err(\n validationError('UNKNOWN_PARENT', `flange '${flange.id}' parent '${flange.parent}' not authored yet`)\n );\n }\n const built = buildFlange(solid, parentFrame, thickness, flange);\n if (!built.ok) return built;\n solid = built.value.solid;\n flanges.push(built.value.flange);\n bends.push(built.value.bend);\n frames.set(flange.id, built.value.childFrame);\n }\n\n for (const seam of spec.seams ?? []) {\n const seamParent = seam.parent === 'face-0' ? ROOT : seam.parent;\n const seamChild = seam.child === 'face-0' ? ROOT : seam.child;\n if (!frames.has(seamParent) || !frames.has(seamChild)) {\n return err(\n validationError('UNKNOWN_SEAM_FLAT', `seam ${seam.parent}↔${seam.child} references an unauthored flat`)\n );\n }\n if (!Number.isFinite(seam.angleDeg) || seam.angleDeg <= 0 || seam.angleDeg > 180) {\n return err(\n validationError('INVALID_SEAM_ANGLE', `seam ${seam.parent}↔${seam.child} angleDeg must be in (0, 180], got ${seam.angleDeg}`)\n );\n }\n if (!Number.isFinite(seam.rule.innerRadius) || seam.rule.innerRadius < 0) {\n return err(\n validationError('INVALID_SEAM_RADIUS', `seam ${seam.parent}↔${seam.child} innerRadius must be non-negative`)\n );\n }\n const parentFrame = frames.get(seamParent) as FlatFrame;\n bends.push({\n id: `seam::${seamParent}::${seamChild}`,\n axisOrigin: [parentFrame.origin[0], parentFrame.origin[1], parentFrame.origin[2]],\n axisDir: [parentFrame.u[0], parentFrame.u[1], parentFrame.u[2]],\n angleDeg: seam.angleDeg,\n direction: 'up',\n rule: seam.rule,\n });\n }\n\n return ok({\n thickness,\n baseLength: baseLen,\n width,\n ...(spec.material !== undefined ? { material: spec.material } : {}),\n flanges,\n bends,\n solid: normalizeSolid(solid),\n });\n}\n\n/**\n * World {@link FlatFrame} of every flat region of an authored part, keyed by region\n * id (`'root'` for the base). Reconstructed from the recorded bend/flange feature\n * tree using the exact same edge/transform/child-frame math {@link authorPart} uses\n * to place the geometry, so a cutout authored in a region's local `(x, y)` lands on\n * the matching folded face. Walks the feature tree in BFS order so a chained\n * flange's parent frame is always known first.\n *\n * @param part - the authored sheet-metal part whose flat regions to resolve.\n * @param tree - optional pre-built {@link FeatureTree}; when omitted the tree is\n * reconstructed from `part` via {@link featureTree}.\n * @returns a `Result<Map<string, FlatFrame>>` — `ok` with a map of region id\n * (`'root'` for the base, otherwise the flange id) to its world {@link FlatFrame},\n * or `err` when a flange's parent frame is missing from the tree.\n */\nexport function worldFrames(\n part: SheetMetalPart,\n tree?: FeatureTree\n): Result<Map<string, FlatFrame>> {\n const frames = new Map<string, FlatFrame>();\n frames.set(ROOT_FLAT_ID, {\n id: ROOT_FLAT_ID,\n origin: [0, 0, 0],\n u: [1, 0, 0],\n v: [0, 1, 0],\n n: [0, 0, 1],\n uLen: part.baseLength,\n vLen: part.width,\n });\n\n const treeResult = tree !== undefined ? ok(tree) : featureTree(part);\n if (!treeResult.ok) return treeResult;\n\n const flangeById = new Map<string, FlangeFeature>();\n for (const f of part.flanges) flangeById.set(f.id, f);\n\n for (const tb of treeResult.value.bends) {\n const flange = flangeById.get(tb.child);\n if (flange === undefined) continue;\n const parent = frames.get(tb.parent);\n if (parent === undefined) {\n return err(validationError('UNKNOWN_PARENT', `worldFrames: parent '${tb.parent}' missing for '${tb.child}'`));\n }\n const side: FlatSide = flange.baseEdge.side ?? 'xmax';\n const direction: 'up' | 'down' = flange.direction ?? 'up';\n const offset = flange.offset ?? flange.baseEdge.offset ?? 0;\n const r = flange.rule.innerRadius;\n const edge = parentEdge(parent, side);\n const sign = direction === 'up' ? 1 : -1;\n const place = frameTransform(edge.dir, edge.out, parent.n, edge.start, offset);\n frames.set(\n flange.id,\n computeChildFrame(flange.id, place, flange.span, flange.angleDeg, part.thickness, r, sign, flange.length)\n );\n }\n\n return ok(frames);\n}\n\n/**\n * Reject two flanges on the same parent edge whose [offset, offset+width] ranges\n * overlap. The edge length a flange's default span fills must be the *resolved*\n * parent-edge length, not the base's: a chained flange folds off another flange\n * whose edges have that flange's own span/length, so keying the default off the\n * base dimensions would compute a bogus span and spuriously reject valid pairs.\n */\nfunction checkEdgeOverlaps(specs: FlangeSpec[], baseLen: number, width: number): Result<void> {\n interface Range {\n id: string;\n lo: number;\n hi: number;\n }\n // Resolved child-frame dims per flange: spanLen along the bend axis, flatLen out.\n // Walked in spec order (a chained flange always follows its parent), mirroring\n // the authoring loop so parent frames are known before their children.\n const dims = new Map<string, { spanLen: number; flatLen: number }>();\n const edgeLenFor = (parentId: string, side: FlatSide): number => {\n const onWidthEdge = side === 'xmax' || side === 'xmin';\n if (parentId === ROOT_FLAT_ID) return onWidthEdge ? width : baseLen;\n const p = dims.get(parentId);\n if (p === undefined) return onWidthEdge ? width : baseLen;\n // Parent flange frame: uLen = its span (xmax/xmin edges), vLen = its length.\n return onWidthEdge ? p.flatLen : p.spanLen;\n };\n\n const byEdge = new Map<string, Range[]>();\n for (const f of specs) {\n const side: FlatSide = f.side ?? 'xmax';\n const parentId = f.parent ?? ROOT_FLAT_ID;\n const key = `${parentId}::${side}`;\n const edgeLen = edgeLenFor(parentId, side);\n const lo = f.offset ?? 0;\n const span = f.width ?? edgeLen;\n const hi = lo + span;\n const list = byEdge.get(key) ?? [];\n for (const r of list) {\n if (lo < r.hi - 1e-9 && r.lo < hi - 1e-9) {\n return err(\n validationError(\n 'OVERLAPPING_FLANGES',\n `flange '${f.id}' overlaps '${r.id}' on edge '${key}' ([${lo}, ${hi}] ∩ [${r.lo}, ${r.hi}])`\n )\n );\n }\n }\n list.push({ id: f.id, lo, hi });\n byEdge.set(key, list);\n dims.set(f.id, { spanLen: span, flatLen: f.length });\n }\n return ok(undefined);\n}\n\ninterface BuiltFlange {\n solid: Solid;\n flange: FlangeFeature;\n bend: BendFeature;\n childFrame: FlatFrame;\n}\n\n/**\n * Build one flange off `parent`'s chosen edge and fuse it to `base`. The flange\n * assembly (cylindrical bend patch + flat) is constructed in a canonical frame\n * (bend axis +Y at the origin, outward run +X, top surface +Z) honouring the\n * up/down fold, then rigidly mapped onto the parent edge's world frame.\n */\nfunction buildFlange(\n base: Solid,\n parent: FlatFrame,\n thickness: number,\n flange: FlangeSpec\n): Result<BuiltFlange> {\n if (!Number.isFinite(flange.length) || flange.length <= 0) {\n return err(validationError('INVALID_FLANGE_LENGTH', `flange '${flange.id}' length must be positive`));\n }\n if (!Number.isFinite(flange.angleDeg) || flange.angleDeg <= 0 || flange.angleDeg > 180) {\n return err(\n validationError('INVALID_FLANGE_ANGLE', `flange '${flange.id}' angleDeg must be in (0, 180], got ${flange.angleDeg}`)\n );\n }\n const r = flange.rule.innerRadius;\n if (!Number.isFinite(r) || r < 0) {\n return err(validationError('INVALID_RADIUS', `flange '${flange.id}' innerRadius must be non-negative`));\n }\n\n const side: FlatSide = flange.side ?? 'xmax';\n const direction: 'up' | 'down' = flange.direction ?? 'up';\n const edge = parentEdge(parent, side);\n const offset = flange.offset ?? 0;\n const span = flange.width ?? edge.length;\n if (!Number.isFinite(offset) || offset < -1e-9) {\n return err(validationError('INVALID_OFFSET', `flange '${flange.id}' offset must be non-negative`));\n }\n if (!Number.isFinite(span) || span <= 0) {\n return err(validationError('INVALID_FLANGE_WIDTH', `flange '${flange.id}' width must be positive`));\n }\n if (offset + span > edge.length + 1e-6) {\n return err(\n validationError('FLANGE_OUT_OF_BOUNDS', `flange '${flange.id}' [${offset}, ${offset + span}] exceeds parent edge length ${edge.length}`)\n );\n }\n\n // Canonical assembly: bend axis +Y, outward run +X, top surface +Z, spanning\n // +Y over [0, span]. Up folds toward +Z, down folds below the base plane.\n const canonAxisZ = direction === 'up' ? thickness + r : -r;\n const canonOrigin: Vec3 = [0, 0, canonAxisZ];\n const patch = buildBendPatch(canonOrigin, flange.angleDeg, r, span, thickness, direction);\n if (!patch.ok) return patch;\n const flat = buildFlangeFlat(canonOrigin, flange.angleDeg, span, thickness, flange.length, direction);\n\n // World frame the canonical assembly maps onto: bend axis = edge.dir, outward\n // run = edge.out, top normal = parent.n. The bend axis sits at offset along the\n // edge; the canonical contact (axis straight above the base seam) maps onto the\n // parent edge line.\n const place = frameTransform(edge.dir, edge.out, parent.n, edge.start, offset);\n const patchPlaced = place.solid(patch.value);\n const flatPlaced = place.solid(flat);\n\n const fusedPatch = fuse(base, patchPlaced);\n if (!fusedPatch.ok) return fusedPatch;\n const fused = fuse(fusedPatch.value, flatPlaced);\n if (!fused.ok) return fused;\n\n const sign = direction === 'up' ? 1 : -1;\n // Recorded bend axis = the cylinder centre line: parent edge + n·(T+r up | r down).\n const axisOrigin = vecAdd(\n vecAdd(edge.start, vecScale(edge.dir, offset)),\n vecScale(parent.n, canonAxisZ)\n );\n const bend: BendFeature = {\n id: flange.id,\n axisOrigin: [axisOrigin[0], axisOrigin[1], axisOrigin[2]],\n axisDir: [edge.dir[0], edge.dir[1], edge.dir[2]],\n angleDeg: flange.angleDeg,\n direction,\n rule: flange.rule,\n };\n\n const childFrame = computeChildFrame(flange.id, place, span, flange.angleDeg, thickness, r, sign, flange.length);\n\n // True folded AABB of the whole flange (bend patch + flat) in world space.\n // Computed from the real placed geometry so chained flanges — whose bend axis\n // sits off the z=0 base plane — get a correct box, not the z=0-flattened one a\n // purely analytic re-fold would produce. The collision check reuses this.\n const foldedBounds = flangeFoldedBounds(childFrame, edge, offset, span, parent.n, canonAxisZ, thickness);\n\n const flangeFeature: FlangeFeature = {\n id: flange.id,\n baseEdge: {\n kind: 'index',\n faceIndex: parent.id === ROOT_FLAT_ID ? 0 : -1,\n edgeIndex: 0,\n parentId: parent.id,\n side,\n offset,\n extent: span,\n },\n length: flange.length,\n span,\n offset,\n angleDeg: flange.angleDeg,\n direction,\n rule: flange.rule,\n foldedBounds,\n ...(flange.miter !== undefined ? { miter: flange.miter } : {}),\n };\n\n return ok({ solid: fused.value, flange: flangeFeature, bend, childFrame });\n}\n\ninterface ParentEdge {\n /** Direction along the edge (the bend axis). */\n dir: Vec3;\n /** Outward in-plane direction the flange runs (perpendicular to dir). */\n out: Vec3;\n /** Start corner of the edge (offset 0). */\n start: Vec3;\n /** Edge length. */\n length: number;\n}\n\n/**\n * Resolve one of the four edges of a flat frame. The bend axis `dir` is chosen so\n * the canonical assembly maps onto it by a proper rotation: `out × dir = n`, i.e.\n * `dir = n × out`. `start` is the edge endpoint from which `dir` runs along the\n * edge, so the flange spans `start + offset·dir` to `start + (offset+span)·dir`.\n */\nfunction parentEdge(f: FlatFrame, side: FlatSide): ParentEdge {\n const o = f.origin;\n const uTop = vecAdd(o, vecScale(f.u, f.uLen));\n const vTop = vecAdd(o, vecScale(f.v, f.vLen));\n const uvTop = vecAdd(uTop, vecScale(f.v, f.vLen));\n\n let out: Vec3;\n let length: number;\n let a: Vec3;\n let b: Vec3;\n switch (side) {\n case 'xmax':\n out = f.u;\n length = f.vLen;\n a = uTop;\n b = uvTop;\n break;\n case 'xmin':\n out = vecScale(f.u, -1);\n length = f.vLen;\n a = o;\n b = vTop;\n break;\n case 'ymax':\n out = f.v;\n length = f.uLen;\n a = vTop;\n b = uvTop;\n break;\n case 'ymin':\n out = vecScale(f.v, -1);\n length = f.uLen;\n a = o;\n b = uTop;\n break;\n }\n const dir = vecNormalize(vecCross(f.n, out));\n // Pick the endpoint from which `dir` points toward the other endpoint.\n const toB = vecSub(b, a);\n const start = vecDot(toB, dir) >= 0 ? a : b;\n return { dir, out, start, length };\n}\n\n/**\n * Frame of the child flange's flat (bottom/−normal surface, near corner), for\n * chaining grandchildren. Derived by folding the canonical flat by ∓θ about the\n * bend axis, then mapping through the same rigid transform that placed the flange.\n */\nfunction computeChildFrame(\n id: string,\n place: PlacedTransform,\n span: number,\n angleDeg: number,\n thickness: number,\n r: number,\n sign: number,\n length: number\n): FlatFrame {\n const theta = (angleDeg * Math.PI) / 180;\n const axisZ = sign > 0 ? thickness + r : -r;\n\n // Canonical fold = rotate by −sign·θ about +Y at pivot [0,0,axisZ]. Run +X and\n // normal +Z fold accordingly; the flat's near-bottom corner ([0,0,0]) rotates\n // about the pivot. (rotate by a about +Y: [x,z]→[x cos a + z sin a, −x sin a + z cos a].)\n const a = -sign * theta;\n const ca = Math.cos(a);\n const sa = Math.sin(a);\n const runC: Vec3 = [ca, 0, -sa];\n const nC: Vec3 = [sa, 0, ca];\n const dz = -axisZ;\n const cornerC: Vec3 = [dz * sa, 0, axisZ + dz * ca];\n\n return {\n id,\n origin: place.point(cornerC),\n u: place.vector([0, 1, 0]),\n v: place.vector(runC),\n n: place.vector(nC),\n uLen: span,\n vLen: length,\n };\n}\n\n/**\n * World-space AABB of a folded flange: the union of the flat box (from its child\n * frame) and the bend region between the parent edge and the bend-axis cylinder.\n * Built from the real placed corners, so a chained flange folded off a vertical\n * wall is bounded correctly rather than collapsed into the z=0 base plane.\n */\nfunction flangeFoldedBounds(\n child: FlatFrame,\n edge: ParentEdge,\n offset: number,\n span: number,\n parentN: Vec3,\n canonAxisZ: number,\n thickness: number\n): Bounds3D {\n const corners: Vec3[] = [];\n // Flat box: child.origin + [0,uLen]·u + [0,vLen]·v + [0,thickness]·n.\n for (const s of [0, child.uLen]) {\n for (const l of [0, child.vLen]) {\n for (const t of [0, thickness]) {\n corners.push(\n vecAdd(\n vecAdd(vecAdd(child.origin, vecScale(child.u, s)), vecScale(child.v, l)),\n vecScale(child.n, t)\n )\n );\n }\n }\n }\n // Bend region: from the parent edge contact (sheet at the seam) out to the bend\n // axis line, over the flange span. Captures the cylindrical patch's footprint.\n const edgeBase = vecAdd(edge.start, vecScale(edge.dir, offset));\n const axisLine = vecAdd(edgeBase, vecScale(parentN, canonAxisZ));\n for (const s of [0, span]) {\n const along = vecScale(edge.dir, s);\n corners.push(vecAdd(edgeBase, along));\n corners.push(vecAdd(vecAdd(edgeBase, along), vecScale(parentN, thickness)));\n corners.push(vecAdd(axisLine, along));\n }\n return aabbOf(corners);\n}\n\nfunction aabbOf(corners: Vec3[]): Bounds3D {\n let xMin = Infinity;\n let xMax = -Infinity;\n let yMin = Infinity;\n let yMax = -Infinity;\n let zMin = Infinity;\n let zMax = -Infinity;\n for (const c of corners) {\n if (c[0] < xMin) xMin = c[0];\n if (c[0] > xMax) xMax = c[0];\n if (c[1] < yMin) yMin = c[1];\n if (c[1] > yMax) yMax = c[1];\n if (c[2] < zMin) zMin = c[2];\n if (c[2] > zMax) zMax = c[2];\n }\n return { xMin, xMax, yMin, yMax, zMin, zMax };\n}\n\ninterface PlacedTransform {\n solid: (s: Solid) => Solid;\n point: (p: Vec3) => Vec3;\n vector: (v: Vec3) => Vec3;\n}\n\n/**\n * Rigid transform mapping the canonical flange assembly (bend axis +Y, run +X,\n * normal +Z, contact at the origin) onto a world edge frame: align +X→`runT`,\n * +Y→`axisT`, +Z→`nT`, then slide the axis to `edgeStart + offset·axisT`.\n */\nfunction frameTransform(\n axisT: Vec3,\n runT: Vec3,\n nT: Vec3,\n edgeStart: Vec3,\n offset: number\n): PlacedTransform {\n // Rotation matrix R with columns [runT | axisT | nT] sends canonical X,Y,Z to\n // the target basis. Convert to axis-angle and rotate about the origin.\n const m: number[] = [\n runT[0], axisT[0], nT[0],\n runT[1], axisT[1], nT[1],\n runT[2], axisT[2], nT[2],\n ];\n const aa = matrixToAxisAngle(m);\n const target = vecAdd(edgeStart, vecScale(axisT, offset));\n const applyR = (v: Vec3): Vec3 =>\n vecAdd(vecAdd(vecScale(runT, v[0]), vecScale(axisT, v[1])), vecScale(nT, v[2]));\n return {\n solid: (s: Solid) => {\n const rotated = aa.angleDeg === 0 ? s : rotate(s, aa.angleDeg, { at: [0, 0, 0], axis: aa.axis });\n return translate(rotated, target);\n },\n point: (p: Vec3) => vecAdd(applyR(p), target),\n vector: applyR,\n };\n}\n\n/** Axis-angle of a 3×3 rotation matrix (row-major). */\nfunction matrixToAxisAngle(m: number[]): { axis: Vec3; angleDeg: number } {\n const m00 = m[0] ?? 0;\n const m01 = m[1] ?? 0;\n const m02 = m[2] ?? 0;\n const m10 = m[3] ?? 0;\n const m11 = m[4] ?? 0;\n const m12 = m[5] ?? 0;\n const m20 = m[6] ?? 0;\n const m21 = m[7] ?? 0;\n const m22 = m[8] ?? 0;\n\n const trace = m00 + m11 + m22;\n const cos = Math.max(-1, Math.min(1, (trace - 1) / 2));\n const angle = Math.acos(cos);\n const angleDeg = (angle * 180) / Math.PI;\n if (angle < 1e-9) return { axis: [0, 0, 1], angleDeg: 0 };\n\n if (Math.PI - angle < 1e-6) {\n // 180°: axis is the column of (R + I) with the largest diagonal.\n const xx = (m00 + 1) / 2;\n const yy = (m11 + 1) / 2;\n const zz = (m22 + 1) / 2;\n let axis: Vec3;\n if (xx >= yy && xx >= zz) {\n const x = Math.sqrt(Math.max(xx, 0));\n axis = [x, (m01 + m10) / (4 * x), (m02 + m20) / (4 * x)];\n } else if (yy >= zz) {\n const y = Math.sqrt(Math.max(yy, 0));\n axis = [(m01 + m10) / (4 * y), y, (m12 + m21) / (4 * y)];\n } else {\n const z = Math.sqrt(Math.max(zz, 0));\n axis = [(m02 + m20) / (4 * z), (m12 + m21) / (4 * z), z];\n }\n return { axis: vecNormalize(axis), angleDeg: 180 };\n }\n\n const denom = 2 * Math.sin(angle);\n const axis: Vec3 = [(m21 - m12) / denom, (m02 - m20) / denom, (m10 - m01) / denom];\n return { axis: vecNormalize(axis), angleDeg };\n}\n\n/**\n * Cylindrical bend patch swept by the fold. Built as a hollow tube (outer R+T,\n * inner R) along +Y, intersected with the angular wedge for the fold. For an up\n * bend the axis sits above the base (sweep from −Z toward the flange); for a down\n * bend it sits below (sweep from +Z toward the flange).\n */\nfunction buildBendPatch(\n axisOrigin: Vec3,\n thetaDeg: number,\n r: number,\n width: number,\n thickness: number,\n direction: 'up' | 'down'\n): Result<ValidSolid> {\n const outerR = r + thickness;\n\n const outer = cylinder(outerR, width, { at: axisOrigin, axis: [0, 1, 0] });\n let tube: Solid = outer;\n if (r > 1e-9) {\n const inner = cylinder(r, width, { at: axisOrigin, axis: [0, 1, 0] });\n const carved = cut(outer, inner);\n if (!carved.ok) return carved;\n tube = carved.value;\n }\n\n const wedge = buildWedge(axisOrigin, thetaDeg, outerR, width, direction);\n if (!wedge.ok) return wedge;\n return intersect(tube, wedge.value) as Result<ValidSolid>;\n}\n\n/**\n * Convex angular wedge (≤180°) isolating the fold sweep. The inner arc starts at\n * the base contact (straight down −Z for an up bend, straight up +Z for a down\n * bend) and sweeps to the flange. Built as the intersection of the +X half-space\n * through the bend axis with that half-space rotated by the fold; the tube\n * intersection trims it to the true annular sector.\n */\nfunction buildWedge(\n axisOrigin: Vec3,\n thetaDeg: number,\n outerR: number,\n width: number,\n direction: 'up' | 'down'\n): Result<Solid> {\n const span = outerR * 2 + 2;\n const margin = 1;\n\n const blockA = box(span, width + 2 * margin, 2 * span);\n const halfA: Solid = translate(blockA, [\n axisOrigin[0],\n axisOrigin[1] - margin,\n axisOrigin[2] - span,\n ]);\n\n // Up bends sweep from −Z (rotate +X start plane by +(180−θ)); down bends mirror\n // about the axis, sweeping from +Z (rotate by −(180−θ)).\n const sign = direction === 'up' ? 1 : -1;\n const halfB = rotate(halfA, sign * (180 - thetaDeg), { at: axisOrigin, axis: [0, 1, 0] });\n\n return intersect(halfA, halfB);\n}\n\n/** The flange flat, built lying along +X past the bend, then folded to angle θ. */\nfunction buildFlangeFlat(\n axisOrigin: Vec3,\n thetaDeg: number,\n width: number,\n thickness: number,\n length: number,\n direction: 'up' | 'down'\n): Solid {\n // Unfolded the flat is coplanar with the base sheet; for an up bend it lies in\n // Z∈[0,T] folding up (rotate −θ about +Y sends +X toward +Z); for a down bend it\n // lies in Z∈[−T,0] folding down (rotate +θ sends +X toward −Z).\n if (direction === 'up') {\n const flat = box(length, width, thickness);\n const positioned: Solid = translate(flat, [axisOrigin[0], axisOrigin[1], 0]);\n return rotate(positioned, -thetaDeg, { at: axisOrigin, axis: [0, 1, 0] });\n }\n const flat = box(length, width, thickness);\n const positioned: Solid = translate(flat, [axisOrigin[0], axisOrigin[1], -thickness]);\n return rotate(positioned, thetaDeg, { at: axisOrigin, axis: [0, 1, 0] });\n}\n"]}
@@ -0,0 +1,87 @@
1
+ import { type Result } from '@faicad/faijs/brepjs-compat';
2
+ import type { BendRule, SheetMetalWarning } from './types.js';
3
+ /**
4
+ * One row of a shop bend table: the tabulated value for a single
5
+ * (thickness, innerRadius, bend-angle) operating point. `value` is a bend
6
+ * allowance (`kind: 'allowance'`) or a bend deduction (`kind: 'deduction'`),
7
+ * per the owning {@link BendTable}.
8
+ */
9
+ export interface BendTableRow {
10
+ /** Material thickness the row was measured at. */
11
+ thickness: number;
12
+ /** Inner bend radius the row was measured at. */
13
+ radius: number;
14
+ /** Swept bend angle in degrees (90° = a right-angle bend). */
15
+ angleDeg: number;
16
+ /** Bend allowance or bend deduction, per the table's {@link BendTable.kind}. */
17
+ value: number;
18
+ }
19
+ /**
20
+ * A named shop bend table: empirical bend-allowance or bend-deduction values
21
+ * measured per (thickness, radius, angle). When a {@link BendRule} references a
22
+ * table by id, {@link resolveBendAllowance} interpolates the table instead of
23
+ * applying the K-factor formula, so the developed length matches the shop's
24
+ * actual press-brake results.
25
+ *
26
+ * `kind` selects how a row's `value` is interpreted: an `'allowance'` table
27
+ * tabulates the developed arc length directly; a `'deduction'` table tabulates
28
+ * the bend deduction, which is converted to an allowance on lookup (see
29
+ * {@link resolveBendAllowance} for the OSSB conversion).
30
+ */
31
+ export interface BendTable {
32
+ id: string;
33
+ kind: 'allowance' | 'deduction';
34
+ rows: BendTableRow[];
35
+ }
36
+ /**
37
+ * The live bend-table registry, explicit as a shared resource object (§7.3):
38
+ * no hidden module-level mutable state. `registerBendTable`,
39
+ * {@link getBendTable} and the built-in resource all read/write the same
40
+ * `byId` map, so hosts can inspect or snapshot the registry directly.
41
+ */
42
+ export declare const bendTables: {
43
+ readonly byId: Map<string, BendTable>;
44
+ };
45
+ /**
46
+ * Register (or replace) a bend table under its id, so a {@link BendRule} with a
47
+ * matching `bendTableRef` resolves against it. Returns the registered table.
48
+ *
49
+ * @param table - the bend table to register.
50
+ * @returns a {@link Result} carrying the stored (copied) table on success, or a
51
+ * validation error when the id, kind, or any row is invalid.
52
+ */
53
+ export declare function registerBendTable(table: BendTable): Result<BendTable>;
54
+ /**
55
+ * Look up a registered bend table by id (registers the starter tables on first use).
56
+ *
57
+ * @param id - the bend table id to look up.
58
+ * @returns the registered {@link BendTable}, or `undefined` when no table is
59
+ * registered under `id`.
60
+ */
61
+ export declare function getBendTable(id: string): BendTable | undefined;
62
+ /**
63
+ * The single source of truth for a bend's developed (neutral-axis) length.
64
+ *
65
+ * Precedence:
66
+ * 1. `rule.bendTableRef` — look up the table and interpolate it (linear in
67
+ * angle, bilinear across thickness × radius), converting a deduction table
68
+ * to an allowance via {@link allowanceFromDeduction}. Outside the table
69
+ * extents the lookup clamps to the nearest breakpoint and reports a
70
+ * `MIN_RADIUS`-class warning through `onWarning` rather than extrapolating.
71
+ * 2. `rule.allowance` — an explicit per-bend override, returned verbatim.
72
+ * 3. The K-factor formula BA = (π/180)·|angle|·(R + K·T).
73
+ *
74
+ * The returned value is in the same units and sense the rest of the package's
75
+ * `developedLength` consumes (a strip width along the developed pattern).
76
+ *
77
+ * @param rule - the bend rule driving the lookup (bend table ref, explicit
78
+ * allowance, or K-factor).
79
+ * @param angleDeg - the bend angle in degrees.
80
+ * @param thickness - the sheet thickness.
81
+ * @param onWarning - optional callback invoked with a {@link SheetMetalWarning}
82
+ * when a table lookup clamped to the nearest breakpoint outside the tabulated range.
83
+ * @returns a {@link Result} carrying the resolved bend allowance on success, or a
84
+ * validation error for an unknown table / non-positive input / failed lookup.
85
+ */
86
+ export declare function resolveBendAllowance(rule: BendRule, angleDeg: number, thickness: number, onWarning?: (warning: SheetMetalWarning) => void): Result<number>;
87
+ //# sourceMappingURL=bendTableFns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bendTableFns.d.ts","sourceRoot":"","sources":["../src/bendTableFns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAA4B,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI9D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC;IAChC,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAE/D,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CA+BrE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAG9D;AAsJD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAC/C,MAAM,CAAC,MAAM,CAAC,CAwChB"}
@@ -0,0 +1,345 @@
1
+ import { ok, err, validationError } from '@faicad/faijs/brepjs-compat';
2
+ const DEG_TO_RAD = Math.PI / 180;
3
+ /**
4
+ * The live bend-table registry, explicit as a shared resource object (§7.3):
5
+ * no hidden module-level mutable state. `registerBendTable`,
6
+ * {@link getBendTable} and the built-in resource all read/write the same
7
+ * `byId` map, so hosts can inspect or snapshot the registry directly.
8
+ */
9
+ export const bendTables = {
10
+ byId: new Map(),
11
+ };
12
+ /**
13
+ * Register (or replace) a bend table under its id, so a {@link BendRule} with a
14
+ * matching `bendTableRef` resolves against it. Returns the registered table.
15
+ *
16
+ * @param table - the bend table to register.
17
+ * @returns a {@link Result} carrying the stored (copied) table on success, or a
18
+ * validation error when the id, kind, or any row is invalid.
19
+ */
20
+ export function registerBendTable(table) {
21
+ if (typeof table.id !== 'string' || table.id.length === 0) {
22
+ return err(validationError('INVALID_TABLE_ID', `bend table id must be a non-empty string, got ${String(table.id)}`));
23
+ }
24
+ if (table.kind !== 'allowance' && table.kind !== 'deduction') {
25
+ return err(validationError('INVALID_TABLE_KIND', `bend table '${table.id}' kind must be 'allowance' or 'deduction', got ${String(table.kind)}`));
26
+ }
27
+ if (!Array.isArray(table.rows) || table.rows.length === 0) {
28
+ return err(validationError('EMPTY_TABLE', `bend table '${table.id}' must have at least one row`));
29
+ }
30
+ for (const row of table.rows) {
31
+ if (!Number.isFinite(row.thickness) ||
32
+ row.thickness <= 0 ||
33
+ !Number.isFinite(row.radius) ||
34
+ row.radius < 0 ||
35
+ !Number.isFinite(row.angleDeg) ||
36
+ !Number.isFinite(row.value) ||
37
+ row.value < 0) {
38
+ return err(validationError('INVALID_TABLE_ROW', `bend table '${table.id}' has an invalid row: ${JSON.stringify(row)} (thickness>0, radius≥0, finite angle, value≥0 required)`));
39
+ }
40
+ }
41
+ const stored = { id: table.id, kind: table.kind, rows: table.rows.map((r) => ({ ...r })) };
42
+ bendTables.byId.set(table.id, stored);
43
+ return ok(stored);
44
+ }
45
+ /**
46
+ * Look up a registered bend table by id (registers the starter tables on first use).
47
+ *
48
+ * @param id - the bend table id to look up.
49
+ * @returns the registered {@link BendTable}, or `undefined` when no table is
50
+ * registered under `id`.
51
+ */
52
+ export function getBendTable(id) {
53
+ ensureStarterTables();
54
+ return bendTables.byId.get(id);
55
+ }
56
+ /**
57
+ * Linear interpolation of `value` over `angleDeg` within a set of rows that
58
+ * already share a (thickness, radius) operating point. Clamps to the nearest
59
+ * endpoint outside the tabulated angle span and records a clamp via `clamped`.
60
+ */
61
+ function interpAngle(rows, angleDeg) {
62
+ const sorted = [...rows].sort((a, b) => a.angleDeg - b.angleDeg);
63
+ const first = sorted[0];
64
+ const last = sorted[sorted.length - 1];
65
+ if (first === undefined || last === undefined)
66
+ return { value: 0, clamped: true };
67
+ if (angleDeg <= first.angleDeg) {
68
+ return { value: first.value, clamped: angleDeg < first.angleDeg };
69
+ }
70
+ if (angleDeg >= last.angleDeg) {
71
+ return { value: last.value, clamped: angleDeg > last.angleDeg };
72
+ }
73
+ for (let i = 0; i + 1 < sorted.length; i++) {
74
+ const lo = sorted[i];
75
+ const hi = sorted[i + 1];
76
+ if (lo === undefined || hi === undefined)
77
+ continue;
78
+ if (angleDeg >= lo.angleDeg && angleDeg <= hi.angleDeg) {
79
+ const span = hi.angleDeg - lo.angleDeg;
80
+ if (span === 0)
81
+ return { value: lo.value, clamped: false };
82
+ const t = (angleDeg - lo.angleDeg) / span;
83
+ return { value: lo.value + t * (hi.value - lo.value), clamped: false };
84
+ }
85
+ }
86
+ return { value: last.value, clamped: true };
87
+ }
88
+ /** Distinct sorted values of a numeric key across the table rows. */
89
+ function distinct(rows, key) {
90
+ return [...new Set(rows.map((r) => r[key]))].sort((a, b) => a - b);
91
+ }
92
+ /** Bracketing pair `[lo, hi]` of a query value within sorted breakpoints, clamping to ends. */
93
+ function bracket(values, q) {
94
+ const first = values[0];
95
+ const last = values[values.length - 1];
96
+ if (first === undefined || last === undefined)
97
+ return { lo: q, hi: q, clamped: true };
98
+ if (q <= first)
99
+ return { lo: first, hi: first, clamped: q < first };
100
+ if (q >= last)
101
+ return { lo: last, hi: last, clamped: q > last };
102
+ for (let i = 0; i + 1 < values.length; i++) {
103
+ const lo = values[i];
104
+ const hi = values[i + 1];
105
+ if (lo === undefined || hi === undefined)
106
+ continue;
107
+ if (q >= lo && q <= hi)
108
+ return { lo, hi, clamped: false };
109
+ }
110
+ return { lo: last, hi: last, clamped: true };
111
+ }
112
+ /**
113
+ * Angle-interpolated value at a (thickness, radius) breakpoint. Prefers rows at
114
+ * the exact breakpoint; if the grid is sparse (a diagonal R-per-gauge table has
115
+ * no row at every t×r corner) it falls back to the rows at the nearest
116
+ * tabulated radius for that thickness, then the nearest thickness, flagging the
117
+ * substitution as clamped. Returns undefined only when the table is empty.
118
+ */
119
+ function valueAt(table, thickness, radius, angleDeg) {
120
+ const exact = table.rows.filter((r) => r.thickness === thickness && r.radius === radius);
121
+ if (exact.length > 0)
122
+ return interpAngle(exact, angleDeg);
123
+ const atThickness = table.rows.filter((r) => r.thickness === thickness);
124
+ if (atThickness.length > 0) {
125
+ const nearestR = nearest(distinct(atThickness, 'radius'), radius);
126
+ const rows = atThickness.filter((r) => r.radius === nearestR);
127
+ if (rows.length > 0) {
128
+ // Sparse-grid substitution (a diagonal one-radius-per-gauge table has no row
129
+ // at this corner) is an internal resolution, NOT a query clamp — genuine
130
+ // out-of-range thickness/radius is already flagged by `bracket` in interpTable,
131
+ // and out-of-range angle by interpAngle. Don't over-warn on in-range interior
132
+ // queries; only propagate the angle clamp.
133
+ const a = interpAngle(rows, angleDeg);
134
+ return { value: a.value, clamped: a.clamped };
135
+ }
136
+ }
137
+ const nearestT = nearest(distinct(table.rows, 'thickness'), thickness);
138
+ const atNearestT = table.rows.filter((r) => r.thickness === nearestT);
139
+ if (atNearestT.length === 0)
140
+ return undefined;
141
+ const nearestR = nearest(distinct(atNearestT, 'radius'), radius);
142
+ const rows = atNearestT.filter((r) => r.radius === nearestR);
143
+ if (rows.length === 0)
144
+ return undefined;
145
+ const a = interpAngle(rows, angleDeg);
146
+ return { value: a.value, clamped: a.clamped };
147
+ }
148
+ /** Nearest value in a set of breakpoints to a query. */
149
+ function nearest(values, q) {
150
+ let best;
151
+ let bestDist = Infinity;
152
+ for (const v of values) {
153
+ const d = Math.abs(v - q);
154
+ if (d < bestDist) {
155
+ bestDist = d;
156
+ best = v;
157
+ }
158
+ }
159
+ return best;
160
+ }
161
+ /**
162
+ * Bilinear-in-(thickness, radius) + linear-in-angle interpolation of a bend
163
+ * table at the query operating point. Brackets the query thickness and radius
164
+ * to the nearest tabulated breakpoints (clamping outside the table extents),
165
+ * interpolates angle within each corner, then blends the corners. Sparse grids
166
+ * (a diagonal one-radius-per-gauge table) resolve each corner by nearest-radius
167
+ * substitution inside {@link valueAt}. Returns the raw tabulated quantity (an
168
+ * allowance or a deduction per the table kind).
169
+ */
170
+ function interpTable(table, thickness, radius, angleDeg) {
171
+ const thicknesses = distinct(table.rows, 'thickness');
172
+ const radii = distinct(table.rows, 'radius');
173
+ const tB = bracket(thicknesses, thickness);
174
+ const rB = bracket(radii, radius);
175
+ const c00 = valueAt(table, tB.lo, rB.lo, angleDeg);
176
+ const c01 = valueAt(table, tB.lo, rB.hi, angleDeg);
177
+ const c10 = valueAt(table, tB.hi, rB.lo, angleDeg);
178
+ const c11 = valueAt(table, tB.hi, rB.hi, angleDeg);
179
+ if (c00 === undefined || c01 === undefined || c10 === undefined || c11 === undefined) {
180
+ return undefined;
181
+ }
182
+ const ft = tB.hi === tB.lo ? 0 : (thickness - tB.lo) / (tB.hi - tB.lo);
183
+ const fr = rB.hi === rB.lo ? 0 : (radius - rB.lo) / (rB.hi - rB.lo);
184
+ const lo = c00.value + fr * (c01.value - c00.value);
185
+ const hi = c10.value + fr * (c11.value - c10.value);
186
+ const value = lo + ft * (hi - lo);
187
+ const clamped = tB.clamped || rB.clamped || c00.clamped || c01.clamped || c10.clamped || c11.clamped;
188
+ return { value, clamped };
189
+ }
190
+ /**
191
+ * Outside setback OSSB = (R + T)·tan(θ/2) for swept bend angle θ — the run from
192
+ * the bend's tangent point to the apex of the two outside faces. (90° → tan45° →
193
+ * OSSB = R + T.)
194
+ */
195
+ function ossb(radius, thickness, angleDeg) {
196
+ return (radius + thickness) * Math.tan((DEG_TO_RAD * Math.abs(angleDeg)) / 2);
197
+ }
198
+ /** Bend allowance from a bend deduction: BD = 2·OSSB − BA ⇒ BA = 2·OSSB − BD. */
199
+ function allowanceFromDeduction(deduction, radius, thickness, angleDeg) {
200
+ return 2 * ossb(radius, thickness, angleDeg) - deduction;
201
+ }
202
+ /**
203
+ * The single source of truth for a bend's developed (neutral-axis) length.
204
+ *
205
+ * Precedence:
206
+ * 1. `rule.bendTableRef` — look up the table and interpolate it (linear in
207
+ * angle, bilinear across thickness × radius), converting a deduction table
208
+ * to an allowance via {@link allowanceFromDeduction}. Outside the table
209
+ * extents the lookup clamps to the nearest breakpoint and reports a
210
+ * `MIN_RADIUS`-class warning through `onWarning` rather than extrapolating.
211
+ * 2. `rule.allowance` — an explicit per-bend override, returned verbatim.
212
+ * 3. The K-factor formula BA = (π/180)·|angle|·(R + K·T).
213
+ *
214
+ * The returned value is in the same units and sense the rest of the package's
215
+ * `developedLength` consumes (a strip width along the developed pattern).
216
+ *
217
+ * @param rule - the bend rule driving the lookup (bend table ref, explicit
218
+ * allowance, or K-factor).
219
+ * @param angleDeg - the bend angle in degrees.
220
+ * @param thickness - the sheet thickness.
221
+ * @param onWarning - optional callback invoked with a {@link SheetMetalWarning}
222
+ * when a table lookup clamped to the nearest breakpoint outside the tabulated range.
223
+ * @returns a {@link Result} carrying the resolved bend allowance on success, or a
224
+ * validation error for an unknown table / non-positive input / failed lookup.
225
+ */
226
+ export function resolveBendAllowance(rule, angleDeg, thickness, onWarning) {
227
+ if (rule.bendTableRef !== undefined) {
228
+ if (!Number.isFinite(angleDeg)) {
229
+ return err(validationError('INVALID_ANGLE', `angleDeg must be finite, got ${angleDeg}`));
230
+ }
231
+ if (!Number.isFinite(thickness) || thickness <= 0) {
232
+ return err(validationError('INVALID_THICKNESS', `thickness must be a finite, positive number, got ${thickness}`));
233
+ }
234
+ if (!Number.isFinite(rule.innerRadius) || rule.innerRadius < 0) {
235
+ return err(validationError('INVALID_RADIUS', `innerRadius must be a finite, non-negative number, got ${rule.innerRadius}`));
236
+ }
237
+ const table = getBendTable(rule.bendTableRef);
238
+ if (table === undefined) {
239
+ return err(validationError('UNKNOWN_BEND_TABLE', `no bend table registered under id '${rule.bendTableRef}'`));
240
+ }
241
+ const angle = Math.abs(angleDeg);
242
+ const interp = interpTable(table, thickness, rule.innerRadius, angle);
243
+ if (interp === undefined) {
244
+ return err(validationError('TABLE_LOOKUP_FAILED', `bend table '${table.id}' has no rows bracketing (t=${thickness}, r=${rule.innerRadius})`));
245
+ }
246
+ const ba = table.kind === 'deduction' ? allowanceFromDeduction(interp.value, rule.innerRadius, thickness, angle) : interp.value;
247
+ if (!Number.isFinite(ba) || ba < 0) {
248
+ return err(validationError('INVALID_TABLE_ALLOWANCE', `bend table '${table.id}' produced a non-positive allowance ${ba} at (t=${thickness}, r=${rule.innerRadius}, θ=${angle})`));
249
+ }
250
+ if (interp.clamped && onWarning !== undefined) {
251
+ onWarning({
252
+ code: 'TABLE_CLAMP',
253
+ message: `bend table '${table.id}' query (t=${thickness}, r=${rule.innerRadius}, θ=${angle}) is outside the tabulated range; clamped to the nearest entry`,
254
+ });
255
+ }
256
+ return ok(ba);
257
+ }
258
+ return fallbackAllowance(rule, angleDeg, thickness);
259
+ }
260
+ /** Explicit-allowance override, then the K-factor formula (the pre-table behaviour). */
261
+ function fallbackAllowance(rule, angleDeg, thickness) {
262
+ if (rule.allowance !== undefined) {
263
+ if (!Number.isFinite(rule.allowance) || rule.allowance < 0) {
264
+ return err(validationError('INVALID_ALLOWANCE', `allowance override must be a finite, non-negative number, got ${rule.allowance}`));
265
+ }
266
+ return ok(rule.allowance);
267
+ }
268
+ if (!Number.isFinite(angleDeg)) {
269
+ return err(validationError('INVALID_ANGLE', `angleDeg must be finite, got ${angleDeg}`));
270
+ }
271
+ if (!Number.isFinite(thickness) || thickness <= 0) {
272
+ return err(validationError('INVALID_THICKNESS', `thickness must be a finite, positive number, got ${thickness}`));
273
+ }
274
+ if (!Number.isFinite(rule.innerRadius) || rule.innerRadius < 0) {
275
+ return err(validationError('INVALID_RADIUS', `innerRadius must be a finite, non-negative number, got ${rule.innerRadius}`));
276
+ }
277
+ if (!Number.isFinite(rule.kFactor) || rule.kFactor < 0 || rule.kFactor > 1) {
278
+ return err(validationError('INVALID_K_FACTOR', `kFactor must be in [0, 1], got ${rule.kFactor}`));
279
+ }
280
+ const neutralRadius = rule.innerRadius + rule.kFactor * thickness;
281
+ return ok(DEG_TO_RAD * Math.abs(angleDeg) * neutralRadius);
282
+ }
283
+ /**
284
+ * Starter shop bend tables, auto-registered on first table access. The values
285
+ * are published 90°-equivalent air-bend allowances scaled across the standard
286
+ * {30, 60, 90, 120}° set by the linear angle ratio, at a single canonical inner
287
+ * radius per gauge.
288
+ *
289
+ * Sources: SheetMetal.Me air-bend / bend-allowance charts and Machinery's
290
+ * Handbook (29th ed.) sheet-metal bend-allowance tables for mild steel and
291
+ * 5052-H32 aluminium. The 90° allowances are the published mid-range air-bend
292
+ * figures; the other angles are the proportional neutral-axis arc lengths
293
+ * (allowance scales ~linearly with the swept angle at a fixed radius).
294
+ */
295
+ const STARTER_TABLES = [
296
+ {
297
+ id: 'steel-airbend',
298
+ kind: 'allowance',
299
+ rows: angleSet([
300
+ { thickness: 0.91, radius: 1.0, ba90: 2.36 },
301
+ { thickness: 1.52, radius: 1.5, ba90: 3.63 },
302
+ { thickness: 1.9, radius: 2.0, ba90: 4.62 },
303
+ { thickness: 2.66, radius: 3.0, ba90: 6.59 },
304
+ ]),
305
+ },
306
+ {
307
+ id: 'aluminum-airbend',
308
+ kind: 'allowance',
309
+ rows: angleSet([
310
+ { thickness: 0.81, radius: 1.0, ba90: 2.27 },
311
+ { thickness: 1.29, radius: 1.5, ba90: 3.44 },
312
+ { thickness: 1.63, radius: 2.0, ba90: 4.49 },
313
+ { thickness: 2.59, radius: 3.0, ba90: 6.51 },
314
+ ]),
315
+ },
316
+ ];
317
+ /** Expand a per-gauge 90° allowance into the {30, 60, 90, 120}° rows by the angle ratio. */
318
+ function angleSet(seeds) {
319
+ const angles = [30, 60, 90, 120];
320
+ const rows = [];
321
+ for (const seed of seeds) {
322
+ for (const angleDeg of angles) {
323
+ rows.push({ thickness: seed.thickness, radius: seed.radius, angleDeg, value: (seed.ba90 * angleDeg) / 90 });
324
+ }
325
+ }
326
+ return rows;
327
+ }
328
+ let starterTablesRegistered = false;
329
+ /**
330
+ * Register the starter tables exactly once. Done lazily (not at module load) so
331
+ * the package keeps `sideEffects: false` — importing the package never mutates
332
+ * the registry; the tables materialise on the first {@link getBendTable} call.
333
+ */
334
+ function ensureStarterTables() {
335
+ if (starterTablesRegistered)
336
+ return;
337
+ starterTablesRegistered = true;
338
+ for (const table of STARTER_TABLES) {
339
+ // Never clobber a table a caller registered under a starter id before first access.
340
+ if (bendTables.byId.has(table.id))
341
+ continue;
342
+ bendTables.byId.set(table.id, { id: table.id, kind: table.kind, rows: table.rows.map((r) => ({ ...r })) });
343
+ }
344
+ }
345
+ //# sourceMappingURL=bendTableFns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bendTableFns.js","sourceRoot":"","sources":["../src/bendTableFns.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Result, ok, err, validationError } from '@faicad/faijs/brepjs-compat';\nimport type { BendRule, SheetMetalWarning } from './types.js';\n\nconst DEG_TO_RAD = Math.PI / 180;\n\n/**\n * One row of a shop bend table: the tabulated value for a single\n * (thickness, innerRadius, bend-angle) operating point. `value` is a bend\n * allowance (`kind: 'allowance'`) or a bend deduction (`kind: 'deduction'`),\n * per the owning {@link BendTable}.\n */\nexport interface BendTableRow {\n /** Material thickness the row was measured at. */\n thickness: number;\n /** Inner bend radius the row was measured at. */\n radius: number;\n /** Swept bend angle in degrees (90° = a right-angle bend). */\n angleDeg: number;\n /** Bend allowance or bend deduction, per the table's {@link BendTable.kind}. */\n value: number;\n}\n\n/**\n * A named shop bend table: empirical bend-allowance or bend-deduction values\n * measured per (thickness, radius, angle). When a {@link BendRule} references a\n * table by id, {@link resolveBendAllowance} interpolates the table instead of\n * applying the K-factor formula, so the developed length matches the shop's\n * actual press-brake results.\n *\n * `kind` selects how a row's `value` is interpreted: an `'allowance'` table\n * tabulates the developed arc length directly; a `'deduction'` table tabulates\n * the bend deduction, which is converted to an allowance on lookup (see\n * {@link resolveBendAllowance} for the OSSB conversion).\n */\nexport interface BendTable {\n id: string;\n kind: 'allowance' | 'deduction';\n rows: BendTableRow[];\n}\n\n/**\n * The live bend-table registry, explicit as a shared resource object (§7.3):\n * no hidden module-level mutable state. `registerBendTable`,\n * {@link getBendTable} and the built-in resource all read/write the same\n * `byId` map, so hosts can inspect or snapshot the registry directly.\n */\nexport const bendTables: { readonly byId: Map<string, BendTable> } = {\n byId: new Map<string, BendTable>(),\n};\n\n/**\n * Register (or replace) a bend table under its id, so a {@link BendRule} with a\n * matching `bendTableRef` resolves against it. Returns the registered table.\n *\n * @param table - the bend table to register.\n * @returns a {@link Result} carrying the stored (copied) table on success, or a\n * validation error when the id, kind, or any row is invalid.\n */\nexport function registerBendTable(table: BendTable): Result<BendTable> {\n if (typeof table.id !== 'string' || table.id.length === 0) {\n return err(validationError('INVALID_TABLE_ID', `bend table id must be a non-empty string, got ${String(table.id)}`));\n }\n if (table.kind !== 'allowance' && table.kind !== 'deduction') {\n return err(validationError('INVALID_TABLE_KIND', `bend table '${table.id}' kind must be 'allowance' or 'deduction', got ${String(table.kind)}`));\n }\n if (!Array.isArray(table.rows) || table.rows.length === 0) {\n return err(validationError('EMPTY_TABLE', `bend table '${table.id}' must have at least one row`));\n }\n for (const row of table.rows) {\n if (\n !Number.isFinite(row.thickness) ||\n row.thickness <= 0 ||\n !Number.isFinite(row.radius) ||\n row.radius < 0 ||\n !Number.isFinite(row.angleDeg) ||\n !Number.isFinite(row.value) ||\n row.value < 0\n ) {\n return err(\n validationError(\n 'INVALID_TABLE_ROW',\n `bend table '${table.id}' has an invalid row: ${JSON.stringify(row)} (thickness>0, radius≥0, finite angle, value≥0 required)`\n )\n );\n }\n }\n const stored = { id: table.id, kind: table.kind, rows: table.rows.map((r) => ({ ...r })) };\n bendTables.byId.set(table.id, stored);\n return ok(stored);\n}\n\n/**\n * Look up a registered bend table by id (registers the starter tables on first use).\n *\n * @param id - the bend table id to look up.\n * @returns the registered {@link BendTable}, or `undefined` when no table is\n * registered under `id`.\n */\nexport function getBendTable(id: string): BendTable | undefined {\n ensureStarterTables();\n return bendTables.byId.get(id);\n}\n\n/**\n * Linear interpolation of `value` over `angleDeg` within a set of rows that\n * already share a (thickness, radius) operating point. Clamps to the nearest\n * endpoint outside the tabulated angle span and records a clamp via `clamped`.\n */\nfunction interpAngle(rows: BendTableRow[], angleDeg: number): { value: number; clamped: boolean } {\n const sorted = [...rows].sort((a, b) => a.angleDeg - b.angleDeg);\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n if (first === undefined || last === undefined) return { value: 0, clamped: true };\n if (angleDeg <= first.angleDeg) {\n return { value: first.value, clamped: angleDeg < first.angleDeg };\n }\n if (angleDeg >= last.angleDeg) {\n return { value: last.value, clamped: angleDeg > last.angleDeg };\n }\n for (let i = 0; i + 1 < sorted.length; i++) {\n const lo = sorted[i];\n const hi = sorted[i + 1];\n if (lo === undefined || hi === undefined) continue;\n if (angleDeg >= lo.angleDeg && angleDeg <= hi.angleDeg) {\n const span = hi.angleDeg - lo.angleDeg;\n if (span === 0) return { value: lo.value, clamped: false };\n const t = (angleDeg - lo.angleDeg) / span;\n return { value: lo.value + t * (hi.value - lo.value), clamped: false };\n }\n }\n return { value: last.value, clamped: true };\n}\n\n/** Distinct sorted values of a numeric key across the table rows. */\nfunction distinct(rows: BendTableRow[], key: 'thickness' | 'radius'): number[] {\n return [...new Set(rows.map((r) => r[key]))].sort((a, b) => a - b);\n}\n\n/** Bracketing pair `[lo, hi]` of a query value within sorted breakpoints, clamping to ends. */\nfunction bracket(values: number[], q: number): { lo: number; hi: number; clamped: boolean } {\n const first = values[0];\n const last = values[values.length - 1];\n if (first === undefined || last === undefined) return { lo: q, hi: q, clamped: true };\n if (q <= first) return { lo: first, hi: first, clamped: q < first };\n if (q >= last) return { lo: last, hi: last, clamped: q > last };\n for (let i = 0; i + 1 < values.length; i++) {\n const lo = values[i];\n const hi = values[i + 1];\n if (lo === undefined || hi === undefined) continue;\n if (q >= lo && q <= hi) return { lo, hi, clamped: false };\n }\n return { lo: last, hi: last, clamped: true };\n}\n\n/**\n * Angle-interpolated value at a (thickness, radius) breakpoint. Prefers rows at\n * the exact breakpoint; if the grid is sparse (a diagonal R-per-gauge table has\n * no row at every t×r corner) it falls back to the rows at the nearest\n * tabulated radius for that thickness, then the nearest thickness, flagging the\n * substitution as clamped. Returns undefined only when the table is empty.\n */\nfunction valueAt(table: BendTable, thickness: number, radius: number, angleDeg: number): { value: number; clamped: boolean } | undefined {\n const exact = table.rows.filter((r) => r.thickness === thickness && r.radius === radius);\n if (exact.length > 0) return interpAngle(exact, angleDeg);\n\n const atThickness = table.rows.filter((r) => r.thickness === thickness);\n if (atThickness.length > 0) {\n const nearestR = nearest(distinct(atThickness, 'radius'), radius);\n const rows = atThickness.filter((r) => r.radius === nearestR);\n if (rows.length > 0) {\n // Sparse-grid substitution (a diagonal one-radius-per-gauge table has no row\n // at this corner) is an internal resolution, NOT a query clamp — genuine\n // out-of-range thickness/radius is already flagged by `bracket` in interpTable,\n // and out-of-range angle by interpAngle. Don't over-warn on in-range interior\n // queries; only propagate the angle clamp.\n const a = interpAngle(rows, angleDeg);\n return { value: a.value, clamped: a.clamped };\n }\n }\n\n const nearestT = nearest(distinct(table.rows, 'thickness'), thickness);\n const atNearestT = table.rows.filter((r) => r.thickness === nearestT);\n if (atNearestT.length === 0) return undefined;\n const nearestR = nearest(distinct(atNearestT, 'radius'), radius);\n const rows = atNearestT.filter((r) => r.radius === nearestR);\n if (rows.length === 0) return undefined;\n const a = interpAngle(rows, angleDeg);\n return { value: a.value, clamped: a.clamped };\n}\n\n/** Nearest value in a set of breakpoints to a query. */\nfunction nearest(values: number[], q: number): number | undefined {\n let best: number | undefined;\n let bestDist = Infinity;\n for (const v of values) {\n const d = Math.abs(v - q);\n if (d < bestDist) {\n bestDist = d;\n best = v;\n }\n }\n return best;\n}\n\n/**\n * Bilinear-in-(thickness, radius) + linear-in-angle interpolation of a bend\n * table at the query operating point. Brackets the query thickness and radius\n * to the nearest tabulated breakpoints (clamping outside the table extents),\n * interpolates angle within each corner, then blends the corners. Sparse grids\n * (a diagonal one-radius-per-gauge table) resolve each corner by nearest-radius\n * substitution inside {@link valueAt}. Returns the raw tabulated quantity (an\n * allowance or a deduction per the table kind).\n */\nfunction interpTable(table: BendTable, thickness: number, radius: number, angleDeg: number): { value: number; clamped: boolean } | undefined {\n const thicknesses = distinct(table.rows, 'thickness');\n const radii = distinct(table.rows, 'radius');\n const tB = bracket(thicknesses, thickness);\n const rB = bracket(radii, radius);\n\n const c00 = valueAt(table, tB.lo, rB.lo, angleDeg);\n const c01 = valueAt(table, tB.lo, rB.hi, angleDeg);\n const c10 = valueAt(table, tB.hi, rB.lo, angleDeg);\n const c11 = valueAt(table, tB.hi, rB.hi, angleDeg);\n if (c00 === undefined || c01 === undefined || c10 === undefined || c11 === undefined) {\n return undefined;\n }\n\n const ft = tB.hi === tB.lo ? 0 : (thickness - tB.lo) / (tB.hi - tB.lo);\n const fr = rB.hi === rB.lo ? 0 : (radius - rB.lo) / (rB.hi - rB.lo);\n\n const lo = c00.value + fr * (c01.value - c00.value);\n const hi = c10.value + fr * (c11.value - c10.value);\n const value = lo + ft * (hi - lo);\n const clamped = tB.clamped || rB.clamped || c00.clamped || c01.clamped || c10.clamped || c11.clamped;\n return { value, clamped };\n}\n\n/**\n * Outside setback OSSB = (R + T)·tan(θ/2) for swept bend angle θ — the run from\n * the bend's tangent point to the apex of the two outside faces. (90° → tan45° →\n * OSSB = R + T.)\n */\nfunction ossb(radius: number, thickness: number, angleDeg: number): number {\n return (radius + thickness) * Math.tan((DEG_TO_RAD * Math.abs(angleDeg)) / 2);\n}\n\n/** Bend allowance from a bend deduction: BD = 2·OSSB − BA ⇒ BA = 2·OSSB − BD. */\nfunction allowanceFromDeduction(deduction: number, radius: number, thickness: number, angleDeg: number): number {\n return 2 * ossb(radius, thickness, angleDeg) - deduction;\n}\n\n/**\n * The single source of truth for a bend's developed (neutral-axis) length.\n *\n * Precedence:\n * 1. `rule.bendTableRef` — look up the table and interpolate it (linear in\n * angle, bilinear across thickness × radius), converting a deduction table\n * to an allowance via {@link allowanceFromDeduction}. Outside the table\n * extents the lookup clamps to the nearest breakpoint and reports a\n * `MIN_RADIUS`-class warning through `onWarning` rather than extrapolating.\n * 2. `rule.allowance` — an explicit per-bend override, returned verbatim.\n * 3. The K-factor formula BA = (π/180)·|angle|·(R + K·T).\n *\n * The returned value is in the same units and sense the rest of the package's\n * `developedLength` consumes (a strip width along the developed pattern).\n *\n * @param rule - the bend rule driving the lookup (bend table ref, explicit\n * allowance, or K-factor).\n * @param angleDeg - the bend angle in degrees.\n * @param thickness - the sheet thickness.\n * @param onWarning - optional callback invoked with a {@link SheetMetalWarning}\n * when a table lookup clamped to the nearest breakpoint outside the tabulated range.\n * @returns a {@link Result} carrying the resolved bend allowance on success, or a\n * validation error for an unknown table / non-positive input / failed lookup.\n */\nexport function resolveBendAllowance(\n rule: BendRule,\n angleDeg: number,\n thickness: number,\n onWarning?: (warning: SheetMetalWarning) => void\n): Result<number> {\n if (rule.bendTableRef !== undefined) {\n if (!Number.isFinite(angleDeg)) {\n return err(validationError('INVALID_ANGLE', `angleDeg must be finite, got ${angleDeg}`));\n }\n if (!Number.isFinite(thickness) || thickness <= 0) {\n return err(validationError('INVALID_THICKNESS', `thickness must be a finite, positive number, got ${thickness}`));\n }\n if (!Number.isFinite(rule.innerRadius) || rule.innerRadius < 0) {\n return err(validationError('INVALID_RADIUS', `innerRadius must be a finite, non-negative number, got ${rule.innerRadius}`));\n }\n const table = getBendTable(rule.bendTableRef);\n if (table === undefined) {\n return err(validationError('UNKNOWN_BEND_TABLE', `no bend table registered under id '${rule.bendTableRef}'`));\n }\n const angle = Math.abs(angleDeg);\n const interp = interpTable(table, thickness, rule.innerRadius, angle);\n if (interp === undefined) {\n return err(\n validationError('TABLE_LOOKUP_FAILED', `bend table '${table.id}' has no rows bracketing (t=${thickness}, r=${rule.innerRadius})`)\n );\n }\n const ba = table.kind === 'deduction' ? allowanceFromDeduction(interp.value, rule.innerRadius, thickness, angle) : interp.value;\n if (!Number.isFinite(ba) || ba < 0) {\n return err(\n validationError(\n 'INVALID_TABLE_ALLOWANCE',\n `bend table '${table.id}' produced a non-positive allowance ${ba} at (t=${thickness}, r=${rule.innerRadius}, θ=${angle})`\n )\n );\n }\n if (interp.clamped && onWarning !== undefined) {\n onWarning({\n code: 'TABLE_CLAMP',\n message: `bend table '${table.id}' query (t=${thickness}, r=${rule.innerRadius}, θ=${angle}) is outside the tabulated range; clamped to the nearest entry`,\n });\n }\n return ok(ba);\n }\n return fallbackAllowance(rule, angleDeg, thickness);\n}\n\n/** Explicit-allowance override, then the K-factor formula (the pre-table behaviour). */\nfunction fallbackAllowance(rule: BendRule, angleDeg: number, thickness: number): Result<number> {\n if (rule.allowance !== undefined) {\n if (!Number.isFinite(rule.allowance) || rule.allowance < 0) {\n return err(\n validationError('INVALID_ALLOWANCE', `allowance override must be a finite, non-negative number, got ${rule.allowance}`)\n );\n }\n return ok(rule.allowance);\n }\n if (!Number.isFinite(angleDeg)) {\n return err(validationError('INVALID_ANGLE', `angleDeg must be finite, got ${angleDeg}`));\n }\n if (!Number.isFinite(thickness) || thickness <= 0) {\n return err(validationError('INVALID_THICKNESS', `thickness must be a finite, positive number, got ${thickness}`));\n }\n if (!Number.isFinite(rule.innerRadius) || rule.innerRadius < 0) {\n return err(validationError('INVALID_RADIUS', `innerRadius must be a finite, non-negative number, got ${rule.innerRadius}`));\n }\n if (!Number.isFinite(rule.kFactor) || rule.kFactor < 0 || rule.kFactor > 1) {\n return err(validationError('INVALID_K_FACTOR', `kFactor must be in [0, 1], got ${rule.kFactor}`));\n }\n const neutralRadius = rule.innerRadius + rule.kFactor * thickness;\n return ok(DEG_TO_RAD * Math.abs(angleDeg) * neutralRadius);\n}\n\n/**\n * Starter shop bend tables, auto-registered on first table access. The values\n * are published 90°-equivalent air-bend allowances scaled across the standard\n * {30, 60, 90, 120}° set by the linear angle ratio, at a single canonical inner\n * radius per gauge.\n *\n * Sources: SheetMetal.Me air-bend / bend-allowance charts and Machinery's\n * Handbook (29th ed.) sheet-metal bend-allowance tables for mild steel and\n * 5052-H32 aluminium. The 90° allowances are the published mid-range air-bend\n * figures; the other angles are the proportional neutral-axis arc lengths\n * (allowance scales ~linearly with the swept angle at a fixed radius).\n */\nconst STARTER_TABLES: readonly BendTable[] = [\n {\n id: 'steel-airbend',\n kind: 'allowance',\n rows: angleSet([\n { thickness: 0.91, radius: 1.0, ba90: 2.36 },\n { thickness: 1.52, radius: 1.5, ba90: 3.63 },\n { thickness: 1.9, radius: 2.0, ba90: 4.62 },\n { thickness: 2.66, radius: 3.0, ba90: 6.59 },\n ]),\n },\n {\n id: 'aluminum-airbend',\n kind: 'allowance',\n rows: angleSet([\n { thickness: 0.81, radius: 1.0, ba90: 2.27 },\n { thickness: 1.29, radius: 1.5, ba90: 3.44 },\n { thickness: 1.63, radius: 2.0, ba90: 4.49 },\n { thickness: 2.59, radius: 3.0, ba90: 6.51 },\n ]),\n },\n];\n\n/** Expand a per-gauge 90° allowance into the {30, 60, 90, 120}° rows by the angle ratio. */\nfunction angleSet(seeds: { thickness: number; radius: number; ba90: number }[]): BendTableRow[] {\n const angles = [30, 60, 90, 120];\n const rows: BendTableRow[] = [];\n for (const seed of seeds) {\n for (const angleDeg of angles) {\n rows.push({ thickness: seed.thickness, radius: seed.radius, angleDeg, value: (seed.ba90 * angleDeg) / 90 });\n }\n }\n return rows;\n}\n\nlet starterTablesRegistered = false;\n\n/**\n * Register the starter tables exactly once. Done lazily (not at module load) so\n * the package keeps `sideEffects: false` — importing the package never mutates\n * the registry; the tables materialise on the first {@link getBendTable} call.\n */\nfunction ensureStarterTables(): void {\n if (starterTablesRegistered) return;\n starterTablesRegistered = true;\n for (const table of STARTER_TABLES) {\n // Never clobber a table a caller registered under a starter id before first access.\n if (bendTables.byId.has(table.id)) continue;\n bendTables.byId.set(table.id, { id: table.id, kind: table.kind, rows: table.rows.map((r) => ({ ...r })) });\n }\n}\n"]}