forgecad 0.9.16 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DcCnj0qo.js} +1 -1
- package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-BVEpJSVk.js} +1 -1
- package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DHaGP50_.js} +1 -1
- package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-CDoxHkz8.js} +40 -859
- package/dist/assets/EditorApp-BJ0Dloyh.js +16446 -0
- package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-CRKZbY0y.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-BxHkYRE7.js} +1 -1
- package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-B-u6FrVv.js} +1 -1
- package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-CzpZ6-Ce.js} +1 -1
- package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-CIZSSAd0.js} +1 -1
- package/dist/assets/{app-CE3sYcV7.css → app-CjsbDlb7.css} +143 -0
- package/dist/assets/{app-T0pDcSX4.js → app-DaTMg3nH.js} +1310 -290
- package/dist/assets/cli/{render-C5pcIISc.js → render-DPf4AYJK.js} +55 -60
- package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
- package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-CjZZWRWW.js} +5209 -2643
- package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
- package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DzQOViQH.js} +1 -1
- package/dist/assets/{manifold-BWgsjmAM.js → manifold-BYlzU521.js} +1 -1
- package/dist/assets/{manifold-D6IFSkhH.js → manifold-DgXo0T5P.js} +2 -2
- package/dist/assets/{manifold-rZexZI0G.js → manifold-K1SkarlQ.js} +1 -1
- package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-B9nWwSrB.js} +8501 -3393
- package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-prBw_s8t.js} +6067 -3479
- package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
- package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +3 -3
- package/dist/docs-raw/AI/usage.md +1 -1
- package/dist/docs-raw/CLI.md +77 -240
- package/dist/docs-raw/README.md +6 -0
- package/dist/docs-raw/component-model.md +17 -150
- package/dist/docs-raw/generated/assembly.md +188 -582
- package/dist/docs-raw/generated/concepts.md +259 -3501
- package/dist/docs-raw/generated/core.md +283 -1250
- package/dist/docs-raw/generated/curves.md +387 -1608
- package/dist/docs-raw/generated/legacy.md +162 -0
- package/dist/docs-raw/generated/lib.md +227 -85
- package/dist/docs-raw/generated/output.md +35 -99
- package/dist/docs-raw/generated/runtime-names.md +23 -23
- package/dist/docs-raw/generated/sdf.md +68 -284
- package/dist/docs-raw/generated/sheet-metal.md +68 -335
- package/dist/docs-raw/generated/sketch.md +240 -1161
- package/dist/docs-raw/generated/viewport.md +75 -316
- package/dist/docs-raw/generated/wood.md +21 -49
- package/dist/docs-raw/guides/coordinate-system.md +4 -42
- package/dist/docs-raw/guides/inspection-bundles.md +44 -442
- package/dist/docs-raw/guides/joint-design.md +18 -79
- package/dist/docs-raw/guides/positioning.md +21 -143
- package/dist/docs-raw/guides/scene-presentation.md +89 -0
- package/dist/docs-raw/guides/simready-quickstart.md +171 -0
- package/dist/docs-raw/simulation-workflow.md +273 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
- package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
- package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
- package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
- package/dist/docs-raw/skills/forgecad-lld.md +19 -113
- package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
- package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
- package/dist/docs-raw/skills/forgecad-project.md +13 -131
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
- package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
- package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
- package/dist/docs-raw/skills/forgecad.md +19 -18
- package/dist/docs-raw/skills/index.md +2 -0
- package/dist/docs-raw/welcome.md +2 -2
- package/dist/index.html +2 -2
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +25 -13
- package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-II7NLPAB.js} +1 -1
- package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-7462TR3R.js} +1 -1
- package/dist-cli/{chunk-SPZE3DUY.js → chunk-UWTJCGXF.js} +5848 -2915
- package/dist-cli/forgecad.js +3496 -703
- package/dist-skill/CONTEXT.md +1797 -7963
- package/dist-skill/SKILL.md +15 -15
- package/dist-skill/docs/API/core/concepts.md +27 -157
- package/dist-skill/docs/CLI.md +77 -240
- package/dist-skill/docs/generated/assembly.md +182 -532
- package/dist-skill/docs/generated/core.md +283 -1250
- package/dist-skill/docs/generated/curves.md +387 -1609
- package/dist-skill/docs/generated/lib.md +227 -85
- package/dist-skill/docs/generated/output.md +35 -99
- package/dist-skill/docs/generated/runtime-names.md +16 -21
- package/dist-skill/docs/generated/sdf.md +68 -284
- package/dist-skill/docs/generated/sheet-metal.md +68 -335
- package/dist-skill/docs/generated/sketch.md +240 -1160
- package/dist-skill/docs/generated/viewport.md +75 -223
- package/dist-skill/docs/generated/wood.md +21 -49
- package/dist-skill/docs/guides/coordinate-system.md +4 -42
- package/dist-skill/docs/guides/inspection-bundles.md +44 -442
- package/dist-skill/docs/guides/joint-design.md +18 -79
- package/dist-skill/docs/guides/positioning.md +21 -143
- package/dist-skill/docs/guides/scene-presentation.md +89 -0
- package/dist-skill/docs/guides/surface-members.md +26 -0
- package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
- package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
- package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
- package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
- package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
- package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
- package/dist-skill/library/forgecad-project/SKILL.md +13 -133
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
- package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
- package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
- package/dist-skill/website/skills/forgecad-component-model.md +53 -0
- package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
- package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
- package/dist-skill/website/skills/forgecad-lld.md +41 -0
- package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
- package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
- package/dist-skill/website/skills/forgecad-project.md +26 -0
- package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
- package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
- package/dist-skill/website/skills/forgecad.md +122 -0
- package/dist-skill/website/skills/index.md +26 -0
- package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
- package/examples/api/conformal-product-ribbon.forge.js +1 -1
- package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
- package/examples/api/extrude-options.forge.js +4 -2
- package/examples/api/field-loft-drive-tip.forge.js +40 -0
- package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +10 -10
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/real-product-curves.forge.js +1 -1
- package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
- package/examples/api/sdf-shapes.forge.js +2 -5
- package/examples/api/sketch-rounding-strategies.forge.js +6 -6
- package/examples/api/surface-member-bottle-cage.forge.js +3 -3
- package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
- package/examples/api/surface-member-razor-inlay.forge.js +1 -1
- package/examples/api/variable-sweep-test.forge.js +3 -3
- package/examples/mechanical/airplane-propeller.forge.js +74 -39
- package/examples/nurbs-surface.forge.js +1 -1
- package/examples/products/iphone.forge.js +1 -1
- package/examples/robotics/README.md +46 -0
- package/examples/robotics/scout-cam-rover-simready/README.md +119 -0
- package/examples/robotics/scout-cam-rover-simready/lib/dims.js +140 -0
- package/examples/robotics/scout-cam-rover-simready/main.forge.js +343 -0
- package/examples/robotics/scout-cam-rover-simready/parts/body.forge.js +304 -0
- package/examples/robotics/scout-cam-rover-simready/parts/chassis.forge.js +320 -0
- package/examples/robotics/scout-cam-rover-simready/parts/hardware.forge.js +21 -0
- package/examples/robotics/scout-cam-rover-simready/parts/turret.forge.js +70 -0
- package/examples/robotics/scout-cam-rover-simready/parts/wheel.forge.js +116 -0
- package/examples/robotics/simready-asset-crate.forge.js +79 -0
- package/examples/robotics/simready-diff-drive-rover.forge.js +141 -0
- package/examples/robotics/simready-parallel-gripper.forge.js +102 -0
- package/package.json +1 -1
- package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
- package/dist/docs-raw/guides/geometry-conventions.md +0 -52
- package/dist/docs-raw/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs/guides/modeling-recipes.md +0 -78
- package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
|
@@ -9,19 +9,18 @@ Folded sheet metal parts with flanges, bends, and flat pattern unfolding.
|
|
|
9
9
|
|
|
10
10
|
## Contents
|
|
11
11
|
|
|
12
|
-
- [Sheet Metal](#sheet-metal)
|
|
13
|
-
- [Laser Cutting](#laser-cutting) — `kerfCompensateOutline`, `kerfCompensateTabs`, `kerfCompensateSlots`, `kerfCompensatePart`, `lookupKerf`, `flatPanel`, `flatPart`, `fingerJoint`, `tabSlot`, `assemblyPreview`, `assemblyInstructions`, `formatInstructions`, `laserKit`
|
|
12
|
+
- [Sheet Metal](#sheet-metal)
|
|
14
13
|
- [SheetMetalPart](#sheetmetalpart)
|
|
15
14
|
- [FlatPart](#flatpart)
|
|
16
15
|
- [LaserKit](#laserkit)
|
|
17
16
|
- [SHEET_METAL_EDGES](#sheet-metal-edges)
|
|
18
|
-
- [
|
|
17
|
+
- [Laser](#laser)
|
|
19
18
|
|
|
20
19
|
## Functions
|
|
21
20
|
|
|
22
21
|
### Sheet Metal
|
|
23
22
|
|
|
24
|
-
#### `sheetMetal()` — Create a parametric sheet metal part with flanges, bend allowances, and flat-pattern unfolding.
|
|
23
|
+
#### `sheetMetal(options: SheetMetalOptions): SheetMetalPart` — Create a parametric sheet metal part with flanges, bend allowances, and flat-pattern unfolding.
|
|
25
24
|
|
|
26
25
|
`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
26
|
|
|
@@ -53,10 +52,6 @@ const folded = cover.folded();
|
|
|
53
52
|
const flat = cover.flatPattern();
|
|
54
53
|
```
|
|
55
54
|
|
|
56
|
-
```ts
|
|
57
|
-
sheetMetal(options: SheetMetalOptions): SheetMetalPart
|
|
58
|
-
```
|
|
59
|
-
|
|
60
55
|
**`SheetMetalOptions`**
|
|
61
56
|
|
|
62
57
|
| Option | Type | Description |
|
|
@@ -67,197 +62,6 @@ sheetMetal(options: SheetMetalOptions): SheetMetalPart
|
|
|
67
62
|
| `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
63
|
| `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
64
|
|
|
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
65
|
---
|
|
262
66
|
|
|
263
67
|
## Classes
|
|
@@ -268,7 +72,7 @@ An immutable sheet metal part that accumulates flanges and cutouts.
|
|
|
268
72
|
|
|
269
73
|
Each mutating method returns a **new** `SheetMetalPart`; the original is unchanged. The part does not produce geometry until you call `.folded()` or `.flatPattern()`.
|
|
270
74
|
|
|
271
|
-
#### `flange()` — Add a 90° flange along one edge of the base panel.
|
|
75
|
+
#### `flange(edge: SheetMetalEdge, options: SheetMetalFlangeOptions): SheetMetalPart` — Add a 90° flange along one edge of the base panel.
|
|
272
76
|
|
|
273
77
|
Each of the four edges (`'top'`, `'right'`, `'bottom'`, `'left'`) may carry at most one flange. Calling `.flange()` twice for the same edge throws.
|
|
274
78
|
|
|
@@ -280,15 +84,11 @@ const part = sheetMetal({ panel: { width: 100, height: 60 }, thickness: 1.5, ben
|
|
|
280
84
|
.flange('bottom', { length: 15 });
|
|
281
85
|
```
|
|
282
86
|
|
|
283
|
-
```ts
|
|
284
|
-
flange(edge: SheetMetalEdge, options: SheetMetalFlangeOptions): SheetMetalPart
|
|
285
|
-
```
|
|
286
|
-
|
|
287
87
|
**`SheetMetalFlangeOptions`**
|
|
288
88
|
- `length: number` — Flange leg length in mm, measured from the outside of the bend to the tip.
|
|
289
89
|
- `angleDeg?: number` — Bend angle in degrees (default: `90`). Only `90°` is supported in v1. Values other than 90 will be rejected at build time.
|
|
290
90
|
|
|
291
|
-
#### `cutout()` — Subtract a 2D sketch cutout from a planar region of the sheet metal part.
|
|
91
|
+
#### `cutout(region: SheetMetalPlanarRegionName, sketch: Sketch, options?: SheetMetalCutoutOptions): SheetMetalPart` — Subtract a 2D sketch cutout from a planar region of the sheet metal part.
|
|
292
92
|
|
|
293
93
|
`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.
|
|
294
94
|
|
|
@@ -303,16 +103,12 @@ const part = sheetMetal({ panel: { width: 180, height: 110 }, thickness: 1.5, be
|
|
|
303
103
|
.cutout('flange-top', roundedRect(26, 10, 5), { selfAnchor: 'center' });
|
|
304
104
|
```
|
|
305
105
|
|
|
306
|
-
```ts
|
|
307
|
-
cutout(region: SheetMetalPlanarRegionName, sketch: Sketch, options?: SheetMetalCutoutOptions): SheetMetalPart
|
|
308
|
-
```
|
|
309
|
-
|
|
310
106
|
**`SheetMetalCutoutOptions`**
|
|
311
107
|
- `u?: number` — Horizontal offset within the region, measured from the region centre (mm). Default: `0`.
|
|
312
108
|
- `v?: number` — Vertical offset within the region, measured from the region centre (mm). Default: `0`.
|
|
313
109
|
- `selfAnchor?: Anchor` — Anchor point on the sketch that aligns to `(u, v)`. Use `'center'` for most cases. For asymmetric profiles, verify orientation by placing one test cutout before committing to the final position. Default: `'center'`.
|
|
314
110
|
|
|
315
|
-
#### `regionNames()` — Return all semantic region names currently available on this part.
|
|
111
|
+
#### `regionNames(): SheetMetalRegionName[]` — Return all semantic region names currently available on this part.
|
|
316
112
|
|
|
317
113
|
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.
|
|
318
114
|
|
|
@@ -320,30 +116,18 @@ Use this to discover valid targets for `.cutout()` or for querying faces by regi
|
|
|
320
116
|
|
|
321
117
|
Defended region names: `panel` | `flange-top` | `flange-right` | `flange-bottom` | `flange-left` | `bend-top` | `bend-right` | `bend-bottom` | `bend-left`
|
|
322
118
|
|
|
323
|
-
|
|
324
|
-
regionNames(): SheetMetalRegionName[]
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
#### `folded()` — Materialize the 3D folded solid.
|
|
119
|
+
#### `folded(): Shape` — Materialize the 3D folded solid.
|
|
328
120
|
|
|
329
121
|
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.).
|
|
330
122
|
|
|
331
123
|
Prefer calling `.folded()` to validate each build step before proceeding to the final model.
|
|
332
124
|
|
|
333
|
-
|
|
334
|
-
folded(): Shape
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
#### `flatPattern()` — Materialize the flat-pattern (unfolded blank) for fabrication.
|
|
125
|
+
#### `flatPattern(): Shape` — Materialize the flat-pattern (unfolded blank) for fabrication.
|
|
338
126
|
|
|
339
127
|
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.
|
|
340
128
|
|
|
341
129
|
The developed length of each bend zone is: `BA = (bendRadius + kFactor × thickness) × angleDeg × π / 180`
|
|
342
130
|
|
|
343
|
-
```ts
|
|
344
|
-
flatPattern(): Shape
|
|
345
|
-
```
|
|
346
|
-
|
|
347
131
|
### `FlatPart`
|
|
348
132
|
|
|
349
133
|
**Properties:**
|
|
@@ -356,158 +140,107 @@ flatPattern(): Shape
|
|
|
356
140
|
|
|
357
141
|
**Methods:**
|
|
358
142
|
|
|
359
|
-
#### `edges()
|
|
360
|
-
|
|
361
|
-
```ts
|
|
362
|
-
get edges(): ReadonlyMap<string, EdgeInfo>
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
#### `edge()` — Look up a named edge. Throws if the edge does not exist.
|
|
366
|
-
|
|
367
|
-
```ts
|
|
368
|
-
edge(name: string): EdgeInfo
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
#### `edgeNames()` — All edge names on this part.
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
|
-
edgeNames(): string[]
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
#### `partNumber()` — BOM part number assigned to this flat part.
|
|
378
|
-
|
|
379
|
-
```ts
|
|
380
|
-
get partNumber(): number
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
#### `joints()` — Joint records that attach this part to other parts in the kit.
|
|
143
|
+
#### `get edges(): ReadonlyMap<string, EdgeInfo>` — All edges as a read-only map.
|
|
384
144
|
|
|
385
|
-
|
|
386
|
-
get joints(): readonly JointRecord[]
|
|
387
|
-
```
|
|
145
|
+
#### `edge(name: string): EdgeInfo` — Look up a named edge. Throws if the edge does not exist.
|
|
388
146
|
|
|
389
|
-
#### `
|
|
147
|
+
#### `edgeNames(): string[]` — All edge names on this part.
|
|
390
148
|
|
|
391
|
-
|
|
392
|
-
get quantity(): number
|
|
393
|
-
```
|
|
149
|
+
#### `get partNumber(): number` — BOM part number assigned to this flat part.
|
|
394
150
|
|
|
395
|
-
#### `
|
|
151
|
+
#### `get joints(): readonly JointRecord[]` — Joint records that attach this part to other parts in the kit.
|
|
396
152
|
|
|
397
|
-
|
|
398
|
-
addGeometry(sketch: Sketch): void
|
|
399
|
-
```
|
|
153
|
+
#### `get quantity(): number` — Requested quantity of this part in the kit. Defaults to `1`.
|
|
400
154
|
|
|
401
|
-
#### `
|
|
155
|
+
#### `addGeometry(sketch: Sketch): void` — Add geometry (e.g. protruding tabs) to the part profile.
|
|
402
156
|
|
|
403
|
-
|
|
404
|
-
subtractGeometry(sketch: Sketch): void
|
|
405
|
-
```
|
|
157
|
+
#### `subtractGeometry(sketch: Sketch): void` — Subtract geometry (e.g. slot cuts) from the part profile.
|
|
406
158
|
|
|
407
|
-
#### `addJoint()` — Record a joint connection for assembly preview.
|
|
159
|
+
#### `addJoint(record: JointRecord): void` — Record a joint connection for assembly preview.
|
|
408
160
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
#### `profile()` — Final 2D profile with joints and optional kerf compensation.
|
|
414
|
-
|
|
415
|
-
```ts
|
|
416
|
-
profile(kerf?: number): Sketch
|
|
417
|
-
```
|
|
161
|
+
**`JointRecord`**
|
|
162
|
+
- `foldAngle: number` — Fold angle in degrees. Default: 90.
|
|
163
|
+
- Also: `type: "finger" | "tabSlot" | "snapFit"`, `partA: string`, `partB: string`, `edgeA: string`, `edgeB: string`.
|
|
418
164
|
|
|
419
|
-
#### `
|
|
165
|
+
#### `profile(kerf?: number): Sketch` — Final 2D profile with joints and optional kerf compensation.
|
|
420
166
|
|
|
421
|
-
|
|
422
|
-
solid(kerf?: number): Shape
|
|
423
|
-
```
|
|
167
|
+
#### `solid(kerf?: number): Shape` — 3D solid — extrude the profile by material thickness.
|
|
424
168
|
|
|
425
169
|
### `LaserKit`
|
|
426
170
|
|
|
427
|
-
#### `kerf()` — Laser kerf in mm.
|
|
171
|
+
#### `get kerf(): number` — Laser kerf in mm.
|
|
428
172
|
|
|
429
|
-
|
|
430
|
-
get kerf(): number
|
|
431
|
-
```
|
|
173
|
+
#### `get parts(): readonly FlatPart[]` — All registered parts (flat, in insertion order).
|
|
432
174
|
|
|
433
|
-
#### `
|
|
175
|
+
#### `get material(): string` — Default material label.
|
|
434
176
|
|
|
435
|
-
|
|
436
|
-
get parts(): readonly FlatPart[]
|
|
437
|
-
```
|
|
177
|
+
#### `get sheetWidth(): number` — Stock sheet width in mm.
|
|
438
178
|
|
|
439
|
-
#### `
|
|
179
|
+
#### `get sheetHeight(): number` — Stock sheet height in mm.
|
|
440
180
|
|
|
441
|
-
|
|
442
|
-
get material(): string
|
|
443
|
-
```
|
|
181
|
+
#### `addPart(part: FlatPart, overrides?: { qty?: number; }): this` — Register a flat part with this kit. Assigns a sequential part number and records the quantity.
|
|
444
182
|
|
|
445
|
-
#### `
|
|
183
|
+
#### `cutSheets(): CuttingLayoutResult` — Generate nested cut sheets using guillotine bin-packing.
|
|
446
184
|
|
|
447
|
-
|
|
448
|
-
get sheetWidth(): number
|
|
449
|
-
```
|
|
185
|
+
#### `bom(): LaserKitBomEntry[]` — Bill of materials listing every part with dimensions.
|
|
450
186
|
|
|
451
|
-
#### `
|
|
187
|
+
#### `partSvgs(): Map<string, string>` — Individual SVG string for each part profile, keyed by part name.
|
|
452
188
|
|
|
453
|
-
|
|
454
|
-
get sheetHeight(): number
|
|
455
|
-
```
|
|
189
|
+
#### `inventorySvg(): string` — Combined inventory SVG showing all parts in a labeled grid.
|
|
456
190
|
|
|
457
|
-
#### `
|
|
191
|
+
#### `assemblyPreview(options?: Omit<AssemblyPreviewOptions, "kerf">): AssemblyPreviewResult` — 3D fold-up preview of the assembled kit.
|
|
458
192
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
193
|
+
**`AssemblyPreviewOptions`**
|
|
194
|
+
- `kerf?: number` — Kerf compensation passed to each part's solid(). Default: 0
|
|
195
|
+
- `fold?: number` — Fold amount: 0 = flat layout, 1 = fully assembled. Default: 1
|
|
196
|
+
- `explode?: number` — Explode distance: 0 = assembled, >0 = parts spread outward. Default: 0
|
|
462
197
|
|
|
463
|
-
#### `
|
|
198
|
+
#### `assemblyInstructions(options?: AssemblyInstructionsOptions): AssemblyInstructionsResult` — Step-by-step assembly instructions.
|
|
464
199
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
```
|
|
200
|
+
**`AssemblyInstructionsOptions`**
|
|
201
|
+
- `rootPart?: string` — Part to start from. Default: part with most joint connections.
|
|
468
202
|
|
|
469
|
-
####
|
|
203
|
+
#### `formatInstructions(options?: AssemblyInstructionsOptions): string` — Human-readable assembly instructions text.
|
|
470
204
|
|
|
471
|
-
|
|
472
|
-
bom(): LaserKitBomEntry[]
|
|
473
|
-
```
|
|
205
|
+
---
|
|
474
206
|
|
|
475
|
-
|
|
207
|
+
## Constants
|
|
476
208
|
|
|
477
|
-
|
|
478
|
-
partSvgs(): Map<string, string>
|
|
479
|
-
```
|
|
209
|
+
### `SHEET_METAL_EDGES`
|
|
480
210
|
|
|
481
|
-
|
|
211
|
+
### `Laser`
|
|
482
212
|
|
|
483
|
-
|
|
484
|
-
inventorySvg(): string
|
|
485
|
-
```
|
|
213
|
+
Laser-cutting namespace — flat parts, joints, kits, kerf data, and assembly previews.
|
|
486
214
|
|
|
487
|
-
|
|
215
|
+
**Workflow:** create parts with `Laser.panel()` / `Laser.part()`, connect them with `Laser.fingerJoint()` / `Laser.tabSlot()`, then collect them in a `Laser.kit()` for BOM, sheet nesting, SVG export, and assembly previews. The kit applies kerf compensation automatically from its `kerf` option.
|
|
488
216
|
|
|
489
|
-
|
|
490
|
-
assemblyPreview(options?: Omit<AssemblyPreviewOptions, "kerf">): AssemblyPreviewResult
|
|
491
|
-
```
|
|
217
|
+
- `panel: (name: string, width: number, height: number, thickness: number, options?: FlatPartOptions) => FlatPart` — Create a rectangular flat panel with 4 named edges.
|
|
492
218
|
|
|
493
|
-
|
|
219
|
+
Profile origin at the bottom-left corner. Edges: `bottom` (y=0), `right` (x=width), `top` (y=height), `left` (x=0). Edge traversal follows CCW winding order.
|
|
220
|
+
- `part: (name: string, profile: Sketch, thickness: number, edges?: Record<string, { start: Vec2; end: Vec2; }>, options?: FlatPartOptions) => FlatPart` — Create a flat part from an arbitrary 2D profile with user-named edges.
|
|
494
221
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
```
|
|
222
|
+
Edge normals are computed automatically (perpendicular to the edge direction, rotated 90 degrees clockwise).
|
|
223
|
+
- `fingerJoint: (partA: FlatPart, edgeNameA: string, partB: FlatPart, edgeNameB: string, options?: FingerJointOptions & { foldAngle?: number; }) => void` — Connect two parts with finger joints along the named edges.
|
|
498
224
|
|
|
499
|
-
|
|
225
|
+
Adds finger geometry to partA's edge and cuts matching slots from partB's edge; the joint is also recorded on both parts for assembly previews and instructions.
|
|
226
|
+
- `tabSlot: (partA: FlatPart, edgeNameA: string, partB: FlatPart, edgeNameB: string, options?: TabSlotOptions & { foldAngle?: number; }) => void` — Connect two parts with tab-and-slot joints along the named edges.
|
|
500
227
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
```
|
|
228
|
+
Adds tab geometry to partA's edge and cuts matching slots from partB's edge; the joint is also recorded on both parts for assembly previews and instructions.
|
|
229
|
+
- `kit: (options?: LaserKitOptions) => LaserKit` — Create a LaserKit container for a flat-pack project.
|
|
504
230
|
|
|
505
|
-
|
|
231
|
+
The kit collects FlatPart instances, assigns sequential part numbers, generates a bill of materials, nests parts onto cut sheets, exports SVG views, and produces kerf-compensated assembly previews and step-by-step instructions. Kerf compensation uses the kit's `kerf` option (default 0.2 mm).
|
|
232
|
+
- `assemblyPreview: (parts: FlatPart[], joints: JointRecord[], options?: AssemblyPreviewOptions) => AssemblyPreviewResult` — Generate a 3D assembly preview from flat parts and their joint records.
|
|
506
233
|
|
|
507
|
-
|
|
234
|
+
Prefer `Laser.kit(...).assemblyPreview(options)` — the kit collects the joint records and applies its kerf automatically. This standalone form defaults `kerf` to 0.
|
|
235
|
+
- `instructions: (parts: FlatPart[], joints: JointRecord[], options?: AssemblyInstructionsOptions) => AssemblyInstructionsResult` — Generate step-by-step assembly instructions from flat parts and joints.
|
|
508
236
|
|
|
509
|
-
|
|
237
|
+
Prefer `Laser.kit(...).assemblyInstructions(options)` — the kit collects the joint records for you. Steps are ordered BFS from the most-connected (base) part so each new part attaches to already-assembled parts.
|
|
238
|
+
- `formatInstructions: (result: AssemblyInstructionsResult) => string` — 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
|
+
- `lookupKerf: (material: string, thickness: number, laserType?: string) => number | undefined` — Look up kerf for a material + thickness + laser combo in `Laser.COMMON_KERFS`.
|
|
510
242
|
|
|
511
|
-
|
|
243
|
+
If `laserType` is omitted, returns the first matching material + thickness entry. Returns `undefined` when no match is found. Always test-cut to verify kerf for a specific machine.
|
|
244
|
+
- `COMMON_KERFS: MaterialKerfEntry[]` — Common full-kerf values by material, thickness, and laser type.
|
|
512
245
|
|
|
513
|
-
|
|
246
|
+
Reference data only — kerf varies per machine, lens, and focus; always test-cut to verify before committing a sheet.
|