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.
Files changed (193) hide show
  1. package/README.md +2 -11
  2. package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-DAu1C1ST.js} +250 -151
  3. package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
  4. package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-Gc_BCdqC.js} +269 -143
  5. package/dist/assets/EditorApp-D9bJvtf7.js +11338 -0
  6. package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-DG1-oUSV.css} +459 -87
  7. package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-CEO8XbV8.js} +2 -4
  8. package/dist/assets/LandingPage-CdCuEOdC.js +451 -0
  9. package/dist/assets/PricingPage-BSrxu6d7.js +232 -0
  10. package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-FUCSIRq6.js} +129 -5
  11. package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-KoR0SNKq.js} +6770 -2914
  12. package/dist/assets/{index-2hfs_ub0.css → index-CyVd1D4D.css} +227 -53
  13. package/dist/assets/{Viewport-CoB46f5R.js → index-wTEK39at.js} +31385 -6439
  14. package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
  15. package/dist/assets/{manifold-CqNMHHKO.js → manifold-B1sGWdYk.js} +4 -3
  16. package/dist/assets/{manifold-Cce9wRFz.js → manifold-D7o0N50J.js} +1 -1
  17. package/dist/assets/{manifold-D6BeHIOo.js → manifold-G5sBaXzi.js} +1 -1
  18. package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-DYcRHhv9.js} +6798 -3341
  19. package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
  20. package/dist/docs-raw/generated/assembly.md +691 -112
  21. package/dist/docs-raw/generated/concepts.md +1225 -1400
  22. package/dist/docs-raw/generated/core.md +464 -1412
  23. package/dist/docs-raw/generated/curves.md +593 -117
  24. package/dist/docs-raw/generated/lib.md +38 -748
  25. package/dist/docs-raw/generated/output.md +139 -245
  26. package/dist/docs-raw/generated/sheet-metal.md +473 -21
  27. package/dist/docs-raw/generated/sketch.md +553 -349
  28. package/dist/docs-raw/generated/viewport.md +345 -303
  29. package/dist/docs-raw/generated/wood.md +104 -0
  30. package/dist/index.html +2 -2
  31. package/dist/sitemap.xml +6 -6
  32. package/dist-cli/chunk-PZ5AY32C.js +10 -0
  33. package/dist-cli/chunk-PZ5AY32C.js.map +1 -0
  34. package/dist-cli/forgecad.js +9435 -5407
  35. package/dist-cli/forgecad.js.map +1 -0
  36. package/dist-cli/solver-FV7TJZGI.js +365 -0
  37. package/dist-cli/solver-FV7TJZGI.js.map +1 -0
  38. package/dist-skill/CONTEXT.md +3186 -7145
  39. package/dist-skill/SKILL-dev.md +21 -63
  40. package/dist-skill/SKILL.md +12 -56
  41. package/dist-skill/docs/API/core/concepts.md +16 -98
  42. package/dist-skill/docs/CLI/export.md +91 -0
  43. package/dist-skill/docs/CLI/projects.md +107 -0
  44. package/dist-skill/docs/CLI/studio_publishing.md +52 -0
  45. package/dist-skill/docs/CLI/validation.md +66 -0
  46. package/dist-skill/docs/generated/assembly.md +691 -112
  47. package/dist-skill/docs/generated/core.md +464 -1412
  48. package/dist-skill/docs/generated/curves.md +593 -117
  49. package/dist-skill/docs/generated/lib.md +38 -748
  50. package/dist-skill/docs/generated/output.md +139 -245
  51. package/dist-skill/docs/generated/sheet-metal.md +473 -21
  52. package/dist-skill/docs/generated/sketch.md +553 -349
  53. package/dist-skill/docs/generated/viewport.md +345 -303
  54. package/dist-skill/docs/generated/wood.md +104 -0
  55. package/dist-skill/docs/guides/coordinate-system.md +11 -17
  56. package/dist-skill/docs/guides/geometry-conventions.md +13 -70
  57. package/dist-skill/docs/guides/modeling-recipes.md +22 -195
  58. package/dist-skill/docs/guides/positioning.md +88 -147
  59. package/dist-skill/docs-dev/API/core/concepts.md +51 -0
  60. package/dist-skill/docs-dev/API/core/sdf-advanced.md +92 -0
  61. package/dist-skill/docs-dev/API/core/sdf-primitives.md +58 -0
  62. package/dist-skill/docs-dev/API/core/sdf-workflow.md +42 -0
  63. package/dist-skill/docs-dev/CLI/export.md +91 -0
  64. package/dist-skill/docs-dev/CLI/projects.md +107 -0
  65. package/dist-skill/docs-dev/CLI/studio_publishing.md +52 -0
  66. package/dist-skill/docs-dev/CLI/validation.md +66 -0
  67. package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
  68. package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
  69. package/dist-skill/{docs → docs-dev}/coding.md +1 -3
  70. package/dist-skill/docs-dev/generated/assembly.md +771 -0
  71. package/dist-skill/docs-dev/generated/core.md +775 -0
  72. package/dist-skill/docs-dev/generated/curves.md +688 -0
  73. package/dist-skill/docs-dev/generated/lib.md +50 -0
  74. package/dist-skill/docs-dev/generated/output.md +234 -0
  75. package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
  76. package/dist-skill/docs-dev/generated/sketch.md +801 -0
  77. package/dist-skill/docs-dev/generated/viewport.md +486 -0
  78. package/dist-skill/docs-dev/generated/wood.md +104 -0
  79. package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
  80. package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
  81. package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
  82. package/dist-skill/docs-dev/guides/positioning.md +151 -0
  83. package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
  84. package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
  85. package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
  86. package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
  87. package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
  88. package/examples/api/attachTo-basics.forge.js +5 -5
  89. package/examples/api/boolean-operations.forge.js +3 -3
  90. package/examples/api/bounding-box-visualizer.forge.js +2 -2
  91. package/examples/api/clone-duplicate.forge.js +1 -1
  92. package/examples/api/colors-union-vs-array.forge.js +6 -6
  93. package/examples/api/connector-assembly.forge.js +4 -4
  94. package/examples/api/connector-basics.forge.js +2 -2
  95. package/examples/api/extrude-options.forge.js +4 -10
  96. package/examples/api/feature-created-faces.forge.js +6 -10
  97. package/examples/api/fillet-showcase.forge.js +1 -1
  98. package/examples/api/folded-service-panel-cover.forge.js +2 -2
  99. package/examples/api/group-test.forge.js +1 -1
  100. package/examples/api/group-vs-union.forge.js +1 -1
  101. package/examples/api/highlight-debug.forge.js +4 -0
  102. package/examples/api/js-module-pillars.js +1 -1
  103. package/examples/api/js-module-scene.js +2 -2
  104. package/examples/api/mesh-import-slats.forge.js +1 -1
  105. package/examples/api/pointAlong-orientation.forge.js +1 -1
  106. package/examples/api/profile-2020-b-slot6.forge.js +0 -1
  107. package/examples/api/route-perimeter-flange.forge.js +1 -1
  108. package/examples/api/sdf-rover-demo.forge.js +10 -10
  109. package/examples/api/sketch-on-face-demo.forge.js +2 -2
  110. package/examples/api/sketch-regions.forge.js +4 -4
  111. package/examples/api/transition-curves.forge.js +1 -1
  112. package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
  113. package/examples/api/variable-sweep-test.forge.js +2 -2
  114. package/examples/api/wood-joinery.forge.js +60 -0
  115. package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
  116. package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
  117. package/examples/experiments/drone-arm.forge.js +53 -0
  118. package/examples/furniture/adjustable-table.forge.js +2 -2
  119. package/examples/furniture/bathroom.forge.js +11 -11
  120. package/examples/furniture/chair.forge.js +1 -1
  121. package/examples/generative/crystal-growth.forge.js +2 -2
  122. package/examples/generative/frost-spires.forge.js +3 -3
  123. package/examples/generative/golden-spiral-tower.forge.js +3 -3
  124. package/examples/mechanical/3d-printer.forge.js +28 -28
  125. package/examples/mechanical/5-finger-robot-hand.forge.js +15 -15
  126. package/examples/mechanical/airplane-propeller.forge.js +2 -2
  127. package/examples/mechanical/fillet-enclosure.forge.js +1 -1
  128. package/examples/mechanical/headphone-hanger-v2.forge.js +2 -2
  129. package/examples/mechanical/robot_hand.forge.js +15 -15
  130. package/examples/mechanical/robot_hand_2.forge.js +9 -9
  131. package/examples/products/bottle.forge.js +1 -1
  132. package/examples/products/chess-set.forge.js +19 -19
  133. package/examples/products/classical-piano.forge.js +11 -11
  134. package/examples/products/clock.forge.js +12 -12
  135. package/examples/products/iphone.forge.js +8 -8
  136. package/examples/products/laptop.forge.js +15 -15
  137. package/examples/products/liquid-soap-dispenser.forge.js +18 -18
  138. package/examples/products/origami-fish.forge.js +8 -6
  139. package/examples/products/spiderman-cake.forge.js +4 -4
  140. package/examples/toolbox/bolted-joint.forge.js +2 -2
  141. package/package.json +7 -4
  142. package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
  143. package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
  144. package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
  145. package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
  146. package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
  147. package/dist/assets/index-1CYp3zUp.js +0 -1455
  148. package/dist/docs-raw/CLI.md +0 -865
  149. package/dist-skill/docs/API/API.md +0 -1666
  150. package/dist-skill/docs/API/README.md +0 -37
  151. package/dist-skill/docs/API/assembly/assembly.md +0 -617
  152. package/dist-skill/docs/API/core/edge-queries.md +0 -130
  153. package/dist-skill/docs/API/core/parameters.md +0 -122
  154. package/dist-skill/docs/API/core/reserved-terms.md +0 -137
  155. package/dist-skill/docs/API/core/sdf.md +0 -326
  156. package/dist-skill/docs/API/core/skill-cli.md +0 -194
  157. package/dist-skill/docs/API/core/skill-guide.md +0 -205
  158. package/dist-skill/docs/API/core/specs.md +0 -186
  159. package/dist-skill/docs/API/core/topology.md +0 -372
  160. package/dist-skill/docs/API/entities.md +0 -268
  161. package/dist-skill/docs/API/output/bom.md +0 -58
  162. package/dist-skill/docs/API/output/brep-export.md +0 -87
  163. package/dist-skill/docs/API/output/dimensions.md +0 -67
  164. package/dist-skill/docs/API/output/export.md +0 -110
  165. package/dist-skill/docs/API/output/gcode.md +0 -195
  166. package/dist-skill/docs/API/runtime/viewport.md +0 -420
  167. package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
  168. package/dist-skill/docs/API/sketch/anchor.md +0 -37
  169. package/dist-skill/docs/API/sketch/booleans.md +0 -91
  170. package/dist-skill/docs/API/sketch/core.md +0 -73
  171. package/dist-skill/docs/API/sketch/extrude.md +0 -62
  172. package/dist-skill/docs/API/sketch/on-face.md +0 -104
  173. package/dist-skill/docs/API/sketch/operations.md +0 -78
  174. package/dist-skill/docs/API/sketch/path.md +0 -75
  175. package/dist-skill/docs/API/sketch/primitives.md +0 -146
  176. package/dist-skill/docs/API/sketch/regions.md +0 -80
  177. package/dist-skill/docs/API/sketch/text.md +0 -108
  178. package/dist-skill/docs/API/sketch/transforms.md +0 -65
  179. package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
  180. package/dist-skill/docs/CLI.md +0 -865
  181. package/dist-skill/docs/INDEX.md +0 -94
  182. package/dist-skill/docs/RELEASING.md +0 -55
  183. package/dist-skill/docs/cli-monetization.md +0 -111
  184. package/dist-skill/docs/deployment.md +0 -281
  185. package/dist-skill/docs/generated/concepts.md +0 -2112
  186. package/dist-skill/docs/internals/shape-from-slices.md +0 -152
  187. package/dist-skill/docs/platform/admin.md +0 -45
  188. package/dist-skill/docs/platform/architecture.md +0 -79
  189. package/dist-skill/docs/platform/auth.md +0 -110
  190. package/dist-skill/docs/platform/email.md +0 -67
  191. package/dist-skill/docs/platform/projects.md +0 -111
  192. package/dist-skill/docs/platform/sharing.md +0 -90
  193. 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.