forgecad 0.9.13 → 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 (216) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-DramHHDf.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-Bjgkh5m9.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-n_HGP3Qm.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-WCIkPmzC.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-DEZKqdfW.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-CeRIctuj.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-rIRa8p4Y.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-BqCUvEXM.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-BUZqJvSO.js → app-D3kDkggg.js} +2305 -960
  18. package/dist/assets/cli/{render-lhGxj50Y.js → render-DSY3mMQa.js} +423 -30
  19. package/dist/assets/{constructionHistoryWorker-ipD1jcIv.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CHXSe_-u.js → evalWorker-CU0Ke6DP.js} +7799 -4163
  21. package/dist/assets/{forgecad_geometry-BVnIeXMG.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/{forgecad_geometry_bg-DufhhCBV.wasm → 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-D1LZIHqn.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-C2fwoTgd.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-BTkzxi9V.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-Cq1qGmg0.js → reportWorker-CdBz5bNg.js} +7537 -10856
  32. package/dist/assets/{scalar-sampling-budget-D9Qv_UlJ.js → scalar-sampling-budget-wJF98aY9.js} +6943 -4345
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{renderSceneState-Dr0xPq1A.js → targets-B9sGB5nB.js} +27 -1
  35. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  36. package/dist/cli/render.html +1 -1
  37. package/dist/docs/index.html +2 -2
  38. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  39. package/dist/docs-raw/AI/usage.md +9 -17
  40. package/dist/docs-raw/CLI.md +71 -21
  41. package/dist/docs-raw/component-model.md +27 -11
  42. package/dist/docs-raw/generated/assembly.md +301 -212
  43. package/dist/docs-raw/generated/concepts.md +238 -240
  44. package/dist/docs-raw/generated/core.md +283 -6
  45. package/dist/docs-raw/generated/curves.md +274 -361
  46. package/dist/docs-raw/generated/lib.md +7 -1
  47. package/dist/docs-raw/generated/output.md +19 -4
  48. package/dist/docs-raw/generated/runtime-names.md +41 -0
  49. package/dist/docs-raw/generated/sdf.md +31 -0
  50. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  51. package/dist/docs-raw/generated/sketch.md +44 -1
  52. package/dist/docs-raw/generated/viewport.md +14 -6
  53. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  54. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  55. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  56. package/dist/docs-raw/guides/joint-design.md +24 -0
  57. package/dist/docs-raw/guides/positioning.md +13 -3
  58. package/dist/docs-raw/legal/privacy.md +63 -0
  59. package/dist/docs-raw/legal/software-license.md +55 -0
  60. package/dist/docs-raw/legal/terms.md +87 -0
  61. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +3 -3
  62. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  63. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  64. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  66. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-make-a-model.md +4 -4
  68. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  69. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  70. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  71. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +4 -4
  72. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  73. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  74. package/dist/docs-raw/skills/forgecad.md +4 -3
  75. package/dist/index.html +40 -12
  76. package/dist/llms.txt +8 -0
  77. package/dist/site.webmanifest +1 -1
  78. package/dist/sitemap.xml +49 -13
  79. package/dist-cli/{check-compiler-LOXCPEOI.js → check-compiler-SDX5QIXI.js} +1 -2
  80. package/dist-cli/{check-query-propagation-BAKNVWXR.js → check-query-propagation-EAYEFT77.js} +1 -2
  81. package/dist-cli/{chunk-RY43WF46.js → chunk-N4O47JLF.js} +13772 -9938
  82. package/dist-cli/forgecad.js +2387 -899
  83. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  84. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  85. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  86. package/dist-skill/CONTEXT.md +1120 -724
  87. package/dist-skill/SKILL.md +3 -2
  88. package/dist-skill/docs/API/core/concepts.md +64 -1
  89. package/dist-skill/docs/CLI.md +71 -21
  90. package/dist-skill/docs/generated/assembly.md +277 -229
  91. package/dist-skill/docs/generated/core.md +283 -6
  92. package/dist-skill/docs/generated/curves.md +272 -362
  93. package/dist-skill/docs/generated/lib.md +7 -1
  94. package/dist-skill/docs/generated/output.md +19 -4
  95. package/dist-skill/docs/generated/runtime-names.md +41 -0
  96. package/dist-skill/docs/generated/sdf.md +31 -0
  97. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  98. package/dist-skill/docs/generated/sketch.md +44 -2
  99. package/dist-skill/docs/generated/viewport.md +5 -90
  100. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  101. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  102. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  103. package/dist-skill/docs/guides/joint-design.md +24 -0
  104. package/dist-skill/docs/guides/positioning.md +13 -3
  105. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +2 -2
  106. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  107. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  108. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  109. package/dist-skill/library/forgecad-make-a-model/SKILL.md +3 -3
  110. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  111. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +3 -3
  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 -18
  135. package/dist/assets/EditorApp-CP9Za6tm.js +0 -13630
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/docs-raw/API/README.md +0 -16
  138. package/dist/docs-raw/API/core/concepts.md +0 -118
  139. package/dist/docs-raw/INDEX.md +0 -138
  140. package/dist/docs-raw/RELEASING.md +0 -87
  141. package/dist/docs-raw/agent-native-api.md +0 -27
  142. package/dist/docs-raw/beta-deployment.md +0 -304
  143. package/dist/docs-raw/beta-operations.md +0 -325
  144. package/dist/docs-raw/blueprint-first.md +0 -145
  145. package/dist/docs-raw/cli-monetization.md +0 -112
  146. package/dist/docs-raw/coding-best-practices.md +0 -120
  147. package/dist/docs-raw/coding.md +0 -340
  148. package/dist/docs-raw/deployment.md +0 -374
  149. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  150. package/dist/docs-raw/guides/surface-members.md +0 -82
  151. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  152. package/dist/docs-raw/internals/compiler.md +0 -307
  153. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  154. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  155. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  156. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  157. package/dist/docs-raw/platform/admin.md +0 -45
  158. package/dist/docs-raw/platform/architecture.md +0 -82
  159. package/dist/docs-raw/platform/auth.md +0 -139
  160. package/dist/docs-raw/platform/email.md +0 -67
  161. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  162. package/dist/docs-raw/platform/observability.md +0 -197
  163. package/dist/docs-raw/platform/projects.md +0 -111
  164. package/dist/docs-raw/platform/sharing.md +0 -90
  165. package/dist/docs-raw/product/README.md +0 -39
  166. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  167. package/dist/docs-raw/product/business-model.md +0 -15
  168. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  169. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  170. package/dist/docs-raw/product/founder-story.md +0 -11
  171. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  172. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  173. package/dist/docs-raw/product/product-loop.md +0 -17
  174. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  175. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  176. package/dist/docs-raw/product/user-segments.md +0 -15
  177. package/dist/docs-raw/product/vision.md +0 -26
  178. package/dist/docs-raw/rl-environments.md +0 -508
  179. package/dist/docs-raw/runbook.md +0 -611
  180. package/dist-cli/check-compiler-LOXCPEOI.js.map +0 -1
  181. package/dist-cli/check-query-propagation-BAKNVWXR.js.map +0 -1
  182. package/dist-cli/chunk-RY43WF46.js.map +0 -1
  183. package/dist-cli/forgecad.js.map +0 -1
  184. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  185. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  186. package/dist-skill/SKILL-dev.md +0 -145
  187. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  188. package/dist-skill/docs-dev/CLI.md +0 -647
  189. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  190. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  191. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  192. package/dist-skill/docs-dev/coding.md +0 -340
  193. package/dist-skill/docs-dev/component-model.md +0 -164
  194. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  195. package/dist-skill/docs-dev/generated/core.md +0 -2117
  196. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  197. package/dist-skill/docs-dev/generated/lib.md +0 -169
  198. package/dist-skill/docs-dev/generated/output.md +0 -247
  199. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  200. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  201. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  202. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  203. package/dist-skill/docs-dev/generated/wood.md +0 -108
  204. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  205. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  206. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  207. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  208. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  209. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  210. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  211. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  212. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  213. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  214. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  215. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  216. 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.