forgecad 0.9.14 → 0.9.15

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 (219) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-eWGs2K6H.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-CTrLKfpo.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-5nPesyds.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-C4Y3nbYc.js → DocsPage-B954L3YN.js} +9 -3
  7. package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
  8. package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
  9. package/dist/assets/{EmbedViewer-C8fB4n5U.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-jSz0LaMM.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
  11. package/dist/assets/LegalPage-BRlScr9A.css +91 -0
  12. package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
  13. package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
  14. package/dist/assets/{PricingPage-B83B90zh.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-DY889pcu.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-bEww1ic4.js → app-D3kDkggg.js} +2293 -946
  18. package/dist/assets/cli/{render-Cho2uKG_.js → render-DSY3mMQa.js} +337 -7
  19. package/dist/assets/{constructionHistoryWorker-HYwzJY4m.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CjQwJSE-.js → evalWorker-CU0Ke6DP.js} +7800 -4164
  21. package/dist/assets/{forgecad_geometry-CH2nvuLA.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/forgecad_geometry_bg-dD4RNQF1.wasm +0 -0
  23. package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
  24. package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
  25. package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
  26. package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
  27. package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
  28. package/dist/assets/{manifold-CG9Fokx-.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-uRzgk5O8.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-rmfAcdwF.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-4cW_ZpoS.js → reportWorker-CdBz5bNg.js} +7538 -10857
  32. package/dist/assets/{scalar-sampling-budget-CfDiFvh7.js → scalar-sampling-budget-wJF98aY9.js} +6935 -4331
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{solver-DuJAO8S6.js → solver-BZ9LPTHs.js} +1 -1
  35. package/dist/assets/solver_bg-DAHZJ_rw.wasm +0 -0
  36. package/dist/assets/{targets-D6PWsv6X.js → targets-B9sGB5nB.js} +1 -1
  37. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  38. package/dist/cli/render.html +1 -1
  39. package/dist/docs/index.html +2 -2
  40. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  41. package/dist/docs-raw/AI/usage.md +3 -12
  42. package/dist/docs-raw/CLI.md +30 -10
  43. package/dist/docs-raw/component-model.md +27 -11
  44. package/dist/docs-raw/generated/assembly.md +301 -212
  45. package/dist/docs-raw/generated/concepts.md +235 -237
  46. package/dist/docs-raw/generated/core.md +283 -6
  47. package/dist/docs-raw/generated/curves.md +274 -361
  48. package/dist/docs-raw/generated/lib.md +7 -1
  49. package/dist/docs-raw/generated/output.md +19 -4
  50. package/dist/docs-raw/generated/runtime-names.md +41 -0
  51. package/dist/docs-raw/generated/sdf.md +31 -0
  52. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  53. package/dist/docs-raw/generated/sketch.md +44 -1
  54. package/dist/docs-raw/generated/viewport.md +11 -3
  55. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  56. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  57. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  58. package/dist/docs-raw/guides/joint-design.md +24 -0
  59. package/dist/docs-raw/guides/positioning.md +13 -3
  60. package/dist/docs-raw/legal/privacy.md +63 -0
  61. package/dist/docs-raw/legal/software-license.md +55 -0
  62. package/dist/docs-raw/legal/terms.md +87 -0
  63. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +1 -1
  64. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  66. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  68. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  69. package/dist/docs-raw/skills/forgecad-make-a-model.md +1 -1
  70. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  71. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  72. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  73. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +1 -1
  74. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  75. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  76. package/dist/docs-raw/skills/forgecad.md +4 -3
  77. package/dist/index.html +40 -12
  78. package/dist/llms.txt +8 -0
  79. package/dist/site.webmanifest +1 -1
  80. package/dist/sitemap.xml +49 -13
  81. package/dist-cli/{check-compiler-U5SOPN7X.js → check-compiler-SDX5QIXI.js} +1 -2
  82. package/dist-cli/{check-query-propagation-XOKNSSYU.js → check-query-propagation-EAYEFT77.js} +1 -2
  83. package/dist-cli/{chunk-EXWGNL6K.js → chunk-N4O47JLF.js} +12540 -9046
  84. package/dist-cli/forgecad.js +1786 -679
  85. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  86. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  87. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  88. package/dist-cli/solver_bg.wasm +0 -0
  89. package/dist-skill/CONTEXT.md +1117 -721
  90. package/dist-skill/SKILL.md +3 -2
  91. package/dist-skill/docs/API/core/concepts.md +64 -1
  92. package/dist-skill/docs/CLI.md +30 -10
  93. package/dist-skill/docs/generated/assembly.md +277 -229
  94. package/dist-skill/docs/generated/core.md +283 -6
  95. package/dist-skill/docs/generated/curves.md +272 -362
  96. package/dist-skill/docs/generated/lib.md +7 -1
  97. package/dist-skill/docs/generated/output.md +19 -4
  98. package/dist-skill/docs/generated/runtime-names.md +41 -0
  99. package/dist-skill/docs/generated/sdf.md +31 -0
  100. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  101. package/dist-skill/docs/generated/sketch.md +44 -2
  102. package/dist-skill/docs/generated/viewport.md +2 -87
  103. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  104. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  105. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  106. package/dist-skill/docs/guides/joint-design.md +24 -0
  107. package/dist-skill/docs/guides/positioning.md +13 -3
  108. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  109. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  110. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  111. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  113. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  114. package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
  115. package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
  116. package/examples/api/assembly-kinematics-limb.forge.js +116 -0
  117. package/examples/api/connector-frame-rig-chain.forge.js +102 -0
  118. package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
  119. package/examples/api/exact-surface-studio.forge.js +6 -8
  120. package/examples/api/helix-basics.forge.js +6 -6
  121. package/examples/api/lean-foundations/README.md +12 -0
  122. package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
  123. package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
  124. package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
  125. package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
  126. package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
  127. package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
  128. package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
  129. package/examples/api/route3d-elbow.forge.js +68 -0
  130. package/examples/api/transition-curves.forge.js +44 -15
  131. package/examples/api/y-blend-corner-showcase.forge.js +0 -2
  132. package/examples/generative/coral-vase.forge.js +1 -1
  133. package/examples/nurbs-tube.forge.js +1 -1
  134. package/package.json +14 -13
  135. package/dist/assets/EditorApp-lXv53A1m.js +0 -13610
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/assets/forgecad_geometry_bg-C5_E9Oa9.wasm +0 -0
  138. package/dist/assets/solver_bg-CWvv4lnN.wasm +0 -0
  139. package/dist/docs-raw/API/README.md +0 -16
  140. package/dist/docs-raw/API/core/concepts.md +0 -118
  141. package/dist/docs-raw/INDEX.md +0 -138
  142. package/dist/docs-raw/RELEASING.md +0 -87
  143. package/dist/docs-raw/agent-native-api.md +0 -27
  144. package/dist/docs-raw/beta-deployment.md +0 -304
  145. package/dist/docs-raw/beta-operations.md +0 -325
  146. package/dist/docs-raw/blueprint-first.md +0 -145
  147. package/dist/docs-raw/cli-monetization.md +0 -112
  148. package/dist/docs-raw/coding-best-practices.md +0 -120
  149. package/dist/docs-raw/coding.md +0 -340
  150. package/dist/docs-raw/deployment.md +0 -374
  151. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  152. package/dist/docs-raw/guides/surface-members.md +0 -82
  153. package/dist/docs-raw/harbor-cli.md +0 -854
  154. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  155. package/dist/docs-raw/internals/compiler.md +0 -307
  156. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  157. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  158. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  159. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  160. package/dist/docs-raw/platform/admin.md +0 -45
  161. package/dist/docs-raw/platform/architecture.md +0 -82
  162. package/dist/docs-raw/platform/auth.md +0 -139
  163. package/dist/docs-raw/platform/email.md +0 -67
  164. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  165. package/dist/docs-raw/platform/observability.md +0 -197
  166. package/dist/docs-raw/platform/projects.md +0 -111
  167. package/dist/docs-raw/platform/sharing.md +0 -90
  168. package/dist/docs-raw/product/README.md +0 -39
  169. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  170. package/dist/docs-raw/product/business-model.md +0 -15
  171. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  172. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  173. package/dist/docs-raw/product/founder-story.md +0 -11
  174. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  175. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  176. package/dist/docs-raw/product/product-loop.md +0 -17
  177. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  178. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  179. package/dist/docs-raw/product/user-segments.md +0 -15
  180. package/dist/docs-raw/product/vision.md +0 -26
  181. package/dist/docs-raw/rl-environments.md +0 -350
  182. package/dist/docs-raw/runbook.md +0 -611
  183. package/dist-cli/check-compiler-U5SOPN7X.js.map +0 -1
  184. package/dist-cli/check-query-propagation-XOKNSSYU.js.map +0 -1
  185. package/dist-cli/chunk-EXWGNL6K.js.map +0 -1
  186. package/dist-cli/forgecad.js.map +0 -1
  187. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  188. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  189. package/dist-skill/SKILL-dev.md +0 -145
  190. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  191. package/dist-skill/docs-dev/CLI.md +0 -677
  192. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  193. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  194. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  195. package/dist-skill/docs-dev/coding.md +0 -340
  196. package/dist-skill/docs-dev/component-model.md +0 -164
  197. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  198. package/dist-skill/docs-dev/generated/core.md +0 -2117
  199. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  200. package/dist-skill/docs-dev/generated/lib.md +0 -169
  201. package/dist-skill/docs-dev/generated/output.md +0 -247
  202. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  203. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  204. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  205. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  206. package/dist-skill/docs-dev/generated/wood.md +0 -108
  207. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  208. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  209. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  210. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  211. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  212. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  213. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  214. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  215. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  216. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  217. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  218. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  219. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
@@ -1,504 +0,0 @@
1
- ---
2
- skill-group: sheet-metal
3
- skill-order: 100
4
- ---
5
-
6
- # Sheet Metal
7
-
8
- Folded sheet metal parts with flanges, bends, and flat pattern unfolding.
9
-
10
- ## Contents
11
-
12
- - [Sheet Metal](#sheet-metal) — `sheetMetal`
13
- - [Laser Cutting](#laser-cutting) — `kerfCompensateOutline`, `kerfCompensateTabs`, `kerfCompensateSlots`, `kerfCompensatePart`, `lookupKerf`, `flatPanel`, `flatPart`, `fingerJoint`, `tabSlot`, `assemblyPreview`, `assemblyInstructions`, `formatInstructions`, `laserKit`
14
- - [SheetMetalPart](#sheetmetalpart)
15
- - [FlatPart](#flatpart)
16
- - [LaserKit](#laserkit)
17
- - [SHEET_METAL_EDGES](#sheet-metal-edges)
18
- - [COMMON_KERFS](#common-kerfs)
19
-
20
- ## Functions
21
-
22
- ### Sheet Metal
23
-
24
- #### `sheetMetal()` — Create a parametric sheet metal part with flanges, bend allowances, and flat-pattern unfolding.
25
-
26
- `sheetMetal()` keeps one semantic model and derives both a folded 3D solid and an accurate flat pattern from it. The K-factor bend allowance is applied during unfolding. This is a strict v1 subset — it does not infer sheet metal from arbitrary solids.
27
-
28
- **Recommended authoring order:**
29
-
30
- 1. Define the base panel + thickness + bend parameters.
31
- 2. Chain `.flange()` calls for each edge. Validate with `.folded()` and `.flatPattern()` before adding cutouts.
32
- 3. Add panel cutouts, then flange cutouts one region at a time.
33
- 4. Validate after each new cutout region.
34
-
35
- **v1 limitations:** one base panel, up to four 90° edge flanges, constant thickness, explicit K-factor, rectangular corner reliefs, planar cutouts only. No hems, jogs, lofted bends, non-90° flanges, or bend-region cutouts.
36
-
37
- ```ts
38
- const cover = sheetMetal({
39
- panel: { width: 180, height: 110 },
40
- thickness: 1.5,
41
- bendRadius: 2,
42
- bendAllowance: { kFactor: 0.42 },
43
- cornerRelief: { size: 4 },
44
- })
45
- .flange('top', { length: 18 })
46
- .flange('right', { length: 18 })
47
- .flange('bottom', { length: 18 })
48
- .flange('left', { length: 18 })
49
- .cutout('panel', rect(72, 36), { selfAnchor: 'center' })
50
- .cutout('flange-right', roundedRect(26, 10, 5), { selfAnchor: 'center' });
51
-
52
- const folded = cover.folded();
53
- const flat = cover.flatPattern();
54
- ```
55
-
56
- ```ts
57
- sheetMetal(options: SheetMetalOptions): SheetMetalPart
58
- ```
59
-
60
- **`SheetMetalOptions`**
61
-
62
- | Option | Type | Description |
63
- |--------|------|-------------|
64
- | `panel` | `{ width: number; height: number; }` | Base panel dimensions. This is the flat blank before flanges are applied. |
65
- | `thickness` | `number` | Sheet thickness in mm. Applied uniformly across the panel and all flanges. |
66
- | `bendRadius` | `number` | Inside bend radius in mm. Must be ≥ 0. Typically 0.5–2× the sheet thickness. |
67
- | `bendAllowance` | `{ kFactor: number; }` | Bend allowance model used when computing the flat-pattern developed length. Currently only K-factor is supported. The K-factor (0–1) describes how far the neutral axis sits from the inner bend surface. Typical values: - Soft materials / large radius: 0.50 - General sheet steel: 0.42–0.44 - Hard materials / tight radius: 0.30–0.38 |
68
- | `cornerRelief?` | `{ kind?: "rect"; size: number; }` | Corner relief cut at each bend intersection. Prevents material overlap when two flanges meet at a corner. Defaults to a rectangular relief sized to `bendRadius + thickness` if omitted. |
69
-
70
- ### Laser Cutting
71
-
72
- #### `kerfCompensateOutline()` — Apply kerf compensation to a complete part outline (outer boundary + holes).
73
-
74
- Offsets inward by half-kerf: the outer boundary shrinks and inner holes grow. This is correct because the laser beam removes material on both sides of the cut line.
75
-
76
- ```ts
77
- kerfCompensateOutline(sketch: Sketch, kerf: number): Sketch
78
- ```
79
-
80
- #### `kerfCompensateTabs()` — Apply kerf compensation to joint protrusions (tabs, fingers).
81
-
82
- These grow by half-kerf so they are slightly oversized and fit tightly in their mating slots after the laser removes material.
83
-
84
- ```ts
85
- kerfCompensateTabs(sketch: Sketch, kerf: number): Sketch
86
- ```
87
-
88
- #### `kerfCompensateSlots()` — Apply kerf compensation to joint cutouts (slots, holes that receive tabs).
89
-
90
- These grow by half-kerf so tabs can fit into them after the laser removes material from both sides of the slot walls.
91
-
92
- ```ts
93
- kerfCompensateSlots(sketch: Sketch, kerf: number): Sketch
94
- ```
95
-
96
- #### `kerfCompensatePart()` — Build a kerf-compensated part profile.
97
-
98
- 1. Start with the base profile.
99
- 2. Kerf-compensate each tab addition (grow by kerf/2), then union with base.
100
- 3. Kerf-compensate each slot subtraction (grow by kerf/2), then subtract from base.
101
- 4. Kerf-compensate the resulting outline (shrink by kerf/2).
102
-
103
- Order matters: joints modify geometry BEFORE outline compensation so the final inward offset applies uniformly to the assembled profile.
104
-
105
- ```ts
106
- kerfCompensatePart(baseProfile: Sketch, joints: PartJoints, kerf: number): Sketch
107
- ```
108
-
109
- **`PartJoints`**
110
- - `additions?: Sketch[]` — Geometry to ADD to the base profile (tabs, fingers protruding from edges).
111
- - `subtractions?: Sketch[]` — Geometry to SUBTRACT from the base profile (slots, holes for mating tabs).
112
-
113
- #### `lookupKerf()` — Look up kerf for a material + thickness + laser combo.
114
-
115
- If `laserType` is omitted, returns the first matching material + thickness entry. Returns `undefined` when no match is found.
116
-
117
- ```ts
118
- lookupKerf(material: string, thickness: number, laserType?: string): number | undefined
119
- ```
120
-
121
- #### `flatPanel()` — Create a rectangular flat panel with 4 named edges.
122
-
123
- Profile origin at bottom-left corner. Edges: bottom (y=0), right (x=width), top (y=height), left (x=0). Edge traversal follows CCW winding order.
124
-
125
- ```ts
126
- flatPanel(name: string, width: number, height: number, thickness: number, options?: FlatPartOptions): FlatPart
127
- ```
128
-
129
- `FlatPartOptions`: `{ material?: string, qty?: number, color?: string }`
130
-
131
- #### `flatPart()` — Create a flat part from an arbitrary profile with user-named edges.
132
-
133
- Edge normals are computed automatically (perpendicular to direction, rotated 90deg CW).
134
-
135
- ```ts
136
- flatPart(name: string, profile: Sketch, thickness: number, edges?: Record<string, { start: [ number, number ]; end: [ number, number ]; }>, options?: FlatPartOptions): FlatPart
137
- ```
138
-
139
- #### `fingerJoint()` — Connect two parts with finger joints along specified edges.
140
-
141
- Adds finger geometry to partA's edge, cuts matching slots from partB's edge. The joint profiles are positioned along each edge using rotation + translation.
142
-
143
- ```ts
144
- fingerJoint(partA: FlatPart, edgeNameA: string, partB: FlatPart, edgeNameB: string, options?: FingerJointOptions & { foldAngle?: number; }): void
145
- ```
146
-
147
- **`FingerJointOptions`**
148
-
149
- | Option | Type | Description |
150
- |--------|------|-------------|
151
- | `fingers?` | `number` | Explicit finger count (must be odd, >= 3). Default: auto from length/thickness. |
152
- | `fingerWidth?` | `number` | Explicit finger width. Default: auto. |
153
- | `clearance?` | `number` | Extra clearance per side (mm). Default: 0. |
154
- | `kerf?` | `number` | Laser kerf (mm). Default: 0. |
155
- | `endStyle?` | `"full" \| "half"` | Whether edge starts with full finger or half. Default: 'full'. |
156
-
157
- #### `tabSlot()` — Connect two parts with tab-and-slot joints along specified edges.
158
-
159
- Adds tab geometry to partA's edge, cuts matching slots from partB's edge.
160
-
161
- ```ts
162
- tabSlot(partA: FlatPart, edgeNameA: string, partB: FlatPart, edgeNameB: string, options?: TabSlotOptions & { foldAngle?: number; }): void
163
- ```
164
-
165
- **`TabSlotOptions`**
166
-
167
- | Option | Type | Description |
168
- |--------|------|-------------|
169
- | `tabCount?` | `number` | Number of tabs. Default: auto (length / (4 * thickness)). |
170
- | `tabWidth?` | `number` | Tab width. Default: 2 * thickness. |
171
- | `clearance?` | `number` | Extra clearance per side (mm). Default: 0. |
172
- | `kerf?` | `number` | Laser kerf (mm). Default: 0. |
173
- | `inset?` | `number` | Distance from panel edges to first/last tab center. Default: thickness. |
174
-
175
- #### `assemblyPreview()` — Generate a 3D assembly preview from flat parts and their joint records.
176
-
177
- The preview can fold joints partially or fully and optionally apply exploded spacing so part relationships are easier to inspect visually.
178
-
179
- ```ts
180
- assemblyPreview(parts: FlatPart[], joints: JointRecord[], options?: AssemblyPreviewOptions): AssemblyPreviewResult
181
- ```
182
-
183
- **`JointRecord`**
184
- - `foldAngle: number` — Fold angle in degrees. Default: 90.
185
- - Also: `type: "finger" | "tabSlot" | "snapFit", partA: string, partB: string, edgeA: string, edgeB: string`
186
-
187
- **`AssemblyPreviewOptions`**
188
- - `kerf?: number` — Kerf compensation passed to each part's solid(). Default: 0
189
- - `fold?: number` — Fold amount: 0 = flat layout, 1 = fully assembled. Default: 1
190
- - `explode?: number` — Explode distance: 0 = assembled, >0 = parts spread outward. Default: 0
191
-
192
- **`AssemblyPreviewResult`**
193
- - `shapes: ShapeGroup` — All part shapes grouped for display.
194
- - `partShapes: Map<string, Shape>` — Individual transformed shapes keyed by part name.
195
-
196
- #### `assemblyInstructions()` — Generate step-by-step assembly instructions from flat parts and joints.
197
-
198
- Algorithm:
199
-
200
- 1. Build adjacency graph from joints
201
- 2. Pick root part (most connections, or user-specified)
202
- 3. BFS from root, creating one step per part addition
203
- 4. Each step describes: which part to add, where it connects, how to orient it
204
-
205
- Heuristics for step ordering:
206
-
207
- - Start with the part that has the most connections (the base)
208
- - Add parts that connect to already-assembled parts first (BFS order)
209
- - Among candidates at the same BFS depth, prefer parts with more connections to already-assembled parts (structurally stable)
210
-
211
- ```ts
212
- assemblyInstructions(parts: FlatPart[], joints: JointRecord[], options?: AssemblyInstructionsOptions): AssemblyInstructionsResult
213
- ```
214
-
215
- **`AssemblyInstructionsOptions`**
216
- - `rootPart?: string` — Part to start from. Default: part with most joint connections.
217
-
218
- **`AssemblyInstructionsResult`**
219
- - `totalParts: number` — Total number of parts in the assembly.
220
- - `orphanParts: string[]` — Parts not connected to the joint graph (orphans).
221
- - Also: `steps: AssemblyStep[]`
222
-
223
- **`AssemblyStep`**
224
-
225
- | Option | Type | Description |
226
- |--------|------|-------------|
227
- | `stepNumber` | `number` | 1-based step number. |
228
- | `description` | `string` | Human-readable instruction. |
229
- | `partName` | `string` | The part being added in this step. |
230
- | `partNumber` | `number` | Part number (for cross-ref with cut sheets). |
231
- | `connectsTo` | `string` | Which existing part it connects to. |
232
- | `jointType` | `"finger" \| "tabSlot" \| "snapFit"` | Joint type used. |
233
- | `newPartEdge` | `string` | The edge on the new part. |
234
- | `existingPartEdge` | `string` | The edge on the existing part. |
235
- | `foldAngle` | `number` | Fold angle in degrees. |
236
- | `assembledParts` | `string[]` | Part names in the assembly so far (after this step). |
237
-
238
- #### `formatInstructions()` — Format assembly instructions as a human-readable text document.
239
-
240
- Includes a "Step 0" preamble identifying the base part, followed by numbered steps, and a note about any orphan parts.
241
-
242
- ```ts
243
- formatInstructions(result: AssemblyInstructionsResult): string
244
- ```
245
-
246
- #### `laserKit()` — Top-level factory for creating a LaserKit container.
247
-
248
- ```ts
249
- laserKit(options?: LaserKitOptions): LaserKit
250
- ```
251
-
252
- **`LaserKitOptions`**
253
-
254
- | Option | Type | Description |
255
- |--------|------|-------------|
256
- | `material?` | `string` | Default material label for parts that don't specify one. |
257
- | `sheetWidth?` | `number` | Stock sheet width in mm (default 600). |
258
- | `sheetHeight?` | `number` | Stock sheet height in mm (default 400). |
259
- | `kerf?` | `number` | Laser kerf in mm (default 0.2). |
260
-
261
- ---
262
-
263
- ## Classes
264
-
265
- ### `SheetMetalPart`
266
-
267
- An immutable sheet metal part that accumulates flanges and cutouts.
268
-
269
- Each mutating method returns a **new** `SheetMetalPart`; the original is unchanged. The part does not produce geometry until you call `.folded()` or `.flatPattern()`.
270
-
271
- #### `flange()` — Add a 90° flange along one edge of the base panel.
272
-
273
- Each of the four edges (`'top'`, `'right'`, `'bottom'`, `'left'`) may carry at most one flange. Calling `.flange()` twice for the same edge throws.
274
-
275
- Corner reliefs are automatically inserted at the intersections of adjacent flanges. Build flanges before cutouts — validate with `.folded()` and `.flatPattern()` after each addition.
276
-
277
- ```ts
278
- const part = sheetMetal({ panel: { width: 100, height: 60 }, thickness: 1.5, bendRadius: 2, bendAllowance: { kFactor: 0.42 } })
279
- .flange('top', { length: 15 })
280
- .flange('bottom', { length: 15 });
281
- ```
282
-
283
- ```ts
284
- flange(edge: SheetMetalEdge, options: SheetMetalFlangeOptions): SheetMetalPart
285
- ```
286
-
287
- #### `cutout()` — Subtract a 2D sketch cutout from a planar region of the sheet metal part.
288
-
289
- `region` must be `'panel'` or one of `'flange-top'`, `'flange-right'`, `'flange-bottom'`, `'flange-left'` (only available once the corresponding flange has been added). Cutouts inside bend regions are **not** supported in v1.
290
-
291
- `sketch` must be an **unplaced** compile-covered 2D profile (e.g. the result of [`circle2d()`](/docs/sketch#circle2d), [`rect()`](/docs/sketch#rect), [`roundedRect()`](/docs/sketch#roundedrect)). Passing an already-placed sketch (one that has had `.onFace(...)` called on it) will throw.
292
-
293
- **Authoring order:** Add all flanges before adding cutouts. Add panel cutouts before flange cutouts. Add one region at a time and validate with `.folded()` / `.flatPattern()` after each step.
294
-
295
- ```ts
296
- const part = sheetMetal({ panel: { width: 180, height: 110 }, thickness: 1.5, bendRadius: 2, bendAllowance: { kFactor: 0.42 } })
297
- .flange('top', { length: 18 })
298
- .cutout('panel', rect(72, 36), { selfAnchor: 'center' })
299
- .cutout('flange-top', roundedRect(26, 10, 5), { selfAnchor: 'center' });
300
- ```
301
-
302
- ```ts
303
- cutout(region: SheetMetalPlanarRegionName, sketch: Sketch, options?: SheetMetalCutoutOptions): SheetMetalPart
304
- ```
305
-
306
- #### `regionNames()` — Return all semantic region names currently available on this part.
307
-
308
- The returned list always includes `'panel'`. For every flange that has been added, the list also includes the corresponding `'flange-<edge>'` and `'bend-<edge>'` entries.
309
-
310
- Use this to discover valid targets for `.cutout()` or for querying faces by region after materializing with `.folded()`.
311
-
312
- Defended region names: `panel` | `flange-top` | `flange-right` | `flange-bottom` | `flange-left` | `bend-top` | `bend-right` | `bend-bottom` | `bend-left`
313
-
314
- ```ts
315
- regionNames(): SheetMetalRegionName[]
316
- ```
317
-
318
- #### `folded()` — Materialize the 3D folded solid.
319
-
320
- Applies all flanges (bent up at their configured angles) and all registered cutouts, then returns the resulting [`Shape`](/docs/core#shape). The shape is compiler-owned and exact-exportable (STEP, IGES, etc.).
321
-
322
- Prefer calling `.folded()` to validate each build step before proceeding to the final model.
323
-
324
- ```ts
325
- folded(): Shape
326
- ```
327
-
328
- #### `flatPattern()` — Materialize the flat-pattern (unfolded blank) for fabrication.
329
-
330
- Unfolds all flanges using the K-factor bend allowance and lays the result flat in the XY plane. Cutouts are projected into the flat geometry. The returned shape is exact-exportable and ready for laser / waterjet / CNC nesting workflows.
331
-
332
- The developed length of each bend zone is: `BA = (bendRadius + kFactor × thickness) × angleDeg × π / 180`
333
-
334
- ```ts
335
- flatPattern(): Shape
336
- ```
337
-
338
- ### `FlatPart`
339
-
340
- **Properties:**
341
-
342
- | Property | Type | Description |
343
- |----------|------|-------------|
344
- | `name` | `string` | — |
345
- | `thickness` | `number` | — |
346
- | `options` | `FlatPartOptions` | — |
347
-
348
- **Methods:**
349
-
350
- #### `edges()` — All edges as a read-only map.
351
-
352
- ```ts
353
- get edges(): ReadonlyMap<string, EdgeInfo>
354
- ```
355
-
356
- #### `edge()` — Look up a named edge. Throws if the edge does not exist.
357
-
358
- ```ts
359
- edge(name: string): EdgeInfo
360
- ```
361
-
362
- #### `edgeNames()` — All edge names on this part.
363
-
364
- ```ts
365
- edgeNames(): string[]
366
- ```
367
-
368
- #### `partNumber()` — BOM part number assigned to this flat part.
369
-
370
- ```ts
371
- get partNumber(): number
372
- ```
373
-
374
- #### `joints()` — Joint records that attach this part to other parts in the kit.
375
-
376
- ```ts
377
- get joints(): readonly JointRecord[]
378
- ```
379
-
380
- #### `quantity()` — Requested quantity of this part in the kit. Defaults to `1`.
381
-
382
- ```ts
383
- get quantity(): number
384
- ```
385
-
386
- #### `addGeometry()` — Add geometry (e.g. protruding tabs) to the part profile.
387
-
388
- ```ts
389
- addGeometry(sketch: Sketch): void
390
- ```
391
-
392
- #### `subtractGeometry()` — Subtract geometry (e.g. slot cuts) from the part profile.
393
-
394
- ```ts
395
- subtractGeometry(sketch: Sketch): void
396
- ```
397
-
398
- #### `addJoint()` — Record a joint connection for assembly preview.
399
-
400
- ```ts
401
- addJoint(record: JointRecord): void
402
- ```
403
-
404
- #### `profile()` — Final 2D profile with joints and optional kerf compensation.
405
-
406
- ```ts
407
- profile(kerf?: number): Sketch
408
- ```
409
-
410
- #### `solid()` — 3D solid — extrude the profile by material thickness.
411
-
412
- ```ts
413
- solid(kerf?: number): Shape
414
- ```
415
-
416
- ### `LaserKit`
417
-
418
- #### `kerf()` — Laser kerf in mm.
419
-
420
- ```ts
421
- get kerf(): number
422
- ```
423
-
424
- #### `parts()` — All registered parts (flat, in insertion order).
425
-
426
- ```ts
427
- get parts(): readonly FlatPart[]
428
- ```
429
-
430
- #### `material()` — Default material label.
431
-
432
- ```ts
433
- get material(): string
434
- ```
435
-
436
- #### `sheetWidth()` — Stock sheet width in mm.
437
-
438
- ```ts
439
- get sheetWidth(): number
440
- ```
441
-
442
- #### `sheetHeight()` — Stock sheet height in mm.
443
-
444
- ```ts
445
- get sheetHeight(): number
446
- ```
447
-
448
- #### `addPart()` — Register a flat part with this kit. Assigns a sequential part number and records the quantity.
449
-
450
- ```ts
451
- addPart(part: FlatPart, overrides?: { qty?: number; }): this
452
- ```
453
-
454
- #### `cutSheets()` — Generate nested cut sheets using guillotine bin-packing.
455
-
456
- ```ts
457
- cutSheets(): CuttingLayoutResult
458
- ```
459
-
460
- #### [`bom()`](/docs/output#bom) — Bill of materials listing every part with dimensions.
461
-
462
- ```ts
463
- bom(): LaserKitBomEntry[]
464
- ```
465
-
466
- #### `partSvgs()` — Individual SVG string for each part profile, keyed by part name.
467
-
468
- ```ts
469
- partSvgs(): Map<string, string>
470
- ```
471
-
472
- #### `inventorySvg()` — Combined inventory SVG showing all parts in a labeled grid.
473
-
474
- ```ts
475
- inventorySvg(): string
476
- ```
477
-
478
- #### `assemblyPreview()` — 3D fold-up preview of the assembled kit.
479
-
480
- ```ts
481
- assemblyPreview(options?: Omit<AssemblyPreviewOptions, "kerf">): AssemblyPreviewResult
482
- ```
483
-
484
- #### `assemblyInstructions()` — Step-by-step assembly instructions.
485
-
486
- ```ts
487
- assemblyInstructions(options?: AssemblyInstructionsOptions): AssemblyInstructionsResult
488
- ```
489
-
490
- #### `formatInstructions()` — Human-readable assembly instructions text.
491
-
492
- ```ts
493
- formatInstructions(options?: AssemblyInstructionsOptions): string
494
- ```
495
-
496
- ---
497
-
498
- ## Constants
499
-
500
- ### `SHEET_METAL_EDGES`
501
-
502
- ### `COMMON_KERFS`
503
-
504
- Common kerf values. Users should always test-cut to verify for their specific setup.