forgecad 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -11
- package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-DAu1C1ST.js} +250 -151
- package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
- package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-Gc_BCdqC.js} +269 -143
- package/dist/assets/EditorApp-D9bJvtf7.js +11338 -0
- package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-DG1-oUSV.css} +459 -87
- package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-CEO8XbV8.js} +2 -4
- package/dist/assets/LandingPage-CdCuEOdC.js +451 -0
- package/dist/assets/PricingPage-BSrxu6d7.js +232 -0
- package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-FUCSIRq6.js} +129 -5
- package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-KoR0SNKq.js} +6770 -2914
- package/dist/assets/{index-2hfs_ub0.css → index-CyVd1D4D.css} +227 -53
- package/dist/assets/{Viewport-CoB46f5R.js → index-wTEK39at.js} +31385 -6439
- package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
- package/dist/assets/{manifold-CqNMHHKO.js → manifold-B1sGWdYk.js} +4 -3
- package/dist/assets/{manifold-Cce9wRFz.js → manifold-D7o0N50J.js} +1 -1
- package/dist/assets/{manifold-D6BeHIOo.js → manifold-G5sBaXzi.js} +1 -1
- package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-DYcRHhv9.js} +6798 -3341
- package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
- package/dist/docs-raw/generated/assembly.md +691 -112
- package/dist/docs-raw/generated/concepts.md +1225 -1400
- package/dist/docs-raw/generated/core.md +464 -1412
- package/dist/docs-raw/generated/curves.md +593 -117
- package/dist/docs-raw/generated/lib.md +38 -748
- package/dist/docs-raw/generated/output.md +139 -245
- package/dist/docs-raw/generated/sheet-metal.md +473 -21
- package/dist/docs-raw/generated/sketch.md +553 -349
- package/dist/docs-raw/generated/viewport.md +345 -303
- package/dist/docs-raw/generated/wood.md +104 -0
- package/dist/index.html +2 -2
- package/dist/sitemap.xml +6 -6
- package/dist-cli/chunk-PZ5AY32C.js +10 -0
- package/dist-cli/chunk-PZ5AY32C.js.map +1 -0
- package/dist-cli/forgecad.js +9435 -5407
- package/dist-cli/forgecad.js.map +1 -0
- package/dist-cli/solver-FV7TJZGI.js +365 -0
- package/dist-cli/solver-FV7TJZGI.js.map +1 -0
- package/dist-skill/CONTEXT.md +3186 -7145
- package/dist-skill/SKILL-dev.md +21 -63
- package/dist-skill/SKILL.md +12 -56
- package/dist-skill/docs/API/core/concepts.md +16 -98
- package/dist-skill/docs/CLI/export.md +91 -0
- package/dist-skill/docs/CLI/projects.md +107 -0
- package/dist-skill/docs/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs/CLI/validation.md +66 -0
- package/dist-skill/docs/generated/assembly.md +691 -112
- package/dist-skill/docs/generated/core.md +464 -1412
- package/dist-skill/docs/generated/curves.md +593 -117
- package/dist-skill/docs/generated/lib.md +38 -748
- package/dist-skill/docs/generated/output.md +139 -245
- package/dist-skill/docs/generated/sheet-metal.md +473 -21
- package/dist-skill/docs/generated/sketch.md +553 -349
- package/dist-skill/docs/generated/viewport.md +345 -303
- package/dist-skill/docs/generated/wood.md +104 -0
- package/dist-skill/docs/guides/coordinate-system.md +11 -17
- package/dist-skill/docs/guides/geometry-conventions.md +13 -70
- package/dist-skill/docs/guides/modeling-recipes.md +22 -195
- package/dist-skill/docs/guides/positioning.md +88 -147
- package/dist-skill/docs-dev/API/core/concepts.md +51 -0
- package/dist-skill/docs-dev/API/core/sdf-advanced.md +92 -0
- package/dist-skill/docs-dev/API/core/sdf-primitives.md +58 -0
- package/dist-skill/docs-dev/API/core/sdf-workflow.md +42 -0
- package/dist-skill/docs-dev/CLI/export.md +91 -0
- package/dist-skill/docs-dev/CLI/projects.md +107 -0
- package/dist-skill/docs-dev/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs-dev/CLI/validation.md +66 -0
- package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
- package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
- package/dist-skill/{docs → docs-dev}/coding.md +1 -3
- package/dist-skill/docs-dev/generated/assembly.md +771 -0
- package/dist-skill/docs-dev/generated/core.md +775 -0
- package/dist-skill/docs-dev/generated/curves.md +688 -0
- package/dist-skill/docs-dev/generated/lib.md +50 -0
- package/dist-skill/docs-dev/generated/output.md +234 -0
- package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
- package/dist-skill/docs-dev/generated/sketch.md +801 -0
- package/dist-skill/docs-dev/generated/viewport.md +486 -0
- package/dist-skill/docs-dev/generated/wood.md +104 -0
- package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
- package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
- package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
- package/dist-skill/docs-dev/guides/positioning.md +151 -0
- package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
- package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
- package/examples/api/attachTo-basics.forge.js +5 -5
- package/examples/api/boolean-operations.forge.js +3 -3
- package/examples/api/bounding-box-visualizer.forge.js +2 -2
- package/examples/api/clone-duplicate.forge.js +1 -1
- package/examples/api/colors-union-vs-array.forge.js +6 -6
- package/examples/api/connector-assembly.forge.js +4 -4
- package/examples/api/connector-basics.forge.js +2 -2
- package/examples/api/extrude-options.forge.js +4 -10
- package/examples/api/feature-created-faces.forge.js +6 -10
- package/examples/api/fillet-showcase.forge.js +1 -1
- package/examples/api/folded-service-panel-cover.forge.js +2 -2
- package/examples/api/group-test.forge.js +1 -1
- package/examples/api/group-vs-union.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +4 -0
- package/examples/api/js-module-pillars.js +1 -1
- package/examples/api/js-module-scene.js +2 -2
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/pointAlong-orientation.forge.js +1 -1
- package/examples/api/profile-2020-b-slot6.forge.js +0 -1
- package/examples/api/route-perimeter-flange.forge.js +1 -1
- package/examples/api/sdf-rover-demo.forge.js +10 -10
- package/examples/api/sketch-on-face-demo.forge.js +2 -2
- package/examples/api/sketch-regions.forge.js +4 -4
- package/examples/api/transition-curves.forge.js +1 -1
- package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
- package/examples/api/variable-sweep-test.forge.js +2 -2
- package/examples/api/wood-joinery.forge.js +60 -0
- package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
- package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
- package/examples/experiments/drone-arm.forge.js +53 -0
- package/examples/furniture/adjustable-table.forge.js +2 -2
- package/examples/furniture/bathroom.forge.js +11 -11
- package/examples/furniture/chair.forge.js +1 -1
- package/examples/generative/crystal-growth.forge.js +2 -2
- package/examples/generative/frost-spires.forge.js +3 -3
- package/examples/generative/golden-spiral-tower.forge.js +3 -3
- package/examples/mechanical/3d-printer.forge.js +28 -28
- package/examples/mechanical/5-finger-robot-hand.forge.js +15 -15
- package/examples/mechanical/airplane-propeller.forge.js +2 -2
- package/examples/mechanical/fillet-enclosure.forge.js +1 -1
- package/examples/mechanical/headphone-hanger-v2.forge.js +2 -2
- package/examples/mechanical/robot_hand.forge.js +15 -15
- package/examples/mechanical/robot_hand_2.forge.js +9 -9
- package/examples/products/bottle.forge.js +1 -1
- package/examples/products/chess-set.forge.js +19 -19
- package/examples/products/classical-piano.forge.js +11 -11
- package/examples/products/clock.forge.js +12 -12
- package/examples/products/iphone.forge.js +8 -8
- package/examples/products/laptop.forge.js +15 -15
- package/examples/products/liquid-soap-dispenser.forge.js +18 -18
- package/examples/products/origami-fish.forge.js +8 -6
- package/examples/products/spiderman-cake.forge.js +4 -4
- package/examples/toolbox/bolted-joint.forge.js +2 -2
- package/package.json +7 -4
- package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
- package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
- package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
- package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
- package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
- package/dist/assets/index-1CYp3zUp.js +0 -1455
- package/dist/docs-raw/CLI.md +0 -865
- package/dist-skill/docs/API/API.md +0 -1666
- package/dist-skill/docs/API/README.md +0 -37
- package/dist-skill/docs/API/assembly/assembly.md +0 -617
- package/dist-skill/docs/API/core/edge-queries.md +0 -130
- package/dist-skill/docs/API/core/parameters.md +0 -122
- package/dist-skill/docs/API/core/reserved-terms.md +0 -137
- package/dist-skill/docs/API/core/sdf.md +0 -326
- package/dist-skill/docs/API/core/skill-cli.md +0 -194
- package/dist-skill/docs/API/core/skill-guide.md +0 -205
- package/dist-skill/docs/API/core/specs.md +0 -186
- package/dist-skill/docs/API/core/topology.md +0 -372
- package/dist-skill/docs/API/entities.md +0 -268
- package/dist-skill/docs/API/output/bom.md +0 -58
- package/dist-skill/docs/API/output/brep-export.md +0 -87
- package/dist-skill/docs/API/output/dimensions.md +0 -67
- package/dist-skill/docs/API/output/export.md +0 -110
- package/dist-skill/docs/API/output/gcode.md +0 -195
- package/dist-skill/docs/API/runtime/viewport.md +0 -420
- package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
- package/dist-skill/docs/API/sketch/anchor.md +0 -37
- package/dist-skill/docs/API/sketch/booleans.md +0 -91
- package/dist-skill/docs/API/sketch/core.md +0 -73
- package/dist-skill/docs/API/sketch/extrude.md +0 -62
- package/dist-skill/docs/API/sketch/on-face.md +0 -104
- package/dist-skill/docs/API/sketch/operations.md +0 -78
- package/dist-skill/docs/API/sketch/path.md +0 -75
- package/dist-skill/docs/API/sketch/primitives.md +0 -146
- package/dist-skill/docs/API/sketch/regions.md +0 -80
- package/dist-skill/docs/API/sketch/text.md +0 -108
- package/dist-skill/docs/API/sketch/transforms.md +0 -65
- package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
- package/dist-skill/docs/CLI.md +0 -865
- package/dist-skill/docs/INDEX.md +0 -94
- package/dist-skill/docs/RELEASING.md +0 -55
- package/dist-skill/docs/cli-monetization.md +0 -111
- package/dist-skill/docs/deployment.md +0 -281
- package/dist-skill/docs/generated/concepts.md +0 -2112
- package/dist-skill/docs/internals/shape-from-slices.md +0 -152
- package/dist-skill/docs/platform/admin.md +0 -45
- package/dist-skill/docs/platform/architecture.md +0 -79
- package/dist-skill/docs/platform/auth.md +0 -110
- package/dist-skill/docs/platform/email.md +0 -67
- package/dist-skill/docs/platform/projects.md +0 -111
- package/dist-skill/docs/platform/sharing.md +0 -90
- package/dist-skill/docs/runbook.md +0 -345
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: core
|
|
3
|
-
skill-order: 3
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Entity-Based API
|
|
7
|
-
|
|
8
|
-
Named geometric entities with stable identity, topology tracking, and constraint integration.
|
|
9
|
-
|
|
10
|
-
## 2D Entities
|
|
11
|
-
|
|
12
|
-
### `point(x, y)` / `new Point2D(x, y)`
|
|
13
|
-
A named 2D point.
|
|
14
|
-
|
|
15
|
-
```javascript
|
|
16
|
-
const p = point(10, 20);
|
|
17
|
-
p.distanceTo(point(30, 40)); // distance
|
|
18
|
-
p.midpointTo(point(30, 40)); // midpoint
|
|
19
|
-
p.translate(5, 5); // new point
|
|
20
|
-
p.toTuple(); // [10, 20]
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### `line(x1, y1, x2, y2)` / `Line2D`
|
|
24
|
-
A named 2D line segment.
|
|
25
|
-
|
|
26
|
-
```javascript
|
|
27
|
-
const l = line(0, 0, 50, 0);
|
|
28
|
-
l.length; // 50
|
|
29
|
-
l.midpoint; // Point2D
|
|
30
|
-
l.angle; // degrees
|
|
31
|
-
l.direction; // [1, 0]
|
|
32
|
-
l.parallel(10); // parallel line offset by 10
|
|
33
|
-
|
|
34
|
-
// Line-line intersection (infinite lines)
|
|
35
|
-
const l2 = line(25, -10, 25, 40);
|
|
36
|
-
l.intersect(l2); // Point2D(25, 0) — treats as infinite lines
|
|
37
|
-
l.intersectSegment(l2); // Point2D or null — only if segments actually cross
|
|
38
|
-
|
|
39
|
-
// Construction methods
|
|
40
|
-
Line2D.fromCoordinates(0, 0, 50, 0);
|
|
41
|
-
Line2D.fromPointAndAngle(point(0, 0), 45, 100);
|
|
42
|
-
Line2D.fromPointAndDirection(point(0, 0), [1, 1], 50);
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### `circle(cx, cy, radius)` / `Circle2D`
|
|
46
|
-
A named 2D circle.
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
const c = circle(0, 0, 25);
|
|
50
|
-
c.diameter; // 50
|
|
51
|
-
c.circumference; // ~157
|
|
52
|
-
c.area; // ~1963
|
|
53
|
-
c.pointAtAngle(90); // Point2D at top
|
|
54
|
-
|
|
55
|
-
// Extrude to cylinder with topology
|
|
56
|
-
const cyl = c.extrude(30);
|
|
57
|
-
cyl.face('top'); // FaceRef (planar)
|
|
58
|
-
cyl.face('side'); // FaceRef (curved, planar === false)
|
|
59
|
-
|
|
60
|
-
// Construction methods
|
|
61
|
-
Circle2D.fromCenterAndRadius(point(0, 0), 25);
|
|
62
|
-
Circle2D.fromDiameter(point(0, 0), 50);
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### `rectangle(x, y, w, h)` / `Rectangle2D`
|
|
66
|
-
A rectangle with named sides and vertices.
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
const r = rectangle(0, 0, 100, 60);
|
|
70
|
-
|
|
71
|
-
// Named sides
|
|
72
|
-
r.side('top'); // Line2D
|
|
73
|
-
r.side('bottom'); // Line2D
|
|
74
|
-
r.side('left'); // Line2D
|
|
75
|
-
r.side('right'); // Line2D
|
|
76
|
-
r.sideAt(0); // bottom (by index)
|
|
77
|
-
|
|
78
|
-
// Named vertices
|
|
79
|
-
r.vertex('top-left'); // Point2D
|
|
80
|
-
r.vertex('bottom-right'); // Point2D
|
|
81
|
-
|
|
82
|
-
// Properties
|
|
83
|
-
r.width; // 100
|
|
84
|
-
r.height; // 60
|
|
85
|
-
r.center; // Point2D
|
|
86
|
-
|
|
87
|
-
// Diagonals — returns [bl-tr, br-tl] as Line2D pair
|
|
88
|
-
const [d1, d2] = r.diagonals();
|
|
89
|
-
const center = d1.intersect(d2); // Point2D at center
|
|
90
|
-
|
|
91
|
-
// Convert to Sketch for rendering
|
|
92
|
-
r.toSketch();
|
|
93
|
-
|
|
94
|
-
// Extrude to 3D with topology tracking
|
|
95
|
-
const tracked = r.extrude(20); // TrackedShape
|
|
96
|
-
|
|
97
|
-
// Construction methods
|
|
98
|
-
Rectangle2D.fromDimensions(0, 0, 100, 60);
|
|
99
|
-
Rectangle2D.fromCenterAndDimensions(point(50, 30), 100, 60);
|
|
100
|
-
Rectangle2D.from2Corners(point(0, 0), point(100, 60));
|
|
101
|
-
Rectangle2D.from3Points(p1, p2, p3); // free-angle rectangle
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## 3D Topology (TrackedShape)
|
|
105
|
-
|
|
106
|
-
When you extrude a `Rectangle2D`, you get a `TrackedShape` that knows its faces and edges by name.
|
|
107
|
-
|
|
108
|
-
```javascript
|
|
109
|
-
const rect = Rectangle2D.fromCenterAndDimensions(point(0, 0), 100, 60);
|
|
110
|
-
const box = rect.extrude(20);
|
|
111
|
-
|
|
112
|
-
// Named faces
|
|
113
|
-
box.face('top'); // FaceRef { normal, center, planar, uAxis, vAxis }
|
|
114
|
-
box.face('bottom');
|
|
115
|
-
box.face('side-left');
|
|
116
|
-
box.face('side-right');
|
|
117
|
-
box.face('side-top'); // the side from rect's top edge
|
|
118
|
-
box.face('side-bottom'); // the side from rect's bottom edge
|
|
119
|
-
|
|
120
|
-
// Named edges
|
|
121
|
-
box.edge('top-left'); // EdgeRef { start, end } — top face, left side
|
|
122
|
-
box.edge('bottom-right'); // bottom face, right side
|
|
123
|
-
box.edge('vert-bl'); // vertical edge at bottom-left corner
|
|
124
|
-
|
|
125
|
-
// List all
|
|
126
|
-
box.faceNames(); // ['top', 'bottom', 'side-bottom', 'side-right', 'side-top', 'side-left']
|
|
127
|
-
box.edgeNames(); // all 12 edges
|
|
128
|
-
|
|
129
|
-
// Use the underlying Shape for booleans
|
|
130
|
-
const result = box.toShape().subtract(cylinder(25, 10));
|
|
131
|
-
|
|
132
|
-
// Translate preserves topology
|
|
133
|
-
const moved = box.translate(50, 0, 0);
|
|
134
|
-
moved.face('top').center; // shifted by [50, 0, 0]
|
|
135
|
-
|
|
136
|
-
// Duplicate preserves topology metadata too
|
|
137
|
-
const copy = box.clone();
|
|
138
|
-
copy.face('side-left');
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Constrained Sketches
|
|
142
|
-
|
|
143
|
-
Parametric 2D sketches driven by geometric constraints and a nonlinear solver. Create geometry, apply constraints, solve, then extrude to 3D.
|
|
144
|
-
|
|
145
|
-
### Basic workflow
|
|
146
|
-
|
|
147
|
-
```javascript
|
|
148
|
-
const sk = constrainedSketch();
|
|
149
|
-
|
|
150
|
-
// Create geometry
|
|
151
|
-
const p1 = sk.point(0, 0);
|
|
152
|
-
const p2 = sk.point(50, 0);
|
|
153
|
-
const p3 = sk.point(50, 30);
|
|
154
|
-
const l1 = sk.line(p1, p2);
|
|
155
|
-
const l2 = sk.line(p2, p3);
|
|
156
|
-
|
|
157
|
-
// Apply constraints (fluent — all return `this`)
|
|
158
|
-
sk.fix(p1, 0, 0);
|
|
159
|
-
sk.horizontal(l1);
|
|
160
|
-
sk.vertical(l2);
|
|
161
|
-
sk.length(l1, 50);
|
|
162
|
-
sk.length(l2, 30);
|
|
163
|
-
|
|
164
|
-
const result = sk.solve();
|
|
165
|
-
return result.extrude(10);
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Concepts — high-level shape factories
|
|
169
|
-
|
|
170
|
-
Instead of creating points and lines individually, use concept factories that create structurally-constrained shapes and return typed handles:
|
|
171
|
-
|
|
172
|
-
```javascript
|
|
173
|
-
const sk = constrainedSketch();
|
|
174
|
-
|
|
175
|
-
// Rectangle: 4 points, 4 sides, horizontal/vertical constraints, CCW winding
|
|
176
|
-
// Returns handle with .top, .bottom, .left, .right (LineIds),
|
|
177
|
-
// .bottomLeft, .topRight, etc. (PointIds), .center, .shape
|
|
178
|
-
const r = sk.rect({ x: 0, y: 0, width: 100, height: 50 });
|
|
179
|
-
sk.fix(r.bottomLeft, 0, 0);
|
|
180
|
-
sk.length(r.bottom, 120); // override initial width
|
|
181
|
-
|
|
182
|
-
// Regular polygon: n equal sides, CCW winding, center point
|
|
183
|
-
const hex = sk.regularPolygon({ sides: 6, radius: 25 });
|
|
184
|
-
sk.fix(hex.center, 0, 0);
|
|
185
|
-
sk.length(hex.side(0), 30); // all sides change (equal constraint)
|
|
186
|
-
|
|
187
|
-
// General polygon: n vertices from coordinates, CCW winding
|
|
188
|
-
const tri = sk.addPolygon({ points: [[0,0], [100,0], [50,80]] });
|
|
189
|
-
sk.fix(tri.vertex(0), 0, 0);
|
|
190
|
-
sk.length(tri.side(0), 100);
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Available constraints
|
|
194
|
-
|
|
195
|
-
**Geometric** (no value parameter):
|
|
196
|
-
`horizontal`, `vertical`, `parallel`, `perpendicular`, `equal`, `coincident`, `collinear`, `symmetric`, `midpoint`, `pointOnLine`, `pointOnCircle`, `tangent`, `concentric`, `equalRadius`, `ccw`
|
|
197
|
-
|
|
198
|
-
**Dimensional** (with `value`):
|
|
199
|
-
`length`, `distance`, `angle`, `absoluteAngle`, `angleBetween`, `radius`, `diameter`, `hDistance`, `vDistance`, `lineDistance`, `pointLineDistance`, `arcLength`, `shapeWidth`, `shapeHeight`, `shapeArea`, `shapeCentroidX`, `shapeCentroidY`
|
|
200
|
-
|
|
201
|
-
**Pinning:**
|
|
202
|
-
`fix(point, x?, y?)` — pins a point at coordinates (or current position if omitted)
|
|
203
|
-
|
|
204
|
-
### Construction geometry
|
|
205
|
-
|
|
206
|
-
Pass `true` as the third argument to `sk.line()` to create construction lines. These participate in constraints but don't appear in the solved sketch output.
|
|
207
|
-
|
|
208
|
-
```javascript
|
|
209
|
-
// Axis of symmetry (construction line)
|
|
210
|
-
const axis = sk.line(sk.point(0, -50), sk.point(0, 50), true);
|
|
211
|
-
sk.symmetric(p1, p2, axis); // p1 mirrors to p2 across axis
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### Path drawing (turtle-style)
|
|
215
|
-
|
|
216
|
-
```javascript
|
|
217
|
-
const sk = constrainedSketch();
|
|
218
|
-
sk.moveTo(0, 0)
|
|
219
|
-
.lineTo(50, 0)
|
|
220
|
-
.lineTo(50, 30)
|
|
221
|
-
.arcTo(25, 40, 15) // arc with radius 15
|
|
222
|
-
.lineTo(0, 30)
|
|
223
|
-
.close();
|
|
224
|
-
// Constraints can reference lines/points by index:
|
|
225
|
-
sk.length(sk.lineAt(0), 50);
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Solver results
|
|
229
|
-
|
|
230
|
-
```javascript
|
|
231
|
-
const result = sk.solve();
|
|
232
|
-
|
|
233
|
-
// Check solve quality
|
|
234
|
-
result.constraintMeta.status; // 'fully' | 'under' | 'over' | 'over-redundant'
|
|
235
|
-
result.constraintMeta.dof; // 0 = fully constrained
|
|
236
|
-
result.constraintMeta.maxError; // residual — should be < 1e-6
|
|
237
|
-
|
|
238
|
-
// Diagnostics
|
|
239
|
-
result.inspect(); // human-readable summary
|
|
240
|
-
|
|
241
|
-
// Update a dimension without rebuilding the sketch
|
|
242
|
-
const updated = result.withUpdatedConstraint('cst-5', 120);
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Importing external geometry
|
|
246
|
-
|
|
247
|
-
```javascript
|
|
248
|
-
const sk = constrainedSketch();
|
|
249
|
-
const r = rectangle(0, 0, 100, 60);
|
|
250
|
-
const sides = sk.importRectangle(r);
|
|
251
|
-
// sides.bottom, sides.right, sides.top, sides.left are LineIds
|
|
252
|
-
sk.length(sides.bottom, 100);
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Constraint methods also accept `Point2D`/`Line2D` directly — they auto-import:
|
|
256
|
-
|
|
257
|
-
```javascript
|
|
258
|
-
const sk = constrainedSketch();
|
|
259
|
-
const myLine = line(0, 0, 50, 0);
|
|
260
|
-
sk.horizontal(myLine); // auto-imported into the sketch
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Troubleshooting
|
|
264
|
-
|
|
265
|
-
**Constraint silently ignored?** All arguments are validated at call time. Passing a wrong entity type (e.g., a LineId where a PointId is expected) throws immediately with available entity IDs listed. Passing `NaN`/`Infinity` as a dimension value also throws.
|
|
266
|
-
|
|
267
|
-
**Under-constrained (dof > 0)?** The sketch has free degrees of freedom. Add `fix()`, `length()`, or other dimensional constraints. Check `result.constraintMeta.dof` for how many DOF remain.
|
|
268
|
-
|
|
269
|
-
**Over-constrained?** Conflicting constraints are auto-rejected. Check `result.constraintMeta.constraints` for conflict flags and `result.inspect()` for details.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
## Patterns
|
|
273
|
-
|
|
274
|
-
### `linearPattern(shape, count, dx, dy, dz?)`
|
|
275
|
-
Repeat a shape along a direction vector, returning the union.
|
|
276
|
-
|
|
277
|
-
```javascript
|
|
278
|
-
const bolt = cylinder(10, 3);
|
|
279
|
-
const row = linearPattern(bolt, 5, 20, 0); // 5 bolts, 20mm apart along X
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### `circularPattern(shape, count, centerX?, centerY?)`
|
|
283
|
-
Repeat a shape around the Z axis, returning the union.
|
|
284
|
-
|
|
285
|
-
```javascript
|
|
286
|
-
const hole = cylinder(12, 4).translate(30, 0, -1);
|
|
287
|
-
const holes = circularPattern(hole, 8); // 8 holes evenly spaced
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### `mirrorCopy(shape, normal)`
|
|
291
|
-
Mirror a shape and union with the original.
|
|
292
|
-
|
|
293
|
-
```javascript
|
|
294
|
-
const half = box(50, 30, 10);
|
|
295
|
-
const full = mirrorCopy(half, [1, 0, 0]); // Mirror across YZ plane
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
For compile-covered source shapes, repeated instances created by `linearPattern`, `circularPattern`, `Shape.mirror()`, and `mirrorCopy()` keep distinct compiler owner lineage. Supported boolean unions now preserve owner-scoped canonical face queries for those repeated descendants, so later compiler inspections can still trace which repeated instance a preserved face came from. Durable post-merge face identity is still narrower than full CAD-style topology naming: reusing the same owner lineage twice without a fresh mirror/pattern owner is reported as ambiguous, and downstream subtract/intersect rewrites still record split descendants explicitly instead of guessing.
|
|
299
|
-
|
|
300
|
-
## Utility Functions
|
|
301
|
-
|
|
302
|
-
### `degrees(deg)` / `radians(rad)`
|
|
303
|
-
Angle conversion helpers for readability:
|
|
304
|
-
|
|
305
|
-
```javascript
|
|
306
|
-
degrees(45); // 45 (identity — just for clarity)
|
|
307
|
-
radians(Math.PI / 4); // 45 (converts radians to degrees)
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
## Fillets & Chamfers
|
|
311
|
-
|
|
312
|
-
### `filletEdge(shape, edge, radius, quadrant?, segments?)`
|
|
313
|
-
Compiler-owned edge fillet for the current tracked-edge subset.
|
|
314
|
-
|
|
315
|
-
Supported today:
|
|
316
|
-
- tracked vertical edges from compile-covered `box()` bodies
|
|
317
|
-
- tracked vertical edges from `rectangle(...).extrude(...)`
|
|
318
|
-
- rigid transforms between the tracked source body and the target shape
|
|
319
|
-
- untouched sibling tracked vertical edges after earlier supported `filletEdge(...)` / `chamferEdge(...)` rewrites on the same body
|
|
320
|
-
- preserved propagated vertical-edge queries after those supported edge-finish rewrites when a later supported boolean union keeps one defended edge lineage
|
|
321
|
-
|
|
322
|
-
Still out of subset today:
|
|
323
|
-
- the selected edge after an earlier `filletEdge(...)` / `chamferEdge(...)` rewrite as a new single finish target, because Forge now records that path as an explicit descendant edge-chain rather than pretending it stayed one edge
|
|
324
|
-
- edge descendants after shell, hole/cut, trim, boolean difference/intersection, or boolean unions that did not already record one supported propagated edge lineage for the selection
|
|
325
|
-
- generic sketch extrudes, tapered extrudes, and arbitrary feature-created edges
|
|
326
|
-
|
|
327
|
-
Canonical quadrants for the supported rectangle/box edges:
|
|
328
|
-
- `vert-bl` -> `[1, -1]`
|
|
329
|
-
- `vert-br` -> `[-1, -1]`
|
|
330
|
-
- `vert-tr` -> `[-1, 1]`
|
|
331
|
-
- `vert-tl` -> `[1, 1]`
|
|
332
|
-
|
|
333
|
-
```javascript
|
|
334
|
-
const b = rectangle(0, 0, 50, 50).extrude(20);
|
|
335
|
-
const filleted = filletEdge(b.toShape(), b.edge('vert-br'), 5, [-1, -1]);
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### `chamferEdge(shape, edge, size, quadrant?)`
|
|
339
|
-
Compiler-owned edge chamfer for the same tracked vertical-edge subset as `filletEdge(...)`.
|
|
340
|
-
|
|
341
|
-
```javascript
|
|
342
|
-
const b = rectangle(0, 0, 50, 50).extrude(20);
|
|
343
|
-
const chamfered = chamferEdge(b.toShape(), b.edge('vert-br'), 3, [-1, -1]);
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
## Arc Bridge
|
|
347
|
-
|
|
348
|
-
### `arcBridgeBetweenRects(rectA, rectB, segments?)`
|
|
349
|
-
Build a smooth arc surface connecting two rectangular areas. Automatically finds the closest pair of parallel edges and bridges them with a semicircular arc.
|
|
350
|
-
|
|
351
|
-
**Parameters:**
|
|
352
|
-
- `rectA` — `Rectangle2D` or `{ corners: [[x,y,z], [x,y,z], [x,y,z], [x,y,z]] }`
|
|
353
|
-
- `rectB` — same format as rectA
|
|
354
|
-
- `segments` (number, optional) — Arc smoothness. Default: 12
|
|
355
|
-
|
|
356
|
-
**Returns:** `Shape` — thin arc solid
|
|
357
|
-
|
|
358
|
-
```javascript
|
|
359
|
-
// 2D rectangles (z=0)
|
|
360
|
-
const base = rectangle(0, 0, 300, 200);
|
|
361
|
-
const screen = rectangle(0, 200, 300, 200);
|
|
362
|
-
const hinge = arcBridgeBetweenRects(base, screen, 16);
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
```javascript
|
|
366
|
-
// 3D corners for non-planar rectangles
|
|
367
|
-
const hinge = arcBridgeBetweenRects(
|
|
368
|
-
{ corners: [[0,0,0], [300,0,0], [300,200,0], [0,200,0]] },
|
|
369
|
-
{ corners: [[0,200,15], [300,200,15], [300,400,15], [0,400,15]] },
|
|
370
|
-
16,
|
|
371
|
-
);
|
|
372
|
-
```
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
# Entity-Based API
|
|
2
|
-
|
|
3
|
-
Named geometric entities with stable identity, topology tracking, and constraint integration.
|
|
4
|
-
|
|
5
|
-
## 2D Entities
|
|
6
|
-
|
|
7
|
-
### `point(x, y)` / `new Point2D(x, y)`
|
|
8
|
-
A named 2D point.
|
|
9
|
-
|
|
10
|
-
```javascript
|
|
11
|
-
const p = point(10, 20);
|
|
12
|
-
p.distanceTo(point(30, 40)); // distance
|
|
13
|
-
p.midpointTo(point(30, 40)); // midpoint
|
|
14
|
-
p.translate(5, 5); // new point
|
|
15
|
-
p.toTuple(); // [10, 20]
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### `line(x1, y1, x2, y2)` / `Line2D`
|
|
19
|
-
A named 2D line segment.
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
const l = line(0, 0, 50, 0);
|
|
23
|
-
l.length; // 50
|
|
24
|
-
l.midpoint; // Point2D
|
|
25
|
-
l.angle; // degrees
|
|
26
|
-
l.direction; // [1, 0]
|
|
27
|
-
l.parallel(10); // parallel line offset by 10
|
|
28
|
-
|
|
29
|
-
// Line-line intersection (infinite lines)
|
|
30
|
-
const l2 = line(25, -10, 25, 40);
|
|
31
|
-
l.intersect(l2); // Point2D(25, 0) — treats as infinite lines
|
|
32
|
-
l.intersectSegment(l2); // Point2D or null — only if segments actually cross
|
|
33
|
-
|
|
34
|
-
// Construction methods
|
|
35
|
-
Line2D.fromCoordinates(0, 0, 50, 0);
|
|
36
|
-
Line2D.fromPointAndAngle(point(0, 0), 45, 100);
|
|
37
|
-
Line2D.fromPointAndDirection(point(0, 0), [1, 1], 50);
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### `circle(cx, cy, radius)` / `Circle2D`
|
|
41
|
-
A named 2D circle.
|
|
42
|
-
|
|
43
|
-
```javascript
|
|
44
|
-
const c = circle(0, 0, 25);
|
|
45
|
-
c.diameter; // 50
|
|
46
|
-
c.circumference; // ~157
|
|
47
|
-
c.area; // ~1963
|
|
48
|
-
c.pointAtAngle(90); // Point2D at top
|
|
49
|
-
|
|
50
|
-
// Extrude to cylinder with topology
|
|
51
|
-
const cyl = c.extrude(30);
|
|
52
|
-
cyl.face('top'); // FaceRef
|
|
53
|
-
cyl.face('side'); // FaceRef
|
|
54
|
-
|
|
55
|
-
// Construction methods
|
|
56
|
-
Circle2D.fromCenterAndRadius(point(0, 0), 25);
|
|
57
|
-
Circle2D.fromDiameter(point(0, 0), 50);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### `rectangle(x, y, w, h)` / `Rectangle2D`
|
|
61
|
-
A rectangle with named sides and vertices.
|
|
62
|
-
|
|
63
|
-
```javascript
|
|
64
|
-
const r = rectangle(0, 0, 100, 60);
|
|
65
|
-
|
|
66
|
-
// Named sides
|
|
67
|
-
r.side('top'); // Line2D
|
|
68
|
-
r.side('bottom'); // Line2D
|
|
69
|
-
r.side('left'); // Line2D
|
|
70
|
-
r.side('right'); // Line2D
|
|
71
|
-
r.sideAt(0); // bottom (by index)
|
|
72
|
-
|
|
73
|
-
// Named vertices
|
|
74
|
-
r.vertex('top-left'); // Point2D
|
|
75
|
-
r.vertex('bottom-right'); // Point2D
|
|
76
|
-
|
|
77
|
-
// Properties
|
|
78
|
-
r.width; // 100
|
|
79
|
-
r.height; // 60
|
|
80
|
-
r.center; // Point2D
|
|
81
|
-
|
|
82
|
-
// Diagonals — returns [bl-tr, br-tl] as Line2D pair
|
|
83
|
-
const [d1, d2] = r.diagonals();
|
|
84
|
-
const center = d1.intersect(d2); // Point2D at center
|
|
85
|
-
|
|
86
|
-
// Convert to Sketch for rendering
|
|
87
|
-
r.toSketch();
|
|
88
|
-
|
|
89
|
-
// Extrude to 3D with topology tracking
|
|
90
|
-
const tracked = r.extrude(20); // TrackedShape
|
|
91
|
-
|
|
92
|
-
// Construction methods
|
|
93
|
-
Rectangle2D.fromDimensions(0, 0, 100, 60);
|
|
94
|
-
Rectangle2D.fromCenterAndDimensions(point(50, 30), 100, 60);
|
|
95
|
-
Rectangle2D.from2Corners(point(0, 0), point(100, 60));
|
|
96
|
-
Rectangle2D.from3Points(p1, p2, p3); // free-angle rectangle
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## 3D Topology (TrackedShape)
|
|
100
|
-
|
|
101
|
-
When you extrude a `Rectangle2D`, you get a `TrackedShape` that knows its faces and edges by name.
|
|
102
|
-
|
|
103
|
-
```javascript
|
|
104
|
-
const rect = Rectangle2D.fromCenterAndDimensions(point(0, 0), 100, 60);
|
|
105
|
-
const box = rect.extrude(20);
|
|
106
|
-
|
|
107
|
-
// Named faces
|
|
108
|
-
box.face('top'); // FaceRef { normal, center }
|
|
109
|
-
box.face('bottom');
|
|
110
|
-
box.face('side-left');
|
|
111
|
-
box.face('side-right');
|
|
112
|
-
box.face('side-top'); // the side from rect's top edge
|
|
113
|
-
box.face('side-bottom'); // the side from rect's bottom edge
|
|
114
|
-
box.face('front'); // alias for side-bottom
|
|
115
|
-
box.face('back'); // alias for side-top
|
|
116
|
-
|
|
117
|
-
// Named edges
|
|
118
|
-
box.edge('top-left'); // EdgeRef { start, end } — top face, left side
|
|
119
|
-
box.edge('bottom-right'); // bottom face, right side
|
|
120
|
-
box.edge('vert-bl'); // vertical edge at bottom-left corner
|
|
121
|
-
box.edge('top-front'); // alias for top-bottom
|
|
122
|
-
|
|
123
|
-
// List all
|
|
124
|
-
box.faceNames(); // ['top', 'bottom', 'side-bottom', 'side-right', 'side-top', 'side-left']
|
|
125
|
-
box.edgeNames(); // canonical names
|
|
126
|
-
box.edgeNames({ includeAliases: true }); // includes aliases
|
|
127
|
-
|
|
128
|
-
// Use the underlying Shape for booleans
|
|
129
|
-
const result = box.toShape().subtract(cylinder(25, 10));
|
|
130
|
-
|
|
131
|
-
// Topology is preserved through transforms
|
|
132
|
-
const moved = box.translate(50, 0, 0);
|
|
133
|
-
moved.face('top').center; // shifted by [50, 0, 0]
|
|
134
|
-
const turned = box.rotate(0, 0, 45);
|
|
135
|
-
turned.edge('vert-bl');
|
|
136
|
-
|
|
137
|
-
// Duplicate preserves topology metadata too
|
|
138
|
-
const copy = box.clone();
|
|
139
|
-
copy.face('side-left');
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Constraint Helpers
|
|
143
|
-
|
|
144
|
-
```javascript
|
|
145
|
-
const sketch = constrainedSketch();
|
|
146
|
-
const p1 = sketch.point(0, 0, true);
|
|
147
|
-
const p2 = sketch.point(50, 0);
|
|
148
|
-
const p3 = sketch.point(50, 30);
|
|
149
|
-
const l1 = sketch.line(p1, p2);
|
|
150
|
-
const l2 = sketch.line(p2, p3);
|
|
151
|
-
|
|
152
|
-
Constraint.horizontal(sketch, l1);
|
|
153
|
-
Constraint.vertical(sketch, l2);
|
|
154
|
-
Constraint.length(sketch, l1, 50);
|
|
155
|
-
Constraint.perpendicular(sketch, l1, l2);
|
|
156
|
-
|
|
157
|
-
const result = sketch.close().solve();
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Entity-aware constraints
|
|
161
|
-
|
|
162
|
-
Constraint functions accept `Point2D`/`Line2D` directly — they auto-import into the builder:
|
|
163
|
-
|
|
164
|
-
```javascript
|
|
165
|
-
const sketch = constrainedSketch();
|
|
166
|
-
const myLine = line(0, 0, 50, 0);
|
|
167
|
-
const myRect = rectangle(10, 10, 40, 30);
|
|
168
|
-
|
|
169
|
-
// Pass Line2D directly — auto-imported
|
|
170
|
-
Constraint.makeParallel(sketch, myLine, myRect.side('top'));
|
|
171
|
-
Constraint.horizontal(sketch, myLine);
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Importing entities into a constrained sketch
|
|
175
|
-
|
|
176
|
-
```javascript
|
|
177
|
-
const sketch = constrainedSketch();
|
|
178
|
-
const r = rectangle(0, 0, 100, 60);
|
|
179
|
-
const sides = sketch.importRectangle(r);
|
|
180
|
-
// sides.bottom, sides.right, sides.top, sides.left are LineIds
|
|
181
|
-
// sides.points is [bl, br, tr, tl] PointIds
|
|
182
|
-
|
|
183
|
-
Constraint.horizontal(sketch, sides.bottom);
|
|
184
|
-
Constraint.length(sketch, sides.bottom, 100);
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
## Patterns
|
|
189
|
-
|
|
190
|
-
### `linearPattern(shape, count, dx, dy, dz?)`
|
|
191
|
-
Repeat a shape along a direction vector, returning the union.
|
|
192
|
-
|
|
193
|
-
```javascript
|
|
194
|
-
const bolt = cylinder(10, 3);
|
|
195
|
-
const row = linearPattern(bolt, 5, 20, 0); // 5 bolts, 20mm apart along X
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### `circularPattern(shape, count, centerX?, centerY?)`
|
|
199
|
-
Repeat a shape around the Z axis, returning the union.
|
|
200
|
-
|
|
201
|
-
```javascript
|
|
202
|
-
const hole = cylinder(12, 4).translate(30, 0, -1);
|
|
203
|
-
const holes = circularPattern(hole, 8); // 8 holes evenly spaced
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### `mirrorCopy(shape, normal)`
|
|
207
|
-
Mirror a shape and union with the original.
|
|
208
|
-
|
|
209
|
-
```javascript
|
|
210
|
-
const half = box(50, 30, 10);
|
|
211
|
-
const full = mirrorCopy(half, [1, 0, 0]); // Mirror across YZ plane
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Utility Functions
|
|
215
|
-
|
|
216
|
-
### `degrees(deg)` / `radians(rad)`
|
|
217
|
-
Angle conversion helpers for readability:
|
|
218
|
-
|
|
219
|
-
```javascript
|
|
220
|
-
degrees(45); // 45 (identity — just for clarity)
|
|
221
|
-
radians(Math.PI / 4); // 45 (converts radians to degrees)
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Fillets & Chamfers
|
|
225
|
-
|
|
226
|
-
### `filletEdge(shape, edge, radius, quadrant?, segments?)`
|
|
227
|
-
Fillet a vertical edge (subtract corner, add quarter-cylinder).
|
|
228
|
-
|
|
229
|
-
```javascript
|
|
230
|
-
const b = rectangle(0, 0, 50, 50).extrude(20);
|
|
231
|
-
const filleted = filletEdge(b, b.edge('vert-br'), 5, [-1, -1]);
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### `chamferEdge(shape, edge, size, quadrant?)`
|
|
235
|
-
Chamfer a vertical edge (subtract triangular prism).
|
|
236
|
-
|
|
237
|
-
```javascript
|
|
238
|
-
const b = rectangle(0, 0, 50, 50).extrude(20);
|
|
239
|
-
const chamfered = chamferEdge(b, b.edge('vert-br'), 3, [-1, -1]);
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## Arc Bridge
|
|
243
|
-
|
|
244
|
-
### `arcBridgeBetweenRects(rectA, rectB, segments?)`
|
|
245
|
-
Build a smooth arc surface connecting two rectangular areas. Automatically finds the closest pair of parallel edges and bridges them with a semicircular arc.
|
|
246
|
-
|
|
247
|
-
**Parameters:**
|
|
248
|
-
- `rectA` — `Rectangle2D` or `{ corners: [[x,y,z], [x,y,z], [x,y,z], [x,y,z]] }`
|
|
249
|
-
- `rectB` — same format as rectA
|
|
250
|
-
- `segments` (number, optional) — Arc smoothness. Default: 12
|
|
251
|
-
|
|
252
|
-
**Returns:** `Shape` — thin arc solid
|
|
253
|
-
|
|
254
|
-
```javascript
|
|
255
|
-
// 2D rectangles (z=0)
|
|
256
|
-
const base = rectangle(0, 0, 300, 200);
|
|
257
|
-
const screen = rectangle(0, 200, 300, 200);
|
|
258
|
-
const hinge = arcBridgeBetweenRects(base, screen, 16);
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
```javascript
|
|
262
|
-
// 3D corners for non-planar rectangles
|
|
263
|
-
const hinge = arcBridgeBetweenRects(
|
|
264
|
-
{ corners: [[0,0,0], [300,0,0], [300,200,0], [0,200,0]] },
|
|
265
|
-
{ corners: [[0,200,15], [300,200,15], [300,400,15], [0,400,15]] },
|
|
266
|
-
16,
|
|
267
|
-
);
|
|
268
|
-
```
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: output
|
|
3
|
-
skill-order: 3
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bill of Materials
|
|
7
|
-
|
|
8
|
-
These APIs annotate a model for report/export workflows. They do not change geometry, so they are outside the required model-building reading set.
|
|
9
|
-
|
|
10
|
-
## `bom(quantity, description, opts?)`
|
|
11
|
-
|
|
12
|
-
Register a bill-of-materials entry for report export.
|
|
13
|
-
|
|
14
|
-
Use this for real-world parts or materials that cannot be inferred reliably from geometry alone.
|
|
15
|
-
|
|
16
|
-
**Parameters:**
|
|
17
|
-
- `quantity` (number) - must be finite and `>= 0`; `0` is ignored
|
|
18
|
-
- `description` (string) - human-readable item description
|
|
19
|
-
- `opts` (object, optional):
|
|
20
|
-
- `unit` (string) - default `"pieces"`
|
|
21
|
-
- `key` (string) - explicit aggregation key when multiple descriptions should collapse to one line item
|
|
22
|
-
|
|
23
|
-
**Returns:** `void`
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
const tubeLen = param("Tube Length", 1200, { min: 300, max: 4000, unit: "mm" });
|
|
27
|
-
const boltCount = param("Bolt Count", 16, { min: 0, max: 200, integer: true });
|
|
28
|
-
const boltLength = param("Bolt Length", 16, { min: 6, max: 80, unit: "mm" });
|
|
29
|
-
|
|
30
|
-
bom(tubeLen, "iron tube 30 x 20", { unit: "mm" });
|
|
31
|
-
bom(boltCount, `M4 bolt of ${boltLength} mm length`, { unit: "pieces" });
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Aggregation behavior:
|
|
35
|
-
- rows are grouped by normalized `description + unit`
|
|
36
|
-
- `key` overrides the default grouping rule
|
|
37
|
-
- grouped rows render on the report's Bill of Materials page
|
|
38
|
-
|
|
39
|
-
## Assembly BOM Helpers
|
|
40
|
-
|
|
41
|
-
Assembly graphs can also carry metadata for downstream reporting:
|
|
42
|
-
|
|
43
|
-
- `addPart(name, shape, { metadata? })`
|
|
44
|
-
- `solved.bom()`
|
|
45
|
-
- `solved.bomCsv()`
|
|
46
|
-
- `bomToCsv(rows)`
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
const mech = assembly("Arm")
|
|
50
|
-
.addPart("base", box(80, 80, 20, true), {
|
|
51
|
-
metadata: { material: "PETG", process: "FDM", qty: 1 },
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const solved = mech.solve();
|
|
55
|
-
const csv = solved.bomCsv();
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
See `examples/api/bill-of-materials.forge.js` for a complete script-authored BOM example.
|