forgecad 0.9.14 → 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 (219) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-eWGs2K6H.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-CTrLKfpo.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-5nPesyds.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-C4Y3nbYc.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-C8fB4n5U.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-jSz0LaMM.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-B83B90zh.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-DY889pcu.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-bEww1ic4.js → app-D3kDkggg.js} +2293 -946
  18. package/dist/assets/cli/{render-Cho2uKG_.js → render-DSY3mMQa.js} +337 -7
  19. package/dist/assets/{constructionHistoryWorker-HYwzJY4m.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CjQwJSE-.js → evalWorker-CU0Ke6DP.js} +7800 -4164
  21. package/dist/assets/{forgecad_geometry-CH2nvuLA.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/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-CG9Fokx-.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-uRzgk5O8.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-rmfAcdwF.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-4cW_ZpoS.js → reportWorker-CdBz5bNg.js} +7538 -10857
  32. package/dist/assets/{scalar-sampling-budget-CfDiFvh7.js → scalar-sampling-budget-wJF98aY9.js} +6935 -4331
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{solver-DuJAO8S6.js → solver-BZ9LPTHs.js} +1 -1
  35. package/dist/assets/solver_bg-DAHZJ_rw.wasm +0 -0
  36. package/dist/assets/{targets-D6PWsv6X.js → targets-B9sGB5nB.js} +1 -1
  37. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  38. package/dist/cli/render.html +1 -1
  39. package/dist/docs/index.html +2 -2
  40. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  41. package/dist/docs-raw/AI/usage.md +3 -12
  42. package/dist/docs-raw/CLI.md +30 -10
  43. package/dist/docs-raw/component-model.md +27 -11
  44. package/dist/docs-raw/generated/assembly.md +301 -212
  45. package/dist/docs-raw/generated/concepts.md +235 -237
  46. package/dist/docs-raw/generated/core.md +283 -6
  47. package/dist/docs-raw/generated/curves.md +274 -361
  48. package/dist/docs-raw/generated/lib.md +7 -1
  49. package/dist/docs-raw/generated/output.md +19 -4
  50. package/dist/docs-raw/generated/runtime-names.md +41 -0
  51. package/dist/docs-raw/generated/sdf.md +31 -0
  52. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  53. package/dist/docs-raw/generated/sketch.md +44 -1
  54. package/dist/docs-raw/generated/viewport.md +11 -3
  55. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  56. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  57. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  58. package/dist/docs-raw/guides/joint-design.md +24 -0
  59. package/dist/docs-raw/guides/positioning.md +13 -3
  60. package/dist/docs-raw/legal/privacy.md +63 -0
  61. package/dist/docs-raw/legal/software-license.md +55 -0
  62. package/dist/docs-raw/legal/terms.md +87 -0
  63. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +1 -1
  64. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  66. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  68. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  69. package/dist/docs-raw/skills/forgecad-make-a-model.md +1 -1
  70. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  71. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  72. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  73. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +1 -1
  74. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  75. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  76. package/dist/docs-raw/skills/forgecad.md +4 -3
  77. package/dist/index.html +40 -12
  78. package/dist/llms.txt +8 -0
  79. package/dist/site.webmanifest +1 -1
  80. package/dist/sitemap.xml +49 -13
  81. package/dist-cli/{check-compiler-U5SOPN7X.js → check-compiler-SDX5QIXI.js} +1 -2
  82. package/dist-cli/{check-query-propagation-XOKNSSYU.js → check-query-propagation-EAYEFT77.js} +1 -2
  83. package/dist-cli/{chunk-EXWGNL6K.js → chunk-N4O47JLF.js} +12540 -9046
  84. package/dist-cli/forgecad.js +1786 -679
  85. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  86. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  87. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  88. package/dist-cli/solver_bg.wasm +0 -0
  89. package/dist-skill/CONTEXT.md +1117 -721
  90. package/dist-skill/SKILL.md +3 -2
  91. package/dist-skill/docs/API/core/concepts.md +64 -1
  92. package/dist-skill/docs/CLI.md +30 -10
  93. package/dist-skill/docs/generated/assembly.md +277 -229
  94. package/dist-skill/docs/generated/core.md +283 -6
  95. package/dist-skill/docs/generated/curves.md +272 -362
  96. package/dist-skill/docs/generated/lib.md +7 -1
  97. package/dist-skill/docs/generated/output.md +19 -4
  98. package/dist-skill/docs/generated/runtime-names.md +41 -0
  99. package/dist-skill/docs/generated/sdf.md +31 -0
  100. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  101. package/dist-skill/docs/generated/sketch.md +44 -2
  102. package/dist-skill/docs/generated/viewport.md +2 -87
  103. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  104. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  105. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  106. package/dist-skill/docs/guides/joint-design.md +24 -0
  107. package/dist-skill/docs/guides/positioning.md +13 -3
  108. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  109. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  110. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  111. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  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 -13
  135. package/dist/assets/EditorApp-lXv53A1m.js +0 -13610
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/assets/forgecad_geometry_bg-C5_E9Oa9.wasm +0 -0
  138. package/dist/assets/solver_bg-CWvv4lnN.wasm +0 -0
  139. package/dist/docs-raw/API/README.md +0 -16
  140. package/dist/docs-raw/API/core/concepts.md +0 -118
  141. package/dist/docs-raw/INDEX.md +0 -138
  142. package/dist/docs-raw/RELEASING.md +0 -87
  143. package/dist/docs-raw/agent-native-api.md +0 -27
  144. package/dist/docs-raw/beta-deployment.md +0 -304
  145. package/dist/docs-raw/beta-operations.md +0 -325
  146. package/dist/docs-raw/blueprint-first.md +0 -145
  147. package/dist/docs-raw/cli-monetization.md +0 -112
  148. package/dist/docs-raw/coding-best-practices.md +0 -120
  149. package/dist/docs-raw/coding.md +0 -340
  150. package/dist/docs-raw/deployment.md +0 -374
  151. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  152. package/dist/docs-raw/guides/surface-members.md +0 -82
  153. package/dist/docs-raw/harbor-cli.md +0 -854
  154. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  155. package/dist/docs-raw/internals/compiler.md +0 -307
  156. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  157. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  158. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  159. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  160. package/dist/docs-raw/platform/admin.md +0 -45
  161. package/dist/docs-raw/platform/architecture.md +0 -82
  162. package/dist/docs-raw/platform/auth.md +0 -139
  163. package/dist/docs-raw/platform/email.md +0 -67
  164. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  165. package/dist/docs-raw/platform/observability.md +0 -197
  166. package/dist/docs-raw/platform/projects.md +0 -111
  167. package/dist/docs-raw/platform/sharing.md +0 -90
  168. package/dist/docs-raw/product/README.md +0 -39
  169. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  170. package/dist/docs-raw/product/business-model.md +0 -15
  171. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  172. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  173. package/dist/docs-raw/product/founder-story.md +0 -11
  174. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  175. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  176. package/dist/docs-raw/product/product-loop.md +0 -17
  177. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  178. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  179. package/dist/docs-raw/product/user-segments.md +0 -15
  180. package/dist/docs-raw/product/vision.md +0 -26
  181. package/dist/docs-raw/rl-environments.md +0 -350
  182. package/dist/docs-raw/runbook.md +0 -611
  183. package/dist-cli/check-compiler-U5SOPN7X.js.map +0 -1
  184. package/dist-cli/check-query-propagation-XOKNSSYU.js.map +0 -1
  185. package/dist-cli/chunk-EXWGNL6K.js.map +0 -1
  186. package/dist-cli/forgecad.js.map +0 -1
  187. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  188. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  189. package/dist-skill/SKILL-dev.md +0 -145
  190. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  191. package/dist-skill/docs-dev/CLI.md +0 -677
  192. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  193. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  194. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  195. package/dist-skill/docs-dev/coding.md +0 -340
  196. package/dist-skill/docs-dev/component-model.md +0 -164
  197. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  198. package/dist-skill/docs-dev/generated/core.md +0 -2117
  199. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  200. package/dist-skill/docs-dev/generated/lib.md +0 -169
  201. package/dist-skill/docs-dev/generated/output.md +0 -247
  202. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  203. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  204. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  205. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  206. package/dist-skill/docs-dev/generated/wood.md +0 -108
  207. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  208. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  209. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  210. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  211. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  212. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  213. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  214. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  215. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  216. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  217. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  218. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  219. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
@@ -1,2583 +0,0 @@
1
- ---
2
- skill-group: curves
3
- skill-order: 100
4
- ---
5
-
6
- # Curves & Surfacing
7
-
8
- Smooth curves, lofted surfaces, swept solids, splines, and high-level product skins.
9
-
10
- ## Contents
11
-
12
- - [Curves & Surfacing](#curves-surfacing) — `Loft.station`, `Loft.leftRail`, `Loft.rightRail`, `Loft.frontRail`, `Loft.backRail`, `Loft.centerRail`, `Loft.pathOnXz`, `Loft.pathOnYz`, `Loft.pathOnXy`, `Loft.withGuideRails`, `Helix.path`, `Helix.coil`, `hermiteTransitionG2`, `nurbs3d`, `spline2d`, `spline3d`, `loft`, `loftAlongSpine`, `sweep`, `variableSweep`, `nurbsSurface`, `surfacePatch`, `transitionCurve`, `transitionSurface`, `connectEdges`
13
- - [Surface Members](#surface-members) — `surfaceBand`, `SurfaceBody`
14
- - [Curve3D](#curve3d)
15
- - [HelixCurve](#helixcurve)
16
- - [NurbsCurve3D](#nurbscurve3d)
17
- - [NurbsSurface](#nurbssurface)
18
- - [PathBuilder](#pathbuilder) — Line Segments, Arcs, Curves, Closing & Output
19
- - [HermiteCurve3D](#hermitecurve3d)
20
- - [QuinticHermiteCurve3D](#quintichermitecurve3d)
21
- - [ProductSkin](#productskin)
22
- - [ProductSurfaceRef](#productsurfaceref)
23
- - [ProductSurfaceBuilder](#productsurfacebuilder)
24
- - [ProductSkinBuilder](#productskinbuilder)
25
- - [ProductStationBuilder](#productstationbuilder)
26
- - [ProductPanelBuilder](#productpanelbuilder)
27
- - [ProductRibbonBuilder](#productribbonbuilder)
28
- - [ProductSpoutBuilder](#productspoutbuilder)
29
- - [ProductHandleBuilder](#producthandlebuilder)
30
- - [ProductHandleFeature](#producthandlefeature)
31
- - [CylinderCarrier](#cylindercarrier)
32
- - [PlaneCarrier](#planecarrier)
33
- - [ProductSkinCarrier](#productskincarrier)
34
- - [SurfacePath](#surfacepath)
35
- - [SurfacePathBuilder](#surfacepathbuilder)
36
- - [SurfaceBand](#surfaceband)
37
- - [SurfaceBodyBuilder](#surfacebodybuilder)
38
- - [SurfaceMemberBuilder](#surfacememberbuilder)
39
- - [SurfaceJoinBuilder](#surfacejoinbuilder)
40
- - [CounterboreBuilder](#counterborebuilder)
41
- - [RoundedSlotBuilder](#roundedslotbuilder)
42
- - [Surface](#surface)
43
- - [Blend](#blend)
44
- - [Analysis](#analysis)
45
- - [Product](#product)
46
- - [Carrier](#carrier)
47
- - [SurfaceMembers](#surfacemembers)
48
- - [Slot](#slot)
49
- - [Counterbore](#counterbore)
50
- - [Ribs](#ribs)
51
- - [Helix](#helix)
52
-
53
- ## Functions
54
-
55
- ### Curves & Surfacing
56
-
57
- #### `Loft.station()` — Create a loft station from a 2D profile and an axis position.
58
-
59
- ```ts
60
- Loft.station(profile: Sketch, position: number): LoftStation
61
- ```
62
-
63
- `LoftStation`: `{ profile: Sketch, position: number }`
64
-
65
- #### `Loft.leftRail()` — Create a guide rail that constrains the section-local negative-X side.
66
-
67
- ```ts
68
- Loft.leftRail(path: LoftGuideRailPath): LoftGuideRail
69
- ```
70
-
71
- `LoftGuideRail`: `{ side: LoftGuideRailSide, path: LoftGuideRailPath }`
72
-
73
- #### `Loft.rightRail()` — Create a guide rail that constrains the section-local positive-X side.
74
-
75
- ```ts
76
- Loft.rightRail(path: LoftGuideRailPath): LoftGuideRail
77
- ```
78
-
79
- #### `Loft.frontRail()` — Create a guide rail that constrains the section-local positive-Y side.
80
-
81
- ```ts
82
- Loft.frontRail(path: LoftGuideRailPath): LoftGuideRail
83
- ```
84
-
85
- #### `Loft.backRail()` — Create a guide rail that constrains the section-local negative-Y side.
86
-
87
- ```ts
88
- Loft.backRail(path: LoftGuideRailPath): LoftGuideRail
89
- ```
90
-
91
- #### `Loft.centerRail()` — Create a guide rail that moves section centers along the loft.
92
-
93
- ```ts
94
- Loft.centerRail(path: LoftGuideRailPath): LoftGuideRail
95
- ```
96
-
97
- #### `Loft.pathOnXz()` — Place a 2D guide path onto the XZ plane.
98
-
99
- The path's first coordinate becomes X and its second coordinate becomes Z. Use this for left/right silhouette rails authored with [`path()`](/docs/sketch#path) or [`constrainedSketch()`](/docs/sketch#constrainedsketch).
100
-
101
- ```ts
102
- Loft.pathOnXz(path: LoftPath2D, y?: number): Vec3[]
103
- ```
104
-
105
- #### `Loft.pathOnYz()` — Place a 2D guide path onto the YZ plane.
106
-
107
- The path's first coordinate becomes Y and its second coordinate becomes Z. Use this for front/back crown rails authored with [`path()`](/docs/sketch#path) or [`constrainedSketch()`](/docs/sketch#constrainedsketch).
108
-
109
- ```ts
110
- Loft.pathOnYz(path: LoftPath2D, x?: number): Vec3[]
111
- ```
112
-
113
- #### `Loft.pathOnXy()` — Place a 2D guide path onto the XY plane.
114
-
115
- The path's first coordinate becomes X and its second coordinate becomes Y. Use this when lofting along X or Y and a rail lives in a horizontal sketch plane.
116
-
117
- ```ts
118
- Loft.pathOnXy(path: LoftPath2D, z?: number): Vec3[]
119
- ```
120
-
121
- #### `Loft.withGuideRails()` — Loft through profile stations while forcing generated sections to follow guide rails.
122
-
123
- Stations define the cross-section family. Guide rails define the side or center paths the loft must pass through. With opposite side rails, the section is scaled to touch both rails. With one side rail, the section keeps its interpolated size unless a center rail is also present.
124
-
125
- ```ts
126
- Loft.withGuideRails(stations: LoftStation[], rails: LoftGuideRail[], options?: LoftWithGuideRailsOptions): Shape
127
- ```
128
-
129
- **`LoftOptions`**
130
- - `edgeLength?: number` — Marching-grid edge length for level-set meshing. Smaller = finer.
131
- - `boundsPadding?: number` — Optional extra bounds padding.
132
-
133
- **`LoftWithGuideRailsOptions`** extends LoftOptions
134
- - `axis?: LoftAxis` — Primary station axis. Default Z.
135
- - `samples?: number` — Number of generated loft stations including ends. Default scales with station count.
136
- - `railSamples?: number` — Number of points sampled from curve-backed rails before axis interpolation. Default 64.
137
-
138
- #### `Helix.path()` — Create a metadata-bearing helical centerline around the Z axis.
139
-
140
- ```ts
141
- Helix.path(options: HelixOptions): HelixCurve
142
- ```
143
-
144
- **`HelixOptions`**
145
-
146
- | Option | Type | Description |
147
- |--------|------|-------------|
148
- | `radius` | `number` | Radius from the central Z axis to the helix centerline. |
149
- | `pitch?` | `number` | Axial distance per full turn. Provide any two of `pitch`, `turns`, and `height`. |
150
- | `turns?` | `number` | Number of full rotations around the axis. Provide any two of `pitch`, `turns`, and `height`. |
151
- | `height?` | `number` | Total height along +Z. Provide any two of `pitch`, `turns`, and `height`. |
152
- | `startAngle?` | `number` | Start angle in degrees. Default 0 starts on +X. |
153
- | `clockwise?` | `boolean` | Reverse winding direction when viewed from +Z. |
154
- | `samplesPerTurn?` | `number` | Point samples per turn for the metadata path. Default 32. |
155
-
156
- #### `Helix.coil()` — Create a solid helical coil by sweeping a profile through helix-local frames.
157
-
158
- Overloads:
159
-
160
- - `Helix.coil(options: HelixCoilOptions): Shape`
161
- - `Helix.coil(profile: Sketch, options: HelixCoilOptions): Shape`
162
-
163
-
164
- **`HelixCoilOptions`** extends HelixOptions
165
- - `wireRadius?: number` — Radius of the circular wire profile. Required unless a custom profile is passed.
166
- - `profileSegments?: number` — Segment count for the default circular wire profile. Default 24.
167
- - `divisionsPerTurn?: number` — Sweep path samples per turn. Default 32.
168
-
169
- #### `hermiteTransitionG2()` — Create a quintic Hermite transition curve between two edge endpoints (G2 continuity).
170
-
171
- The curve starts at `a.point` tangent to `a.tangent` with curvature `a.curvature`, and ends at `b.point` tangent to `b.tangent` with curvature `b.curvature`, with smooth G2-continuous interpolation matching position, tangent, and curvature.
172
-
173
- ```ts
174
- hermiteTransitionG2(a: QuinticHermiteCurveEndpoint, b: QuinticHermiteCurveEndpoint): QuinticHermiteCurve3D
175
- ```
176
-
177
- **`QuinticHermiteCurveEndpoint`**
178
-
179
- | Option | Type | Description |
180
- |--------|------|-------------|
181
- | `point` | `Vec3` | Position |
182
- | `tangent` | `Vec3` | Tangent direction (will be normalized internally) |
183
- | `curvature?` | `Vec3` | Second derivative / curvature vector. Default [0, 0, 0]. |
184
- | `weight?` | `number` | Weight: scales tangent magnitude relative to chord length. Default 1.0. |
185
-
186
- #### `nurbs3d()` — Create a NURBS curve from control points.
187
-
188
- With default options, creates a cubic non-rational B-spline with uniform clamped knots. Set `weights` for rational curves (exact circles, conics). Set `degree` for linear (1), quadratic (2), cubic (3), or higher-order curves.
189
-
190
- ```js
191
- // Simple cubic B-spline through control points
192
- const curve = nurbs3d([[0,0,0], [10,5,0], [20,-5,10], [30,0,5]]);
193
- const tube = sweep(circle(2), curve);
194
- ```
195
-
196
- ```js
197
- // Rational quadratic — exact circular arc
198
- const arc = nurbs3d(
199
- [[10,0,0], [10,10,0], [0,10,0]],
200
- { degree: 2, weights: [1, Math.SQRT1_2, 1] }
201
- );
202
- ```
203
-
204
- ```ts
205
- nurbs3d(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D
206
- ```
207
-
208
- **`NurbsCurve3DOptions`**
209
-
210
- | Option | Type | Description |
211
- |--------|------|-------------|
212
- | `degree?` | `number` | Polynomial degree (default 3 = cubic). Must be ≥ 1. |
213
- | `weights?` | `number[]` | Rational weights, one per control point (default: all 1.0 = non-rational). |
214
- | `knots?` | `number[]` | Knot vector (default: uniform clamped). Must have length = controlPoints.length + degree + 1. |
215
- | `closed?` | `boolean` | Whether the curve is closed/periodic (default false). |
216
-
217
- #### `spline2d()` — Build a smooth Catmull-Rom spline sketch from 2D control points.
218
-
219
- A closed spline (default) returns a filled profile. An open spline requires a strokeWidth option to produce a solid sketch. Use tension (0..1, default 0.5) to control curve tightness.
220
-
221
- ```ts
222
- spline2d(points: Vec2[], options?: Spline2DOptions): Sketch
223
- ```
224
-
225
- **`Spline2DOptions`**
226
-
227
- | Option | Type | Description |
228
- |--------|------|-------------|
229
- | `closed?` | `boolean` | Closed loop (default true). |
230
- | `tension?` | `number` | Catmull-Rom tension in [0, 1]. 0 = very round, 1 = linear-ish. Default 0.5. |
231
- | `samplesPerSegment?` | `number` | Samples per segment (minimum 3). Default 16. |
232
- | `strokeWidth?` | `number` | For open splines, provide stroke width to return a solid Sketch. If omitted for open splines, an error is thrown. |
233
- | `join?` | `"Round" \| "Square"` | Stroke join for open splines. Default 'Round'. |
234
-
235
- #### `spline3d()` — Create a reusable 3D spline curve object (Catmull-Rom).
236
-
237
- The returned Curve3D provides sample(), pointAt(t), tangentAt(t), and length() for downstream use in sweep() or manual path operations.
238
-
239
- ```ts
240
- spline3d(points: Vec3[], options?: Spline3DOptions): Curve3D
241
- ```
242
-
243
- **`Spline3DOptions`**
244
- - `closed?: boolean` — Closed loop (default false).
245
- - `tension?: number` — Catmull-Rom tension in [0, 1]. 0 = very round, 1 = linear-ish. Default 0.5.
246
-
247
- #### `loft()` — Loft between multiple sketches along Z stations.
248
-
249
- Profiles can differ in topology and vertex count: interpolation is done on signed-distance fields and meshed with level-set extraction. Heights must be strictly increasing. Compatible loft stacks can also stay on the maintained export-backend path.
250
-
251
- Performance note: loft is significantly heavier than primitive/extrude/revolve. If the part is axis-symmetric (bottles, vases, knobs), prefer revolve().
252
-
253
- ```ts
254
- loft(profiles: Sketch[], heights: number[], options?: LoftOptions): Shape
255
- ```
256
-
257
- #### `loftAlongSpine()` — Loft between multiple profiles positioned along an arbitrary 3D spine curve.
258
-
259
- Unlike loft() which only supports Z heights, loftAlongSpine() places each profile at a position along a 3D spine, oriented perpendicular to the spine tangent. This enables lofting along curved paths — e.g., a wing root-to-tip transition that follows a swept-back leading edge.
260
-
261
- The tValues array specifies where each profile sits along the spine (0 = start, 1 = end). Must have the same length as profiles and be in [0, 1].
262
-
263
- Internally uses variableSweep infrastructure with SDF interpolation.
264
-
265
- Performance note: uses level-set meshing, heavier than simple loft().
266
-
267
- ```ts
268
- loftAlongSpine(profiles: Sketch[], spine: Curve3D | Vec3[], tValues: number[], options?: LoftAlongSpineOptions): Shape
269
- ```
270
-
271
- **`LoftAlongSpineOptions`**
272
-
273
- | Option | Type | Description |
274
- |--------|------|-------------|
275
- | `samples?` | `number` | Number of samples when spine is a Curve3D. Default 48. |
276
- | `edgeLength?` | `number` | Marching-grid edge length for level-set meshing. Smaller = finer. |
277
- | `boundsPadding?` | `number` | Optional extra bounds padding. |
278
- | `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
279
-
280
- #### `sweep()`
281
-
282
- ```ts
283
- sweep(profile: Sketch, path: SweepPathInput, options?: SweepOptions): Shape
284
- ```
285
-
286
- **`SweepOptions`**
287
-
288
- | Option | Type | Description |
289
- |--------|------|-------------|
290
- | `samples?` | `number` | Number of samples when path is a Curve3D. Default 48. |
291
- | `edgeLength?` | `number` | Marching-grid edge length for level-set meshing. Smaller = finer. |
292
- | `boundsPadding?` | `number` | Optional extra bounds padding. |
293
- | `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
294
-
295
- #### `variableSweep()` — Sweep a variable cross-section along a 3D spine curve.
296
-
297
- Unlike sweep(), which uses a single constant profile, variableSweep() interpolates between multiple profiles at different stations along the spine. This enables organic shapes like tapering tubes, bone-like structures, and sculptural forms.
298
-
299
- Each section specifies a t parameter (0 = start, 1 = end of spine) and a 2D profile sketch. The SDF-based level-set mesher smoothly blends between profiles at intermediate positions.
300
-
301
- Performance note: like sweep(), this uses level-set meshing internally.
302
-
303
- ```ts
304
- variableSweep(spine: SweepPathInput, sections: VariableSweepSection[], options?: VariableSweepOptions): Shape
305
- ```
306
-
307
- **`VariableSweepSection`**
308
- - `t: number` — Parameter along the spine (0 = start, 1 = end).
309
- - `profile: Sketch` — Cross-section profile at this station.
310
-
311
- **`VariableSweepOptions`**
312
-
313
- | Option | Type | Description |
314
- |--------|------|-------------|
315
- | `samples?` | `number` | Number of samples when spine is a Curve3D. Default 48. |
316
- | `edgeLength?` | `number` | Marching-grid edge length for level-set meshing. Smaller = finer. |
317
- | `boundsPadding?` | `number` | Optional extra bounds padding. |
318
- | `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
319
-
320
- #### `nurbsSurface()` — Create a NURBS surface from a grid of control points.
321
-
322
- The control grid is indexed as `controlGrid[u][v]` — each row is a curve in the V direction, and columns trace curves in the U direction.
323
-
324
- With default options, creates a bicubic non-rational B-spline surface with uniform clamped knots.
325
-
326
- ```js
327
- // Simple 4×4 control grid — a gently curved surface
328
- const grid = [
329
- [[0,0,0], [10,0,2], [20,0,2], [30,0,0]],
330
- [[0,10,1], [10,10,5], [20,10,5], [30,10,1]],
331
- [[0,20,1], [10,20,5], [20,20,5], [30,20,1]],
332
- [[0,30,0], [10,30,2], [20,30,2], [30,30,0]],
333
- ];
334
- const surface = nurbsSurface(grid, { thickness: 2 });
335
- ```
336
-
337
- ```ts
338
- nurbsSurface(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape
339
- ```
340
-
341
- **`NurbsSurfaceOptions`**
342
-
343
- | Option | Type | Description |
344
- |--------|------|-------------|
345
- | `degreeU?` | `number` | Degree in U direction (default 3). |
346
- | `degreeV?` | `number` | Degree in V direction (default 3). |
347
- | `weights?` | `number[][]` | Weights grid — same dimensions as controlGrid (default: all 1.0). |
348
- | `knotsU?` | `number[]` | Knot vector in U direction (default: uniform clamped). |
349
- | `knotsV?` | `number[]` | Knot vector in V direction (default: uniform clamped). |
350
- | `thickness?` | `number` | Sheet thickness — if > 0, thickens the surface into a solid (default 0 = surface only). |
351
- | `resolution?` | `number` | Tessellation resolution — points per direction (default 32). |
352
- | `domain?` | `SurfaceDomainOptions` | Optional rectangular parameter domain in normalized [0, 1] U/V space. |
353
- | `trim?` | `SurfaceTrimOptions` | Optional polygonal or NURBS-curve UV trim loops. Truck and OCCT support open trimmed surfaces; Manifold supports sampled thickened trimmed solids. |
354
- | `tessellation?` | `SurfaceTessellationOptions` | Optional Truck kernel tessellation controls for render mesh generation. |
355
- | `approximate?` | `boolean` | Explicit opt-in for sampled approximation paths on non-exact backends. |
356
-
357
- **`SurfaceDomainOptions`**
358
-
359
- | Option | Type | Description |
360
- |--------|------|-------------|
361
- | `uMin?` | `number` | Lower U parameter bound in normalized surface space (default 0). |
362
- | `uMax?` | `number` | Upper U parameter bound in normalized surface space (default 1). |
363
- | `vMin?` | `number` | Lower V parameter bound in normalized surface space (default 0). |
364
- | `vMax?` | `number` | Upper V parameter bound in normalized surface space (default 1). |
365
-
366
- **`SurfaceTrimOptions`**
367
- - `outer: SurfaceTrimLoopInput` — Outer trim loop in normalized post-domain UV space.
368
- - `holes?: SurfaceTrimLoopInput[]` — Optional hole loops in normalized post-domain UV space.
369
-
370
- **`SurfaceTessellationOptions`**
371
-
372
- | Option | Type | Description |
373
- |--------|------|-------------|
374
- | `mode?` | `"uniform" \| "adaptive"` | `uniform` uses resolution directly; `adaptive` lets the Truck kernel refine open sheets from chord error. |
375
- | `tolerance?` | `number` | Target chord-error tolerance in model units for adaptive Truck tessellation. |
376
- | `minResolution?` | `number` | Minimum adaptive samples per direction. |
377
- | `maxResolution?` | `number` | Maximum adaptive samples per direction. Defaults to `resolution` when omitted. |
378
-
379
- #### `surfacePatch()` — Create a smooth surface patch from 4 boundary curves (Coons patch).
380
-
381
- The four curves form the boundary of a quadrilateral patch:
382
-
383
- - bottom: u=0..1 at v=0 (from corner00 to corner10)
384
- - top: u=0..1 at v=1 (from corner01 to corner11)
385
- - left: v=0..1 at u=0 (from corner00 to corner01)
386
- - right: v=0..1 at u=1 (from corner10 to corner11)
387
-
388
- The interior is filled using bilinear Coons patch interpolation: P(u,v) = Lc(u,v) + Ld(u,v) - B(u,v)
389
-
390
- The result is a thin solid created by offsetting the surface mesh along its normals by the specified thickness.
391
-
392
- Note: curves should meet at corners. Small gaps are tolerated.
393
-
394
- ```ts
395
- surfacePatch(curves: { ... }, options?: SurfacePatchOptions): Shape
396
- ```
397
-
398
- **`SurfacePatchOptions`**
399
- - `resolution?: number` — Number of samples along each direction. Default 24.
400
- - `thickness?: number` — Thickness of the generated solid. Default 0 for an open exact sheet.
401
- - `approximate?: boolean` — Allow explicit approximation for non-exact curve inputs such as Curve3D samples.
402
-
403
- #### `transitionCurve()` — Create a smooth transition curve between two edges.
404
-
405
- Returns a `HermiteCurve3D` that starts at `edgeA.point` tangent to `edgeA.tangent` and ends at `edgeB.point` tangent to `edgeB.tangent`.
406
-
407
- The curve maintains G1 continuity (matching tangent direction) at both endpoints. Weight parameters control the shape of the transition.
408
-
409
- ```js
410
- // Connect two edges with a balanced transition
411
- const curve = transitionCurve(
412
- { point: [0, 0, 0], tangent: [1, 0, 0] },
413
- { point: [10, 5, 0], tangent: [1, 0, 0] },
414
- );
415
- ```
416
-
417
- // Weighted: curve hugs edge A longer const weighted = transitionCurve( { point: [0, 0, 0], tangent: [1, 0, 0] }, { point: [10, 5, 0], tangent: [1, 0, 0] }, { weightA: 2.0, weightB: 0.5 }, );
418
-
419
- ```
420
-
421
- ```ts
422
- transitionCurve(edgeA: TransitionEdge, edgeB: TransitionEdge, options?: TransitionCurveOptions): HermiteCurve3D
423
- ```
424
-
425
- **`TransitionEdge`**
426
- - `point: Vec3` — Connection point on the edge. Can be any point along the edge where the transition should connect.
427
- - `tangent: Vec3` — Tangent direction at the connection point. This is the direction the curve should initially follow when leaving this edge. For a straight edge, this is typically the edge direction pointing "outward" (away from the body of the edge, toward the other edge).
428
- - `normal?: Vec3` — Surface normal at the connection point (optional). Used as a hint for the sweep frame's up vector.
429
-
430
- **`TransitionCurveOptions`**
431
- - `weightA?: number` — Weight for the start edge. Controls tangent magnitude at the start. - 1.0 (default): balanced transition - > 1.0: curve follows start edge longer before turning - < 1.0: curve turns sooner at the start
432
- - `weightB?: number` — Weight for the end edge. Controls tangent magnitude at the end. - 1.0 (default): balanced transition - > 1.0: curve follows end edge longer before turning - < 1.0: curve turns sooner at the end
433
- - `samples?: number` — Number of sample points for the output polyline. Default 64. Higher values give smoother curves at the cost of more geometry.
434
-
435
- #### `transitionSurface()` — Create a solid transition surface between two edges by sweeping a profile along a Hermite transition curve.
436
-
437
- This produces a watertight solid that smoothly connects the two edges. Works with both Manifold and OCCT backends.
438
-
439
- ```js
440
- // Circular tube connecting two edges
441
- const tube = transitionSurface(
442
- { point: [0, 0, 0], tangent: [1, 0, 0] },
443
- { point: [10, 5, 3], tangent: [0, 1, 0] },
444
- { radius: 0.5 },
445
- );
446
- ```
447
-
448
- // Custom profile with weights const custom = transitionSurface( { point: [0, 0, 0], tangent: [1, 0, 0] }, { point: [10, 5, 3], tangent: [0, 1, 0] }, { profile: mySketch, weightA: 1.5, weightB: 0.8 }, );
449
-
450
- ```
451
-
452
- ```ts
453
- transitionSurface(edgeA: TransitionEdge, edgeB: TransitionEdge, options?: TransitionSurfaceOptions): Shape
454
- ```
455
-
456
-
457
- **`TransitionSurfaceOptions`** extends TransitionCurveOptions
458
-
459
- | Option | Type | Description |
460
- |--------|------|-------------|
461
- | `profile?` | `Sketch` | Cross-section profile to sweep along the transition curve. If omitted, a circular profile with `radius` is used. |
462
- | `radius?` | `number` | Radius of circular cross-section (used when `profile` is omitted). Default: 5% of chord length. |
463
- | `rectangleSection?` | `{ width: number; height: number; }` | Width and height for rectangular cross-section. Alternative to `radius` when `profile` is omitted. |
464
- | `up?` | `Vec3` | Preferred up vector for the sweep frame. Default: auto-detected. |
465
- | `edgeLength?` | `number` | Edge length for level-set meshing. Smaller = finer. |
466
- | `boundsPadding?` | `number` | Extra bounds padding for level-set meshing. |
467
-
468
- #### `connectEdges()` — Create a transition surface or solid bridge between two edge segments.
469
-
470
- Tangents can be inferred from neighboring geometry or supplied explicitly through `options`. This is useful for loft-like blends where you want a direct connection between two edge spans.
471
-
472
- ```ts
473
- connectEdges(edgeA: EdgeSegment, edgeB: EdgeSegment, options?: ConnectEdgesOptions): Shape
474
- ```
475
-
476
- **`EdgeSegment`**
477
-
478
- | Option | Type | Description |
479
- |--------|------|-------------|
480
- | `index` | `number` | Stable index within the extraction (deterministic for a given mesh). |
481
- | `direction` | `Vec3` | Normalized direction from start → end. |
482
- | `dihedralAngle` | `number` | Dihedral angle in degrees (0 = coplanar, 180 = knife edge). |
483
- | `convex` | `boolean` | true = outside corner (convex), false = inside corner (concave). |
484
- | `normalA` | `Vec3` | Normal of first adjacent face. |
485
- | `normalB` | `Vec3` | Normal of second adjacent face (same as normalA for boundary edges). |
486
- | `boundary` | `boolean` | true if this is a boundary (unmatched) edge — unusual for closed solids. |
487
- | `start`, `end`, `midpoint`, `length` | | — |
488
-
489
-
490
- **`ConnectEdgesOptions`** extends TransitionSurfaceOptions
491
-
492
- | Option | Type | Description |
493
- |--------|------|-------------|
494
- | `endA?` | `EdgeEnd` | Which end of edge A to connect. Default: 'start'. |
495
- | `endB?` | `EdgeEnd` | Which end of edge B to connect. Default: 'start'. |
496
- | `tangentModeA?` | `TangentMode` | Tangent mode for edge A. Default: 'along'. |
497
- | `tangentModeB?` | `TangentMode` | Tangent mode for edge B. Default: 'along'. |
498
- | `tangentA?` | `Vec3` | Explicit tangent for edge A. |
499
- | `tangentB?` | `Vec3` | Explicit tangent for edge B. |
500
- | `flipA?` | `boolean` | Flip tangent A. |
501
- | `flipB?` | `boolean` | Flip tangent B. |
502
-
503
- ### Surface Members
504
-
505
- #### `surfaceBand()`
506
-
507
- ```ts
508
- surfaceBand<C extends SurfaceCoordinate>(path: SurfacePath<C> | SurfacePathBuilder<C>, width: WidthProfile, cap?: SurfaceBandCap): SurfaceBand<C>
509
- ```
510
-
511
- #### `SurfaceBody()` — Start a surface-member body builder for straps, inlays, guards, braces, cuffs, and similar physical members that live on a carrier surface.
512
-
513
- ```js
514
- const carrier = Carrier.cylinder('guard-envelope').diameter(84).height(36).clearance(2);
515
- const guard = SurfaceBody('simple-guard')
516
- .carrier(carrier)
517
- .member('left-strut')
518
- .band()
519
- .path(carrier.path().from({ angle: -132, z: 6 }).to({ angle: -58, z: 18 }))
520
- .section({ width: 5.5, thickness: 2.8, edgeRadius: 0.6 })
521
- .member('right-strut')
522
- .mirrorOf('left-strut')
523
- .member('front-hoop')
524
- .band()
525
- .path(carrier.path().around({ z: 18, fromAngle: -58, toAngle: 58 }))
526
- .section({ width: 6.2, thickness: 3, edgeRadius: 0.7 })
527
- .join('left-strut', 'front-hoop').blend({ radius: 3.2 })
528
- .join('right-strut', 'front-hoop').blend({ radius: 3.2 })
529
- .build();
530
- ```
531
-
532
- ```ts
533
- SurfaceBody(name: string): SurfaceBodyBuilder
534
- ```
535
-
536
- ---
537
-
538
- ## Classes
539
-
540
- ### `Curve3D`
541
-
542
- **Properties:**
543
-
544
- | Property | Type | Description |
545
- |----------|------|-------------|
546
- | `points` | `Vec3[]` | — |
547
- | `closed` | `boolean` | — |
548
- | `tension` | `number` | — |
549
-
550
- **Methods:**
551
-
552
- #### `sampleBySegment()` — Sample the curve with a fixed number of points per segment.
553
-
554
- ```ts
555
- sampleBySegment(samplesPerSegment?: number): Vec3[]
556
- ```
557
-
558
- #### `sample()` — Sample the curve to an approximate total point count.
559
-
560
- ```ts
561
- sample(count?: number): Vec3[]
562
- ```
563
-
564
- #### `pointAt()` — Return the position on the curve at normalized parameter `t` in `[0, 1]`. O(1), no allocations.
565
-
566
- ```ts
567
- pointAt(t: number): Vec3
568
- ```
569
-
570
- #### `tangentAt()` — Return a unit tangent vector at normalized parameter `t` in `[0, 1]`. O(1), analytical derivative.
571
-
572
- ```ts
573
- tangentAt(t: number): Vec3
574
- ```
575
-
576
- #### `length()` — Approximate the curve length by polyline sampling.
577
-
578
- ```ts
579
- length(samples?: number): number
580
- ```
581
-
582
- ### `HelixCurve`
583
-
584
- Metadata-bearing helical curve around the Z axis. Use `Helix.path(...)` for sampling, placement, or `sweep()`, and `Helix.coil(...)` for helix-oriented solids.
585
-
586
- **Properties:**
587
-
588
- | Property | Type | Description |
589
- |----------|------|-------------|
590
- | `radius` | `number` | — |
591
- | `pitch` | `number` | — |
592
- | `turns` | `number` | — |
593
- | `height` | `number` | — |
594
- | `startAngle` | `number` | — |
595
- | `clockwise` | `boolean` | — |
596
-
597
- **Methods:**
598
-
599
- #### `pointAt()`
600
-
601
- ```ts
602
- pointAt(t: number): Vec3
603
- ```
604
-
605
- #### `tangentAt()`
606
-
607
- ```ts
608
- tangentAt(t: number): Vec3
609
- ```
610
-
611
- #### `sample()`
612
-
613
- ```ts
614
- sample(count?: number): Vec3[]
615
- ```
616
-
617
- #### `length()`
618
-
619
- ```ts
620
- length(): number
621
- ```
622
-
623
- ### `NurbsCurve3D`
624
-
625
- **Properties:**
626
-
627
- | Property | Type | Description |
628
- |----------|------|-------------|
629
- | `controlPoints` | `Vec3[]` | — |
630
- | `weights` | `number[]` | — |
631
- | `knots` | `number[]` | — |
632
- | `degree` | `number` | — |
633
- | `closed` | `boolean` | — |
634
-
635
- **Methods:**
636
-
637
- #### `pointAt()` — Evaluate the curve at parameter t ∈ [0, 1]. Uses De Boor's algorithm — exact, O(degree²).
638
-
639
- ```ts
640
- pointAt(t: number): Vec3
641
- ```
642
-
643
- #### `tangentAt()` — Evaluate the unit tangent vector at parameter t ∈ [0, 1].
644
-
645
- ```ts
646
- tangentAt(t: number): Vec3
647
- ```
648
-
649
- #### `sample()` — Sample the curve uniformly at `count` points.
650
-
651
- ```ts
652
- sample(count?: number): Vec3[]
653
- ```
654
-
655
- #### `sampleAdaptive()` — Sample with adaptive density — more points in high-curvature regions.
656
-
657
- ```ts
658
- sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
659
- ```
660
-
661
- #### `length()` — Approximate arc length by summing polyline segment lengths.
662
-
663
- ```ts
664
- length(samples?: number): number
665
- ```
666
-
667
- #### `toPolyline()` — Convert to a format compatible with sweep() path input.
668
-
669
- ```ts
670
- toPolyline(samples?: number): Vec3[]
671
- ```
672
-
673
- ### `NurbsSurface`
674
-
675
- **Properties:**
676
-
677
- | Property | Type | Description |
678
- |----------|------|-------------|
679
- | `controlGrid` | `Vec3[][]` | — |
680
- | `weightsGrid` | `number[][]` | — |
681
- | `knotsU` | `number[]` | — |
682
- | `knotsV` | `number[]` | — |
683
- | `degreeU` | `number` | — |
684
- | `degreeV` | `number` | — |
685
- | `nU` | `number` | — |
686
- | `nV` | `number` | — |
687
- | `domain` | `SurfaceDomainCompilePlan` | — |
688
-
689
- **Methods:**
690
-
691
- #### `pointAt()` — Evaluate the surface at parameters (u, v) ∈ [0, 1]². Uses tensor product evaluation: evaluate basis functions in U and V independently.
692
-
693
- ```ts
694
- pointAt(u: number, v: number): Vec3
695
- ```
696
-
697
- #### `normalAt()` — Evaluate the surface normal at (u, v) via cross product of partial derivatives.
698
-
699
- ```ts
700
- normalAt(u: number, v: number): Vec3
701
- ```
702
-
703
- #### `tessellate()` — Tessellate the surface into a triangle mesh. Returns positions, normals, and triangle indices.
704
-
705
- ```ts
706
- tessellate(resU?: number, resV?: number): { positions: Vec3[]; normals: Vec3[]; indices: number[]; }
707
- ```
708
-
709
- ### `PathBuilder`
710
-
711
- **Line Segments**
712
-
713
- #### `moveTo()` — Move the cursor to an absolute position without drawing a segment.
714
-
715
- When called after the initial [`path()`](/docs/sketch#path), this establishes the start of the outline. Calling `moveTo` again mid-path starts a new sub-path (hole in `close()`, separate segment for [`stroke()`](/docs/sketch#stroke)).
716
-
717
- ```ts
718
- moveTo(x: number, y: number): this
719
- ```
720
-
721
- #### `lineTo()` — Draw a straight line from the current cursor to an absolute position.
722
-
723
- ```ts
724
- lineTo(x: number, y: number): this
725
- ```
726
-
727
- #### `lineH()` — Draw a horizontal line segment by `dx` units from the current cursor.
728
-
729
- Positive `dx` moves right; negative moves left.
730
-
731
- ```ts
732
- lineH(dx: number): this
733
- ```
734
-
735
- #### `lineV()` — Draw a vertical line segment by `dy` units from the current cursor.
736
-
737
- Positive `dy` moves up; negative moves down.
738
-
739
- ```ts
740
- lineV(dy: number): this
741
- ```
742
-
743
- #### `lineAngled()` — Draw a line at the given angle and length from the current cursor.
744
-
745
- Angle convention: `0°` points right (+X), `90°` points up (+Y).
746
-
747
- ```ts
748
- // L-bracket with angled return
749
- path().moveTo(0, 0).lineH(50).lineV(-70).lineAngled(20, 235).stroke(4);
750
- ```
751
-
752
- ```ts
753
- lineAngled(length: number, degrees: number): this
754
- ```
755
-
756
- **Arcs**
757
-
758
- #### `arc()` — Draw an arc defined by center, radius, and angle range (no trig needed). If the path has no segments yet, automatically moves to the arc start. Positive sweep (startDeg < endDeg) = CCW, negative = CW.
759
-
760
- ```js
761
- // Arc centered at (10, 0), radius 50, from -30° to +30°
762
- path().arc(10, 0, 50, -30, 30).stroke(8, 'Round')
763
- ```
764
-
765
- ```ts
766
- arc(cx: number, cy: number, radius: number, startDeg: number, endDeg: number): this
767
- ```
768
-
769
- #### `arcTo()` — Draw a circular arc from the current position to (x, y) with the given radius. `clockwise=true` → arc curves to the right of the start→end direction. `clockwise=false` → arc curves to the left of the start→end direction.
770
-
771
- ```ts
772
- arcTo(x: number, y: number, radius: number, clockwise?: boolean): this
773
- ```
774
-
775
- #### `tangentArcTo()` — G1-continuous arc — radius derived from current tangent + endpoint. Throws if endpoint is collinear with current direction.
776
-
777
- ```ts
778
- tangentArcTo(x: number, y: number): this
779
- ```
780
-
781
- **Curves**
782
-
783
- #### `bezierTo()` — Cubic bezier from current position to (x, y) via two control points.
784
-
785
- ```ts
786
- bezierTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): this
787
- ```
788
-
789
- **Closing & Output**
790
-
791
- #### `close()` — Close the path and return a filled [`Sketch`](/docs/sketch#sketch).
792
-
793
- The winding of the polygon is automatically corrected to CCW (the expected orientation for ForgeCAD sketches). If the path contains multiple sub-paths (started with subsequent `moveTo` calls), the first sub-path is the outer contour and subsequent sub-paths become holes subtracted from it.
794
-
795
- Edge labels (assigned with `.label('name')`) are transferred to the resulting sketch and propagate through `extrude()`, `revolve()`, `loft()`, and `sweep()` into named faces on the resulting [`Shape`](/docs/core#shape).
796
-
797
- ```ts
798
- const triangle = path().moveTo(0, 0).lineH(50).lineV(30).close();
799
-
800
- // With a hole (second sub-path)
801
- const frame = path()
802
- .moveTo(0, 0).lineH(40).lineV(30).lineH(-40).close(); // outer
803
- // (hole would be added with another moveTo and line sequence before close)
804
- ```
805
-
806
- ```ts
807
- close(): Sketch
808
- ```
809
-
810
- #### `closeLabel()` — Label the closing segment and close the path. Shorthand for labeling the implicit line from the last point back to the start, then closing.
811
-
812
- ```ts
813
- closeLabel(name: string): Sketch
814
- ```
815
-
816
- #### [`stroke()`](/docs/sketch#stroke) — Thicken an open polyline (centerline) into a solid filled profile with uniform width.
817
-
818
- Expands the path into a closed profile `width` units wide (half-width on each side of the centerline). Use `'Round'` for ribs, wire traces, and organic profiles — it adds semicircular endcaps and rounds joins. Use `'Square'` (default) for sharp miter joins without endcaps.
819
-
820
- Not the same as rounding corners of a closed polygon — for mixed sharp-and-rounded outlines, build the polygon first and apply [`filletCorners()`](/docs/sketch#filletcorners).
821
-
822
- ```ts
823
- // Square-join L-bracket
824
- const bracket = path().moveTo(0, 0).lineH(50).lineV(-70).lineAngled(20, 235).stroke(4);
825
-
826
- // Round-join rib
827
- const rib = path().moveTo(0, 0).lineH(60).stroke(6, 'Round');
828
-
829
- // Equivalent standalone form
830
- const wire = stroke([[0, 0], [50, 0], [50, -70]], 4);
831
- ```
832
-
833
- and semicircular endcaps.
834
-
835
- ```ts
836
- stroke(width: number, join?: "Round" | "Square"): Sketch
837
- ```
838
-
839
- #### `label()` — Label the most recently added segment. Labels are born here and grow into face names when the sketch is extruded, lofted, swept, or revolved.
840
-
841
- Labels must be unique within a path. Each segment can have at most one label.
842
-
843
- ```ts
844
- label(name: string): this
845
- ```
846
-
847
- **Other**
848
-
849
- #### `getX()` — Current cursor X position.
850
-
851
- ```ts
852
- getX(): number
853
- ```
854
-
855
- #### `getY()` — Current cursor Y position.
856
-
857
- ```ts
858
- getY(): number
859
- ```
860
-
861
- #### `lineBy()` — Draw a line by a relative `(dx, dy)` displacement from the current cursor.
862
-
863
- ```ts
864
- lineBy(dx: number, dy: number): this
865
- ```
866
-
867
- #### `arcBy()` — Draw an arc to a point offset from the current cursor.
868
-
869
- ```ts
870
- arcBy(dx: number, dy: number, radius: number, clockwise?: boolean): this
871
- ```
872
-
873
- #### `bezierBy()` — Draw a cubic Bezier using control points relative to the current cursor.
874
-
875
- ```ts
876
- bezierBy(dcp1x: number, dcp1y: number, dcp2x: number, dcp2y: number, dx: number, dy: number): this
877
- ```
878
-
879
- #### `arcAround()` — Arc around a known center point, sweeping by the given angle. Radius is derived from the distance between the current position and the center. Positive sweep = CCW (math convention), negative = CW.
880
-
881
- ```js
882
- // Arc 90° CCW around (50, 50)
883
- path().moveTo(70, 50).arcAround(50, 50, 90)
884
- // Arc 45° CW around the origin
885
- path().moveTo(10, 0).arcAround(0, 0, -45)
886
- ```
887
-
888
- ```ts
889
- arcAround(cx: number, cy: number, sweepDeg: number): this
890
- ```
891
-
892
- #### `arcAroundRelative()` — Arc around a center point given as an offset from the current position. `(dx, dy)` is the vector from the current point to the center. Positive sweep = CCW (math convention), negative = CW.
893
-
894
- ```js
895
- // Arc 90° CCW around a center 20 units to the right
896
- path().moveTo(50, 50).arcAroundRelative(20, 0, 90)
897
- // Equivalent to: path().moveTo(50, 50).arcAround(70, 50, 90)
898
- ```
899
-
900
- ```ts
901
- arcAroundRelative(dx: number, dy: number, sweepDeg: number): this
902
- ```
903
-
904
- #### `smoothCapTo()` — Smooth three-arc end cap from the current position to (endX, endY). Inserts: small corner arc → large cap arc → small corner arc, all G1-continuous.
905
-
906
- ```ts
907
- smoothCapTo(endX: number, endY: number, cornerRadius: number, capRadius: number): this
908
- ```
909
-
910
- #### `tangentBezierTo()` — G1-continuous cubic bezier — first control point is auto-derived from the current tangent direction. `weight` controls how far the auto-placed control point extends along the tangent (default: 1/3 of the chord).
911
-
912
- The second control point `(cp2x, cp2y)` must be provided — it controls the arrival curvature. For a fully automatic smooth curve, see `smoothThrough`.
913
-
914
- ```ts
915
- tangentBezierTo(cp2x: number, cp2y: number, x: number, y: number, weight?: number): this
916
- ```
917
-
918
- #### `smoothThrough()` — Catmull-Rom spline through a list of waypoints from the current position. The current position is included as the first point. The last waypoint becomes the new cursor position.
919
-
920
- ```ts
921
- smoothThrough(waypoints: [ number, number ][], tension?: number): this
922
- ```
923
-
924
- #### `nurbsTo()` — Rational B-spline edge to (x, y) with explicit control points and weights.
925
-
926
- The control points define the B-spline shape between the current position and (x, y). The current position is NOT included in `controlPoints` — it is automatically prepended. The endpoint (x, y) is the last control point.
927
-
928
- ```ts
929
- nurbsTo(controlPoints: [ number, number ][], opts?: { weights?: number[]; degree?: number; }): this
930
- ```
931
-
932
- #### `exactArcTo()` — Exact circular arc to (x, y) using a rational quadratic NURBS.
933
-
934
- Unlike `arcTo()` which tessellates to a polyline, this preserves the exact arc definition. When extruded through the OCCT backend, it produces a true cylindrical face — not a faceted approximation.
935
-
936
- ```ts
937
- exactArcTo(x: number, y: number, opts?: { radius?: number; clockwise?: boolean; }): this
938
- ```
939
-
940
- #### [`fillet()`](/docs/core#fillet) — Round the last corner (the junction between the previous two segments) with a tangent arc of the given radius.
941
-
942
- Must be called after at least two line/arc segments that form a corner. The fillet trims back both segments and inserts a tangent arc.
943
-
944
- ```js
945
- path().moveTo(0,0).lineTo(10,0).lineTo(10,10).fillet(2).lineTo(0,10).close()
946
- ```
947
-
948
- ```ts
949
- fillet(radius: number): this
950
- ```
951
-
952
- #### [`chamfer()`](/docs/core#chamfer) — Chamfer the last corner with a straight cut of the given distance.
953
-
954
- ```js
955
- path().moveTo(0,0).lineTo(10,0).lineTo(10,10).chamfer(2).lineTo(0,10).close()
956
- ```
957
-
958
- ```ts
959
- chamfer(distance: number): this
960
- ```
961
-
962
- #### `mirror()` — Mirror all existing segments across an axis and append the mirrored copy in reverse order, creating a symmetric path. The axis passes through the current cursor position.
963
-
964
- 'y' mirrors across the local Y-axis (flips X), or `[nx, ny]` for an arbitrary axis direction.
965
-
966
- ```js
967
- // Build right half, mirror to get full symmetric profile
968
- path().moveTo(0,0).lineTo(10,0).lineTo(10,5).mirror('x').close()
969
- ```
970
-
971
- ```ts
972
- mirror(axis: "x" | "y" | [ number, number ]): this
973
- ```
974
-
975
- #### `toPolyline()` — Return the open path as a sampled 2D polyline.
976
-
977
- This is for construction geometry such as guide rails, measured centerlines, and curve-driven helpers where the authored path should stay open instead of becoming a filled sketch or stroked profile.
978
-
979
- ```ts
980
- const rail = path()
981
- .moveTo(24, 0)
982
- .bezierTo(32, 44, 28, 92, 18, 120)
983
- .toPolyline();
984
- ```
985
-
986
- ```ts
987
- toPolyline(): [ number, number ][]
988
- ```
989
-
990
- #### `closeOffset()` — Close the path and return an offset version of the filled Sketch. Positive delta expands outward, negative shrinks inward.
991
-
992
- ```ts
993
- closeOffset(delta: number, join?: "Round" | "Square" | "Miter"): Sketch
994
- ```
995
-
996
- ### `HermiteCurve3D`
997
-
998
- **Properties:**
999
-
1000
- | Property | Type | Description |
1001
- |----------|------|-------------|
1002
- | `p0` | `Vec3` | Start position |
1003
- | `p1` | `Vec3` | End position |
1004
- | `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
1005
- | `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
1006
- | `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
1007
-
1008
- **Methods:**
1009
-
1010
- #### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
1011
-
1012
- ```ts
1013
- pointAt(t: number): Vec3
1014
- ```
1015
-
1016
- #### `tangentAt()` — Evaluate tangent (first derivative) at parameter t ∈ [0, 1]
1017
-
1018
- ```ts
1019
- tangentAt(t: number): Vec3
1020
- ```
1021
-
1022
- #### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
1023
-
1024
- ```ts
1025
- curvatureAt(t: number): Vec3
1026
- ```
1027
-
1028
- #### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
1029
-
1030
- ```ts
1031
- sample(count?: number): Vec3[]
1032
- ```
1033
-
1034
- #### `length()` — Approximate arc length by sampling.
1035
-
1036
- ```ts
1037
- length(samples?: number): number
1038
- ```
1039
-
1040
- #### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
1041
-
1042
- ```ts
1043
- sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
1044
- ```
1045
-
1046
- #### `toPolyline()` — Convert to a format compatible with sweep() path input.
1047
-
1048
- ```ts
1049
- toPolyline(samples?: number): Vec3[]
1050
- ```
1051
-
1052
- ### `QuinticHermiteCurve3D`
1053
-
1054
- **Properties:**
1055
-
1056
- | Property | Type | Description |
1057
- |----------|------|-------------|
1058
- | `p0` | `Vec3` | Start position |
1059
- | `p1` | `Vec3` | End position |
1060
- | `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
1061
- | `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
1062
- | `c0` | `Vec3` | Scaled second derivative at start (curvature * weight² * chordLength²) |
1063
- | `c1` | `Vec3` | Scaled second derivative at end (curvature * weight² * chordLength²) |
1064
- | `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
1065
-
1066
- **Methods:**
1067
-
1068
- #### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
1069
-
1070
- ```ts
1071
- pointAt(t: number): Vec3
1072
- ```
1073
-
1074
- #### `tangentAt()` — Evaluate tangent (first derivative, normalized) at parameter t ∈ [0, 1]
1075
-
1076
- ```ts
1077
- tangentAt(t: number): Vec3
1078
- ```
1079
-
1080
- #### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
1081
-
1082
- ```ts
1083
- curvatureAt(t: number): Vec3
1084
- ```
1085
-
1086
- #### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
1087
-
1088
- ```ts
1089
- sample(count?: number): Vec3[]
1090
- ```
1091
-
1092
- #### `length()` — Approximate arc length by sampling.
1093
-
1094
- ```ts
1095
- length(samples?: number): number
1096
- ```
1097
-
1098
- #### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
1099
-
1100
- ```ts
1101
- sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
1102
- ```
1103
-
1104
- #### `toPolyline()` — Convert to a format compatible with sweep() path input.
1105
-
1106
- ```ts
1107
- toPolyline(samples?: number): Vec3[]
1108
- ```
1109
-
1110
- ### `ProductSkin`
1111
-
1112
- **Properties:**
1113
-
1114
- | Property | Type | Description |
1115
- |----------|------|-------------|
1116
- | `name` | `string` | — |
1117
- | `shape` | `Shape` | — |
1118
- | `axis` | `ProductSkinAxis` | — |
1119
- | `stations` | `ProductStationSpec[]` | — |
1120
- | `rails` | `Record<string, ProductRailSpec>` | — |
1121
-
1122
- **Methods:**
1123
-
1124
- #### [`toShape()`](/docs/sdf#toshape) — Return the renderable shape generated for this product skin.
1125
-
1126
- ```ts
1127
- toShape(): Shape
1128
- ```
1129
-
1130
- #### `with()` — Create a group containing this skin plus named child details.
1131
-
1132
- ```ts
1133
- with(...children: GroupInput[]): ShapeGroup
1134
- ```
1135
-
1136
- #### `integrate()` — Boolean-union structural details into the skin body.
1137
-
1138
- ```ts
1139
- integrate(...details: Shape[]): Shape
1140
- ```
1141
-
1142
- #### `uv()` — Create a side/u/v surface-ref query on this skin.
1143
-
1144
- ```ts
1145
- uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery
1146
- ```
1147
-
1148
- **`ProductSkinSide`** — Semantic side of a ProductSkin. `back` is accepted as an alias for `rear`.
1149
-
1150
- `"left" | "right" | "top" | "bottom" | "front" | "rear" | "back"`
1151
-
1152
- **`ProductSkinRefQuery`**
1153
-
1154
- | Option | Type | Description |
1155
- |--------|------|-------------|
1156
- | `side` | `ProductSkinSide` | Side of the product skin. `front` is the minimum axis cap, `rear`/`back` is the maximum axis cap. |
1157
- | `u?` | `number` | Across-side parameter for side refs. Defaults to 0.5. |
1158
- | `v?` | `number` | Along-axis parameter, 0 at the first cap and 1 at the rear/back cap. Defaults to 0.5. |
1159
- | `offset?` | `number` | Positive distance away from the surface along the resolved normal. |
1160
-
1161
- #### `ref()` — Resolve a named ref published with Product.skin().refs(...).
1162
-
1163
- ```ts
1164
- ref(name: string): ProductSurfaceRef
1165
- ```
1166
-
1167
- #### `curveOnSurface()` — Create a sampled curve as a sequence of surface refs on this skin.
1168
-
1169
- ```ts
1170
- curveOnSurface(name: string, points: Array<Partial<ProductSkinRefQuery> & { side: ProductSkinSide; }>): ProductSurfaceRef[]
1171
- ```
1172
-
1173
- #### `surface()` — Create a fluent surface helper for refs and conformal features on one side of this skin.
1174
-
1175
- Use this when several refs or ribbons share the same skin side; side-local helpers keep path points concise and make it harder to mix sides accidentally.
1176
-
1177
- ```ts
1178
- surface(side: ProductSkinSide): ProductSurfaceBuilder
1179
- ```
1180
-
1181
- #### `stationAt()` — Interpolate center, width, and depth at a normalized v or absolute axis value.
1182
-
1183
- ```ts
1184
- stationAt(vOrAxis: number): { ... }
1185
- ```
1186
-
1187
- **`ProductProfileKind`**
1188
-
1189
- `"oval" | "roundedRect" | "circle" | "superEllipse" | "custom"`
1190
-
1191
- #### `frame()` — Build a local surface frame from a side/u/v query.
1192
-
1193
- ```ts
1194
- frame(query: ProductSkinRefQuery): ProductSurfaceFrame
1195
- ```
1196
-
1197
- `ProductSurfaceFrame`: `{ point: Vec3, normal: Vec3, tangentU: Vec3, tangentV: Vec3, matrix: Mat4, skin: string }`
1198
-
1199
- ### `ProductSurfaceRef`
1200
-
1201
- **Properties:**
1202
-
1203
- | Property | Type | Description |
1204
- |----------|------|-------------|
1205
- | `name` | `string | undefined` | — |
1206
-
1207
- **Methods:**
1208
-
1209
- #### `frame()` — Resolve this semantic surface ref into a point, normal, tangents, and placement matrix.
1210
-
1211
- ```ts
1212
- frame(overrides?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame
1213
- ```
1214
-
1215
- #### `with()` — Return a copy of this ref with side/u/v/offset overrides.
1216
-
1217
- ```ts
1218
- with(overrides: Partial<ProductSkinRefQuery>): ProductSurfaceRef
1219
- ```
1220
-
1221
- #### `attach()` — Place a detail shape or group on this ref's local surface frame.
1222
-
1223
- ```ts
1224
- attach(detail: Shape | ShapeGroup, options?: ProductAttachOptions): Shape | ShapeGroup
1225
- ```
1226
-
1227
- `ProductAttachOptions`: `{ offset?: number, inset?: number }`
1228
-
1229
- #### `querySpec()` — Return the serializable side/u/v query behind this ref.
1230
-
1231
- ```ts
1232
- querySpec(): ProductSkinRefQuery
1233
- ```
1234
-
1235
- ### `ProductSurfaceBuilder`
1236
-
1237
- Fluent helper bound to one ProductSkin side for refs and side-local conformal features.
1238
-
1239
- **Properties:**
1240
-
1241
- | Property | Type | Description |
1242
- |----------|------|-------------|
1243
- | `side` | `ProductSkinSide` | — |
1244
-
1245
- **Methods:**
1246
-
1247
- #### `ref()` — Create a ref on this skin side.
1248
-
1249
- ```ts
1250
- ref(u?: number, v?: number, offset?: number): ProductSurfaceRef
1251
- ```
1252
-
1253
- #### `uv()` — Create a side/u/v query on this skin side.
1254
-
1255
- ```ts
1256
- uv(u?: number, v?: number, offset?: number): ProductSkinRefQuery
1257
- ```
1258
-
1259
- #### `frame()` — Resolve a point/frame on this surface using the builder's side.
1260
-
1261
- ```ts
1262
- frame(query?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame
1263
- ```
1264
-
1265
- #### `ribbon()` — Start a conformal ribbon on this skin side.
1266
-
1267
- Path points use side-local `u`/`v` coordinates; this builder supplies the side. The returned ProductRibbonBuilder is already bound to the source skin and can be further configured before build(). Use `widthSamples` >= 3 when the ribbon must visibly wrap over curved product sections instead of behaving like a flat strip.
1268
-
1269
- ```ts
1270
- ribbon(name: string, points: ProductSurfacePathPoint[], options?: ProductRibbonBuildOptions): ProductRibbonBuilder
1271
- ```
1272
-
1273
- **`ProductSurfacePathPoint`** — Side-local path point for Product.surface(side).ribbon(...); the surface helper supplies `side`.
1274
- - `u?: number` — Across-side parameter on the bound side. Defaults to 0.5.
1275
- - `v?: number` — Along-axis parameter, 0 at the first cap and 1 at the rear/back cap. Defaults to 0.5.
1276
- - `offset?: number` — Positive distance away from the surface along the resolved normal.
1277
-
1278
- **`ProductRibbonBuildOptions`** — Options shared by Product.ribbon() builders and Product.surface(...).ribbon(...).
1279
-
1280
- | Option | Type | Description |
1281
- |--------|------|-------------|
1282
- | `width?` | `number` | Width across the surface in millimeters. |
1283
- | `thickness?` | `number` | Solid thickness outward from the source surface in millimeters. |
1284
- | `offset?` | `number` | Positive clearance between the source surface and the ribbon's inner face. |
1285
- | `samples?` | `number` | Samples along the ribbon path. Higher values bend more smoothly. |
1286
- | `widthSamples?` | `number` | Samples across the ribbon width. Use 3+ to visibly wrap over curved cross-sections. |
1287
- | `resolution?` | `number` | Tessellation resolution passed to the lowered NURBS surface. |
1288
- | `material?` | `ProductMaterial` | Apply a product material preset to the ribbon. |
1289
- | `color?` | `string` | Apply a simple color override. |
1290
-
1291
- `ProductMaterial`: `{ color?: string, material?: ShapeMaterialProps }`
1292
-
1293
- **`ShapeMaterialProps`**
1294
-
1295
- | Option | Type | Description |
1296
- |--------|------|-------------|
1297
- | `metalness?` | `number` | Metalness factor (0 = dielectric, 1 = metal). Default: 0.05 |
1298
- | `roughness?` | `number` | Roughness factor (0 = mirror, 1 = fully diffuse). Default: 0.35 |
1299
- | `emissive?` | `string` | Emissive glow color (hex string, e.g. "#ff6b35"). |
1300
- | `emissiveIntensity?` | `number` | Emissive intensity multiplier. Default: 1 |
1301
- | `opacity?` | `number` | Opacity (0 = fully transparent, 1 = fully opaque). Default: 1 |
1302
- | `wireframe?` | `boolean` | Render as wireframe. Default: false |
1303
- | `clearcoat?` | `number` | Clearcoat intensity (0–1). Default: 0.1 |
1304
- | `clearcoatRoughness?` | `number` | Clearcoat roughness (0–1). Default: 0.4 |
1305
- | `transmission?` | `number` | Glass/translucency transmission factor (0–1). Renderer support depends on target. |
1306
- | `ior?` | `number` | Index of refraction for transmissive materials. Typical glass is ~1.45. |
1307
- | `thickness?` | `number` | Approximate transmissive volume thickness in model units. |
1308
- | `specularIntensity?` | `number` | Specular highlight intensity (0–1). |
1309
- | `specularColor?` | `string` | Specular highlight tint. |
1310
- | `reflectivity?` | `number` | Reflection strength for supported renderers (0–1). |
1311
-
1312
- ### `ProductSkinBuilder`
1313
-
1314
- **Properties:**
1315
-
1316
- | Property | Type | Description |
1317
- |----------|------|-------------|
1318
- | `name` | `string` | — |
1319
-
1320
- **Methods:**
1321
-
1322
- #### `axis()` — Choose the primary station axis for the skin loft.
1323
-
1324
- ```ts
1325
- axis(axis: ProductSkinAxis): this
1326
- ```
1327
-
1328
- **`ProductSkinAxis`** — Primary world axis used to order ProductSkin loft stations.
1329
-
1330
- `"X" | "Y" | "Z"`
1331
-
1332
- #### `stations()` — Set named cross-section stations for the product skin.
1333
-
1334
- ```ts
1335
- stations(stations: Array<ProductStationBuilder | ProductStationSpec>): this
1336
- ```
1337
-
1338
- `ProductStationSpec`: `{ name: string, center: Vec3, profile: ProductStationProfile, crown?: number }`
1339
-
1340
- `ProductStationProfile`: `{ sketch: Sketch, width: number, depth: number, kind: ProductProfileKind, radius?: number, exponent?: number }`
1341
-
1342
- #### `rails()` — Attach named guide rails for product-skin construction and downstream surface references.
1343
-
1344
- ```ts
1345
- rails(rails: Record<string, ProductRailSpec>): this
1346
- ```
1347
-
1348
- `ProductRailSpec`: `{ kind: ProductRailKind, points: Vec3[], degree?: number, name?: string }`
1349
-
1350
- **`ProductRailKind`**
1351
-
1352
- `"bezier" | "nurbs" | "polyline"`
1353
-
1354
- #### `ref()` — Publish a named semantic surface ref on the skin.
1355
-
1356
- ```ts
1357
- ref(name: string, query: ProductSkinRefQuery): this
1358
- ```
1359
-
1360
- #### `refs()` — Publish multiple named semantic surface refs on the skin.
1361
-
1362
- ```ts
1363
- refs(refs: Record<string, ProductSkinRefQuery>): this
1364
- ```
1365
-
1366
- #### `uv()` — Create a side/u/v surface-ref query for use in refs(...) or Product.ref(...).
1367
-
1368
- ```ts
1369
- uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery
1370
- ```
1371
-
1372
- #### `material()` — Apply a product material preset to the lowered skin.
1373
-
1374
- ```ts
1375
- material(material: ProductMaterial): this
1376
- ```
1377
-
1378
- #### `color()` — Apply a simple color override to the lowered skin.
1379
-
1380
- ```ts
1381
- color(color: string): this
1382
- ```
1383
-
1384
- #### `edgeLength()` — Set the sampled loft target edge length.
1385
-
1386
- ```ts
1387
- edgeLength(value: number): this
1388
- ```
1389
-
1390
- #### `wall()` — Record intended wall thickness for product design metadata. Use explicit shelling when the model needs real inner-wall geometry.
1391
-
1392
- ```ts
1393
- wall(thickness: number): this
1394
- ```
1395
-
1396
- #### `build()` — Lower stations and refs into a ProductSkin body.
1397
-
1398
- ```ts
1399
- build(): ProductSkin
1400
- ```
1401
-
1402
- ### `ProductStationBuilder`
1403
-
1404
- **Properties:**
1405
-
1406
- | Property | Type | Description |
1407
- |----------|------|-------------|
1408
- | `name` | `string` | — |
1409
-
1410
- **Methods:**
1411
-
1412
- #### `at()` — Position this station in world coordinates.
1413
-
1414
- ```ts
1415
- at(point: Vec3): this
1416
- ```
1417
-
1418
- #### `z()` — Convenience for traditional Z-up section stacks.
1419
-
1420
- ```ts
1421
- z(z: number): this
1422
- ```
1423
-
1424
- #### `y()` — Convenience for product bodies running front-to-back along Y.
1425
-
1426
- ```ts
1427
- y(y: number): this
1428
- ```
1429
-
1430
- #### `x()` — Convenience for product bodies running left-to-right along X.
1431
-
1432
- ```ts
1433
- x(x: number): this
1434
- ```
1435
-
1436
- #### `oval()` — Use an oval cross-section with full width and depth dimensions.
1437
-
1438
- ```ts
1439
- oval(width: number, depth: number, options?: { segments?: number; }): this
1440
- ```
1441
-
1442
- #### `superEllipse()` — Use a superellipse cross-section for soft-square product surfaces.
1443
-
1444
- ```ts
1445
- superEllipse(width: number, depth: number, options?: ProductStationSuperEllipseOptions): this
1446
- ```
1447
-
1448
- `ProductStationSuperEllipseOptions`: `{ segments?: number, exponent?: number }`
1449
-
1450
- #### [`roundedRect()`](/docs/sketch#roundedrect) — Use a rounded-rectangle cross-section with the given corner radius.
1451
-
1452
- ```ts
1453
- roundedRect(width: number, depth: number, radius: number): this
1454
- ```
1455
-
1456
- #### [`circle()`](/docs/sketch#circle) — Use a circular cross-section from a full diameter.
1457
-
1458
- ```ts
1459
- circle(diameter: number, options?: { segments?: number; }): this
1460
- ```
1461
-
1462
- #### `custom()` — Use a custom 2D sketch as the station cross-section.
1463
-
1464
- ```ts
1465
- custom(sketch: Sketch, width: number, depth: number): this
1466
- ```
1467
-
1468
- #### `crown()` — Set the station crown amount for soft product-section intent.
1469
-
1470
- ```ts
1471
- crown(amount: number): this
1472
- ```
1473
-
1474
- #### `toSpec()` — Return the immutable station spec consumed by Product.skin().
1475
-
1476
- ```ts
1477
- toSpec(): ProductStationSpec
1478
- ```
1479
-
1480
- ### `ProductPanelBuilder`
1481
-
1482
- **Properties:**
1483
-
1484
- | Property | Type | Description |
1485
- |----------|------|-------------|
1486
- | `name` | `string` | — |
1487
-
1488
- **Methods:**
1489
-
1490
- #### `rounded()` — Use a rounded rectangle panel profile.
1491
-
1492
- ```ts
1493
- rounded(width: number, height: number, radius?: number): this
1494
- ```
1495
-
1496
- #### `oval()` — Use an oval panel profile.
1497
-
1498
- ```ts
1499
- oval(width: number, height: number): this
1500
- ```
1501
-
1502
- #### `profile()` — Use a custom 2D panel profile.
1503
-
1504
- ```ts
1505
- profile(profile: Sketch): this
1506
- ```
1507
-
1508
- #### `thickness()` — Set panel extrusion thickness.
1509
-
1510
- ```ts
1511
- thickness(thickness: number): this
1512
- ```
1513
-
1514
- #### `material()` — Apply a product material preset to the panel.
1515
-
1516
- ```ts
1517
- material(material: ProductMaterial): this
1518
- ```
1519
-
1520
- #### `color()` — Apply a simple color override to the panel.
1521
-
1522
- ```ts
1523
- color(color: string): this
1524
- ```
1525
-
1526
- #### `build()` — Build the panel in local coordinates.
1527
-
1528
- ```ts
1529
- build(): Shape
1530
- ```
1531
-
1532
- #### `attachTo()` — Build and attach this panel to a ProductSurfaceRef.
1533
-
1534
- ```ts
1535
- attachTo(ref: ProductRefInput, options?: ProductPanelAttachOptions): Shape
1536
- ```
1537
-
1538
- **`ProductRefInput`**
1539
-
1540
- `ProductSurfaceRef`
1541
-
1542
-
1543
- `ProductPanelAttachOptions`: `{ at?: Partial<ProductSkinRefQuery>, thickness?: number, material?: ProductMaterial, color?: string }`
1544
-
1545
- ### `ProductRibbonBuilder`
1546
-
1547
- Builder for thin trim, label, grip, and split-line features that bend with a ProductSkin surface.
1548
-
1549
- **Properties:**
1550
-
1551
- | Property | Type | Description |
1552
- |----------|------|-------------|
1553
- | `name` | `string` | — |
1554
-
1555
- **Methods:**
1556
-
1557
- #### `on()` — Follow a ProductSkin with side/u/v path queries or refs.
1558
-
1559
- This is the highest-fidelity mode because every interpolated sample is resolved through ProductSkin.frame(), so the ribbon bends along the selected side as station width/depth changes. All query path points must stay on one side; split side transitions into separate ribbons.
1560
-
1561
- ```ts
1562
- on(skin: ProductSkin, points: ProductRibbonPathPoint[], options?: ProductRibbonBuildOptions): this
1563
- ```
1564
-
1565
- **`ProductRibbonPathPoint`** — Path point for Product.ribbon().on(...): either a side/u/v query or a resolved surface ref.
1566
-
1567
- `ProductSkinRefQuery | ProductSurfaceRef`
1568
-
1569
- #### `fromRefs()` — Follow explicit surface refs.
1570
-
1571
- Useful for named refs or paths assembled elsewhere. The builder resolves each ref frame and interpolates between those frames; use on(skin, points) when you need full skin-side sampling between sparse control points.
1572
-
1573
- ```ts
1574
- fromRefs(points: ProductSurfaceRef[], options?: ProductRibbonBuildOptions): this
1575
- ```
1576
-
1577
- #### `width()` — Set ribbon width in millimeters.
1578
-
1579
- ```ts
1580
- width(width: number): this
1581
- ```
1582
-
1583
- #### `thickness()` — Set solid thickness outward from the source surface in millimeters.
1584
-
1585
- ```ts
1586
- thickness(thickness: number): this
1587
- ```
1588
-
1589
- #### `offset()` — Set positive clearance between the source surface and the ribbon's inner face.
1590
-
1591
- ```ts
1592
- offset(offset: number): this
1593
- ```
1594
-
1595
- #### `samples()` — Set samples along the path.
1596
-
1597
- ```ts
1598
- samples(samples: number): this
1599
- ```
1600
-
1601
- #### `widthSamples()` — Set samples across the width. Use 3+ to bend over curved cross-sections.
1602
-
1603
- ```ts
1604
- widthSamples(samples: number): this
1605
- ```
1606
-
1607
- #### `resolution()` — Set NURBS tessellation resolution.
1608
-
1609
- ```ts
1610
- resolution(resolution: number): this
1611
- ```
1612
-
1613
- #### `material()` — Apply a product material preset.
1614
-
1615
- ```ts
1616
- material(material: ProductMaterial): this
1617
- ```
1618
-
1619
- #### `color()` — Apply a simple color override.
1620
-
1621
- ```ts
1622
- color(color: string): this
1623
- ```
1624
-
1625
- #### `build()` — Build a conformal ribbon as a thin NURBS surface solid.
1626
-
1627
- ```ts
1628
- build(options?: ProductRibbonBuildOptions): Shape
1629
- ```
1630
-
1631
- ### `ProductSpoutBuilder`
1632
-
1633
- **Properties:**
1634
-
1635
- | Property | Type | Description |
1636
- |----------|------|-------------|
1637
- | `name` | `string` | — |
1638
-
1639
- **Methods:**
1640
-
1641
- #### `from()` — Set the skin ref this spout projects from.
1642
-
1643
- ```ts
1644
- from(ref: ProductSurfaceRef): this
1645
- ```
1646
-
1647
- #### `sections()` — Set local spout section profiles from root to mouth.
1648
-
1649
- ```ts
1650
- sections(sections: Array<Sketch | ProductStationBuilder | ProductStationSpec>): this
1651
- ```
1652
-
1653
- #### `projection()` — Set the projection length along the source ref normal.
1654
-
1655
- ```ts
1656
- projection(length: number): this
1657
- ```
1658
-
1659
- #### `edgeLength()` — Set the sampled loft target edge length for the spout.
1660
-
1661
- ```ts
1662
- edgeLength(value: number): this
1663
- ```
1664
-
1665
- #### `material()` — Apply a product material preset to the spout.
1666
-
1667
- ```ts
1668
- material(material: ProductMaterial): this
1669
- ```
1670
-
1671
- #### `color()` — Apply a simple color override to the spout.
1672
-
1673
- ```ts
1674
- color(color: string): this
1675
- ```
1676
-
1677
- #### `build()` — Build the spout in local coordinates.
1678
-
1679
- ```ts
1680
- build(): Shape
1681
- ```
1682
-
1683
- #### `attach()` — Build and place the spout on its source ref.
1684
-
1685
- ```ts
1686
- attach(options?: ProductAttachOptions): Shape
1687
- ```
1688
-
1689
- ### `ProductHandleBuilder`
1690
-
1691
- **Properties:**
1692
-
1693
- | Property | Type | Description |
1694
- |----------|------|-------------|
1695
- | `name` | `string` | — |
1696
-
1697
- **Methods:**
1698
-
1699
- #### `between()` — Set the upper body ref and lower world anchor for the handle.
1700
-
1701
- ```ts
1702
- between(upper: ProductSurfaceRef, lower: Vec3): this
1703
- ```
1704
-
1705
- #### `spine()` — Set an explicit handle centerline from points or a rail spec.
1706
-
1707
- ```ts
1708
- spine(points: Vec3[] | ProductRailSpec): this
1709
- ```
1710
-
1711
- #### `grip()` — Set the grip cross-section profile.
1712
-
1713
- ```ts
1714
- grip(profile: Sketch): this
1715
- ```
1716
-
1717
- #### `material()` — Apply a product material preset to the grip.
1718
-
1719
- ```ts
1720
- material(material: ProductMaterial): this
1721
- ```
1722
-
1723
- #### `padMaterial()` — Apply a product material preset to handle landing pads.
1724
-
1725
- ```ts
1726
- padMaterial(material: ProductMaterial): this
1727
- ```
1728
-
1729
- #### `edgeLength()` — Set the sampled loft target edge length for the grip.
1730
-
1731
- ```ts
1732
- edgeLength(value: number): this
1733
- ```
1734
-
1735
- #### `build()` — Build the handle grip and landing pads.
1736
-
1737
- ```ts
1738
- build(): ProductHandleFeature
1739
- ```
1740
-
1741
- ### `ProductHandleFeature`
1742
-
1743
- **Properties:**
1744
-
1745
- | Property | Type | Description |
1746
- |----------|------|-------------|
1747
- | `grip` | `Shape` | — |
1748
- | `upperPad` | `Shape` | — |
1749
- | `lowerPad` | `Shape` | — |
1750
-
1751
- **Methods:**
1752
-
1753
- #### `structural()` — Return the physical shapes that make up this handle feature.
1754
-
1755
- ```ts
1756
- structural(): Shape[]
1757
- ```
1758
-
1759
- #### [`toShape()`](/docs/sdf#toshape) — Boolean-union the handle feature into a single shape.
1760
-
1761
- ```ts
1762
- toShape(): Shape
1763
- ```
1764
-
1765
- #### `toGroup()` — Return the handle as a named ShapeGroup preserving child colors.
1766
-
1767
- ```ts
1768
- toGroup(): ShapeGroup
1769
- ```
1770
-
1771
- ### `CylinderCarrier`
1772
-
1773
- **Properties:**
1774
-
1775
- | Property | Type | Description |
1776
- |----------|------|-------------|
1777
- | `name` | `string` | — |
1778
- | `kind` | `"cylinder"` | — |
1779
-
1780
- **Methods:**
1781
-
1782
- #### `diameter()`
1783
-
1784
- ```ts
1785
- diameter(value: number): this
1786
- ```
1787
-
1788
- #### `radius()`
1789
-
1790
- ```ts
1791
- radius(value: number): this
1792
- ```
1793
-
1794
- #### `height()`
1795
-
1796
- ```ts
1797
- height(value: number): this
1798
- ```
1799
-
1800
- #### `clearance()`
1801
-
1802
- ```ts
1803
- clearance(value: number): this
1804
- ```
1805
-
1806
- #### `center()`
1807
-
1808
- ```ts
1809
- center(point: Vec3): this
1810
- ```
1811
-
1812
- #### [`path()`](/docs/sketch#path)
1813
-
1814
- ```ts
1815
- path(): SurfacePathBuilder<CylinderSurfaceCoordinate>
1816
- ```
1817
-
1818
- #### `anchor()`
1819
-
1820
- ```ts
1821
- anchor(angle: number, z?: number, options?: { offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1822
- ```
1823
-
1824
- #### `front()`
1825
-
1826
- ```ts
1827
- front(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1828
- ```
1829
-
1830
- #### `back()`
1831
-
1832
- ```ts
1833
- back(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1834
- ```
1835
-
1836
- #### `left()`
1837
-
1838
- ```ts
1839
- left(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1840
- ```
1841
-
1842
- #### `right()`
1843
-
1844
- ```ts
1845
- right(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1846
- ```
1847
-
1848
- #### `top()`
1849
-
1850
- ```ts
1851
- top(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1852
- ```
1853
-
1854
- #### `bottom()`
1855
-
1856
- ```ts
1857
- bottom(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
1858
- ```
1859
-
1860
- #### `pointAt()`
1861
-
1862
- ```ts
1863
- pointAt(coordinate: CylinderSurfaceCoordinate): Vec3
1864
- ```
1865
-
1866
- #### `mirrorPoint()`
1867
-
1868
- ```ts
1869
- mirrorPoint(point: Vec3): Vec3
1870
- ```
1871
-
1872
- #### `normalAt()`
1873
-
1874
- ```ts
1875
- normalAt(coordinate: CylinderSurfaceCoordinate): Vec3
1876
- ```
1877
-
1878
- #### `tangentAt()`
1879
-
1880
- ```ts
1881
- tangentAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): Vec3
1882
- ```
1883
-
1884
- #### `frameAt()`
1885
-
1886
- ```ts
1887
- frameAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
1888
- ```
1889
-
1890
- #### `bounds()`
1891
-
1892
- ```ts
1893
- bounds(): SurfaceBounds
1894
- ```
1895
-
1896
- #### `offset()`
1897
-
1898
- ```ts
1899
- offset(distance: number): CylinderCarrier
1900
- ```
1901
-
1902
- #### `mirrorCoordinate()`
1903
-
1904
- ```ts
1905
- mirrorCoordinate(coordinate: CylinderSurfaceCoordinate): CylinderSurfaceCoordinate
1906
- ```
1907
-
1908
- #### `radiusValueWithClearance()`
1909
-
1910
- ```ts
1911
- radiusValueWithClearance(): number
1912
- ```
1913
-
1914
- ### `PlaneCarrier`
1915
-
1916
- **Properties:**
1917
-
1918
- | Property | Type | Description |
1919
- |----------|------|-------------|
1920
- | `name` | `string` | — |
1921
- | `kind` | `"plane"` | — |
1922
-
1923
- **Methods:**
1924
-
1925
- #### `size()`
1926
-
1927
- ```ts
1928
- size(width: number, height: number): this
1929
- ```
1930
-
1931
- #### `origin()`
1932
-
1933
- ```ts
1934
- origin(point: Vec3): this
1935
- ```
1936
-
1937
- #### `normal()`
1938
-
1939
- ```ts
1940
- normal(normal: Vec3): this
1941
- ```
1942
-
1943
- #### [`path()`](/docs/sketch#path)
1944
-
1945
- ```ts
1946
- path(): SurfacePathBuilder<PlaneSurfaceCoordinate>
1947
- ```
1948
-
1949
- #### `anchor()`
1950
-
1951
- ```ts
1952
- anchor(x?: number, y?: number, options?: { offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
1953
- ```
1954
-
1955
- #### `left()`
1956
-
1957
- ```ts
1958
- left(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
1959
- ```
1960
-
1961
- #### `right()`
1962
-
1963
- ```ts
1964
- right(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
1965
- ```
1966
-
1967
- #### `top()`
1968
-
1969
- ```ts
1970
- top(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
1971
- ```
1972
-
1973
- #### `bottom()`
1974
-
1975
- ```ts
1976
- bottom(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
1977
- ```
1978
-
1979
- #### `pointAt()`
1980
-
1981
- ```ts
1982
- pointAt(coordinate: PlaneSurfaceCoordinate): Vec3
1983
- ```
1984
-
1985
- #### `mirrorPoint()`
1986
-
1987
- ```ts
1988
- mirrorPoint(point: Vec3): Vec3
1989
- ```
1990
-
1991
- #### `normalAt()`
1992
-
1993
- ```ts
1994
- normalAt(): Vec3
1995
- ```
1996
-
1997
- #### `tangentAt()`
1998
-
1999
- ```ts
2000
- tangentAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): Vec3
2001
- ```
2002
-
2003
- #### `frameAt()`
2004
-
2005
- ```ts
2006
- frameAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
2007
- ```
2008
-
2009
- #### `bounds()`
2010
-
2011
- ```ts
2012
- bounds(): SurfaceBounds
2013
- ```
2014
-
2015
- #### `offset()`
2016
-
2017
- ```ts
2018
- offset(distance: number): PlaneCarrier
2019
- ```
2020
-
2021
- #### `mirrorCoordinate()`
2022
-
2023
- ```ts
2024
- mirrorCoordinate(coordinate: PlaneSurfaceCoordinate): PlaneSurfaceCoordinate
2025
- ```
2026
-
2027
- ### `ProductSkinCarrier`
2028
-
2029
- **Properties:**
2030
-
2031
- | Property | Type | Description |
2032
- |----------|------|-------------|
2033
- | `skin` | `ProductSkin` | — |
2034
- | `name` | `string` | — |
2035
- | `kind` | `"productSkin"` | — |
2036
-
2037
- **Methods:**
2038
-
2039
- #### `surface()`
2040
-
2041
- ```ts
2042
- surface(side: ProductSkinSide): ProductSkinCarrier
2043
- ```
2044
-
2045
- #### [`path()`](/docs/sketch#path)
2046
-
2047
- ```ts
2048
- path(): SurfacePathBuilder<ProductSkinSurfaceCoordinate>
2049
- ```
2050
-
2051
- `ProductSkinSurfaceCoordinate`: `{ kind?: "productSkin", side?: ProductSkinSide, u?: number, v?: number, offset?: number }`
2052
-
2053
- #### `sideTransition()` — Return matching side-local coordinates for an explicit split-member transition.
2054
-
2055
- Each SurfacePath still stays on one ProductSkin side. Use this helper to create one member ending on `from`, another starting on `to`, then join named anchors. The helper validates normalized `v`, non-empty names, adjacency, and physical coincidence before returning anchors.
2056
-
2057
- ```ts
2058
- sideTransition(fromSide: ProductSkinSide, toSide: ProductSkinSide, input?: ProductSkinSideTransitionInput): ProductSkinSideTransition
2059
- ```
2060
-
2061
- `ProductSkinSideTransitionInput`: `{ name?: string, v?: number, offset?: number }`
2062
-
2063
- `ProductSkinSideTransition`: `{ name?: string, from: ProductSkinSurfaceCoordinate, to: ProductSkinSurfaceCoordinate }`
2064
-
2065
- #### `sideTransitionChain()` — Return a sequence of matching side-local coordinates for an explicit multi-side split-member route.
2066
-
2067
- Each adjacent side pair becomes one named transition. Build one member per side segment, add transition anchors at each returned pair, then join the anchors. The same validation as `sideTransition()` applies to every adjacent pair.
2068
-
2069
- ```ts
2070
- sideTransitionChain(sides: ProductSkinSide[], input?: ProductSkinSideTransitionInput): ProductSkinSideTransition[]
2071
- ```
2072
-
2073
- #### `sideRoute()` — Return side-local member segments for a generated multi-side split-member route.
2074
-
2075
- The route still compiles as explicit members plus named-anchor joins. This helper only generates the per-side segment endpoints and transition names.
2076
-
2077
- ```ts
2078
- sideRoute(input: ProductSkinSideRouteInput): ProductSkinSideRoute
2079
- ```
2080
-
2081
- **`ProductSkinSideRouteInput`**: `name?: string`, `sides: ProductSkinSide[]`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `v?: number`, `offset?: number`
2082
-
2083
- `ProductSkinSideRoute`: `{ name?: string, transitions: ProductSkinSideTransition[], segments: ProductSkinSideRouteSegment[] }`
2084
-
2085
- **`ProductSkinSideRouteSegment`**: `name: string`, `side: ProductSkinSide`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `startAnchorName?: string`, `endAnchorName?: string`
2086
-
2087
- #### `pointAt()`
2088
-
2089
- ```ts
2090
- pointAt(coordinate: ProductSkinSurfaceCoordinate): Vec3
2091
- ```
2092
-
2093
- #### `mirrorPoint()`
2094
-
2095
- ```ts
2096
- mirrorPoint(point: Vec3): Vec3
2097
- ```
2098
-
2099
- #### `normalAt()`
2100
-
2101
- ```ts
2102
- normalAt(coordinate: ProductSkinSurfaceCoordinate): Vec3
2103
- ```
2104
-
2105
- #### `tangentAt()`
2106
-
2107
- ```ts
2108
- tangentAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): Vec3
2109
- ```
2110
-
2111
- #### `frameAt()`
2112
-
2113
- ```ts
2114
- frameAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
2115
- ```
2116
-
2117
- **`SurfaceFrame`**: `point: Vec3`, `normal: Vec3`, `tangentAlong: Vec3`, `tangentAcross: Vec3`, `matrix: Mat4`, `carrier: string`, `representation: SurfaceCarrierKind | string`, `coordinate: SurfaceCoordinate`
2118
-
2119
- #### `bounds()`
2120
-
2121
- ```ts
2122
- bounds(): SurfaceBounds
2123
- ```
2124
-
2125
- **`SurfaceBounds`**: `u?: [ number, number ]`, `v?: [ number, number ]`, `angle?: [ number, number ]`, `z?: [ number, number ]`, `x?: [ number, number ]`, `y?: [ number, number ]`
2126
-
2127
- #### `offset()`
2128
-
2129
- ```ts
2130
- offset(distance: number): ProductSkinCarrier
2131
- ```
2132
-
2133
- #### `mirrorCoordinate()`
2134
-
2135
- ```ts
2136
- mirrorCoordinate(coordinate: ProductSkinSurfaceCoordinate): ProductSkinSurfaceCoordinate
2137
- ```
2138
-
2139
- ### `SurfacePath`
2140
-
2141
- **Properties:**
2142
-
2143
- | Property | Type | Description |
2144
- |----------|------|-------------|
2145
- | `carrier` | `CarrierSurface<C>` | — |
2146
- | `points` | `C[]` | — |
2147
- | `closedValue` | `boolean` | — |
2148
-
2149
- **Methods:**
2150
-
2151
- #### `closed()`
2152
-
2153
- ```ts
2154
- closed(): SurfacePath<C>
2155
- ```
2156
-
2157
- #### `mirror()`
2158
-
2159
- ```ts
2160
- mirror(): SurfacePath<C>
2161
- ```
2162
-
2163
- #### `coordinateAt()`
2164
-
2165
- ```ts
2166
- coordinateAt(t: number): C
2167
- ```
2168
-
2169
- #### `sample()`
2170
-
2171
- ```ts
2172
- sample(count?: number): SurfacePathSample<C>[]
2173
- ```
2174
-
2175
- #### `length()`
2176
-
2177
- ```ts
2178
- length(samples?: number): number
2179
- ```
2180
-
2181
- ### `SurfacePathBuilder`
2182
-
2183
- **Properties:**
2184
-
2185
- | Property | Type | Description |
2186
- |----------|------|-------------|
2187
- | `carrier` | `CarrierSurface<C>` | — |
2188
-
2189
- **Methods:**
2190
-
2191
- #### `from()`
2192
-
2193
- ```ts
2194
- from(coordinate: C): this
2195
- ```
2196
-
2197
- #### `through()`
2198
-
2199
- ```ts
2200
- through(coordinate: C): this
2201
- ```
2202
-
2203
- #### `to()`
2204
-
2205
- ```ts
2206
- to(coordinate: C): this
2207
- ```
2208
-
2209
- #### `around()`
2210
-
2211
- ```ts
2212
- around(input: { z: number; fromAngle: number; toAngle: number; offset?: number; }): this
2213
- ```
2214
-
2215
- #### `closed()`
2216
-
2217
- ```ts
2218
- closed(): this
2219
- ```
2220
-
2221
- #### `mirror()`
2222
-
2223
- ```ts
2224
- mirror(): SurfacePath<C>
2225
- ```
2226
-
2227
- #### `build()`
2228
-
2229
- ```ts
2230
- build(): SurfacePath<C>
2231
- ```
2232
-
2233
- #### `sample()`
2234
-
2235
- ```ts
2236
- sample(count?: number): SurfacePathSample<C>[]
2237
- ```
2238
-
2239
- ### `SurfaceBand`
2240
-
2241
- **Properties:**
2242
-
2243
- | Property | Type | Description |
2244
- |----------|------|-------------|
2245
- | `centerPath` | `SurfacePath<C>` | — |
2246
- | `widthProfile` | `WidthProfile` | — |
2247
- | `capStyle` | `SurfaceBandCap` | — |
2248
-
2249
- **Methods:**
2250
-
2251
- #### `widthAt()`
2252
-
2253
- ```ts
2254
- widthAt(t: number): number
2255
- ```
2256
-
2257
- #### `boundaries()`
2258
-
2259
- ```ts
2260
- boundaries(samples?: number): SurfaceBandBoundarySample[]
2261
- ```
2262
-
2263
- #### `withHole()` — Return a new band with a named member-local rounded-slot hole region recorded as inspectable intent.
2264
-
2265
- ```ts
2266
- withHole(name: string, input: SurfaceBandHoleInput): SurfaceBand<C>
2267
- ```
2268
-
2269
- #### `holes()` — Resolve recorded hole regions into member-local across/along loops.
2270
-
2271
- ```ts
2272
- holes(): SurfaceBandHoleRegion[]
2273
- ```
2274
-
2275
- ### `SurfaceBodyBuilder`
2276
-
2277
- **Properties:**
2278
-
2279
- | Property | Type | Description |
2280
- |----------|------|-------------|
2281
- | `name` | `string` | — |
2282
-
2283
- **Methods:**
2284
-
2285
- #### `carrier()`
2286
-
2287
- ```ts
2288
- carrier(carrier: CarrierSurface): this
2289
- ```
2290
-
2291
- #### `member()`
2292
-
2293
- ```ts
2294
- member(name: string): SurfaceMemberBuilder
2295
- ```
2296
-
2297
- #### `join()`
2298
-
2299
- ```ts
2300
- join(from: string, to: string | string[]): SurfaceJoinBuilder
2301
- ```
2302
-
2303
- #### `autoJoinAtSharedAnchors()`
2304
-
2305
- ```ts
2306
- autoJoinAtSharedAnchors(): this
2307
- ```
2308
-
2309
- #### `build()`
2310
-
2311
- ```ts
2312
- build(): Shape | ShapeGroup
2313
- ```
2314
-
2315
- ### `SurfaceMemberBuilder`
2316
-
2317
- #### `plate()`
2318
-
2319
- ```ts
2320
- plate(): this
2321
- ```
2322
-
2323
- #### `band()`
2324
-
2325
- ```ts
2326
- band(): this
2327
- ```
2328
-
2329
- #### `at()`
2330
-
2331
- ```ts
2332
- at(anchor: SurfaceAnchor<C>): this
2333
- ```
2334
-
2335
- #### `size()`
2336
-
2337
- ```ts
2338
- size(width: number, height: number): this
2339
- ```
2340
-
2341
- #### [`path()`](/docs/sketch#path)
2342
-
2343
- ```ts
2344
- path(path: SurfacePath<C> | SurfacePathBuilder<C>): this
2345
- ```
2346
-
2347
- #### `section()`
2348
-
2349
- ```ts
2350
- section(section: MemberSectionInput): this
2351
- ```
2352
-
2353
- #### `cap()`
2354
-
2355
- ```ts
2356
- cap(style: SurfaceBandCap): this
2357
- ```
2358
-
2359
- #### [`slot()`](/docs/sketch#slot)
2360
-
2361
- ```ts
2362
- slot(name: string, feature: MemberFeature | RoundedSlotBuilder): this
2363
- ```
2364
-
2365
- #### `cutout()`
2366
-
2367
- ```ts
2368
- cutout(name: string, feature: MemberFeature | RoundedSlotBuilder): this
2369
- ```
2370
-
2371
- #### `counterbore()`
2372
-
2373
- ```ts
2374
- counterbore(name: string, feature: MemberFeature | CounterboreBuilder): this
2375
- ```
2376
-
2377
- #### `anchorAt()` — Add a named anchor at a carrier surface coordinate for explicit member joins.
2378
-
2379
- ```ts
2380
- anchorAt(name: string, coordinate: C | SurfaceAnchor<C>): this
2381
- ```
2382
-
2383
- #### `features()`
2384
-
2385
- ```ts
2386
- features(features: MemberFeature | MemberFeature[]): this
2387
- ```
2388
-
2389
- #### `profile()`
2390
-
2391
- ```ts
2392
- profile(name: string, options?: { depth?: number; height?: number; }): this
2393
- ```
2394
-
2395
- #### `mirrorOf()`
2396
-
2397
- ```ts
2398
- mirrorOf(memberName: string): SurfaceBodyBuilder
2399
- ```
2400
-
2401
- #### `member()`
2402
-
2403
- ```ts
2404
- member(name: string): SurfaceMemberBuilder
2405
- ```
2406
-
2407
- #### `join()`
2408
-
2409
- ```ts
2410
- join(from: string, to: string | string[]): SurfaceJoinBuilder
2411
- ```
2412
-
2413
- #### `autoJoinAtSharedAnchors()`
2414
-
2415
- ```ts
2416
- autoJoinAtSharedAnchors(): SurfaceBodyBuilder
2417
- ```
2418
-
2419
- #### `build()`
2420
-
2421
- ```ts
2422
- build(): Shape | ShapeGroup
2423
- ```
2424
-
2425
- ### `SurfaceJoinBuilder`
2426
-
2427
- #### `betweenAnchors()` — Select named anchors on the source and target members before lowering this join.
2428
-
2429
- ```ts
2430
- betweenAnchors(fromAnchor: string, toAnchor: string): this
2431
- ```
2432
-
2433
- #### `blend()`
2434
-
2435
- ```ts
2436
- blend(input?: { radius?: number; style?: string; priority?: number; continuity?: string; }): SurfaceBodyBuilder
2437
- ```
2438
-
2439
- ### `CounterboreBuilder`
2440
-
2441
- #### `at()`
2442
-
2443
- ```ts
2444
- at(input: { along?: number; across?: number; z?: number; }): this
2445
- ```
2446
-
2447
- #### `named()`
2448
-
2449
- ```ts
2450
- named(name: string): MemberFeature
2451
- ```
2452
-
2453
- #### `toFeature()`
2454
-
2455
- ```ts
2456
- toFeature(name?: string): MemberFeature
2457
- ```
2458
-
2459
- ### `RoundedSlotBuilder`
2460
-
2461
- #### `verticalTravel()`
2462
-
2463
- ```ts
2464
- verticalTravel(value: number): this
2465
- ```
2466
-
2467
- #### `at()`
2468
-
2469
- ```ts
2470
- at(input: { along?: number; across?: number; z?: number; }): this
2471
- ```
2472
-
2473
- #### `named()`
2474
-
2475
- ```ts
2476
- named(name: string): MemberFeature
2477
- ```
2478
-
2479
- #### `toFeature()`
2480
-
2481
- ```ts
2482
- toFeature(name?: string): MemberFeature
2483
- ```
2484
-
2485
- ---
2486
-
2487
- ## Constants
2488
-
2489
- ### `Surface`
2490
-
2491
- - `Plane(options: SurfacePlaneOptions): Shape` — Create a finite analytic plane sheet that can be trimmed, sewn, thickened, or used as a low-level face.
2492
- - `Cylinder(options: SurfaceCylinderOptions): Shape` — Create a finite analytic cylindrical sheet, optionally bounded by start/end angles.
2493
- - `Cone(options: SurfaceConeOptions): Shape` — Create a finite analytic conical or frustum sheet, optionally bounded by start/end angles.
2494
- - `Sphere(options: SurfaceSphereOptions): Shape` — Create a finite analytic spherical sheet bounded by longitude and latitude ranges.
2495
- - `Torus(options: SurfaceTorusOptions): Shape` — Create a finite analytic torus sheet bounded by major and tube angle ranges.
2496
- - `Nurbs(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape`
2497
- - `Ruled(curveA: ExactCurveInput, curveB: ExactCurveInput, options?: SurfaceCommonOptions): Shape`
2498
- - `Patch(curves: { bottom: ExactCurveInput; top: ExactCurveInput; left: ExactCurveInput; right: ExactCurveInput; }, options?: SurfacePatchOptions): Shape`
2499
- - `Boundary(input: SurfaceBoundaryInput): Shape`
2500
- - `Fill(input: SurfaceFillInput): Shape`
2501
- - `Sew(shapes: Shape[], options?: { tolerance?: number; }): Shape`
2502
- - `Solid(input: Shape | Shape[], options?: SurfaceSolidOptions): Shape` — Sew surface faces or consume an existing sewn shell and make a solid B-rep.
2503
- - `Extend(shape: Shape, options: SurfaceExtendOptions): Shape`
2504
- - `Trim(shape: Shape, tool: Shape | SurfacePlaneOp): Shape`
2505
- - `Split(shape: Shape, tool: Shape | SurfacePlaneOp): [ Shape, Shape ]`
2506
- - `Match(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape`
2507
- - `MatchEdge(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape`
2508
-
2509
- ### `Blend`
2510
-
2511
- - `Edge(options: BlendEdgeOptions): Shape`
2512
- - `Surface(options: BlendSurfaceOptions): Shape`
2513
-
2514
- ### `Analysis`
2515
-
2516
- - `EdgeContinuity(shape: Shape, options?: EdgeContinuityThresholds): EdgeContinuityReport`
2517
- - `SurfaceContinuity(shape: Shape, options?: EdgeContinuityThresholds): EdgeContinuityReport`
2518
- - `CurvatureComb(input: NurbsCurve3D | EdgeRef, options?: { samples?: number; }): CurvatureSample[]`
2519
- - `SurfaceHealth(shape: Shape, options?: { tinyEdgeThreshold?: number; sliverThreshold?: number; }): SurfaceHealthReport`
2520
- - `BRepValidity(shape: Shape, options?: BRepValidityOptions): BRepValidityReport` — Validate B-rep/shell/solid structure and return closedness, manifoldness, orientation, and issue diagnostics.
2521
-
2522
- ### `Product`
2523
-
2524
- - `skin(name: string): ProductSkinBuilder` — Start a named product skin builder.
2525
- - `station(name: string): ProductStationBuilder` — Start a named cross-section station for Product.skin(...).stations(...).
2526
- - `rail: { bezier(points: Vec3[], options?: { name?: string; }): ProductRailSpec; nurbs(points: Vec3[], options?: { degree?: number; name?: string; }): ProductRailSpec; polyline(points: Vec3[], options?: { name?: string; }): ProductRailSpec; }` — Namespaced rail builders for product skin guide rails and handle spines.
2527
- - `profiles: { ... }` — Namespaced product profile helpers for stations, panels, trims, and openings.
2528
- - `materials: { ... }` — Namespaced product material presets for molded plastic, rubber, metal, and transparent parts.
2529
- - `applyMaterial(shape: Shape, preset: ProductMaterial | undefined): Shape` — Apply a product material preset to a Shape.
2530
- - `scenePreset(name: ProductScenePreset): void` — Apply an opinionated scene preset for product review renders.
2531
- - `ovalProfile(width: number, depth: number, options?: ProductProfileOptions): Sketch` — Create a centered oval profile from full width/depth dimensions.
2532
- - `roundedRectProfile(width: number, depth: number, radius: number): Sketch` — Create a centered rounded-rectangle profile.
2533
- - `circleProfile(diameter: number, options?: ProductProfileOptions): Sketch` — Create a centered circular profile from full diameter.
2534
- - `superEllipseProfile(width: number, depth: number, options?: ProductSuperEllipseOptions): Sketch` — Create a centered superellipse profile for soft-square product sections.
2535
- - `profileSize(sketch: Sketch): { width: number; depth: number; }` — Measure the width and depth of a 2D profile sketch.
2536
- - `describeProfile(sketch: Sketch, kind?: ProductProfileKind, radius?: number): ProductProfileDescriptor` — Describe a custom sketch as a product profile.
2537
- - `scaleProfileTo(sketch: Sketch, width: number, depth: number): Sketch` — Scale an existing profile sketch to a target width/depth.
2538
- - `ref(skin: ProductSkin, query: ProductSkinRefQuery): ProductSurfaceRef` — Create an ad-hoc ProductSurfaceRef from a skin and side/u/v query.
2539
- - `surface(skin: ProductSkin, side: ProductSkinSide): ProductSurfaceBuilder` — Create a fluent surface helper for refs and conformal features on one side of a skin. Equivalent to skin.surface(side), useful when writing in Product.* namespace style.
2540
- - `panel(name: string): ProductPanelBuilder` — Start a panel feature builder.
2541
- - `ribbon(name: string): ProductRibbonBuilder` — Start a conformal ribbon/trim builder for details that should bend with a ProductSkin. Call .on(skin, points) for side/u/v sampling or .fromRefs(points) for explicit surface refs, then configure width, thickness, offset, sampling, material, and color before build().
2542
- - `spout(name: string): ProductSpoutBuilder` — Start a spout/nozzle feature builder.
2543
- - `handle(name: string): ProductHandleBuilder` — Start a handle feature builder.
2544
- - `place(detail: Shape | ShapeGroup, ref: ProductRefInput, options?: ProductAttachOptions): Shape | ShapeGroup` — Place a shape or group on a ProductSurfaceRef.
2545
- - `landing(name: string, radius?: number, material?: ProductMaterial): Shape` — Small blended landing volume for manual structural bridges and connection proofs.
2546
-
2547
- ### `Carrier`
2548
-
2549
- - `cylinder(name: string): CylinderCarrier` — Create an analytic cylinder carrier for bottles, limbs, tubes, guards, and cuffs.
2550
- - `plane(name: string): PlaneCarrier` — Create an analytic plane carrier for plates and local flat construction surfaces.
2551
- - `productSkin(skin: ProductSkin): ProductSkinCarrier` — Adapt an existing ProductSkin into the general surface-member carrier protocol.
2552
-
2553
- ### `SurfaceMembers`
2554
-
2555
- - `Body(name: string): SurfaceBodyBuilder` — Start a surface-member body builder for straps, inlays, guards, braces, cuffs, and similar physical members that live on a carrier surface.
2556
- - `Band: typeof SurfaceBand`
2557
- - `band<C extends SurfaceCoordinate>(path: SurfacePath<C> | SurfacePathBuilder<C>, width: WidthProfile, cap?: SurfaceBandCap): SurfaceBand<C>`
2558
-
2559
- ### `Slot`
2560
-
2561
- - `rounded(input: { length: number; width: number; }): RoundedSlotBuilder` — Create a rounded member-local slot feature.
2562
-
2563
- ### `Counterbore`
2564
-
2565
- - `cylindrical(input: { diameter: number; clearanceDiameter: number; depth: number; }): CounterboreBuilder` — Create a cylindrical member-local counterbore feature.
2566
-
2567
- ### `Ribs`
2568
-
2569
- - `repeated(input: { count: number; height: number; }): MemberFeature` — Create repeated ribs that belong to a surface member before lowering.
2570
-
2571
- ### `Helix`
2572
-
2573
- Helical curve helpers.
2574
-
2575
- ```ts
2576
- const guide = Helix.path({ radius: 20, pitch: 6, turns: 4 });
2577
- const wire = Helix.coil({ radius: 20, pitch: 6, turns: 4, wireRadius: 1 });
2578
- const rectangular = Helix.coil(rect(2, 1), { radius: 20, height: 30, turns: 5 });
2579
- ```
2580
-
2581
- - `path(options: HelixOptions): HelixCurve` — Create a metadata-bearing helical centerline around the Z axis.
2582
- - `coil(options: HelixCoilOptions): Shape` — Create a solid helical coil by sweeping a circular profile through helix-local frames.
2583
- - `coil(profile: Sketch, options: HelixCoilOptions): Shape` — Create a solid helical coil by sweeping a profile through helix-local frames.