forgecad 0.9.13 → 0.9.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-DramHHDf.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-Bjgkh5m9.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-n_HGP3Qm.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-WCIkPmzC.js → DocsPage-B954L3YN.js} +9 -3
  7. package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
  8. package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
  9. package/dist/assets/{EmbedViewer-DEZKqdfW.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-CeRIctuj.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
  11. package/dist/assets/LegalPage-BRlScr9A.css +91 -0
  12. package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
  13. package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
  14. package/dist/assets/{PricingPage-rIRa8p4Y.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-BqCUvEXM.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-BUZqJvSO.js → app-D3kDkggg.js} +2305 -960
  18. package/dist/assets/cli/{render-lhGxj50Y.js → render-DSY3mMQa.js} +423 -30
  19. package/dist/assets/{constructionHistoryWorker-ipD1jcIv.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CHXSe_-u.js → evalWorker-CU0Ke6DP.js} +7799 -4163
  21. package/dist/assets/{forgecad_geometry-BVnIeXMG.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/{forgecad_geometry_bg-DufhhCBV.wasm → forgecad_geometry_bg-dD4RNQF1.wasm} +0 -0
  23. package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
  24. package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
  25. package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
  26. package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
  27. package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
  28. package/dist/assets/{manifold-D1LZIHqn.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-C2fwoTgd.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-BTkzxi9V.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-Cq1qGmg0.js → reportWorker-CdBz5bNg.js} +7537 -10856
  32. package/dist/assets/{scalar-sampling-budget-D9Qv_UlJ.js → scalar-sampling-budget-wJF98aY9.js} +6943 -4345
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{renderSceneState-Dr0xPq1A.js → targets-B9sGB5nB.js} +27 -1
  35. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  36. package/dist/cli/render.html +1 -1
  37. package/dist/docs/index.html +2 -2
  38. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  39. package/dist/docs-raw/AI/usage.md +9 -17
  40. package/dist/docs-raw/CLI.md +71 -21
  41. package/dist/docs-raw/component-model.md +27 -11
  42. package/dist/docs-raw/generated/assembly.md +301 -212
  43. package/dist/docs-raw/generated/concepts.md +238 -240
  44. package/dist/docs-raw/generated/core.md +283 -6
  45. package/dist/docs-raw/generated/curves.md +274 -361
  46. package/dist/docs-raw/generated/lib.md +7 -1
  47. package/dist/docs-raw/generated/output.md +19 -4
  48. package/dist/docs-raw/generated/runtime-names.md +41 -0
  49. package/dist/docs-raw/generated/sdf.md +31 -0
  50. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  51. package/dist/docs-raw/generated/sketch.md +44 -1
  52. package/dist/docs-raw/generated/viewport.md +14 -6
  53. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  54. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  55. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  56. package/dist/docs-raw/guides/joint-design.md +24 -0
  57. package/dist/docs-raw/guides/positioning.md +13 -3
  58. package/dist/docs-raw/legal/privacy.md +63 -0
  59. package/dist/docs-raw/legal/software-license.md +55 -0
  60. package/dist/docs-raw/legal/terms.md +87 -0
  61. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +3 -3
  62. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  63. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  64. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  66. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-make-a-model.md +4 -4
  68. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  69. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  70. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  71. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +4 -4
  72. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  73. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  74. package/dist/docs-raw/skills/forgecad.md +4 -3
  75. package/dist/index.html +40 -12
  76. package/dist/llms.txt +8 -0
  77. package/dist/site.webmanifest +1 -1
  78. package/dist/sitemap.xml +49 -13
  79. package/dist-cli/{check-compiler-LOXCPEOI.js → check-compiler-SDX5QIXI.js} +1 -2
  80. package/dist-cli/{check-query-propagation-BAKNVWXR.js → check-query-propagation-EAYEFT77.js} +1 -2
  81. package/dist-cli/{chunk-RY43WF46.js → chunk-N4O47JLF.js} +13772 -9938
  82. package/dist-cli/forgecad.js +2387 -899
  83. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  84. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  85. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  86. package/dist-skill/CONTEXT.md +1120 -724
  87. package/dist-skill/SKILL.md +3 -2
  88. package/dist-skill/docs/API/core/concepts.md +64 -1
  89. package/dist-skill/docs/CLI.md +71 -21
  90. package/dist-skill/docs/generated/assembly.md +277 -229
  91. package/dist-skill/docs/generated/core.md +283 -6
  92. package/dist-skill/docs/generated/curves.md +272 -362
  93. package/dist-skill/docs/generated/lib.md +7 -1
  94. package/dist-skill/docs/generated/output.md +19 -4
  95. package/dist-skill/docs/generated/runtime-names.md +41 -0
  96. package/dist-skill/docs/generated/sdf.md +31 -0
  97. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  98. package/dist-skill/docs/generated/sketch.md +44 -2
  99. package/dist-skill/docs/generated/viewport.md +5 -90
  100. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  101. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  102. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  103. package/dist-skill/docs/guides/joint-design.md +24 -0
  104. package/dist-skill/docs/guides/positioning.md +13 -3
  105. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +2 -2
  106. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  107. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  108. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  109. package/dist-skill/library/forgecad-make-a-model/SKILL.md +3 -3
  110. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  111. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +3 -3
  113. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  114. package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
  115. package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
  116. package/examples/api/assembly-kinematics-limb.forge.js +116 -0
  117. package/examples/api/connector-frame-rig-chain.forge.js +102 -0
  118. package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
  119. package/examples/api/exact-surface-studio.forge.js +6 -8
  120. package/examples/api/helix-basics.forge.js +6 -6
  121. package/examples/api/lean-foundations/README.md +12 -0
  122. package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
  123. package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
  124. package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
  125. package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
  126. package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
  127. package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
  128. package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
  129. package/examples/api/route3d-elbow.forge.js +68 -0
  130. package/examples/api/transition-curves.forge.js +44 -15
  131. package/examples/api/y-blend-corner-showcase.forge.js +0 -2
  132. package/examples/generative/coral-vase.forge.js +1 -1
  133. package/examples/nurbs-tube.forge.js +1 -1
  134. package/package.json +14 -18
  135. package/dist/assets/EditorApp-CP9Za6tm.js +0 -13630
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/docs-raw/API/README.md +0 -16
  138. package/dist/docs-raw/API/core/concepts.md +0 -118
  139. package/dist/docs-raw/INDEX.md +0 -138
  140. package/dist/docs-raw/RELEASING.md +0 -87
  141. package/dist/docs-raw/agent-native-api.md +0 -27
  142. package/dist/docs-raw/beta-deployment.md +0 -304
  143. package/dist/docs-raw/beta-operations.md +0 -325
  144. package/dist/docs-raw/blueprint-first.md +0 -145
  145. package/dist/docs-raw/cli-monetization.md +0 -112
  146. package/dist/docs-raw/coding-best-practices.md +0 -120
  147. package/dist/docs-raw/coding.md +0 -340
  148. package/dist/docs-raw/deployment.md +0 -374
  149. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  150. package/dist/docs-raw/guides/surface-members.md +0 -82
  151. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  152. package/dist/docs-raw/internals/compiler.md +0 -307
  153. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  154. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  155. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  156. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  157. package/dist/docs-raw/platform/admin.md +0 -45
  158. package/dist/docs-raw/platform/architecture.md +0 -82
  159. package/dist/docs-raw/platform/auth.md +0 -139
  160. package/dist/docs-raw/platform/email.md +0 -67
  161. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  162. package/dist/docs-raw/platform/observability.md +0 -197
  163. package/dist/docs-raw/platform/projects.md +0 -111
  164. package/dist/docs-raw/platform/sharing.md +0 -90
  165. package/dist/docs-raw/product/README.md +0 -39
  166. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  167. package/dist/docs-raw/product/business-model.md +0 -15
  168. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  169. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  170. package/dist/docs-raw/product/founder-story.md +0 -11
  171. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  172. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  173. package/dist/docs-raw/product/product-loop.md +0 -17
  174. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  175. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  176. package/dist/docs-raw/product/user-segments.md +0 -15
  177. package/dist/docs-raw/product/vision.md +0 -26
  178. package/dist/docs-raw/rl-environments.md +0 -508
  179. package/dist/docs-raw/runbook.md +0 -611
  180. package/dist-cli/check-compiler-LOXCPEOI.js.map +0 -1
  181. package/dist-cli/check-query-propagation-BAKNVWXR.js.map +0 -1
  182. package/dist-cli/chunk-RY43WF46.js.map +0 -1
  183. package/dist-cli/forgecad.js.map +0 -1
  184. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  185. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  186. package/dist-skill/SKILL-dev.md +0 -145
  187. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  188. package/dist-skill/docs-dev/CLI.md +0 -647
  189. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  190. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  191. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  192. package/dist-skill/docs-dev/coding.md +0 -340
  193. package/dist-skill/docs-dev/component-model.md +0 -164
  194. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  195. package/dist-skill/docs-dev/generated/core.md +0 -2117
  196. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  197. package/dist-skill/docs-dev/generated/lib.md +0 -169
  198. package/dist-skill/docs-dev/generated/output.md +0 -247
  199. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  200. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  201. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  202. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  203. package/dist-skill/docs-dev/generated/wood.md +0 -108
  204. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  205. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  206. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  207. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  208. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  209. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  210. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  211. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  212. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  213. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  214. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  215. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  216. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
@@ -25,6 +25,8 @@ skill-order: 100
25
25
  - [SurfacePattern](#surfacepattern)
26
26
  - [Pattern2D](#pattern2d)
27
27
  - [Pattern2DBuilder](#pattern2dbuilder)
28
+ - [HermiteCurve3D](#hermitecurve3d)
29
+ - [QuinticHermiteCurve3D](#quintichermitecurve3d)
28
30
  - [ShapeRef](#shaperef)
29
31
  - [ANCHOR3D_NAMES](#anchor3d-names)
30
32
  - [verify](#verify)
@@ -364,9 +366,9 @@ selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]
364
366
  | `minLength?` | `number` | Filter: minimum edge length. |
365
367
  | `maxLength?` | `number` | Filter: maximum edge length. |
366
368
  | `within?` | `BoundingRegion` | Filter: edge midpoint must be within this bounding region. |
367
- | `atZ?` | `number` | Shorthand: edge midpoint Z this value (within `tolerance`). Equivalent to `within: { zMin: atZ - tol, zMax: atZ + tol }`. |
368
- | `tolerance?` | `number` | Position tolerance for approximate matches (default: `1.0`). Used by `atZ` and `near`. |
369
- | `angleTolerance?` | `number` | Angular tolerance in degrees for `parallel`/`perpendicular` filters (default: `10`). |
369
+ | `atZ?` | `number` | Shorthand: edge midpoint Z is approximately this value within `tolerance`. |
370
+ | `tolerance?` | `number` | Position tolerance for approximate matches. Used by `atZ` and `near`. Default: `1.0`. |
371
+ | `angleTolerance?` | `number` | Angular tolerance in degrees for `parallel`/`perpendicular` filters. Default: `10`. |
370
372
 
371
373
  `BoundingRegion`: `{ xMin?: number, xMax?: number, yMin?: number, yMax?: number, zMin?: number, zMax?: number }`
372
374
 
@@ -418,7 +420,16 @@ coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]
418
420
 
419
421
  #### `require()` — Import a module with optional ForgeCAD parameter overrides. Returns the module's exports.
420
422
 
421
- When importing a `.forge.js` file, the return value is what the script returns. If the script returns a metadata object (e.g. `{ shape: myShape, bolts: {...} }`), the caller receives the full object — renderable values and metadata together.
423
+ When importing a `.forge.js` file, most return values are passed through exactly as the script returns them. Assembly returns have one extra composition rule: an unsolved [`Assembly`](/docs/assembly#assembly) is wrapped as an [`ImportedAssembly`](/docs/assembly#importedassembly), preserving `solve(state)` and `mergeInto()` across file boundaries, while a returned [`SolvedAssembly`](/docs/assembly#solvedassembly) stays a [`SolvedAssembly`](/docs/assembly#solvedassembly). If the script returns a metadata object (e.g. `{ shape: myShape, bolts: {...} }`), the caller receives the full object — renderable values and metadata together.
424
+
425
+ **Assembly return contract**
426
+
427
+ | `.forge.js` return value | `require()` result |
428
+ |---|---|
429
+ | `Assembly` | `ImportedAssembly` |
430
+ | `SolvedAssembly` | `SolvedAssembly` |
431
+
432
+ [`ImportedAssembly`](/docs/assembly#importedassembly) exposes default-pose helpers such as `getPart()`, `collisionReport()`, and `minClearance()`. Use `solve(state)` first when inspecting a non-default pose.
422
433
 
423
434
  **Path rule:** Always include the file extension in relative imports: use `require("./part.forge.js")` for model files and `require("./helpers.js")` for plain helper modules. ForgeCAD does not apply Node-style extension inference, so `require("./part")` will not find `part.forge.js` or `part.js`.
424
435
 
@@ -449,6 +460,26 @@ mount.bolts.pos // access the metadata
449
460
  mount.shape // access the geometry
450
461
  ```
451
462
 
463
+ **Forge-aware builder module pattern** — use `.forge.js` modules for reusable sketch, profile, shape, or assembly builders that need ForgeCAD runtime APIs:
464
+
465
+ ```js
466
+ // profiles.forge.js — inspectable on its own, reusable through require()
467
+ function wheelProfile() {
468
+ return circle2d(40).subtract(circle2d(18));
469
+ }
470
+
471
+ return {
472
+ preview: [{ name: 'Wheel profile', sketch: wheelProfile() }],
473
+ make: { wheelProfile },
474
+ };
475
+
476
+ // main.forge.js
477
+ const profiles = require('./profiles.forge.js');
478
+ const wheel = profiles.make.wheelProfile().extrude(8);
479
+ ```
480
+
481
+ Keep exported builders pure over top-level constants, top-level `param()` values, or explicit function arguments. Do not declare new `param()` values inside an exported builder if callers need `require('./profiles.forge.js', { Width: 80 })` overrides: import overrides are validated while the module loads, before any exported builder is called. Use plain `.js` modules only for pure constants, tables, math helpers, and formatting code that does not construct ForgeCAD geometry.
482
+
452
483
  ```ts
453
484
  require(path: string, paramOverrides?: Record<string, number | string>): any
454
485
  ```
@@ -477,10 +508,18 @@ importSvgSketch(fileName: string, options?: SvgImportOptions): Sketch
477
508
  | `simplify?` | `number` | Simplification tolerance for final sketch cleanup. |
478
509
  | `invertY?` | `boolean` | Flip SVG Y-down coordinates to CAD Y-up. Enabled by default. |
479
510
 
480
- #### `importMesh()` — Import an external mesh file (STL, OBJ, 3MF) as a Shape.
511
+ #### `importMesh()` — Import an external mesh file (STL, OBJ, 3MF).
512
+
513
+ By default, 3MF build items are flattened into one Shape for compatibility. Use `separateObjects: true` to import 3MF build items/resource objects as a named ShapeGroup whose children are targetable by `forgecad ls`. Use `object` to import one item by the stable ref/name reported by `forgecad run`.
514
+
515
+ ```js
516
+ const all = importMesh("./assembly.3mf", { separateObjects: true });
517
+ const pin = all.child("Pin #001");
518
+ const plate = importMesh("./assembly.3mf", { object: "3mf:build:001:object:7" });
519
+ ```
481
520
 
482
521
  ```ts
483
- importMesh(fileName: string, options?: { scale?: number; center?: boolean; }): Shape
522
+ importMesh(fileName: string, options?: { scale?: number; center?: boolean; object?: string; separateObjects?: boolean; }): Shape | ShapeGroup
484
523
  ```
485
524
 
486
525
  #### `importStep()` — Import a STEP file (.step, .stp) as an exact OCCT-backed Shape. Preserves NURBS curves, B-spline surfaces, and exact topology. Requires running with the OCCT backend.
@@ -953,6 +992,25 @@ box(100, 100, 10).color('#gold').material({ metalness: 0.95, roughness: 0.05 }).
953
992
  material(props: ShapeMaterialProps): Shape
954
993
  ```
955
994
 
995
+ **`ShapeMaterialProps`**
996
+
997
+ | Option | Type | Description |
998
+ |--------|------|-------------|
999
+ | `metalness?` | `number` | Metalness factor (0 = dielectric, 1 = metal). Default: 0.05 |
1000
+ | `roughness?` | `number` | Roughness factor (0 = mirror, 1 = fully diffuse). Default: 0.35 |
1001
+ | `emissive?` | `string` | Emissive glow color (hex string, e.g. "#ff6b35"). |
1002
+ | `emissiveIntensity?` | `number` | Emissive intensity multiplier. Default: 1 |
1003
+ | `opacity?` | `number` | Opacity (0 = fully transparent, 1 = fully opaque). Default: 1 |
1004
+ | `wireframe?` | `boolean` | Render as wireframe. Default: false |
1005
+ | `clearcoat?` | `number` | Clearcoat intensity (0–1). Default: 0.1 |
1006
+ | `clearcoatRoughness?` | `number` | Clearcoat roughness (0–1). Default: 0.4 |
1007
+ | `transmission?` | `number` | Glass/translucency transmission factor (0–1). Renderer support depends on target. |
1008
+ | `ior?` | `number` | Index of refraction for transmissive materials. Typical glass is ~1.45. |
1009
+ | `thickness?` | `number` | Approximate transmissive volume thickness in model units. |
1010
+ | `specularIntensity?` | `number` | Specular highlight intensity (0–1). |
1011
+ | `specularColor?` | `string` | Specular highlight tint. |
1012
+ | `reflectivity?` | `number` | Reflection strength for supported renderers (0–1). |
1013
+
956
1014
  **Face Topology**
957
1015
 
958
1016
  #### `face()` — Resolve a face by user-authored label or compiler-owned name. Returns a `FaceRef` that can be passed to `.onFace()`, `projectToPlane()`, or used directly in placement.
@@ -1073,6 +1131,15 @@ body.edgesOf('top', { concave: true })
1073
1131
  edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]
1074
1132
  ```
1075
1133
 
1134
+ **`EdgesOfOptions`**
1135
+
1136
+ | Option | Type | Description |
1137
+ |--------|------|-------------|
1138
+ | `exclude?` | `string \| string[]` | Exclude edges shared with these named faces. |
1139
+ | `convex?` | `boolean` | Additional geometric filter: only convex edges. |
1140
+ | `concave?` | `boolean` | Additional geometric filter: only concave edges. |
1141
+ | `minLength?` | `number` | Minimum edge length filter. |
1142
+
1076
1143
  #### `edgesBetween()` — Return edges shared between two named faces.
1077
1144
 
1078
1145
  An edge is "between" faces A and B when one of its adjacent mesh triangles belongs to A and the other belongs to B. This is the most precise topological edge selection — "fillet the edges where the top meets the wall."
@@ -1154,6 +1221,8 @@ rotateZ(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Sh
1154
1221
  rotateAroundTo(axis: [ number, number, number ], pivot: [ number, number, number ], movingPoint: RotationPointLike, targetPoint: RotationPointLike, options?: RotateAroundToOptions): Shape
1155
1222
  ```
1156
1223
 
1224
+ `RotateAroundToOptions`: `{ mode?: RotateAroundToMode }`
1225
+
1157
1226
  #### `transform()` — Apply a 4x4 affine transform matrix (column-major) or a Transform object.
1158
1227
 
1159
1228
  ```ts
@@ -1250,6 +1319,11 @@ box(100, 100, 20).pocket('top', 8, { scale: 0.8 })
1250
1319
  pocket(face: FaceSelector, depth: number, opts?: PocketOptions): Shape
1251
1320
  ```
1252
1321
 
1322
+ **`PocketOptions`**
1323
+ - `inset?: number` — Shrink the face boundary inward by this many mm before extruding. Produces angled walls when combined with depth. Default: 0 (full face).
1324
+ - `scale?: number` — Scale the face profile uniformly (e.g. 0.8 = 80% of the face area). Mutually exclusive with `inset`; `inset` takes precedence if both are set.
1325
+ - `join?: "Square" | "Round" | "Miter"` — Corner join style when using `inset`. Default: 'Round'.
1326
+
1253
1327
  #### `boss()` — Add a boss (protrusion) from the named face.
1254
1328
 
1255
1329
  ```js
@@ -1272,6 +1346,30 @@ box(50, 50, 20).hole('top', { diameter: 6, counterbore: { diameter: 12, depth: 3
1272
1346
  hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape
1273
1347
  ```
1274
1348
 
1349
+ **`FaceRef`**
1350
+
1351
+ | Option | Type | Description |
1352
+ |--------|------|-------------|
1353
+ | `normal` | `[ number, number, number ]` | Normal direction of the face |
1354
+ | `center` | `[ number, number, number ]` | Center point of the face |
1355
+ | `query?` | `FaceQueryRef` | Compiler-owned face query when available. |
1356
+ | `planar?` | `boolean` | True when the face can host a 2D sketch placement frame |
1357
+ | `uAxis?` | `[ number, number, number ]` | Face-local horizontal axis for planar faces |
1358
+ | `vAxis?` | `[ number, number, number ]` | Face-local vertical axis for planar faces |
1359
+ | `surface?` | `FaceSurface` | Analytic surface family when the backend can identify one. |
1360
+ | `descendant?` | `FaceDescendantMetadata` | Shared descendant-resolution metadata when this face is a semantic region/set. |
1361
+ | `name` | | — |
1362
+
1363
+ **`FaceDescendantMetadata`**: `kind: "single" | "face-set"`, `semantic: FaceDescendantSemantic`, `memberCount: number`, `memberNames: string[]`, `coplanar: boolean`
1364
+
1365
+ **`ShapeHoleOptions`**: `diameter: number`, `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `u?: number`, `v?: number`, `counterbore?: { diameter: number; depth: number; }`, `countersink?: { diameter: number; angleDeg?: number; }`, `thread?: ShapeHoleThreadOptions`
1366
+
1367
+ `ShapeFeatureExtentOptions`: `{ forward: ShapeFeatureExtentSideOptions, reverse?: ShapeFeatureExtentSideOptions }`
1368
+
1369
+ `ShapeFeatureExtentSideOptions`: `{ depth?: number, upToFace?: SketchFaceTarget | FaceRef, through?: boolean }`
1370
+
1371
+ **`ShapeHoleThreadOptions`**: `designation?: string`, `pitch?: number`, `class?: string`, `handedness?: "right" | "left"`, `depth?: number`, `modeled?: boolean`
1372
+
1275
1373
  #### `cutout()` — Cut a profile-shaped pocket through a face using a placed sketch.
1276
1374
 
1277
1375
  The sketch must be placed on a face with `Sketch.onFace(...)`. The cut follows the sketch's 2D profile.
@@ -1285,6 +1383,8 @@ body.cutout(profile, { depth: 5 })
1285
1383
  cutout(sketch: Sketch, opts?: ShapeCutoutOptions): Shape
1286
1384
  ```
1287
1385
 
1386
+ **`ShapeCutoutOptions`**: `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `taperScale?: number | [ number, number ]`
1387
+
1288
1388
  **Placement**
1289
1389
 
1290
1390
  #### `placeReference()` — Translate the shape so the given anchor or reference lands on the target coordinate.
@@ -1348,6 +1448,11 @@ mast.translate(0, station, radius + 50).seatInto(fuselage, 'mount', { depth: 'fl
1348
1448
  seatInto(target: Shape, surface: string, options?: SeatIntoOptions): Shape
1349
1449
  ```
1350
1450
 
1451
+ **`SeatIntoOptions`**
1452
+ - `along?: [ number, number, number ]` — Movement axis. Default: inverted face normal (points into target).
1453
+ - `depth?: "full" | "flush" | number` — How deep to embed. 'full' = entire face inside. 'flush' = nearest point touches. number = mm past flush. Default: 'full'.
1454
+ - `gap?: number` — Standoff gap in mm. Positive = gap between face and target. Negative = extra penetration. Default: 0.
1455
+
1351
1456
  #### `seatOver()` — Slide this shape until a target's labeled face is fully covered (inside this shape).
1352
1457
 
1353
1458
  The inverse of `seatInto`: instead of embedding *your* face into the target, you move until the *target's* face is embedded inside you.
@@ -1372,6 +1477,10 @@ seatOver(target: Shape, targetSurface: string, options?: SeatIntoOptions): Shape
1372
1477
  withConnectors(connectors: Record<string, ConnectorInput>): Shape
1373
1478
  ```
1374
1479
 
1480
+ **`PortInput`**: `origin?: [ number, number, number ]`, `axis?: [ number, number, number ]`, `start?: [ number, number, number ]`, `end?: [ number, number, number ]`, `up?: [ number, number, number ]`, `kind?: JointType`, `min?: number`, `max?: number`
1481
+
1482
+ `ConnectorInput`: `{ connectorType?: string, gender?: ConnectorGender, measurements?: Record<string, number | string> }`
1483
+
1375
1484
  #### `connectorNames()` — List all connector names on this shape.
1376
1485
 
1377
1486
  ```ts
@@ -1408,6 +1517,8 @@ Overloads:
1408
1517
  matchTo(targetOrPairs: Shape | MatchTarget | Array<[ Shape | MatchTarget, string, string ]>, selfConnOrDict?: string | Record<string, string>, targetConnOrOptions?: string | MatchToOptions, maybeOptions?: MatchToOptions): Shape
1409
1518
  ```
1410
1519
 
1520
+ `MatchToOptions`: `{ force?: boolean, angle?: number, distance?: number }`
1521
+
1411
1522
  **References**
1412
1523
 
1413
1524
  #### `withReferences()` — Attach named placement references that survive normal transforms and imports.
@@ -1416,6 +1527,12 @@ matchTo(targetOrPairs: Shape | MatchTarget | Array<[ Shape | MatchTarget, string
1416
1527
  withReferences(refs: PlacementReferenceInput): Shape
1417
1528
  ```
1418
1529
 
1530
+ **`PlacementReferenceInput`**: `points?: Record<string, [ number, number, number ]>`, `edges?: Record<string, PlacementEdgeRef>`, `surfaces?: Record<string, PlacementSurfaceRef>`, `objects?: Record<string, PlacementObjectInput>`
1531
+
1532
+ `PlacementEdgeRef`: `{ start: Vec3, end: Vec3 }`
1533
+
1534
+ `PlacementSurfaceRef`: `{ center: Vec3, normal: Vec3 }`
1535
+
1419
1536
  #### `referenceNames()` — List named placement references carried by this shape.
1420
1537
 
1421
1538
  ```ts
@@ -1577,6 +1694,24 @@ translate(x: number, y: number, z: number): Transform
1577
1694
  rotateAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform
1578
1695
  ```
1579
1696
 
1697
+ #### `rotateX()` — Rotate about the X axis after the current transform (parity with `Shape.rotateX`).
1698
+
1699
+ ```ts
1700
+ rotateX(angleDeg: number, pivot?: Vec3): Transform
1701
+ ```
1702
+
1703
+ #### `rotateY()` — Rotate about the Y axis after the current transform (parity with `Shape.rotateY`).
1704
+
1705
+ ```ts
1706
+ rotateY(angleDeg: number, pivot?: Vec3): Transform
1707
+ ```
1708
+
1709
+ #### `rotateZ()` — Rotate about the Z axis after the current transform (parity with `Shape.rotateZ`).
1710
+
1711
+ ```ts
1712
+ rotateZ(angleDeg: number, pivot?: Vec3): Transform
1713
+ ```
1714
+
1580
1715
  #### `inverse()` — Return the inverse transform.
1581
1716
 
1582
1717
  ```ts
@@ -1920,18 +2055,160 @@ constant(value?: number): Pattern2D
1920
2055
  sineWave(options: Pattern2DSineWaveOptions): Pattern2D
1921
2056
  ```
1922
2057
 
2058
+ **`Pattern2DSineWaveOptions`**
2059
+
2060
+ | Option | Type | Description |
2061
+ |--------|------|-------------|
2062
+ | `direction?` | `Vec2` | Direction the wave advances in UV space. Default: [1, 0]. |
2063
+ | `wavelength` | `number` | Distance between wave peaks in surface millimeters. |
2064
+ | `amplitude?` | `number` | Height amplitude in millimeters. Default: 1. |
2065
+ | `phase?` | `number` | Phase offset in radians. Default: 0. |
2066
+ | `bias?` | `number` | Constant height offset in millimeters. Default: 0. |
2067
+
1923
2068
  #### `stripes()` — Create recessed stripe bands in UV space.
1924
2069
 
1925
2070
  ```ts
1926
2071
  stripes(options: Pattern2DStripesOptions): Pattern2D
1927
2072
  ```
1928
2073
 
2074
+ **`Pattern2DStripesOptions`**
2075
+
2076
+ | Option | Type | Description |
2077
+ |--------|------|-------------|
2078
+ | `direction?` | `Vec2` | Direction perpendicular to the stripe bands in UV space. Default: [1, 0]. |
2079
+ | `spacing` | `number` | Center-to-center spacing in surface millimeters. |
2080
+ | `width` | `number` | Stripe width in surface millimeters. |
2081
+ | `depth?` | `number` | Stripe groove depth in millimeters. Default: 1. |
2082
+
1929
2083
  #### `overUnderWeave()` — Create an over-under woven relief pattern in UV space.
1930
2084
 
1931
2085
  ```ts
1932
2086
  overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D
1933
2087
  ```
1934
2088
 
2089
+ **`Pattern2DOverUnderWeaveOptions`**
2090
+
2091
+ | Option | Type | Description |
2092
+ |--------|------|-------------|
2093
+ | `spacing` | `number \| Vec2` | Thread center-to-center spacing. A number uses the same spacing for U and V. |
2094
+ | `threadWidth` | `number \| Vec2` | Thread width. A number uses the same width for U and V. |
2095
+ | `depth?` | `number` | Thread groove depth in millimeters. Default: 0.8. |
2096
+ | `underScale?` | `number` | Relative height of the under-crossing thread. Default: 0.15. |
2097
+
2098
+ ### `HermiteCurve3D`
2099
+
2100
+ **Properties:**
2101
+
2102
+ | Property | Type | Description |
2103
+ |----------|------|-------------|
2104
+ | `p0` | `Vec3` | Start position |
2105
+ | `p1` | `Vec3` | End position |
2106
+ | `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
2107
+ | `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
2108
+ | `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
2109
+
2110
+ **Methods:**
2111
+
2112
+ #### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
2113
+
2114
+ ```ts
2115
+ pointAt(t: number): Vec3
2116
+ ```
2117
+
2118
+ #### `tangentAt()` — Evaluate tangent (first derivative) at parameter t ∈ [0, 1]
2119
+
2120
+ ```ts
2121
+ tangentAt(t: number): Vec3
2122
+ ```
2123
+
2124
+ #### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
2125
+
2126
+ ```ts
2127
+ curvatureAt(t: number): Vec3
2128
+ ```
2129
+
2130
+ #### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
2131
+
2132
+ ```ts
2133
+ sample(count?: number): Vec3[]
2134
+ ```
2135
+
2136
+ #### `length()` — Approximate arc length by sampling.
2137
+
2138
+ ```ts
2139
+ length(samples?: number): number
2140
+ ```
2141
+
2142
+ #### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
2143
+
2144
+ ```ts
2145
+ sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
2146
+ ```
2147
+
2148
+ #### `toPolyline()` — Convert to a format compatible with sweep() path input.
2149
+
2150
+ ```ts
2151
+ toPolyline(samples?: number): Vec3[]
2152
+ ```
2153
+
2154
+ ### `QuinticHermiteCurve3D`
2155
+
2156
+ **Properties:**
2157
+
2158
+ | Property | Type | Description |
2159
+ |----------|------|-------------|
2160
+ | `p0` | `Vec3` | Start position |
2161
+ | `p1` | `Vec3` | End position |
2162
+ | `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
2163
+ | `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
2164
+ | `c0` | `Vec3` | Scaled second derivative at start (curvature * weight² * chordLength²) |
2165
+ | `c1` | `Vec3` | Scaled second derivative at end (curvature * weight² * chordLength²) |
2166
+ | `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
2167
+
2168
+ **Methods:**
2169
+
2170
+ #### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
2171
+
2172
+ ```ts
2173
+ pointAt(t: number): Vec3
2174
+ ```
2175
+
2176
+ #### `tangentAt()` — Evaluate tangent (first derivative, normalized) at parameter t ∈ [0, 1]
2177
+
2178
+ ```ts
2179
+ tangentAt(t: number): Vec3
2180
+ ```
2181
+
2182
+ #### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
2183
+
2184
+ ```ts
2185
+ curvatureAt(t: number): Vec3
2186
+ ```
2187
+
2188
+ #### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
2189
+
2190
+ ```ts
2191
+ sample(count?: number): Vec3[]
2192
+ ```
2193
+
2194
+ #### `length()` — Approximate arc length by sampling.
2195
+
2196
+ ```ts
2197
+ length(samples?: number): number
2198
+ ```
2199
+
2200
+ #### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
2201
+
2202
+ ```ts
2203
+ sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
2204
+ ```
2205
+
2206
+ #### `toPolyline()` — Convert to a format compatible with sweep() path input.
2207
+
2208
+ ```ts
2209
+ toPolyline(samples?: number): Vec3[]
2210
+ ```
2211
+
1935
2212
  ### `ShapeRef`
1936
2213
 
1937
2214
  A first-class reference path over a shape's semantic faces and face relationships.