forgecad 0.9.16 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DwYHz72L.js} +1 -1
- package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-a9_f-1US.js} +1 -1
- package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DodHpvmf.js} +1 -1
- package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-B5LePEuj.js} +8 -858
- package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
- package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-DdEHGUMU.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-yhhOodbf.js} +1 -1
- package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-5RbKRGYK.js} +1 -1
- package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-E3Rma7aV.js} +1 -1
- package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-BJZcM97j.js} +1 -1
- package/dist/assets/{app-T0pDcSX4.js → app-DSYrDg0V.js} +733 -205
- package/dist/assets/cli/{render-C5pcIISc.js → render-ZMHR9HkV.js} +19 -46
- package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
- package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-DbNs7Dkp.js} +3798 -1622
- package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
- package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DO6mnXn_.js} +1 -1
- package/dist/assets/{manifold-BWgsjmAM.js → manifold-BGlQBBH9.js} +1 -1
- package/dist/assets/{manifold-rZexZI0G.js → manifold-BU-tJwQh.js} +1 -1
- package/dist/assets/{manifold-D6IFSkhH.js → manifold-fy2MV7K1.js} +2 -2
- package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-DO6hcQbh.js} +7155 -2437
- package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-o90NSNmF.js} +3940 -1742
- package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
- package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +3 -3
- package/dist/docs-raw/AI/usage.md +1 -1
- package/dist/docs-raw/CLI.md +63 -241
- package/dist/docs-raw/README.md +6 -0
- package/dist/docs-raw/component-model.md +17 -150
- package/dist/docs-raw/generated/assembly.md +139 -598
- package/dist/docs-raw/generated/concepts.md +245 -3501
- package/dist/docs-raw/generated/core.md +277 -1251
- package/dist/docs-raw/generated/curves.md +387 -1608
- package/dist/docs-raw/generated/legacy.md +162 -0
- package/dist/docs-raw/generated/lib.md +227 -85
- package/dist/docs-raw/generated/output.md +38 -73
- package/dist/docs-raw/generated/runtime-names.md +23 -23
- package/dist/docs-raw/generated/sdf.md +68 -284
- package/dist/docs-raw/generated/sheet-metal.md +68 -335
- package/dist/docs-raw/generated/sketch.md +240 -1161
- package/dist/docs-raw/generated/viewport.md +75 -316
- package/dist/docs-raw/generated/wood.md +21 -49
- package/dist/docs-raw/guides/coordinate-system.md +4 -42
- package/dist/docs-raw/guides/inspection-bundles.md +44 -442
- package/dist/docs-raw/guides/joint-design.md +18 -79
- package/dist/docs-raw/guides/positioning.md +21 -143
- package/dist/docs-raw/guides/scene-presentation.md +89 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
- package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
- package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
- package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
- package/dist/docs-raw/skills/forgecad-lld.md +19 -113
- package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
- package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
- package/dist/docs-raw/skills/forgecad-project.md +13 -131
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
- package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
- package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
- package/dist/docs-raw/skills/forgecad.md +19 -18
- package/dist/docs-raw/skills/index.md +2 -0
- package/dist/docs-raw/welcome.md +2 -2
- package/dist/index.html +1 -1
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +13 -13
- package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-JTVBITCR.js} +1 -1
- package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-3FFLSMVN.js} +1 -1
- package/dist-cli/{chunk-SPZE3DUY.js → chunk-OAN5T4XD.js} +4412 -2212
- package/dist-cli/forgecad.js +507 -179
- package/dist-skill/CONTEXT.md +2172 -8377
- package/dist-skill/SKILL.md +15 -15
- package/dist-skill/docs/API/core/concepts.md +27 -157
- package/dist-skill/docs/CLI.md +63 -241
- package/dist-skill/docs/generated/assembly.md +138 -549
- package/dist-skill/docs/generated/core.md +277 -1251
- package/dist-skill/docs/generated/curves.md +387 -1609
- package/dist-skill/docs/generated/lib.md +227 -85
- package/dist-skill/docs/generated/output.md +38 -73
- package/dist-skill/docs/generated/runtime-names.md +16 -21
- package/dist-skill/docs/generated/sdf.md +68 -284
- package/dist-skill/docs/generated/sheet-metal.md +68 -335
- package/dist-skill/docs/generated/sketch.md +240 -1160
- package/dist-skill/docs/generated/viewport.md +75 -223
- package/dist-skill/docs/generated/wood.md +21 -49
- package/dist-skill/docs/guides/coordinate-system.md +4 -42
- package/dist-skill/docs/guides/inspection-bundles.md +44 -442
- package/dist-skill/docs/guides/joint-design.md +18 -79
- package/dist-skill/docs/guides/positioning.md +21 -143
- package/dist-skill/docs/guides/scene-presentation.md +89 -0
- package/dist-skill/docs/guides/surface-members.md +26 -0
- package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
- package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
- package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
- package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
- package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
- package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
- package/dist-skill/library/forgecad-project/SKILL.md +13 -133
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
- package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
- package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
- package/dist-skill/website/skills/forgecad-component-model.md +53 -0
- package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
- package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
- package/dist-skill/website/skills/forgecad-lld.md +41 -0
- package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
- package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
- package/dist-skill/website/skills/forgecad-project.md +26 -0
- package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
- package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
- package/dist-skill/website/skills/forgecad.md +122 -0
- package/dist-skill/website/skills/index.md +26 -0
- package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
- package/examples/api/conformal-product-ribbon.forge.js +1 -1
- package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
- package/examples/api/extrude-options.forge.js +4 -2
- package/examples/api/field-loft-drive-tip.forge.js +40 -0
- package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +10 -10
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/real-product-curves.forge.js +1 -1
- package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
- package/examples/api/sdf-shapes.forge.js +2 -5
- package/examples/api/sketch-rounding-strategies.forge.js +6 -6
- package/examples/api/surface-member-bottle-cage.forge.js +3 -3
- package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
- package/examples/api/surface-member-razor-inlay.forge.js +1 -1
- package/examples/api/variable-sweep-test.forge.js +3 -3
- package/examples/mechanical/airplane-propeller.forge.js +74 -39
- package/examples/nurbs-surface.forge.js +1 -1
- package/examples/products/iphone.forge.js +1 -1
- package/package.json +1 -1
- package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
- package/dist/docs-raw/guides/geometry-conventions.md +0 -52
- package/dist/docs-raw/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs/guides/modeling-recipes.md +0 -78
- package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
|
@@ -9,8 +9,8 @@ Smooth curves, lofted surfaces, swept solids, splines, and high-level product sk
|
|
|
9
9
|
|
|
10
10
|
## Contents
|
|
11
11
|
|
|
12
|
-
- [Curves & Surfacing](#curves-surfacing)
|
|
13
|
-
- [Surface Members](#surface-members)
|
|
12
|
+
- [Curves & Surfacing](#curves-surfacing)
|
|
13
|
+
- [Surface Members](#surface-members)
|
|
14
14
|
- [Curve3D](#curve3d)
|
|
15
15
|
- [Route3D](#route3d)
|
|
16
16
|
- [NurbsCurve3D](#nurbscurve3d)
|
|
@@ -23,9 +23,6 @@ Smooth curves, lofted surfaces, swept solids, splines, and high-level product sk
|
|
|
23
23
|
- [ProductStationBuilder](#productstationbuilder)
|
|
24
24
|
- [ProductPanelBuilder](#productpanelbuilder)
|
|
25
25
|
- [ProductRibbonBuilder](#productribbonbuilder)
|
|
26
|
-
- [ProductSpoutBuilder](#productspoutbuilder)
|
|
27
|
-
- [ProductHandleBuilder](#producthandlebuilder)
|
|
28
|
-
- [ProductHandleFeature](#producthandlefeature)
|
|
29
26
|
- [CylinderCarrier](#cylindercarrier)
|
|
30
27
|
- [PlaneCarrier](#planecarrier)
|
|
31
28
|
- [ProductSkinCarrier](#productskincarrier)
|
|
@@ -44,15 +41,12 @@ Smooth curves, lofted surfaces, swept solids, splines, and high-level product sk
|
|
|
44
41
|
- [Product](#product)
|
|
45
42
|
- [Carrier](#carrier)
|
|
46
43
|
- [SurfaceMembers](#surfacemembers)
|
|
47
|
-
- [Slot](#slot)
|
|
48
|
-
- [Counterbore](#counterbore)
|
|
49
|
-
- [Ribs](#ribs)
|
|
50
44
|
|
|
51
45
|
## Functions
|
|
52
46
|
|
|
53
47
|
### Curves & Surfacing
|
|
54
48
|
|
|
55
|
-
#### `Curve.Blend()` — Create an exact G1 blend curve between two directed endpoints.
|
|
49
|
+
#### `Curve.Blend(start: CurveBlendEndpoint, end: CurveBlendEndpoint): NurbsCurve3D` — Create an exact G1 blend curve between two directed endpoints.
|
|
56
50
|
|
|
57
51
|
The returned curve is a cubic non-rational `NurbsCurve3D`: ForgeCAD converts the endpoint positions and tangents into Bezier control points, so the curve can feed `sweep` and exact surface boundaries through the existing `nurbs` IR rather than a sampled polyline.
|
|
58
52
|
|
|
@@ -64,16 +58,12 @@ const rail = Curve.Blend(
|
|
|
64
58
|
const tube = sweep(circle2d(2), rail);
|
|
65
59
|
```
|
|
66
60
|
|
|
67
|
-
```ts
|
|
68
|
-
Curve.Blend(start: CurveBlendEndpoint, end: CurveBlendEndpoint): NurbsCurve3D
|
|
69
|
-
```
|
|
70
|
-
|
|
71
61
|
**`CurveBlendEndpoint`**
|
|
72
62
|
- `point: Vec3` — Endpoint position.
|
|
73
63
|
- `tangent: Vec3` — Tangent direction at this endpoint. Magnitude is ignored.
|
|
74
64
|
- `weight?: number` — Tangent reach relative to the endpoint chord length. Default 1.
|
|
75
65
|
|
|
76
|
-
#### `Curve.BlendG2()` — Create an exact G2 blend curve between two directed endpoints.
|
|
66
|
+
#### `Curve.BlendG2(start: CurveBlendG2Endpoint, end: CurveBlendG2Endpoint): NurbsCurve3D` — Create an exact G2 blend curve between two directed endpoints.
|
|
77
67
|
|
|
78
68
|
This is the curvature-aware companion to `Curve.Blend()`. It returns a degree-5 non-rational `NurbsCurve3D` that matches endpoint position, tangent direction, and optional curvature/second-derivative vectors.
|
|
79
69
|
|
|
@@ -84,14 +74,10 @@ const rail = Curve.BlendG2(
|
|
|
84
74
|
);
|
|
85
75
|
```
|
|
86
76
|
|
|
87
|
-
```ts
|
|
88
|
-
Curve.BlendG2(start: CurveBlendG2Endpoint, end: CurveBlendG2Endpoint): NurbsCurve3D
|
|
89
|
-
```
|
|
90
|
-
|
|
91
77
|
**`CurveBlendG2Endpoint`** extends CurveBlendEndpoint
|
|
92
78
|
- `curvature?: Vec3` — Optional endpoint curvature/second-derivative vector. Default is zero.
|
|
93
79
|
|
|
94
|
-
#### `Curve.Arc()` — Create an exact circular 3D arc from start, end, and start tangent.
|
|
80
|
+
#### `Curve.Arc(options: CurveArcOptions): NurbsCurve3D` — Create an exact circular 3D arc from start, end, and start tangent.
|
|
95
81
|
|
|
96
82
|
The returned curve is a rational quadratic `NurbsCurve3D`, split into stable spans when needed, so it can feed `sweep` without sampling the authoring intent away.
|
|
97
83
|
|
|
@@ -104,57 +90,25 @@ const rail = Curve.Arc({
|
|
|
104
90
|
const tube = sweep(circle2d(2), rail);
|
|
105
91
|
```
|
|
106
92
|
|
|
107
|
-
```ts
|
|
108
|
-
Curve.Arc(options: CurveArcOptions): NurbsCurve3D
|
|
109
|
-
```
|
|
110
|
-
|
|
111
93
|
**`CurveArcOptions`**
|
|
112
94
|
- `start: Vec3` — Arc start point.
|
|
113
95
|
- `end: Vec3` — Arc end point.
|
|
114
96
|
- `tangent: Vec3` — Tangent direction at the start point. Magnitude is ignored.
|
|
115
97
|
|
|
116
|
-
#### `Curve.Line()` — Create an exact straight 3D NURBS line segment.
|
|
98
|
+
#### `Curve.Line(start: Vec3, end: Vec3): NurbsCurve3D` — Create an exact straight 3D NURBS line segment.
|
|
117
99
|
|
|
118
100
|
```js
|
|
119
101
|
const rail = Curve.Line([0, 0, 0], [80, 0, 15]);
|
|
120
102
|
const rib = sweep(circle2d(2), rail);
|
|
121
103
|
```
|
|
122
104
|
|
|
123
|
-
|
|
124
|
-
Curve.Line(start: Vec3, end: Vec3): NurbsCurve3D
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
#### `Curve.Polyline()` — Create a polyline path as cloned 3D points.
|
|
128
|
-
|
|
129
|
-
Polylines are exact as route/path input to `sweep`. Use `Curve.Route` when the centerline needs bend and endpoint-frame metadata.
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
Curve.Polyline(points: Vec3[]): Vec3[]
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
#### `Curve.Spline()` — Create a smooth Catmull-Rom spline path.
|
|
136
|
-
|
|
137
|
-
This is a smooth sampled curve object. Use `Curve.Nurbs` when the path must preserve exact control-point and knot data.
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
Curve.Spline(points: Vec3[], options?: Spline3DOptions): Curve3D
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**`Spline3DOptions`**
|
|
144
|
-
- `closed?: boolean` — Closed loop (default false).
|
|
145
|
-
- `tension?: number` — Catmull-Rom tension in [0, 1]. 0 = very round, 1 = linear-ish. Default 0.5.
|
|
146
|
-
|
|
147
|
-
#### `Curve.Nurbs()` — Create an exact NURBS 3D curve from control points, weights, knots, and degree.
|
|
105
|
+
#### `Curve.Nurbs(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D` — Create an exact NURBS 3D curve from control points, weights, knots, and degree.
|
|
148
106
|
|
|
149
107
|
```js
|
|
150
108
|
const rail = Curve.Nurbs([[0, 0, 0], [30, 4, 12], [60, -4, 12], [90, 0, 0]]);
|
|
151
109
|
const tube = sweep(circle2d(2), rail);
|
|
152
110
|
```
|
|
153
111
|
|
|
154
|
-
```ts
|
|
155
|
-
Curve.Nurbs(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D
|
|
156
|
-
```
|
|
157
|
-
|
|
158
112
|
**`NurbsCurve3DOptions`**
|
|
159
113
|
|
|
160
114
|
| Option | Type | Description |
|
|
@@ -164,9 +118,9 @@ Curve.Nurbs(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D
|
|
|
164
118
|
| `knots?` | `number[]` | Knot vector (default: uniform clamped). Must have length = controlPoints.length + degree + 1. |
|
|
165
119
|
| `closed?` | `boolean` | Whether the curve is closed/periodic (default false). |
|
|
166
120
|
|
|
167
|
-
#### `Curve.Fit()` — Fit a non-rational NURBS curve that interpolates every input point.
|
|
121
|
+
#### `Curve.Fit(points: Vec3[], options?: CurveFitOptions): NurbsCurve3D` — Fit a non-rational NURBS curve that interpolates every input point.
|
|
168
122
|
|
|
169
|
-
This is global B-spline interpolation, not approximate curve reduction: ForgeCAD computes chord-length parameters, averaged clamped knots, solves the control points, then verifies the interpolation residual against `tolerance`.
|
|
123
|
+
This is global B-spline interpolation, not approximate curve reduction: ForgeCAD computes chord-length parameters, averaged clamped knots, solves the control points, then verifies the interpolation residual against `tolerance`. With `{ closed: true }` the fit is standard periodic B-spline interpolation: the curve loops smoothly from the last point back to the first (do not repeat the first point at the end).
|
|
170
124
|
|
|
171
125
|
```js
|
|
172
126
|
const rail = Curve.Fit(
|
|
@@ -174,33 +128,28 @@ const rail = Curve.Fit(
|
|
|
174
128
|
{ degree: 3, tolerance: 0.001 },
|
|
175
129
|
);
|
|
176
130
|
const tube = sweep(circle2d(2), rail);
|
|
177
|
-
```
|
|
178
131
|
|
|
179
|
-
|
|
180
|
-
Curve.Fit(
|
|
132
|
+
// Closed loop through four points — no duplicated closing point
|
|
133
|
+
const loop = Curve.Fit(
|
|
134
|
+
[[30, 0, 0], [0, 30, 0], [-30, 0, 0], [0, -30, 0]],
|
|
135
|
+
{ closed: true },
|
|
136
|
+
);
|
|
181
137
|
```
|
|
182
138
|
|
|
183
139
|
**`CurveFitOptions`**
|
|
184
140
|
- `degree?: number` — Polynomial degree. Default is cubic, reduced automatically for short point lists.
|
|
185
141
|
- `tolerance?: number` — Maximum allowed interpolation residual in model units. Default 1e-7.
|
|
142
|
+
- `closed?: boolean` — Interpolate a closed periodic loop through the points. The loop closes from the last point back to the first automatically — do not repeat the first point at the end.
|
|
186
143
|
|
|
187
|
-
#### `Curve.Trim()
|
|
144
|
+
#### `Curve.Trim<T extends CurveTrimInput>(curve: T, start: number, end: number): CurveTrimOutput<T>` — Extract an exact curve segment from normalized parameter `start` to `end`.
|
|
188
145
|
|
|
189
146
|
`NurbsCurve3D` inputs are trimmed with exact knot insertion/subdomain extraction. Polyline point arrays are trimmed by arclength over their exact line segments. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
190
147
|
|
|
191
|
-
|
|
192
|
-
Curve.Trim<T extends CurveTrimInput>(curve: T, start: number, end: number): CurveTrimOutput<T>
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
#### `Curve.Reverse()` — Reverse an exact curve without changing its geometry.
|
|
148
|
+
#### `Curve.Reverse<T extends CurveTrimInput>(curve: T): CurveTrimOutput<T>` — Reverse an exact curve without changing its geometry.
|
|
196
149
|
|
|
197
150
|
`NurbsCurve3D` inputs reverse control points, weights, and knots. Polyline point arrays are cloned and reversed. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
198
151
|
|
|
199
|
-
|
|
200
|
-
Curve.Reverse<T extends CurveTrimInput>(curve: T): CurveTrimOutput<T>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
#### `Curve.Route()` — Build analytic 3D line/arc routes for sweeps.
|
|
152
|
+
#### `Curve.Route: typeof Route3D` — Build analytic 3D line/arc routes for sweeps.
|
|
204
153
|
|
|
205
154
|
`Curve.Route.fromPolyline()` is the canonical route API. It returns a `Route3D` value object, preserving exact route segments, named port frames, and the lowerable `route3d` sweep compile plan.
|
|
206
155
|
|
|
@@ -212,11 +161,7 @@ const route = Curve.Route.fromPolyline(
|
|
|
212
161
|
const tube = sweep(circle2d(4), route);
|
|
213
162
|
```
|
|
214
163
|
|
|
215
|
-
|
|
216
|
-
Curve.Route: typeof Route3D
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
#### `Curve.Helix()` — Build helical paths and swept coils.
|
|
164
|
+
#### `Curve.Helix: { path(options: HelixOptions): CurveHelixPath; coil: CurveHelixCoil; }` — Build helical paths and swept coils.
|
|
220
165
|
|
|
221
166
|
`Curve.Helix` is the canonical namespace for helical paths and coils. It uses the same sweep-based lowering as other curve paths.
|
|
222
167
|
|
|
@@ -225,10 +170,6 @@ const guide = Curve.Helix.path({ radius: 20, pitch: 6, turns: 4 });
|
|
|
225
170
|
const spring = Curve.Helix.coil({ radius: 20, pitch: 6, turns: 4, wireRadius: 1 });
|
|
226
171
|
```
|
|
227
172
|
|
|
228
|
-
```ts
|
|
229
|
-
Curve.Helix: { path(options: HelixOptions): CurveHelixPath; coil: CurveHelixCoil; }
|
|
230
|
-
```
|
|
231
|
-
|
|
232
173
|
**`HelixOptions`**
|
|
233
174
|
|
|
234
175
|
| Option | Type | Description |
|
|
@@ -243,95 +184,59 @@ Curve.Helix: { path(options: HelixOptions): CurveHelixPath; coil: CurveHelixCoil
|
|
|
243
184
|
|
|
244
185
|
`CurveHelixPath`: `{ radius: number, pitch: number, turns: number, height: number, startAngle: number, clockwise: boolean }`
|
|
245
186
|
|
|
246
|
-
#### `Loft.station()` — Create a loft station from a 2D profile and an axis position.
|
|
247
|
-
|
|
248
|
-
```ts
|
|
249
|
-
Loft.station(profile: Sketch, position: number): LoftStation
|
|
250
|
-
```
|
|
187
|
+
#### `Loft.station(profile: Sketch, position: number): LoftStation` — Create a loft station from a 2D profile and an axis position.
|
|
251
188
|
|
|
252
189
|
`LoftStation`: `{ profile: Sketch, position: number }`
|
|
253
190
|
|
|
254
|
-
#### `Loft.
|
|
191
|
+
#### `Loft.field(profiles: Sketch[], heights: number[], options?: FieldLoftOptions): Shape` — Loft by interpolating signed-distance fields instead of matching vertices.
|
|
255
192
|
|
|
256
|
-
|
|
257
|
-
Loft.leftRail(path: LoftGuideRailPath): LoftGuideRail
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
`LoftGuideRail`: `{ side: LoftGuideRailSide, path: LoftGuideRailPath }`
|
|
193
|
+
Use this path when profiles change character, such as round shafts blending into flat, cruciform, or lobed tips. It is Manifold-only, mesh-based, and slower than stitched lofting, but it avoids profile-point correspondence artifacts because it blends profile fields instead of boundary vertices.
|
|
261
194
|
|
|
262
|
-
|
|
195
|
+
**`LoftOptions`**
|
|
196
|
+
- `edgeLength?: number` — Marching-grid edge length for level-set meshing. Smaller = finer.
|
|
197
|
+
- `boundsPadding?: number` — Optional extra bounds padding.
|
|
263
198
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
199
|
+
**`FieldLoftOptions`** extends LoftOptions
|
|
200
|
+
- `simplify?: boolean | "safe"` — Simplification control after field extraction. Default is topology-safe simplification.
|
|
201
|
+
- `maxTriangles?: number` — Hard post-extraction triangle budget. Must be a positive integer. If safe simplification cannot reach it, the build fails.
|
|
267
202
|
|
|
268
|
-
#### `Loft.
|
|
203
|
+
#### `Loft.leftRail(path: LoftGuideRailPath): LoftGuideRail` — Create a guide rail that constrains the section-local negative-X side.
|
|
269
204
|
|
|
270
|
-
|
|
271
|
-
Loft.frontRail(path: LoftGuideRailPath): LoftGuideRail
|
|
272
|
-
```
|
|
205
|
+
`LoftGuideRail`: `{ side: LoftGuideRailSide, path: LoftGuideRailPath }`
|
|
273
206
|
|
|
274
|
-
#### `Loft.
|
|
207
|
+
#### `Loft.rightRail(path: LoftGuideRailPath): LoftGuideRail` — Create a guide rail that constrains the section-local positive-X side.
|
|
275
208
|
|
|
276
|
-
|
|
277
|
-
Loft.backRail(path: LoftGuideRailPath): LoftGuideRail
|
|
278
|
-
```
|
|
209
|
+
#### `Loft.frontRail(path: LoftGuideRailPath): LoftGuideRail` — Create a guide rail that constrains the section-local positive-Y side.
|
|
279
210
|
|
|
280
|
-
#### `Loft.
|
|
211
|
+
#### `Loft.backRail(path: LoftGuideRailPath): LoftGuideRail` — Create a guide rail that constrains the section-local negative-Y side.
|
|
281
212
|
|
|
282
|
-
|
|
283
|
-
Loft.centerRail(path: LoftGuideRailPath): LoftGuideRail
|
|
284
|
-
```
|
|
213
|
+
#### `Loft.centerRail(path: LoftGuideRailPath): LoftGuideRail` — Create a guide rail that moves section centers along the loft.
|
|
285
214
|
|
|
286
|
-
#### `Loft.pathOnXz()` — Place a 2D guide path onto the XZ plane.
|
|
215
|
+
#### `Loft.pathOnXz(path: LoftPath2D, y?: number): Vec3[]` — Place a 2D guide path onto the XZ plane.
|
|
287
216
|
|
|
288
217
|
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).
|
|
289
218
|
|
|
290
|
-
|
|
291
|
-
Loft.pathOnXz(path: LoftPath2D, y?: number): Vec3[]
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
#### `Loft.pathOnYz()` — Place a 2D guide path onto the YZ plane.
|
|
219
|
+
#### `Loft.pathOnYz(path: LoftPath2D, x?: number): Vec3[]` — Place a 2D guide path onto the YZ plane.
|
|
295
220
|
|
|
296
221
|
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).
|
|
297
222
|
|
|
298
|
-
|
|
299
|
-
Loft.pathOnYz(path: LoftPath2D, x?: number): Vec3[]
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
#### `Loft.pathOnXy()` — Place a 2D guide path onto the XY plane.
|
|
223
|
+
#### `Loft.pathOnXy(path: LoftPath2D, z?: number): Vec3[]` — Place a 2D guide path onto the XY plane.
|
|
303
224
|
|
|
304
225
|
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.
|
|
305
226
|
|
|
306
|
-
|
|
307
|
-
Loft.pathOnXy(path: LoftPath2D, z?: number): Vec3[]
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
#### `Loft.withGuideRails()` — Loft through profile stations while forcing generated sections to follow guide rails.
|
|
227
|
+
#### `Loft.withGuideRails(stations: LoftStation[], rails: LoftGuideRail[], options?: LoftWithGuideRailsOptions): Shape` — Loft through profile stations while forcing generated sections to follow guide rails.
|
|
311
228
|
|
|
312
229
|
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.
|
|
313
230
|
|
|
314
|
-
```ts
|
|
315
|
-
Loft.withGuideRails(stations: LoftStation[], rails: LoftGuideRail[], options?: LoftWithGuideRailsOptions): Shape
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
**`LoftOptions`**
|
|
319
|
-
- `edgeLength?: number` — Marching-grid edge length for level-set meshing. Smaller = finer.
|
|
320
|
-
- `boundsPadding?: number` — Optional extra bounds padding.
|
|
321
|
-
|
|
322
231
|
**`LoftWithGuideRailsOptions`** extends LoftOptions
|
|
323
232
|
- `axis?: LoftAxis` — Primary station axis. Default Z.
|
|
324
233
|
- `samples?: number` — Number of generated loft stations including ends. Default scales with station count.
|
|
325
234
|
- `railSamples?: number` — Number of points sampled from curve-backed rails before axis interpolation. Default 64.
|
|
326
235
|
|
|
327
|
-
#### `spline2d()` — Build a smooth Catmull-Rom spline sketch from 2D control points.
|
|
236
|
+
#### `spline2d(points: Vec2[], options?: Spline2DOptions): Sketch` — Build a smooth Catmull-Rom spline sketch from 2D control points.
|
|
328
237
|
|
|
329
238
|
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.
|
|
330
239
|
|
|
331
|
-
```ts
|
|
332
|
-
spline2d(points: Vec2[], options?: Spline2DOptions): Sketch
|
|
333
|
-
```
|
|
334
|
-
|
|
335
240
|
**`Spline2DOptions`**
|
|
336
241
|
|
|
337
242
|
| Option | Type | Description |
|
|
@@ -342,21 +247,15 @@ spline2d(points: Vec2[], options?: Spline2DOptions): Sketch
|
|
|
342
247
|
| `strokeWidth?` | `number` | For open splines, provide stroke width to return a solid Sketch. If omitted for open splines, an error is thrown. |
|
|
343
248
|
| `join?` | `"Round" \| "Square"` | Stroke join for open splines. Default 'Round'. |
|
|
344
249
|
|
|
345
|
-
#### `loft()` — Loft between multiple sketches along Z stations.
|
|
250
|
+
#### `loft(profiles: Sketch[], heights: number[], options?: LoftOptions): Shape` — Loft between multiple sketches along Z stations.
|
|
346
251
|
|
|
347
252
|
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.
|
|
348
253
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
```ts
|
|
352
|
-
loft(profiles: Sketch[], heights: number[], options?: LoftOptions): Shape
|
|
353
|
-
```
|
|
254
|
+
The surface is smooth through 3+ stations (C1 spanwise interpolation, like CAD lofts), so it can bow slightly past the straight ruling between stations; sections are matched exactly at their stations. Two-station lofts are ruled. `edgeLength` caps the sample spacing in curved or twisted regions (quality presets scale it); straight regions keep input density.
|
|
354
255
|
|
|
355
|
-
|
|
256
|
+
Performance note: loft is significantly heavier than primitive/extrude/revolve. If the part is axis-symmetric (bottles, vases, knobs), prefer revolve().
|
|
356
257
|
|
|
357
|
-
|
|
358
|
-
sweep(profile: Sketch, path: SweepPathInput, options?: SweepOptions): Shape
|
|
359
|
-
```
|
|
258
|
+
#### `sweep(profile: Sketch, path: SweepPathInput, options?: SweepOptions): Shape`
|
|
360
259
|
|
|
361
260
|
**`SweepOptions`**
|
|
362
261
|
|
|
@@ -367,7 +266,7 @@ sweep(profile: Sketch, path: SweepPathInput, options?: SweepOptions): Shape
|
|
|
367
266
|
| `boundsPadding?` | `number` | Optional extra bounds padding. |
|
|
368
267
|
| `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
|
|
369
268
|
|
|
370
|
-
#### `variableSweep()` — Sweep a variable cross-section along a 3D spine curve.
|
|
269
|
+
#### `variableSweep(spine: SweepPathInput, sections: VariableSweepSection[], options?: VariableSweepOptions): Shape` — Sweep a variable cross-section along a 3D spine curve.
|
|
371
270
|
|
|
372
271
|
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.
|
|
373
272
|
|
|
@@ -375,10 +274,6 @@ Each section specifies a t parameter (0 = start, 1 = end of spine) and a 2D prof
|
|
|
375
274
|
|
|
376
275
|
Performance note: like sweep(), this uses level-set meshing internally.
|
|
377
276
|
|
|
378
|
-
```ts
|
|
379
|
-
variableSweep(spine: SweepPathInput, sections: VariableSweepSection[], options?: VariableSweepOptions): Shape
|
|
380
|
-
```
|
|
381
|
-
|
|
382
277
|
**`VariableSweepSection`**
|
|
383
278
|
- `t: number` — Parameter along the spine (0 = start, 1 = end).
|
|
384
279
|
- `profile: Sketch` — Cross-section profile at this station.
|
|
@@ -392,98 +287,11 @@ variableSweep(spine: SweepPathInput, sections: VariableSweepSection[], options?:
|
|
|
392
287
|
| `boundsPadding?` | `number` | Optional extra bounds padding. |
|
|
393
288
|
| `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
|
|
394
289
|
|
|
395
|
-
#### `nurbsSurface()` — Create a NURBS surface from a grid of control points.
|
|
396
|
-
|
|
397
|
-
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.
|
|
398
|
-
|
|
399
|
-
With default options, creates a bicubic non-rational B-spline surface with uniform clamped knots.
|
|
400
|
-
|
|
401
|
-
```js
|
|
402
|
-
// Simple 4×4 control grid — a gently curved surface
|
|
403
|
-
const grid = [
|
|
404
|
-
[[0,0,0], [10,0,2], [20,0,2], [30,0,0]],
|
|
405
|
-
[[0,10,1], [10,10,5], [20,10,5], [30,10,1]],
|
|
406
|
-
[[0,20,1], [10,20,5], [20,20,5], [30,20,1]],
|
|
407
|
-
[[0,30,0], [10,30,2], [20,30,2], [30,30,0]],
|
|
408
|
-
];
|
|
409
|
-
const surface = nurbsSurface(grid, { thickness: 2 });
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
```ts
|
|
413
|
-
nurbsSurface(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**`NurbsSurfaceOptions`**
|
|
417
|
-
|
|
418
|
-
| Option | Type | Description |
|
|
419
|
-
|--------|------|-------------|
|
|
420
|
-
| `degreeU?` | `number` | Degree in U direction (default 3). |
|
|
421
|
-
| `degreeV?` | `number` | Degree in V direction (default 3). |
|
|
422
|
-
| `weights?` | `number[][]` | Weights grid — same dimensions as controlGrid (default: all 1.0). |
|
|
423
|
-
| `knotsU?` | `number[]` | Knot vector in U direction (default: uniform clamped). |
|
|
424
|
-
| `knotsV?` | `number[]` | Knot vector in V direction (default: uniform clamped). |
|
|
425
|
-
| `thickness?` | `number` | Sheet thickness — if > 0, thickens the surface into a solid (default 0 = surface only). |
|
|
426
|
-
| `resolution?` | `number` | Tessellation resolution — points per direction (default 32). |
|
|
427
|
-
| `domain?` | `SurfaceDomainOptions` | Optional rectangular parameter domain in normalized [0, 1] U/V space. |
|
|
428
|
-
| `trim?` | `SurfaceTrimOptions` | Optional polygonal or NURBS-curve UV trim loops. Truck and OCCT support open trimmed surfaces; Manifold supports sampled thickened trimmed solids. |
|
|
429
|
-
| `tessellation?` | `SurfaceTessellationOptions` | Optional Truck kernel tessellation controls for render mesh generation. |
|
|
430
|
-
| `approximate?` | `boolean` | Explicit opt-in for sampled approximation paths on non-exact backends. |
|
|
431
|
-
|
|
432
|
-
**`SurfaceDomainOptions`**
|
|
433
|
-
|
|
434
|
-
| Option | Type | Description |
|
|
435
|
-
|--------|------|-------------|
|
|
436
|
-
| `uMin?` | `number` | Lower U parameter bound in normalized surface space (default 0). |
|
|
437
|
-
| `uMax?` | `number` | Upper U parameter bound in normalized surface space (default 1). |
|
|
438
|
-
| `vMin?` | `number` | Lower V parameter bound in normalized surface space (default 0). |
|
|
439
|
-
| `vMax?` | `number` | Upper V parameter bound in normalized surface space (default 1). |
|
|
440
|
-
|
|
441
|
-
**`SurfaceTrimOptions`**
|
|
442
|
-
- `outer: SurfaceTrimLoopInput` — Outer trim loop in normalized post-domain UV space.
|
|
443
|
-
- `holes?: SurfaceTrimLoopInput[]` — Optional hole loops in normalized post-domain UV space.
|
|
444
|
-
|
|
445
|
-
**`SurfaceTessellationOptions`**
|
|
446
|
-
|
|
447
|
-
| Option | Type | Description |
|
|
448
|
-
|--------|------|-------------|
|
|
449
|
-
| `mode?` | `"uniform" \| "adaptive"` | `uniform` uses resolution directly; `adaptive` lets the Truck kernel refine open sheets from chord error. |
|
|
450
|
-
| `tolerance?` | `number` | Target chord-error tolerance in model units for adaptive Truck tessellation. |
|
|
451
|
-
| `minResolution?` | `number` | Minimum adaptive samples per direction. |
|
|
452
|
-
| `maxResolution?` | `number` | Maximum adaptive samples per direction. Defaults to `resolution` when omitted. |
|
|
453
|
-
|
|
454
|
-
#### `surfacePatch()` — Create a smooth surface patch from 4 boundary curves (Coons patch).
|
|
455
|
-
|
|
456
|
-
The four curves form the boundary of a quadrilateral patch:
|
|
457
|
-
|
|
458
|
-
- bottom: u=0..1 at v=0 (from corner00 to corner10)
|
|
459
|
-
- top: u=0..1 at v=1 (from corner01 to corner11)
|
|
460
|
-
- left: v=0..1 at u=0 (from corner00 to corner01)
|
|
461
|
-
- right: v=0..1 at u=1 (from corner10 to corner11)
|
|
462
|
-
|
|
463
|
-
The interior is filled using bilinear Coons patch interpolation: P(u,v) = Lc(u,v) + Ld(u,v) - B(u,v)
|
|
464
|
-
|
|
465
|
-
The result is a thin solid created by offsetting the surface mesh along its normals by the specified thickness.
|
|
466
|
-
|
|
467
|
-
Note: curves should meet at corners. Small gaps are tolerated.
|
|
468
|
-
|
|
469
|
-
```ts
|
|
470
|
-
surfacePatch(curves: { ... }, options?: SurfacePatchOptions): Shape
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
**`SurfacePatchOptions`**
|
|
474
|
-
- `resolution?: number` — Number of samples along each direction. Default 24.
|
|
475
|
-
- `thickness?: number` — Thickness of the generated solid. Default 0 for an open exact sheet.
|
|
476
|
-
- `approximate?: boolean` — Allow explicit approximation for non-exact curve inputs such as Curve3D samples.
|
|
477
|
-
|
|
478
290
|
### Surface Members
|
|
479
291
|
|
|
480
|
-
#### `surfaceBand()
|
|
292
|
+
#### `surfaceBand<C extends SurfaceCoordinate>(path: SurfacePath<C> | SurfacePathBuilder<C>, width: WidthProfile, cap?: SurfaceBandCap): SurfaceBand<C>`
|
|
481
293
|
|
|
482
|
-
|
|
483
|
-
surfaceBand<C extends SurfaceCoordinate>(path: SurfacePath<C> | SurfacePathBuilder<C>, width: WidthProfile, cap?: SurfaceBandCap): SurfaceBand<C>
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
#### `SurfaceBody()` — Start a surface-member body builder for straps, inlays, guards, braces, cuffs, and similar physical members that live on a carrier surface.
|
|
294
|
+
#### `SurfaceBody(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.
|
|
487
295
|
|
|
488
296
|
```js
|
|
489
297
|
const carrier = Carrier.cylinder('guard-envelope').diameter(84).height(36).clearance(2);
|
|
@@ -504,10 +312,6 @@ const guard = SurfaceBody('simple-guard')
|
|
|
504
312
|
.build();
|
|
505
313
|
```
|
|
506
314
|
|
|
507
|
-
```ts
|
|
508
|
-
SurfaceBody(name: string): SurfaceBodyBuilder
|
|
509
|
-
```
|
|
510
|
-
|
|
511
315
|
---
|
|
512
316
|
|
|
513
317
|
## Classes
|
|
@@ -524,35 +328,15 @@ SurfaceBody(name: string): SurfaceBodyBuilder
|
|
|
524
328
|
|
|
525
329
|
**Methods:**
|
|
526
330
|
|
|
527
|
-
#### `sampleBySegment()` — Sample the curve with a fixed number of points per segment.
|
|
528
|
-
|
|
529
|
-
```ts
|
|
530
|
-
sampleBySegment(samplesPerSegment?: number): Vec3[]
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
#### `sample()` — Sample the curve to an approximate total point count.
|
|
534
|
-
|
|
535
|
-
```ts
|
|
536
|
-
sample(count?: number): Vec3[]
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
#### `pointAt()` — Return the position on the curve at normalized parameter `t` in `[0, 1]`. O(1), no allocations.
|
|
540
|
-
|
|
541
|
-
```ts
|
|
542
|
-
pointAt(t: number): Vec3
|
|
543
|
-
```
|
|
331
|
+
#### `sampleBySegment(samplesPerSegment?: number): Vec3[]` — Sample the curve with a fixed number of points per segment.
|
|
544
332
|
|
|
545
|
-
#### `
|
|
333
|
+
#### `sample(count?: number): Vec3[]` — Sample the curve to an approximate total point count.
|
|
546
334
|
|
|
547
|
-
|
|
548
|
-
tangentAt(t: number): Vec3
|
|
549
|
-
```
|
|
335
|
+
#### `pointAt(t: number): Vec3` — Return the position on the curve at normalized parameter `t` in `[0, 1]`. O(1), no allocations.
|
|
550
336
|
|
|
551
|
-
#### `
|
|
337
|
+
#### `tangentAt(t: number): Vec3` — Return a unit tangent vector at normalized parameter `t` in `[0, 1]`. O(1), analytical derivative.
|
|
552
338
|
|
|
553
|
-
|
|
554
|
-
length(samples?: number): number
|
|
555
|
-
```
|
|
339
|
+
#### `length(samples?: number): number` — Approximate the curve length by polyline sampling.
|
|
556
340
|
|
|
557
341
|
### `Route3D`
|
|
558
342
|
|
|
@@ -569,11 +353,7 @@ const pipe = sweep(difference2d(circle2d(8), circle2d(6)), route);
|
|
|
569
353
|
const outlet = route.port("outlet");
|
|
570
354
|
```
|
|
571
355
|
|
|
572
|
-
#### `fromPolyline()` — Build a line/arc route from virtual polyline corner points.
|
|
573
|
-
|
|
574
|
-
```ts
|
|
575
|
-
static fromPolyline(points: Route3DVec3[], options?: Route3DFromPolylineOptions): Route3D
|
|
576
|
-
```
|
|
356
|
+
#### `static fromPolyline(points: Route3DVec3[], options?: Route3DFromPolylineOptions): Route3D` — Build a line/arc route from virtual polyline corner points.
|
|
577
357
|
|
|
578
358
|
**`Route3DFromPolylineOptions`**
|
|
579
359
|
|
|
@@ -584,41 +364,17 @@ static fromPolyline(points: Route3DVec3[], options?: Route3DFromPolylineOptions)
|
|
|
584
364
|
| `endPort?` | `string` | Name for the end port. Default "end". |
|
|
585
365
|
| `up?` | `Vec3` | Preferred up vector for deterministic port frames. Default [0, 0, 1]. |
|
|
586
366
|
|
|
587
|
-
#### `length()` — Total centerline length, including line and bend arc segments.
|
|
367
|
+
#### `get length(): number` — Total centerline length, including line and bend arc segments.
|
|
588
368
|
|
|
589
|
-
|
|
590
|
-
get length(): number
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
#### `segments()` — Exact line and arc segments that make up this route.
|
|
594
|
-
|
|
595
|
-
```ts
|
|
596
|
-
get segments(): Route3DSegment[]
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
#### `ports()` — Named port frames, keyed by port name.
|
|
600
|
-
|
|
601
|
-
```ts
|
|
602
|
-
get ports(): Record<string, RoutePortFrame>
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
#### `port()` — Return one named route port frame.
|
|
606
|
-
|
|
607
|
-
```ts
|
|
608
|
-
port(name: string): RoutePortFrame
|
|
609
|
-
```
|
|
369
|
+
#### `get segments(): Route3DSegment[]` — Exact line and arc segments that make up this route.
|
|
610
370
|
|
|
611
|
-
#### `
|
|
371
|
+
#### `get ports(): Record<string, RoutePortFrame>` — Named port frames, keyed by port name.
|
|
612
372
|
|
|
613
|
-
|
|
614
|
-
toSweepPathPlan(): SweepPathCompilePlan
|
|
615
|
-
```
|
|
373
|
+
#### `port(name: string): RoutePortFrame` — Return one named route port frame.
|
|
616
374
|
|
|
617
|
-
#### `
|
|
375
|
+
#### `toSweepPathPlan(): SweepPathCompilePlan` — Convert this route to the compile plan consumed by sweep().
|
|
618
376
|
|
|
619
|
-
|
|
620
|
-
toPolyline(options?: number | Route3DToPolylineOptions): Route3DVec3[]
|
|
621
|
-
```
|
|
377
|
+
#### `toPolyline(options?: number | Route3DToPolylineOptions): Route3DVec3[]` — Sample this analytic route as a polyline for inspection or backend lowering.
|
|
622
378
|
|
|
623
379
|
**`Route3DToPolylineOptions`**
|
|
624
380
|
- `samples?: number` — Approximate target point count for the full route.
|
|
@@ -638,41 +394,17 @@ toPolyline(options?: number | Route3DToPolylineOptions): Route3DVec3[]
|
|
|
638
394
|
|
|
639
395
|
**Methods:**
|
|
640
396
|
|
|
641
|
-
#### `pointAt()` — Evaluate the curve at parameter t ∈ [0, 1]. Uses De Boor's algorithm — exact, O(degree²).
|
|
642
|
-
|
|
643
|
-
```ts
|
|
644
|
-
pointAt(t: number): Vec3
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
#### `tangentAt()` — Evaluate the unit tangent vector at parameter t ∈ [0, 1].
|
|
648
|
-
|
|
649
|
-
```ts
|
|
650
|
-
tangentAt(t: number): Vec3
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
#### `sample()` — Sample the curve uniformly at `count` points.
|
|
654
|
-
|
|
655
|
-
```ts
|
|
656
|
-
sample(count?: number): Vec3[]
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
#### `sampleAdaptive()` — Sample with adaptive density — more points in high-curvature regions.
|
|
397
|
+
#### `pointAt(t: number): Vec3` — Evaluate the curve at parameter t ∈ [0, 1]. Uses De Boor's algorithm — exact, O(degree²).
|
|
660
398
|
|
|
661
|
-
|
|
662
|
-
sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
|
|
663
|
-
```
|
|
399
|
+
#### `tangentAt(t: number): Vec3` — Evaluate the unit tangent vector at parameter t ∈ [0, 1].
|
|
664
400
|
|
|
665
|
-
#### `
|
|
401
|
+
#### `sample(count?: number): Vec3[]` — Sample the curve uniformly at `count` points.
|
|
666
402
|
|
|
667
|
-
|
|
668
|
-
length(samples?: number): number
|
|
669
|
-
```
|
|
403
|
+
#### `sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]` — Sample with adaptive density — more points in high-curvature regions.
|
|
670
404
|
|
|
671
|
-
#### `
|
|
405
|
+
#### `length(samples?: number): number` — Approximate arc length by summing polyline segment lengths.
|
|
672
406
|
|
|
673
|
-
|
|
674
|
-
toPolyline(samples?: number): Vec3[]
|
|
675
|
-
```
|
|
407
|
+
#### `toPolyline(samples?: number): Vec3[]` — Convert to a format compatible with sweep() path input.
|
|
676
408
|
|
|
677
409
|
### `NurbsSurface`
|
|
678
410
|
|
|
@@ -692,59 +424,31 @@ toPolyline(samples?: number): Vec3[]
|
|
|
692
424
|
|
|
693
425
|
**Methods:**
|
|
694
426
|
|
|
695
|
-
#### `pointAt()` — Evaluate the surface at parameters (u, v) ∈ [0, 1]². Uses tensor product evaluation: evaluate basis functions in U and V independently.
|
|
696
|
-
|
|
697
|
-
```ts
|
|
698
|
-
pointAt(u: number, v: number): Vec3
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
#### `normalAt()` — Evaluate the surface normal at (u, v) via cross product of partial derivatives.
|
|
427
|
+
#### `pointAt(u: number, v: number): Vec3` — Evaluate the surface at parameters (u, v) ∈ [0, 1]². Uses tensor product evaluation: evaluate basis functions in U and V independently.
|
|
702
428
|
|
|
703
|
-
|
|
704
|
-
normalAt(u: number, v: number): Vec3
|
|
705
|
-
```
|
|
429
|
+
#### `normalAt(u: number, v: number): Vec3` — Evaluate the surface normal at (u, v) via cross product of partial derivatives.
|
|
706
430
|
|
|
707
|
-
#### `tessellate()` — Tessellate the surface into a triangle mesh. Returns positions, normals, and triangle indices.
|
|
708
|
-
|
|
709
|
-
```ts
|
|
710
|
-
tessellate(resU?: number, resV?: number): { positions: Vec3[]; normals: Vec3[]; indices: number[]; }
|
|
711
|
-
```
|
|
431
|
+
#### `tessellate(resU?: number, resV?: number): { positions: Vec3[]; normals: Vec3[]; indices: number[]; }` — Tessellate the surface into a triangle mesh. Returns positions, normals, and triangle indices.
|
|
712
432
|
|
|
713
433
|
### `PathBuilder`
|
|
714
434
|
|
|
715
435
|
**Line Segments**
|
|
716
436
|
|
|
717
|
-
#### `moveTo()` — Move the cursor to an absolute position without drawing a segment.
|
|
437
|
+
#### `moveTo(x: number, y: number): this` — Move the cursor to an absolute position without drawing a segment.
|
|
718
438
|
|
|
719
439
|
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)).
|
|
720
440
|
|
|
721
|
-
|
|
722
|
-
moveTo(x: number, y: number): this
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
#### `lineTo()` — Draw a straight line from the current cursor to an absolute position.
|
|
441
|
+
#### `lineTo(x: number, y: number): this` — Draw a straight line from the current cursor to an absolute position.
|
|
726
442
|
|
|
727
|
-
|
|
728
|
-
lineTo(x: number, y: number): this
|
|
729
|
-
```
|
|
730
|
-
|
|
731
|
-
#### `lineH()` — Draw a horizontal line segment by `dx` units from the current cursor.
|
|
443
|
+
#### `lineH(dx: number): this` — Draw a horizontal line segment by `dx` units from the current cursor.
|
|
732
444
|
|
|
733
445
|
Positive `dx` moves right; negative moves left.
|
|
734
446
|
|
|
735
|
-
|
|
736
|
-
lineH(dx: number): this
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
#### `lineV()` — Draw a vertical line segment by `dy` units from the current cursor.
|
|
447
|
+
#### `lineV(dy: number): this` — Draw a vertical line segment by `dy` units from the current cursor.
|
|
740
448
|
|
|
741
449
|
Positive `dy` moves up; negative moves down.
|
|
742
450
|
|
|
743
|
-
|
|
744
|
-
lineV(dy: number): this
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
#### `lineAngled()` — Draw a line at the given angle and length from the current cursor.
|
|
451
|
+
#### `lineAngled(length: number, degrees: number): this` — Draw a line at the given angle and length from the current cursor.
|
|
748
452
|
|
|
749
453
|
Angle convention: `0°` points right (+X), `90°` points up (+Y).
|
|
750
454
|
|
|
@@ -753,46 +457,26 @@ Angle convention: `0°` points right (+X), `90°` points up (+Y).
|
|
|
753
457
|
path().moveTo(0, 0).lineH(50).lineV(-70).lineAngled(20, 235).stroke(4);
|
|
754
458
|
```
|
|
755
459
|
|
|
756
|
-
```ts
|
|
757
|
-
lineAngled(length: number, degrees: number): this
|
|
758
|
-
```
|
|
759
|
-
|
|
760
460
|
**Arcs**
|
|
761
461
|
|
|
762
|
-
#### `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.
|
|
462
|
+
#### `arc(cx: number, cy: number, radius: number, startDeg: number, endDeg: number): this` — 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.
|
|
763
463
|
|
|
764
464
|
```js
|
|
765
465
|
// Arc centered at (10, 0), radius 50, from -30° to +30°
|
|
766
466
|
path().arc(10, 0, 50, -30, 30).stroke(8, 'Round')
|
|
767
467
|
```
|
|
768
468
|
|
|
769
|
-
|
|
770
|
-
arc(cx: number, cy: number, radius: number, startDeg: number, endDeg: number): this
|
|
771
|
-
```
|
|
772
|
-
|
|
773
|
-
#### `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.
|
|
774
|
-
|
|
775
|
-
```ts
|
|
776
|
-
arcTo(x: number, y: number, radius: number, clockwise?: boolean): this
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
#### `tangentArcTo()` — G1-continuous arc — radius derived from current tangent + endpoint. Throws if endpoint is collinear with current direction.
|
|
469
|
+
#### `arcTo(x: number, y: number, radius: number, clockwise?: boolean): this` — 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.
|
|
780
470
|
|
|
781
|
-
|
|
782
|
-
tangentArcTo(x: number, y: number): this
|
|
783
|
-
```
|
|
471
|
+
#### `tangentArcTo(x: number, y: number): this` — G1-continuous arc — radius derived from current tangent + endpoint. Throws if endpoint is collinear with current direction.
|
|
784
472
|
|
|
785
473
|
**Curves**
|
|
786
474
|
|
|
787
|
-
#### `bezierTo()` — Cubic bezier from current position to (x, y) via two control points.
|
|
788
|
-
|
|
789
|
-
```ts
|
|
790
|
-
bezierTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): this
|
|
791
|
-
```
|
|
475
|
+
#### `bezierTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): this` — Cubic bezier from current position to (x, y) via two control points.
|
|
792
476
|
|
|
793
477
|
**Closing & Output**
|
|
794
478
|
|
|
795
|
-
#### `close()` — Close the path and return a filled [`Sketch`](/docs/sketch#sketch).
|
|
479
|
+
#### `close(): Sketch` — Close the path and return a filled [`Sketch`](/docs/sketch#sketch).
|
|
796
480
|
|
|
797
481
|
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.
|
|
798
482
|
|
|
@@ -807,21 +491,13 @@ const frame = path()
|
|
|
807
491
|
// (hole would be added with another moveTo and line sequence before close)
|
|
808
492
|
```
|
|
809
493
|
|
|
810
|
-
|
|
811
|
-
close(): Sketch
|
|
812
|
-
```
|
|
813
|
-
|
|
814
|
-
#### `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.
|
|
815
|
-
|
|
816
|
-
```ts
|
|
817
|
-
closeLabel(name: string): Sketch
|
|
818
|
-
```
|
|
494
|
+
#### `closeLabel(name: string): Sketch` — Label the closing segment and close the path. Shorthand for labeling the implicit line from the last point back to the start, then closing.
|
|
819
495
|
|
|
820
|
-
####
|
|
496
|
+
#### `stroke(width: number, join?: "Round" | "Square"): Sketch` — Thicken an open polyline (centerline) into a solid filled profile with uniform width.
|
|
821
497
|
|
|
822
498
|
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.
|
|
823
499
|
|
|
824
|
-
Not the same as rounding corners of a closed polygon — for mixed sharp-and-rounded outlines, build the polygon first and apply [
|
|
500
|
+
Not the same as rounding corners of a closed polygon — for mixed sharp-and-rounded outlines, build the polygon first and apply `.filletCorner([x, y], radius)` per corner.
|
|
825
501
|
|
|
826
502
|
```ts
|
|
827
503
|
// Square-join L-bracket
|
|
@@ -836,51 +512,23 @@ const wire = stroke([[0, 0], [50, 0], [50, -70]], 4);
|
|
|
836
512
|
|
|
837
513
|
and semicircular endcaps.
|
|
838
514
|
|
|
839
|
-
|
|
840
|
-
stroke(width: number, join?: "Round" | "Square"): Sketch
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
#### `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.
|
|
515
|
+
#### `label(name: string): this` — Label the most recently added segment. Labels are born here and grow into face names when the sketch is extruded, lofted, swept, or revolved.
|
|
844
516
|
|
|
845
517
|
Labels must be unique within a path. Each segment can have at most one label.
|
|
846
518
|
|
|
847
|
-
```ts
|
|
848
|
-
label(name: string): this
|
|
849
|
-
```
|
|
850
|
-
|
|
851
519
|
**Other**
|
|
852
520
|
|
|
853
|
-
#### `getX()` — Current cursor X position.
|
|
854
|
-
|
|
855
|
-
```ts
|
|
856
|
-
getX(): number
|
|
857
|
-
```
|
|
858
|
-
|
|
859
|
-
#### `getY()` — Current cursor Y position.
|
|
521
|
+
#### `getX(): number` — Current cursor X position.
|
|
860
522
|
|
|
861
|
-
|
|
862
|
-
getY(): number
|
|
863
|
-
```
|
|
864
|
-
|
|
865
|
-
#### `lineBy()` — Draw a line by a relative `(dx, dy)` displacement from the current cursor.
|
|
866
|
-
|
|
867
|
-
```ts
|
|
868
|
-
lineBy(dx: number, dy: number): this
|
|
869
|
-
```
|
|
523
|
+
#### `getY(): number` — Current cursor Y position.
|
|
870
524
|
|
|
871
|
-
#### `
|
|
872
|
-
|
|
873
|
-
```ts
|
|
874
|
-
arcBy(dx: number, dy: number, radius: number, clockwise?: boolean): this
|
|
875
|
-
```
|
|
525
|
+
#### `lineBy(dx: number, dy: number): this` — Draw a line by a relative `(dx, dy)` displacement from the current cursor.
|
|
876
526
|
|
|
877
|
-
#### `
|
|
527
|
+
#### `arcBy(dx: number, dy: number, radius: number, clockwise?: boolean): this` — Draw an arc to a point offset from the current cursor.
|
|
878
528
|
|
|
879
|
-
|
|
880
|
-
bezierBy(dcp1x: number, dcp1y: number, dcp2x: number, dcp2y: number, dx: number, dy: number): this
|
|
881
|
-
```
|
|
529
|
+
#### `bezierBy(dcp1x: number, dcp1y: number, dcp2x: number, dcp2y: number, dx: number, dy: number): this` — Draw a cubic Bezier using control points relative to the current cursor.
|
|
882
530
|
|
|
883
|
-
#### `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.
|
|
531
|
+
#### `arcAround(cx: number, cy: number, sweepDeg: number): this` — 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.
|
|
884
532
|
|
|
885
533
|
```js
|
|
886
534
|
// Arc 90° CCW around (50, 50)
|
|
@@ -889,11 +537,7 @@ path().moveTo(70, 50).arcAround(50, 50, 90)
|
|
|
889
537
|
path().moveTo(10, 0).arcAround(0, 0, -45)
|
|
890
538
|
```
|
|
891
539
|
|
|
892
|
-
|
|
893
|
-
arcAround(cx: number, cy: number, sweepDeg: number): this
|
|
894
|
-
```
|
|
895
|
-
|
|
896
|
-
#### `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.
|
|
540
|
+
#### `arcAroundRelative(dx: number, dy: number, sweepDeg: number): this` — 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.
|
|
897
541
|
|
|
898
542
|
```js
|
|
899
543
|
// Arc 90° CCW around a center 20 units to the right
|
|
@@ -901,47 +545,23 @@ path().moveTo(50, 50).arcAroundRelative(20, 0, 90)
|
|
|
901
545
|
// Equivalent to: path().moveTo(50, 50).arcAround(70, 50, 90)
|
|
902
546
|
```
|
|
903
547
|
|
|
904
|
-
|
|
905
|
-
arcAroundRelative(dx: number, dy: number, sweepDeg: number): this
|
|
906
|
-
```
|
|
548
|
+
#### `smoothCapTo(endX: number, endY: number, cornerRadius: number, capRadius: number): this` — 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.
|
|
907
549
|
|
|
908
|
-
#### `
|
|
550
|
+
#### `tangentBezierTo(cp2x: number, cp2y: number, x: number, y: number, weight?: number): this` — 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).
|
|
909
551
|
|
|
910
|
-
|
|
911
|
-
smoothCapTo(endX: number, endY: number, cornerRadius: number, capRadius: number): this
|
|
912
|
-
```
|
|
552
|
+
The second control point `(cp2x, cp2y)` must be provided — it controls the arrival curvature. For a fully automatic smooth curve, see `smoothThrough`.
|
|
913
553
|
|
|
914
|
-
#### `
|
|
554
|
+
#### `smoothThrough(waypoints: Vec2[], tension?: number): this` — 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.
|
|
915
555
|
|
|
916
|
-
|
|
556
|
+
#### `nurbsTo(controlPoints: Vec2[], opts?: { weights?: number[]; degree?: number; }): this` — Rational B-spline edge to (x, y) with explicit control points and weights.
|
|
917
557
|
|
|
918
|
-
|
|
919
|
-
tangentBezierTo(cp2x: number, cp2y: number, x: number, y: number, weight?: number): this
|
|
920
|
-
```
|
|
558
|
+
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.
|
|
921
559
|
|
|
922
|
-
#### `
|
|
923
|
-
|
|
924
|
-
```ts
|
|
925
|
-
smoothThrough(waypoints: [ number, number ][], tension?: number): this
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
#### `nurbsTo()` — Rational B-spline edge to (x, y) with explicit control points and weights.
|
|
929
|
-
|
|
930
|
-
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.
|
|
931
|
-
|
|
932
|
-
```ts
|
|
933
|
-
nurbsTo(controlPoints: [ number, number ][], opts?: { weights?: number[]; degree?: number; }): this
|
|
934
|
-
```
|
|
935
|
-
|
|
936
|
-
#### `exactArcTo()` — Exact circular arc to (x, y) using a rational quadratic NURBS.
|
|
560
|
+
#### `exactArcTo(x: number, y: number, opts?: { radius?: number; clockwise?: boolean; }): this` — Exact circular arc to (x, y) using a rational quadratic NURBS.
|
|
937
561
|
|
|
938
562
|
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.
|
|
939
563
|
|
|
940
|
-
|
|
941
|
-
exactArcTo(x: number, y: number, opts?: { radius?: number; clockwise?: boolean; }): this
|
|
942
|
-
```
|
|
943
|
-
|
|
944
|
-
#### [`fillet()`](/docs/core#fillet) — Round the last corner (the junction between the previous two segments) with a tangent arc of the given radius.
|
|
564
|
+
#### `fillet(radius: number): this` — Round the last corner (the junction between the previous two segments) with a tangent arc of the given radius.
|
|
945
565
|
|
|
946
566
|
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.
|
|
947
567
|
|
|
@@ -949,21 +569,13 @@ Must be called after at least two line/arc segments that form a corner. The fill
|
|
|
949
569
|
path().moveTo(0,0).lineTo(10,0).lineTo(10,10).fillet(2).lineTo(0,10).close()
|
|
950
570
|
```
|
|
951
571
|
|
|
952
|
-
|
|
953
|
-
fillet(radius: number): this
|
|
954
|
-
```
|
|
955
|
-
|
|
956
|
-
#### [`chamfer()`](/docs/core#chamfer) — Chamfer the last corner with a straight cut of the given distance.
|
|
572
|
+
#### `chamfer(distance: number): this` — Chamfer the last corner with a straight cut of the given distance.
|
|
957
573
|
|
|
958
574
|
```js
|
|
959
575
|
path().moveTo(0,0).lineTo(10,0).lineTo(10,10).chamfer(2).lineTo(0,10).close()
|
|
960
576
|
```
|
|
961
577
|
|
|
962
|
-
|
|
963
|
-
chamfer(distance: number): this
|
|
964
|
-
```
|
|
965
|
-
|
|
966
|
-
#### `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.
|
|
578
|
+
#### `mirror(axis: "x" | "y" | Vec2): this` — 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.
|
|
967
579
|
|
|
968
580
|
'y' mirrors across the local Y-axis (flips X), or `[nx, ny]` for an arbitrary axis direction.
|
|
969
581
|
|
|
@@ -972,11 +584,7 @@ chamfer(distance: number): this
|
|
|
972
584
|
path().moveTo(0,0).lineTo(10,0).lineTo(10,5).mirror('x').close()
|
|
973
585
|
```
|
|
974
586
|
|
|
975
|
-
|
|
976
|
-
mirror(axis: "x" | "y" | [ number, number ]): this
|
|
977
|
-
```
|
|
978
|
-
|
|
979
|
-
#### `toPolyline()` — Return the open path as a sampled 2D polyline.
|
|
587
|
+
#### `toPolyline(): Vec2[]` — Return the open path as a sampled 2D polyline.
|
|
980
588
|
|
|
981
589
|
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.
|
|
982
590
|
|
|
@@ -987,15 +595,7 @@ const rail = path()
|
|
|
987
595
|
.toPolyline();
|
|
988
596
|
```
|
|
989
597
|
|
|
990
|
-
|
|
991
|
-
toPolyline(): [ number, number ][]
|
|
992
|
-
```
|
|
993
|
-
|
|
994
|
-
#### `closeOffset()` — Close the path and return an offset version of the filled Sketch. Positive delta expands outward, negative shrinks inward.
|
|
995
|
-
|
|
996
|
-
```ts
|
|
997
|
-
closeOffset(delta: number, join?: "Round" | "Square" | "Miter"): Sketch
|
|
998
|
-
```
|
|
598
|
+
#### `closeOffset(delta: number, join?: "Round" | "Square" | "Miter"): Sketch` — Close the path and return an offset version of the filled Sketch. Positive delta expands outward, negative shrinks inward.
|
|
999
599
|
|
|
1000
600
|
### `ProductSkin`
|
|
1001
601
|
|
|
@@ -1011,29 +611,13 @@ closeOffset(delta: number, join?: "Round" | "Square" | "Miter"): Sketch
|
|
|
1011
611
|
|
|
1012
612
|
**Methods:**
|
|
1013
613
|
|
|
1014
|
-
####
|
|
1015
|
-
|
|
1016
|
-
```ts
|
|
1017
|
-
toShape(): Shape
|
|
1018
|
-
```
|
|
1019
|
-
|
|
1020
|
-
#### `with()` — Create a group containing this skin plus named child details.
|
|
1021
|
-
|
|
1022
|
-
```ts
|
|
1023
|
-
with(...children: GroupInput[]): ShapeGroup
|
|
1024
|
-
```
|
|
614
|
+
#### `toShape(): Shape` — Return the renderable shape generated for this product skin.
|
|
1025
615
|
|
|
1026
|
-
#### `
|
|
1027
|
-
|
|
1028
|
-
```ts
|
|
1029
|
-
integrate(...details: Shape[]): Shape
|
|
1030
|
-
```
|
|
616
|
+
#### `with(...children: GroupInput[]): ShapeGroup` — Create a group containing this skin plus named child details.
|
|
1031
617
|
|
|
1032
|
-
#### `
|
|
618
|
+
#### `integrate(...details: Shape[]): Shape` — Boolean-union structural details into the skin body.
|
|
1033
619
|
|
|
1034
|
-
|
|
1035
|
-
uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery
|
|
1036
|
-
```
|
|
620
|
+
#### `uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery` — Create a side/u/v surface-ref query on this skin.
|
|
1037
621
|
|
|
1038
622
|
**`ProductSkinSide`** — Semantic side of a ProductSkin. `back` is accepted as an alias for `rear`.
|
|
1039
623
|
|
|
@@ -1048,41 +632,21 @@ uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery
|
|
|
1048
632
|
| `v?` | `number` | Along-axis parameter, 0 at the first cap and 1 at the rear/back cap. Defaults to 0.5. |
|
|
1049
633
|
| `offset?` | `number` | Positive distance away from the surface along the resolved normal. |
|
|
1050
634
|
|
|
1051
|
-
#### `ref()` — Resolve a named ref published with Product.skin().refs(...).
|
|
1052
|
-
|
|
1053
|
-
```ts
|
|
1054
|
-
ref(name: string): ProductSurfaceRef
|
|
1055
|
-
```
|
|
635
|
+
#### `ref(name: string): ProductSurfaceRef` — Resolve a named ref published with Product.skin().refs(...).
|
|
1056
636
|
|
|
1057
|
-
#### `curveOnSurface()` — Create a sampled curve as a sequence of surface refs on this skin.
|
|
1058
|
-
|
|
1059
|
-
```ts
|
|
1060
|
-
curveOnSurface(name: string, points: Array<Partial<ProductSkinRefQuery> & { side: ProductSkinSide; }>): ProductSurfaceRef[]
|
|
1061
|
-
```
|
|
637
|
+
#### `curveOnSurface(name: string, points: Array<Partial<ProductSkinRefQuery> & { side: ProductSkinSide; }>): ProductSurfaceRef[]` — Create a sampled curve as a sequence of surface refs on this skin.
|
|
1062
638
|
|
|
1063
|
-
#### `surface()` — Create a fluent surface helper for refs and conformal features on one side of this skin.
|
|
639
|
+
#### `surface(side: ProductSkinSide): ProductSurfaceBuilder` — Create a fluent surface helper for refs and conformal features on one side of this skin.
|
|
1064
640
|
|
|
1065
641
|
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.
|
|
1066
642
|
|
|
1067
|
-
|
|
1068
|
-
surface(side: ProductSkinSide): ProductSurfaceBuilder
|
|
1069
|
-
```
|
|
1070
|
-
|
|
1071
|
-
#### `stationAt()` — Interpolate center, width, and depth at a normalized v or absolute axis value.
|
|
1072
|
-
|
|
1073
|
-
```ts
|
|
1074
|
-
stationAt(vOrAxis: number): { ... }
|
|
1075
|
-
```
|
|
643
|
+
#### `stationAt(vOrAxis: number): { ... }` — Interpolate center, width, and depth at a normalized v or absolute axis value.
|
|
1076
644
|
|
|
1077
645
|
**`ProductProfileKind`**
|
|
1078
646
|
|
|
1079
647
|
`"oval" | "roundedRect" | "circle" | "superEllipse" | "custom"`
|
|
1080
648
|
|
|
1081
|
-
#### `frame()` — Build a local surface frame from a side/u/v query.
|
|
1082
|
-
|
|
1083
|
-
```ts
|
|
1084
|
-
frame(query: ProductSkinRefQuery): ProductSurfaceFrame
|
|
1085
|
-
```
|
|
649
|
+
#### `frame(query: ProductSkinRefQuery): ProductSurfaceFrame` — Build a local surface frame from a side/u/v query.
|
|
1086
650
|
|
|
1087
651
|
`ProductSurfaceFrame`: `{ point: Vec3, normal: Vec3, tangentU: Vec3, tangentV: Vec3, matrix: Mat4, skin: string }`
|
|
1088
652
|
|
|
@@ -1092,35 +656,19 @@ frame(query: ProductSkinRefQuery): ProductSurfaceFrame
|
|
|
1092
656
|
|
|
1093
657
|
| Property | Type | Description |
|
|
1094
658
|
|----------|------|-------------|
|
|
1095
|
-
| `name` | `string
|
|
659
|
+
| `name` | `string \| undefined` | — |
|
|
1096
660
|
|
|
1097
661
|
**Methods:**
|
|
1098
662
|
|
|
1099
|
-
#### `frame()` — Resolve this semantic surface ref into a point, normal, tangents, and placement matrix.
|
|
1100
|
-
|
|
1101
|
-
```ts
|
|
1102
|
-
frame(overrides?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
#### `with()` — Return a copy of this ref with side/u/v/offset overrides.
|
|
1106
|
-
|
|
1107
|
-
```ts
|
|
1108
|
-
with(overrides: Partial<ProductSkinRefQuery>): ProductSurfaceRef
|
|
1109
|
-
```
|
|
663
|
+
#### `frame(overrides?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame` — Resolve this semantic surface ref into a point, normal, tangents, and placement matrix.
|
|
1110
664
|
|
|
1111
|
-
#### `
|
|
665
|
+
#### `with(overrides: Partial<ProductSkinRefQuery>): ProductSurfaceRef` — Return a copy of this ref with side/u/v/offset overrides.
|
|
1112
666
|
|
|
1113
|
-
|
|
1114
|
-
attach(detail: Shape | ShapeGroup, options?: ProductAttachOptions): Shape | ShapeGroup
|
|
1115
|
-
```
|
|
667
|
+
#### `attach(detail: Shape | ShapeGroup, options?: ProductAttachOptions): Shape | ShapeGroup` — Place a detail shape or group on this ref's local surface frame.
|
|
1116
668
|
|
|
1117
669
|
`ProductAttachOptions`: `{ offset?: number, inset?: number }`
|
|
1118
670
|
|
|
1119
|
-
#### `querySpec()` — Return the serializable side/u/v query behind this ref.
|
|
1120
|
-
|
|
1121
|
-
```ts
|
|
1122
|
-
querySpec(): ProductSkinRefQuery
|
|
1123
|
-
```
|
|
671
|
+
#### `querySpec(): ProductSkinRefQuery` — Return the serializable side/u/v query behind this ref.
|
|
1124
672
|
|
|
1125
673
|
### `ProductSurfaceBuilder`
|
|
1126
674
|
|
|
@@ -1134,32 +682,16 @@ Fluent helper bound to one ProductSkin side for refs and side-local conformal fe
|
|
|
1134
682
|
|
|
1135
683
|
**Methods:**
|
|
1136
684
|
|
|
1137
|
-
#### `ref()` — Create a ref on this skin side.
|
|
1138
|
-
|
|
1139
|
-
```ts
|
|
1140
|
-
ref(u?: number, v?: number, offset?: number): ProductSurfaceRef
|
|
1141
|
-
```
|
|
1142
|
-
|
|
1143
|
-
#### `uv()` — Create a side/u/v query on this skin side.
|
|
1144
|
-
|
|
1145
|
-
```ts
|
|
1146
|
-
uv(u?: number, v?: number, offset?: number): ProductSkinRefQuery
|
|
1147
|
-
```
|
|
685
|
+
#### `ref(u?: number, v?: number, offset?: number): ProductSurfaceRef` — Create a ref on this skin side.
|
|
1148
686
|
|
|
1149
|
-
#### `
|
|
687
|
+
#### `uv(u?: number, v?: number, offset?: number): ProductSkinRefQuery` — Create a side/u/v query on this skin side.
|
|
1150
688
|
|
|
1151
|
-
|
|
1152
|
-
frame(query?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame
|
|
1153
|
-
```
|
|
689
|
+
#### `frame(query?: Partial<ProductSkinRefQuery>): ProductSurfaceFrame` — Resolve a point/frame on this surface using the builder's side.
|
|
1154
690
|
|
|
1155
|
-
#### `ribbon()` — Start a conformal ribbon on this skin side.
|
|
691
|
+
#### `ribbon(name: string, points: ProductSurfacePathPoint[], options?: ProductRibbonBuildOptions): ProductRibbonBuilder` — Start a conformal ribbon on this skin side.
|
|
1156
692
|
|
|
1157
693
|
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.
|
|
1158
694
|
|
|
1159
|
-
```ts
|
|
1160
|
-
ribbon(name: string, points: ProductSurfacePathPoint[], options?: ProductRibbonBuildOptions): ProductRibbonBuilder
|
|
1161
|
-
```
|
|
1162
|
-
|
|
1163
695
|
**`ProductSurfacePathPoint`** — Side-local path point for Product.surface(side).ribbon(...); the surface helper supplies `side`.
|
|
1164
696
|
- `u?: number` — Across-side parameter on the bound side. Defaults to 0.5.
|
|
1165
697
|
- `v?: number` — Along-axis parameter, 0 at the first cap and 1 at the rear/back cap. Defaults to 0.5.
|
|
@@ -1180,24 +712,7 @@ ribbon(name: string, points: ProductSurfacePathPoint[], options?: ProductRibbonB
|
|
|
1180
712
|
|
|
1181
713
|
`ProductMaterial`: `{ color?: string, material?: ShapeMaterialProps }`
|
|
1182
714
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
| Option | Type | Description |
|
|
1186
|
-
|--------|------|-------------|
|
|
1187
|
-
| `metalness?` | `number` | Metalness factor (0 = dielectric, 1 = metal). Default: 0.05 |
|
|
1188
|
-
| `roughness?` | `number` | Roughness factor (0 = mirror, 1 = fully diffuse). Default: 0.35 |
|
|
1189
|
-
| `emissive?` | `string` | Emissive glow color (hex string, e.g. "#ff6b35"). |
|
|
1190
|
-
| `emissiveIntensity?` | `number` | Emissive intensity multiplier. Default: 1 |
|
|
1191
|
-
| `opacity?` | `number` | Opacity (0 = fully transparent, 1 = fully opaque). Default: 1 |
|
|
1192
|
-
| `wireframe?` | `boolean` | Render as wireframe. Default: false |
|
|
1193
|
-
| `clearcoat?` | `number` | Clearcoat intensity (0–1). Default: 0.1 |
|
|
1194
|
-
| `clearcoatRoughness?` | `number` | Clearcoat roughness (0–1). Default: 0.4 |
|
|
1195
|
-
| `transmission?` | `number` | Glass/translucency transmission factor (0–1). Renderer support depends on target. |
|
|
1196
|
-
| `ior?` | `number` | Index of refraction for transmissive materials. Typical glass is ~1.45. |
|
|
1197
|
-
| `thickness?` | `number` | Approximate transmissive volume thickness in model units. |
|
|
1198
|
-
| `specularIntensity?` | `number` | Specular highlight intensity (0–1). |
|
|
1199
|
-
| `specularColor?` | `string` | Specular highlight tint. |
|
|
1200
|
-
| `reflectivity?` | `number` | Reflection strength for supported renderers (0–1). |
|
|
715
|
+
`ShapeMaterialProps` — defined in [core](/docs/core).
|
|
1201
716
|
|
|
1202
717
|
### `ProductSkinBuilder`
|
|
1203
718
|
|
|
@@ -1209,31 +724,19 @@ ribbon(name: string, points: ProductSurfacePathPoint[], options?: ProductRibbonB
|
|
|
1209
724
|
|
|
1210
725
|
**Methods:**
|
|
1211
726
|
|
|
1212
|
-
#### `axis()` — Choose the primary station axis for the skin loft.
|
|
1213
|
-
|
|
1214
|
-
```ts
|
|
1215
|
-
axis(axis: ProductSkinAxis): this
|
|
1216
|
-
```
|
|
727
|
+
#### `axis(axis: ProductSkinAxis): this` — Choose the primary station axis for the skin loft.
|
|
1217
728
|
|
|
1218
729
|
**`ProductSkinAxis`** — Primary world axis used to order ProductSkin loft stations.
|
|
1219
730
|
|
|
1220
731
|
`"X" | "Y" | "Z"`
|
|
1221
732
|
|
|
1222
|
-
#### `stations()` — Set named cross-section stations for the product skin.
|
|
1223
|
-
|
|
1224
|
-
```ts
|
|
1225
|
-
stations(stations: Array<ProductStationBuilder | ProductStationSpec>): this
|
|
1226
|
-
```
|
|
733
|
+
#### `stations(stations: Array<ProductStationBuilder | ProductStationSpec>): this` — Set named cross-section stations for the product skin.
|
|
1227
734
|
|
|
1228
735
|
`ProductStationSpec`: `{ name: string, center: Vec3, profile: ProductStationProfile, crown?: number }`
|
|
1229
736
|
|
|
1230
737
|
`ProductStationProfile`: `{ sketch: Sketch, width: number, depth: number, kind: ProductProfileKind, radius?: number, exponent?: number }`
|
|
1231
738
|
|
|
1232
|
-
#### `rails()` — Attach named guide rails for product-skin construction and downstream surface references.
|
|
1233
|
-
|
|
1234
|
-
```ts
|
|
1235
|
-
rails(rails: Record<string, ProductRailSpec>): this
|
|
1236
|
-
```
|
|
739
|
+
#### `rails(rails: Record<string, ProductRailSpec>): this` — Attach named guide rails for product-skin construction and downstream surface references.
|
|
1237
740
|
|
|
1238
741
|
`ProductRailSpec`: `{ kind: ProductRailKind, points: Vec3[], degree?: number, name?: string }`
|
|
1239
742
|
|
|
@@ -1241,53 +744,21 @@ rails(rails: Record<string, ProductRailSpec>): this
|
|
|
1241
744
|
|
|
1242
745
|
`"bezier" | "nurbs" | "polyline"`
|
|
1243
746
|
|
|
1244
|
-
#### `ref()` — Publish a named semantic surface ref on the skin.
|
|
1245
|
-
|
|
1246
|
-
```ts
|
|
1247
|
-
ref(name: string, query: ProductSkinRefQuery): this
|
|
1248
|
-
```
|
|
1249
|
-
|
|
1250
|
-
#### `refs()` — Publish multiple named semantic surface refs on the skin.
|
|
1251
|
-
|
|
1252
|
-
```ts
|
|
1253
|
-
refs(refs: Record<string, ProductSkinRefQuery>): this
|
|
1254
|
-
```
|
|
1255
|
-
|
|
1256
|
-
#### `uv()` — Create a side/u/v surface-ref query for use in refs(...) or Product.ref(...).
|
|
1257
|
-
|
|
1258
|
-
```ts
|
|
1259
|
-
uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery
|
|
1260
|
-
```
|
|
1261
|
-
|
|
1262
|
-
#### `material()` — Apply a product material preset to the lowered skin.
|
|
1263
|
-
|
|
1264
|
-
```ts
|
|
1265
|
-
material(material: ProductMaterial): this
|
|
1266
|
-
```
|
|
1267
|
-
|
|
1268
|
-
#### `color()` — Apply a simple color override to the lowered skin.
|
|
747
|
+
#### `ref(name: string, query: ProductSkinRefQuery): this` — Publish a named semantic surface ref on the skin.
|
|
1269
748
|
|
|
1270
|
-
|
|
1271
|
-
color(color: string): this
|
|
1272
|
-
```
|
|
749
|
+
#### `refs(refs: Record<string, ProductSkinRefQuery>): this` — Publish multiple named semantic surface refs on the skin.
|
|
1273
750
|
|
|
1274
|
-
#### `
|
|
751
|
+
#### `uv(side: ProductSkinSide, u?: number, v?: number): ProductSkinRefQuery` — Create a side/u/v surface-ref query for use in refs(...) or Product.ref(...).
|
|
1275
752
|
|
|
1276
|
-
|
|
1277
|
-
edgeLength(value: number): this
|
|
1278
|
-
```
|
|
753
|
+
#### `material(material: ProductMaterial): this` — Apply a product material preset to the lowered skin.
|
|
1279
754
|
|
|
1280
|
-
#### `
|
|
755
|
+
#### `color(color: string): this` — Apply a simple color override to the lowered skin.
|
|
1281
756
|
|
|
1282
|
-
|
|
1283
|
-
wall(thickness: number): this
|
|
1284
|
-
```
|
|
757
|
+
#### `edgeLength(value: number): this` — Set the sampled loft target edge length.
|
|
1285
758
|
|
|
1286
|
-
#### `
|
|
759
|
+
#### `wall(thickness: number): this` — Record intended wall thickness for product design metadata. Use explicit shelling when the model needs real inner-wall geometry.
|
|
1287
760
|
|
|
1288
|
-
|
|
1289
|
-
build(): ProductSkin
|
|
1290
|
-
```
|
|
761
|
+
#### `build(): ProductSkin` — Lower stations and refs into a ProductSkin body.
|
|
1291
762
|
|
|
1292
763
|
### `ProductStationBuilder`
|
|
1293
764
|
|
|
@@ -1299,73 +770,29 @@ build(): ProductSkin
|
|
|
1299
770
|
|
|
1300
771
|
**Methods:**
|
|
1301
772
|
|
|
1302
|
-
#### `at()` — Position this station in world coordinates.
|
|
1303
|
-
|
|
1304
|
-
```ts
|
|
1305
|
-
at(point: Vec3): this
|
|
1306
|
-
```
|
|
1307
|
-
|
|
1308
|
-
#### `z()` — Convenience for traditional Z-up section stacks.
|
|
1309
|
-
|
|
1310
|
-
```ts
|
|
1311
|
-
z(z: number): this
|
|
1312
|
-
```
|
|
1313
|
-
|
|
1314
|
-
#### `y()` — Convenience for product bodies running front-to-back along Y.
|
|
1315
|
-
|
|
1316
|
-
```ts
|
|
1317
|
-
y(y: number): this
|
|
1318
|
-
```
|
|
1319
|
-
|
|
1320
|
-
#### `x()` — Convenience for product bodies running left-to-right along X.
|
|
773
|
+
#### `at(point: Vec3): this` — Position this station in world coordinates.
|
|
1321
774
|
|
|
1322
|
-
|
|
1323
|
-
x(x: number): this
|
|
1324
|
-
```
|
|
775
|
+
#### `z(z: number): this` — Convenience for traditional Z-up section stacks.
|
|
1325
776
|
|
|
1326
|
-
#### `
|
|
777
|
+
#### `y(y: number): this` — Convenience for product bodies running front-to-back along Y.
|
|
1327
778
|
|
|
1328
|
-
|
|
1329
|
-
oval(width: number, depth: number, options?: { segments?: number; }): this
|
|
1330
|
-
```
|
|
779
|
+
#### `x(x: number): this` — Convenience for product bodies running left-to-right along X.
|
|
1331
780
|
|
|
1332
|
-
#### `
|
|
781
|
+
#### `oval(width: number, depth: number, options?: { segments?: number; }): this` — Use an oval cross-section with full width and depth dimensions.
|
|
1333
782
|
|
|
1334
|
-
|
|
1335
|
-
superEllipse(width: number, depth: number, options?: ProductStationSuperEllipseOptions): this
|
|
1336
|
-
```
|
|
783
|
+
#### `superEllipse(width: number, depth: number, options?: ProductStationSuperEllipseOptions): this` — Use a superellipse cross-section for soft-square product surfaces.
|
|
1337
784
|
|
|
1338
785
|
`ProductStationSuperEllipseOptions`: `{ segments?: number, exponent?: number }`
|
|
1339
786
|
|
|
1340
|
-
####
|
|
1341
|
-
|
|
1342
|
-
```ts
|
|
1343
|
-
roundedRect(width: number, depth: number, radius: number): this
|
|
1344
|
-
```
|
|
1345
|
-
|
|
1346
|
-
#### [`circle()`](/docs/sketch#circle) — Use a circular cross-section from a full diameter.
|
|
787
|
+
#### `roundedRect(width: number, depth: number, radius: number): this` — Use a rounded-rectangle cross-section with the given corner radius.
|
|
1347
788
|
|
|
1348
|
-
|
|
1349
|
-
circle(diameter: number, options?: { segments?: number; }): this
|
|
1350
|
-
```
|
|
1351
|
-
|
|
1352
|
-
#### `custom()` — Use a custom 2D sketch as the station cross-section.
|
|
1353
|
-
|
|
1354
|
-
```ts
|
|
1355
|
-
custom(sketch: Sketch, width: number, depth: number): this
|
|
1356
|
-
```
|
|
789
|
+
#### `circle(diameter: number, options?: { segments?: number; }): this` — Use a circular cross-section from a full diameter.
|
|
1357
790
|
|
|
1358
|
-
#### `
|
|
1359
|
-
|
|
1360
|
-
```ts
|
|
1361
|
-
crown(amount: number): this
|
|
1362
|
-
```
|
|
791
|
+
#### `custom(sketch: Sketch, width: number, depth: number): this` — Use a custom 2D sketch as the station cross-section.
|
|
1363
792
|
|
|
1364
|
-
#### `
|
|
793
|
+
#### `crown(amount: number): this` — Set the station crown amount for soft product-section intent.
|
|
1365
794
|
|
|
1366
|
-
|
|
1367
|
-
toSpec(): ProductStationSpec
|
|
1368
|
-
```
|
|
795
|
+
#### `toSpec(): ProductStationSpec` — Return the immutable station spec consumed by Product.skin().
|
|
1369
796
|
|
|
1370
797
|
### `ProductPanelBuilder`
|
|
1371
798
|
|
|
@@ -1377,53 +804,21 @@ toSpec(): ProductStationSpec
|
|
|
1377
804
|
|
|
1378
805
|
**Methods:**
|
|
1379
806
|
|
|
1380
|
-
#### `rounded()` — Use a rounded rectangle panel profile.
|
|
1381
|
-
|
|
1382
|
-
```ts
|
|
1383
|
-
rounded(width: number, height: number, radius?: number): this
|
|
1384
|
-
```
|
|
1385
|
-
|
|
1386
|
-
#### `oval()` — Use an oval panel profile.
|
|
1387
|
-
|
|
1388
|
-
```ts
|
|
1389
|
-
oval(width: number, height: number): this
|
|
1390
|
-
```
|
|
1391
|
-
|
|
1392
|
-
#### `profile()` — Use a custom 2D panel profile.
|
|
1393
|
-
|
|
1394
|
-
```ts
|
|
1395
|
-
profile(profile: Sketch): this
|
|
1396
|
-
```
|
|
1397
|
-
|
|
1398
|
-
#### `thickness()` — Set panel extrusion thickness.
|
|
1399
|
-
|
|
1400
|
-
```ts
|
|
1401
|
-
thickness(thickness: number): this
|
|
1402
|
-
```
|
|
807
|
+
#### `rounded(width: number, height: number, radius?: number): this` — Use a rounded rectangle panel profile.
|
|
1403
808
|
|
|
1404
|
-
#### `
|
|
1405
|
-
|
|
1406
|
-
```ts
|
|
1407
|
-
material(material: ProductMaterial): this
|
|
1408
|
-
```
|
|
809
|
+
#### `oval(width: number, height: number): this` — Use an oval panel profile.
|
|
1409
810
|
|
|
1410
|
-
#### `
|
|
811
|
+
#### `profile(profile: Sketch): this` — Use a custom 2D panel profile.
|
|
1411
812
|
|
|
1412
|
-
|
|
1413
|
-
color(color: string): this
|
|
1414
|
-
```
|
|
813
|
+
#### `thickness(thickness: number): this` — Set panel extrusion thickness.
|
|
1415
814
|
|
|
1416
|
-
#### `
|
|
815
|
+
#### `material(material: ProductMaterial): this` — Apply a product material preset to the panel.
|
|
1417
816
|
|
|
1418
|
-
|
|
1419
|
-
build(): Shape
|
|
1420
|
-
```
|
|
817
|
+
#### `color(color: string): this` — Apply a simple color override to the panel.
|
|
1421
818
|
|
|
1422
|
-
#### `
|
|
819
|
+
#### `build(): Shape` — Build the panel in local coordinates.
|
|
1423
820
|
|
|
1424
|
-
|
|
1425
|
-
attachTo(ref: ProductRefInput, options?: ProductPanelAttachOptions): Shape
|
|
1426
|
-
```
|
|
821
|
+
#### `attachTo(ref: ProductRefInput, options?: ProductPanelAttachOptions): Shape` — Build and attach this panel to a ProductSurfaceRef.
|
|
1427
822
|
|
|
1428
823
|
**`ProductRefInput`**
|
|
1429
824
|
|
|
@@ -1443,691 +838,188 @@ Builder for thin trim, label, grip, and split-line features that bend with a Pro
|
|
|
1443
838
|
|
|
1444
839
|
**Methods:**
|
|
1445
840
|
|
|
1446
|
-
#### `on()` — Follow a ProductSkin with side/u/v path queries or refs.
|
|
841
|
+
#### `on(skin: ProductSkin, points: ProductRibbonPathPoint[], options?: ProductRibbonBuildOptions): this` — Follow a ProductSkin with side/u/v path queries or refs.
|
|
1447
842
|
|
|
1448
843
|
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.
|
|
1449
844
|
|
|
1450
|
-
```ts
|
|
1451
|
-
on(skin: ProductSkin, points: ProductRibbonPathPoint[], options?: ProductRibbonBuildOptions): this
|
|
1452
|
-
```
|
|
1453
|
-
|
|
1454
845
|
**`ProductRibbonPathPoint`** — Path point for Product.ribbon().on(...): either a side/u/v query or a resolved surface ref.
|
|
1455
846
|
|
|
1456
847
|
`ProductSkinRefQuery | ProductSurfaceRef`
|
|
1457
848
|
|
|
1458
|
-
#### `fromRefs()` — Follow explicit surface refs.
|
|
849
|
+
#### `fromRefs(points: ProductSurfaceRef[], options?: ProductRibbonBuildOptions): this` — Follow explicit surface refs.
|
|
1459
850
|
|
|
1460
851
|
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.
|
|
1461
852
|
|
|
1462
|
-
|
|
1463
|
-
fromRefs(points: ProductSurfaceRef[], options?: ProductRibbonBuildOptions): this
|
|
1464
|
-
```
|
|
853
|
+
#### `width(width: number): this` — Set ribbon width in millimeters.
|
|
1465
854
|
|
|
1466
|
-
#### `
|
|
855
|
+
#### `thickness(thickness: number): this` — Set solid thickness outward from the source surface in millimeters.
|
|
1467
856
|
|
|
1468
|
-
|
|
1469
|
-
width(width: number): this
|
|
1470
|
-
```
|
|
857
|
+
#### `offset(offset: number): this` — Set positive clearance between the source surface and the ribbon's inner face.
|
|
1471
858
|
|
|
1472
|
-
#### `
|
|
859
|
+
#### `samples(samples: number): this` — Set samples along the path.
|
|
1473
860
|
|
|
1474
|
-
|
|
1475
|
-
thickness(thickness: number): this
|
|
1476
|
-
```
|
|
861
|
+
#### `widthSamples(samples: number): this` — Set samples across the width. Use 3+ to bend over curved cross-sections.
|
|
1477
862
|
|
|
1478
|
-
#### `
|
|
863
|
+
#### `resolution(resolution: number): this` — Set NURBS tessellation resolution.
|
|
1479
864
|
|
|
1480
|
-
|
|
1481
|
-
offset(offset: number): this
|
|
1482
|
-
```
|
|
865
|
+
#### `material(material: ProductMaterial): this` — Apply a product material preset.
|
|
1483
866
|
|
|
1484
|
-
#### `
|
|
867
|
+
#### `color(color: string): this` — Apply a simple color override.
|
|
1485
868
|
|
|
1486
|
-
|
|
1487
|
-
samples(samples: number): this
|
|
1488
|
-
```
|
|
869
|
+
#### `build(options?: ProductRibbonBuildOptions): Shape` — Build a conformal ribbon as a thin NURBS surface solid.
|
|
1489
870
|
|
|
1490
|
-
|
|
871
|
+
### `CylinderCarrier`
|
|
1491
872
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
873
|
+
**Properties:**
|
|
874
|
+
|
|
875
|
+
| Property | Type | Description |
|
|
876
|
+
|----------|------|-------------|
|
|
877
|
+
| `name` | `string` | — |
|
|
878
|
+
| `kind` | `"cylinder"` | — |
|
|
1495
879
|
|
|
1496
|
-
|
|
880
|
+
**Methods:**
|
|
1497
881
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
882
|
+
- `diameter(value: number): this`
|
|
883
|
+
- `radius(value: number): this`
|
|
884
|
+
- `height(value: number): this`
|
|
885
|
+
- `clearance(value: number): this`
|
|
886
|
+
- `center(point: Vec3): this`
|
|
887
|
+
- `path(): SurfacePathBuilder<CylinderSurfaceCoordinate>`
|
|
888
|
+
- `anchor(angle: number, z?: number, options?: { offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
889
|
+
- `front(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
890
|
+
- `back(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
891
|
+
- `left(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
892
|
+
- `right(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
893
|
+
- `top(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
894
|
+
- `bottom(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>`
|
|
895
|
+
- `pointAt(coordinate: CylinderSurfaceCoordinate): Vec3`
|
|
896
|
+
- `mirrorPoint(point: Vec3): Vec3`
|
|
897
|
+
- `normalAt(coordinate: CylinderSurfaceCoordinate): Vec3`
|
|
898
|
+
- `tangentAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): Vec3`
|
|
899
|
+
- `frameAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame`
|
|
900
|
+
- `bounds(): SurfaceBounds`
|
|
901
|
+
- `offset(distance: number): CylinderCarrier`
|
|
902
|
+
- `mirrorCoordinate(coordinate: CylinderSurfaceCoordinate): CylinderSurfaceCoordinate`
|
|
903
|
+
- `radiusValueWithClearance(): number`
|
|
1501
904
|
|
|
1502
|
-
|
|
905
|
+
`CylinderSurfaceCoordinate`: `{ kind?: "cylinder", angle: number, z: number, offset?: number }`
|
|
1503
906
|
|
|
1504
|
-
|
|
1505
|
-
material(material: ProductMaterial): this
|
|
1506
|
-
```
|
|
907
|
+
### `PlaneCarrier`
|
|
1507
908
|
|
|
1508
|
-
|
|
909
|
+
**Properties:**
|
|
1509
910
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
911
|
+
| Property | Type | Description |
|
|
912
|
+
|----------|------|-------------|
|
|
913
|
+
| `name` | `string` | — |
|
|
914
|
+
| `kind` | `"plane"` | — |
|
|
915
|
+
|
|
916
|
+
**Methods:**
|
|
1513
917
|
|
|
1514
|
-
|
|
918
|
+
- `size(width: number, height: number): this`
|
|
919
|
+
- `origin(point: Vec3): this`
|
|
920
|
+
- `normal(normal: Vec3): this`
|
|
921
|
+
- `path(): SurfacePathBuilder<PlaneSurfaceCoordinate>`
|
|
922
|
+
- `anchor(x?: number, y?: number, options?: { offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>`
|
|
923
|
+
- `left(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>`
|
|
924
|
+
- `right(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>`
|
|
925
|
+
- `top(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>`
|
|
926
|
+
- `bottom(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>`
|
|
927
|
+
- `pointAt(coordinate: PlaneSurfaceCoordinate): Vec3`
|
|
928
|
+
- `mirrorPoint(point: Vec3): Vec3`
|
|
929
|
+
- `normalAt(): Vec3`
|
|
930
|
+
- `tangentAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): Vec3`
|
|
931
|
+
- `frameAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame`
|
|
932
|
+
- `bounds(): SurfaceBounds`
|
|
933
|
+
- `offset(distance: number): PlaneCarrier`
|
|
934
|
+
- `mirrorCoordinate(coordinate: PlaneSurfaceCoordinate): PlaneSurfaceCoordinate`
|
|
1515
935
|
|
|
1516
|
-
|
|
1517
|
-
build(options?: ProductRibbonBuildOptions): Shape
|
|
1518
|
-
```
|
|
936
|
+
`PlaneSurfaceCoordinate`: `{ kind?: "plane", x: number, y: number, offset?: number }`
|
|
1519
937
|
|
|
1520
|
-
### `
|
|
938
|
+
### `ProductSkinCarrier`
|
|
1521
939
|
|
|
1522
940
|
**Properties:**
|
|
1523
941
|
|
|
1524
942
|
| Property | Type | Description |
|
|
1525
943
|
|----------|------|-------------|
|
|
944
|
+
| `skin` | `ProductSkin` | — |
|
|
1526
945
|
| `name` | `string` | — |
|
|
946
|
+
| `kind` | `"productSkin"` | — |
|
|
1527
947
|
|
|
1528
948
|
**Methods:**
|
|
1529
949
|
|
|
1530
|
-
#### `
|
|
1531
|
-
|
|
1532
|
-
```ts
|
|
1533
|
-
from(ref: ProductSurfaceRef): this
|
|
1534
|
-
```
|
|
950
|
+
#### `sideTransition(fromSide: ProductSkinSide, toSide: ProductSkinSide, input?: ProductSkinSideTransitionInput): ProductSkinSideTransition` — Return matching side-local coordinates for an explicit split-member transition.
|
|
1535
951
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
```ts
|
|
1539
|
-
sections(sections: Array<Sketch | ProductStationBuilder | ProductStationSpec>): this
|
|
1540
|
-
```
|
|
952
|
+
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.
|
|
1541
953
|
|
|
1542
|
-
|
|
954
|
+
Rules: only adjacent `left`/`top`/`right`/`bottom` sides are supported — for front/rear caps use `Product.panel()`. `v` is normalized 0–1 along the shared boundary (default 0.5); `name` must be non-empty when provided; `offset` lifts both coordinates off the surface. Throws if the returned boundary coordinates are not physically coincident — check side order, `v`, and `offset`.
|
|
1543
955
|
|
|
1544
|
-
|
|
1545
|
-
projection(length: number): this
|
|
1546
|
-
```
|
|
956
|
+
`ProductSkinSideTransitionInput`: `{ name?: string, v?: number, offset?: number }`
|
|
1547
957
|
|
|
1548
|
-
|
|
958
|
+
`ProductSkinSideTransition`: `{ name?: string, from: ProductSkinSurfaceCoordinate, to: ProductSkinSurfaceCoordinate }`
|
|
1549
959
|
|
|
1550
|
-
|
|
1551
|
-
edgeLength(value: number): this
|
|
1552
|
-
```
|
|
960
|
+
`ProductSkinSurfaceCoordinate`: `{ kind?: "productSkin", side?: ProductSkinSide, u?: number, v?: number, offset?: number }`
|
|
1553
961
|
|
|
1554
|
-
#### `
|
|
962
|
+
#### `sideTransitionChain(sides: ProductSkinSide[], input?: ProductSkinSideTransitionInput): ProductSkinSideTransition[]` — Return a sequence of matching side-local coordinates for an explicit multi-side split-member route.
|
|
1555
963
|
|
|
1556
|
-
|
|
1557
|
-
material(material: ProductMaterial): this
|
|
1558
|
-
```
|
|
964
|
+
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.
|
|
1559
965
|
|
|
1560
|
-
#### `
|
|
966
|
+
#### `sideRoute(input: ProductSkinSideRouteInput): ProductSkinSideRoute` — Return side-local member segments for a generated multi-side split-member route.
|
|
1561
967
|
|
|
1562
|
-
|
|
1563
|
-
color(color: string): this
|
|
1564
|
-
```
|
|
968
|
+
The route still compiles as explicit members plus named-anchor joins. This helper only generates the per-side segment endpoints and transition names.
|
|
1565
969
|
|
|
1566
|
-
|
|
970
|
+
**`ProductSkinSideRouteInput`**: `name?: string`, `sides: ProductSkinSide[]`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `v?: number`, `offset?: number`
|
|
1567
971
|
|
|
1568
|
-
|
|
1569
|
-
build(): Shape
|
|
1570
|
-
```
|
|
972
|
+
`ProductSkinSideRoute`: `{ name?: string, transitions: ProductSkinSideTransition[], segments: ProductSkinSideRouteSegment[] }`
|
|
1571
973
|
|
|
1572
|
-
|
|
974
|
+
**`ProductSkinSideRouteSegment`**: `name: string`, `side: ProductSkinSide`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `startAnchorName?: string`, `endAnchorName?: string`
|
|
1573
975
|
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
976
|
+
- `surface(side: ProductSkinSide): ProductSkinCarrier`
|
|
977
|
+
- `path(): SurfacePathBuilder<ProductSkinSurfaceCoordinate>`
|
|
978
|
+
- `pointAt(coordinate: ProductSkinSurfaceCoordinate): Vec3`
|
|
979
|
+
- `mirrorPoint(point: Vec3): Vec3`
|
|
980
|
+
- `normalAt(coordinate: ProductSkinSurfaceCoordinate): Vec3`
|
|
981
|
+
- `tangentAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): Vec3`
|
|
982
|
+
- `frameAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame`
|
|
983
|
+
- `bounds(): SurfaceBounds`
|
|
984
|
+
- `offset(distance: number): ProductSkinCarrier`
|
|
985
|
+
- `mirrorCoordinate(coordinate: ProductSkinSurfaceCoordinate): ProductSkinSurfaceCoordinate`
|
|
1577
986
|
|
|
1578
|
-
### `
|
|
987
|
+
### `SurfacePath`
|
|
1579
988
|
|
|
1580
989
|
**Properties:**
|
|
1581
990
|
|
|
1582
991
|
| Property | Type | Description |
|
|
1583
992
|
|----------|------|-------------|
|
|
1584
|
-
| `
|
|
993
|
+
| `carrier` | `CarrierSurface<C>` | — |
|
|
994
|
+
| `points` | `C[]` | — |
|
|
995
|
+
| `closedValue` | `boolean` | — |
|
|
1585
996
|
|
|
1586
997
|
**Methods:**
|
|
1587
998
|
|
|
1588
|
-
|
|
999
|
+
- `closed(): SurfacePath<C>`
|
|
1000
|
+
- `mirror(): SurfacePath<C>`
|
|
1001
|
+
- `coordinateAt(t: number): C`
|
|
1002
|
+
- `sample(count?: number): SurfacePathSample<C>[]`
|
|
1003
|
+
- `length(samples?: number): number`
|
|
1589
1004
|
|
|
1590
|
-
|
|
1591
|
-
between(upper: ProductSurfaceRef, lower: Vec3): this
|
|
1592
|
-
```
|
|
1005
|
+
### `SurfacePathBuilder`
|
|
1593
1006
|
|
|
1594
|
-
|
|
1007
|
+
**Properties:**
|
|
1595
1008
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1009
|
+
| Property | Type | Description |
|
|
1010
|
+
|----------|------|-------------|
|
|
1011
|
+
| `carrier` | `CarrierSurface<C>` | — |
|
|
1599
1012
|
|
|
1600
|
-
|
|
1013
|
+
**Methods:**
|
|
1601
1014
|
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
```
|
|
1611
|
-
|
|
1612
|
-
#### `padMaterial()` — Apply a product material preset to handle landing pads.
|
|
1613
|
-
|
|
1614
|
-
```ts
|
|
1615
|
-
padMaterial(material: ProductMaterial): this
|
|
1616
|
-
```
|
|
1617
|
-
|
|
1618
|
-
#### `edgeLength()` — Set the sampled loft target edge length for the grip.
|
|
1619
|
-
|
|
1620
|
-
```ts
|
|
1621
|
-
edgeLength(value: number): this
|
|
1622
|
-
```
|
|
1623
|
-
|
|
1624
|
-
#### `build()` — Build the handle grip and landing pads.
|
|
1625
|
-
|
|
1626
|
-
```ts
|
|
1627
|
-
build(): ProductHandleFeature
|
|
1628
|
-
```
|
|
1629
|
-
|
|
1630
|
-
### `ProductHandleFeature`
|
|
1631
|
-
|
|
1632
|
-
**Properties:**
|
|
1633
|
-
|
|
1634
|
-
| Property | Type | Description |
|
|
1635
|
-
|----------|------|-------------|
|
|
1636
|
-
| `grip` | `Shape` | — |
|
|
1637
|
-
| `upperPad` | `Shape` | — |
|
|
1638
|
-
| `lowerPad` | `Shape` | — |
|
|
1639
|
-
|
|
1640
|
-
**Methods:**
|
|
1641
|
-
|
|
1642
|
-
#### `structural()` — Return the physical shapes that make up this handle feature.
|
|
1643
|
-
|
|
1644
|
-
```ts
|
|
1645
|
-
structural(): Shape[]
|
|
1646
|
-
```
|
|
1647
|
-
|
|
1648
|
-
#### [`toShape()`](/docs/sdf#toshape) — Boolean-union the handle feature into a single shape.
|
|
1649
|
-
|
|
1650
|
-
```ts
|
|
1651
|
-
toShape(): Shape
|
|
1652
|
-
```
|
|
1653
|
-
|
|
1654
|
-
#### `toGroup()` — Return the handle as a named ShapeGroup preserving child colors.
|
|
1655
|
-
|
|
1656
|
-
```ts
|
|
1657
|
-
toGroup(): ShapeGroup
|
|
1658
|
-
```
|
|
1659
|
-
|
|
1660
|
-
### `CylinderCarrier`
|
|
1661
|
-
|
|
1662
|
-
**Properties:**
|
|
1663
|
-
|
|
1664
|
-
| Property | Type | Description |
|
|
1665
|
-
|----------|------|-------------|
|
|
1666
|
-
| `name` | `string` | — |
|
|
1667
|
-
| `kind` | `"cylinder"` | — |
|
|
1668
|
-
|
|
1669
|
-
**Methods:**
|
|
1670
|
-
|
|
1671
|
-
#### `diameter()`
|
|
1672
|
-
|
|
1673
|
-
```ts
|
|
1674
|
-
diameter(value: number): this
|
|
1675
|
-
```
|
|
1676
|
-
|
|
1677
|
-
#### `radius()`
|
|
1678
|
-
|
|
1679
|
-
```ts
|
|
1680
|
-
radius(value: number): this
|
|
1681
|
-
```
|
|
1682
|
-
|
|
1683
|
-
#### `height()`
|
|
1684
|
-
|
|
1685
|
-
```ts
|
|
1686
|
-
height(value: number): this
|
|
1687
|
-
```
|
|
1688
|
-
|
|
1689
|
-
#### `clearance()`
|
|
1690
|
-
|
|
1691
|
-
```ts
|
|
1692
|
-
clearance(value: number): this
|
|
1693
|
-
```
|
|
1694
|
-
|
|
1695
|
-
#### `center()`
|
|
1696
|
-
|
|
1697
|
-
```ts
|
|
1698
|
-
center(point: Vec3): this
|
|
1699
|
-
```
|
|
1700
|
-
|
|
1701
|
-
#### [`path()`](/docs/sketch#path)
|
|
1702
|
-
|
|
1703
|
-
```ts
|
|
1704
|
-
path(): SurfacePathBuilder<CylinderSurfaceCoordinate>
|
|
1705
|
-
```
|
|
1706
|
-
|
|
1707
|
-
#### `anchor()`
|
|
1708
|
-
|
|
1709
|
-
```ts
|
|
1710
|
-
anchor(angle: number, z?: number, options?: { offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1711
|
-
```
|
|
1712
|
-
|
|
1713
|
-
#### `front()`
|
|
1714
|
-
|
|
1715
|
-
```ts
|
|
1716
|
-
front(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1717
|
-
```
|
|
1718
|
-
|
|
1719
|
-
#### `back()`
|
|
1720
|
-
|
|
1721
|
-
```ts
|
|
1722
|
-
back(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1723
|
-
```
|
|
1724
|
-
|
|
1725
|
-
#### `left()`
|
|
1726
|
-
|
|
1727
|
-
```ts
|
|
1728
|
-
left(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1729
|
-
```
|
|
1730
|
-
|
|
1731
|
-
#### `right()`
|
|
1732
|
-
|
|
1733
|
-
```ts
|
|
1734
|
-
right(options?: { z?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1735
|
-
```
|
|
1736
|
-
|
|
1737
|
-
#### `top()`
|
|
1738
|
-
|
|
1739
|
-
```ts
|
|
1740
|
-
top(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1741
|
-
```
|
|
1742
|
-
|
|
1743
|
-
#### `bottom()`
|
|
1744
|
-
|
|
1745
|
-
```ts
|
|
1746
|
-
bottom(options?: { angle?: number; offset?: number; }): SurfaceAnchor<CylinderSurfaceCoordinate>
|
|
1747
|
-
```
|
|
1748
|
-
|
|
1749
|
-
#### `pointAt()`
|
|
1750
|
-
|
|
1751
|
-
```ts
|
|
1752
|
-
pointAt(coordinate: CylinderSurfaceCoordinate): Vec3
|
|
1753
|
-
```
|
|
1754
|
-
|
|
1755
|
-
`CylinderSurfaceCoordinate`: `{ kind?: "cylinder", angle: number, z: number, offset?: number }`
|
|
1756
|
-
|
|
1757
|
-
#### `mirrorPoint()`
|
|
1758
|
-
|
|
1759
|
-
```ts
|
|
1760
|
-
mirrorPoint(point: Vec3): Vec3
|
|
1761
|
-
```
|
|
1762
|
-
|
|
1763
|
-
#### `normalAt()`
|
|
1764
|
-
|
|
1765
|
-
```ts
|
|
1766
|
-
normalAt(coordinate: CylinderSurfaceCoordinate): Vec3
|
|
1767
|
-
```
|
|
1768
|
-
|
|
1769
|
-
#### `tangentAt()`
|
|
1770
|
-
|
|
1771
|
-
```ts
|
|
1772
|
-
tangentAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): Vec3
|
|
1773
|
-
```
|
|
1774
|
-
|
|
1775
|
-
#### `frameAt()`
|
|
1776
|
-
|
|
1777
|
-
```ts
|
|
1778
|
-
frameAt(coordinate: CylinderSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
|
|
1779
|
-
```
|
|
1780
|
-
|
|
1781
|
-
#### `bounds()`
|
|
1782
|
-
|
|
1783
|
-
```ts
|
|
1784
|
-
bounds(): SurfaceBounds
|
|
1785
|
-
```
|
|
1786
|
-
|
|
1787
|
-
#### `offset()`
|
|
1788
|
-
|
|
1789
|
-
```ts
|
|
1790
|
-
offset(distance: number): CylinderCarrier
|
|
1791
|
-
```
|
|
1792
|
-
|
|
1793
|
-
#### `mirrorCoordinate()`
|
|
1794
|
-
|
|
1795
|
-
```ts
|
|
1796
|
-
mirrorCoordinate(coordinate: CylinderSurfaceCoordinate): CylinderSurfaceCoordinate
|
|
1797
|
-
```
|
|
1798
|
-
|
|
1799
|
-
#### `radiusValueWithClearance()`
|
|
1800
|
-
|
|
1801
|
-
```ts
|
|
1802
|
-
radiusValueWithClearance(): number
|
|
1803
|
-
```
|
|
1804
|
-
|
|
1805
|
-
### `PlaneCarrier`
|
|
1806
|
-
|
|
1807
|
-
**Properties:**
|
|
1808
|
-
|
|
1809
|
-
| Property | Type | Description |
|
|
1810
|
-
|----------|------|-------------|
|
|
1811
|
-
| `name` | `string` | — |
|
|
1812
|
-
| `kind` | `"plane"` | — |
|
|
1813
|
-
|
|
1814
|
-
**Methods:**
|
|
1815
|
-
|
|
1816
|
-
#### `size()`
|
|
1817
|
-
|
|
1818
|
-
```ts
|
|
1819
|
-
size(width: number, height: number): this
|
|
1820
|
-
```
|
|
1821
|
-
|
|
1822
|
-
#### `origin()`
|
|
1823
|
-
|
|
1824
|
-
```ts
|
|
1825
|
-
origin(point: Vec3): this
|
|
1826
|
-
```
|
|
1827
|
-
|
|
1828
|
-
#### `normal()`
|
|
1829
|
-
|
|
1830
|
-
```ts
|
|
1831
|
-
normal(normal: Vec3): this
|
|
1832
|
-
```
|
|
1833
|
-
|
|
1834
|
-
#### [`path()`](/docs/sketch#path)
|
|
1835
|
-
|
|
1836
|
-
```ts
|
|
1837
|
-
path(): SurfacePathBuilder<PlaneSurfaceCoordinate>
|
|
1838
|
-
```
|
|
1839
|
-
|
|
1840
|
-
#### `anchor()`
|
|
1841
|
-
|
|
1842
|
-
```ts
|
|
1843
|
-
anchor(x?: number, y?: number, options?: { offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
|
|
1844
|
-
```
|
|
1845
|
-
|
|
1846
|
-
#### `left()`
|
|
1847
|
-
|
|
1848
|
-
```ts
|
|
1849
|
-
left(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
|
|
1850
|
-
```
|
|
1851
|
-
|
|
1852
|
-
#### `right()`
|
|
1853
|
-
|
|
1854
|
-
```ts
|
|
1855
|
-
right(options?: { y?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
|
|
1856
|
-
```
|
|
1857
|
-
|
|
1858
|
-
#### `top()`
|
|
1859
|
-
|
|
1860
|
-
```ts
|
|
1861
|
-
top(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
|
|
1862
|
-
```
|
|
1863
|
-
|
|
1864
|
-
#### `bottom()`
|
|
1865
|
-
|
|
1866
|
-
```ts
|
|
1867
|
-
bottom(options?: { x?: number; offset?: number; }): SurfaceAnchor<PlaneSurfaceCoordinate>
|
|
1868
|
-
```
|
|
1869
|
-
|
|
1870
|
-
#### `pointAt()`
|
|
1871
|
-
|
|
1872
|
-
```ts
|
|
1873
|
-
pointAt(coordinate: PlaneSurfaceCoordinate): Vec3
|
|
1874
|
-
```
|
|
1875
|
-
|
|
1876
|
-
`PlaneSurfaceCoordinate`: `{ kind?: "plane", x: number, y: number, offset?: number }`
|
|
1877
|
-
|
|
1878
|
-
#### `mirrorPoint()`
|
|
1879
|
-
|
|
1880
|
-
```ts
|
|
1881
|
-
mirrorPoint(point: Vec3): Vec3
|
|
1882
|
-
```
|
|
1883
|
-
|
|
1884
|
-
#### `normalAt()`
|
|
1885
|
-
|
|
1886
|
-
```ts
|
|
1887
|
-
normalAt(): Vec3
|
|
1888
|
-
```
|
|
1889
|
-
|
|
1890
|
-
#### `tangentAt()`
|
|
1891
|
-
|
|
1892
|
-
```ts
|
|
1893
|
-
tangentAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): Vec3
|
|
1894
|
-
```
|
|
1895
|
-
|
|
1896
|
-
#### `frameAt()`
|
|
1897
|
-
|
|
1898
|
-
```ts
|
|
1899
|
-
frameAt(coordinate: PlaneSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
|
|
1900
|
-
```
|
|
1901
|
-
|
|
1902
|
-
#### `bounds()`
|
|
1903
|
-
|
|
1904
|
-
```ts
|
|
1905
|
-
bounds(): SurfaceBounds
|
|
1906
|
-
```
|
|
1907
|
-
|
|
1908
|
-
#### `offset()`
|
|
1909
|
-
|
|
1910
|
-
```ts
|
|
1911
|
-
offset(distance: number): PlaneCarrier
|
|
1912
|
-
```
|
|
1913
|
-
|
|
1914
|
-
#### `mirrorCoordinate()`
|
|
1915
|
-
|
|
1916
|
-
```ts
|
|
1917
|
-
mirrorCoordinate(coordinate: PlaneSurfaceCoordinate): PlaneSurfaceCoordinate
|
|
1918
|
-
```
|
|
1919
|
-
|
|
1920
|
-
### `ProductSkinCarrier`
|
|
1921
|
-
|
|
1922
|
-
**Properties:**
|
|
1923
|
-
|
|
1924
|
-
| Property | Type | Description |
|
|
1925
|
-
|----------|------|-------------|
|
|
1926
|
-
| `skin` | `ProductSkin` | — |
|
|
1927
|
-
| `name` | `string` | — |
|
|
1928
|
-
| `kind` | `"productSkin"` | — |
|
|
1929
|
-
|
|
1930
|
-
**Methods:**
|
|
1931
|
-
|
|
1932
|
-
#### `surface()`
|
|
1933
|
-
|
|
1934
|
-
```ts
|
|
1935
|
-
surface(side: ProductSkinSide): ProductSkinCarrier
|
|
1936
|
-
```
|
|
1937
|
-
|
|
1938
|
-
#### [`path()`](/docs/sketch#path)
|
|
1939
|
-
|
|
1940
|
-
```ts
|
|
1941
|
-
path(): SurfacePathBuilder<ProductSkinSurfaceCoordinate>
|
|
1942
|
-
```
|
|
1943
|
-
|
|
1944
|
-
`ProductSkinSurfaceCoordinate`: `{ kind?: "productSkin", side?: ProductSkinSide, u?: number, v?: number, offset?: number }`
|
|
1945
|
-
|
|
1946
|
-
#### `sideTransition()` — Return matching side-local coordinates for an explicit split-member transition.
|
|
1947
|
-
|
|
1948
|
-
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.
|
|
1949
|
-
|
|
1950
|
-
```ts
|
|
1951
|
-
sideTransition(fromSide: ProductSkinSide, toSide: ProductSkinSide, input?: ProductSkinSideTransitionInput): ProductSkinSideTransition
|
|
1952
|
-
```
|
|
1953
|
-
|
|
1954
|
-
`ProductSkinSideTransitionInput`: `{ name?: string, v?: number, offset?: number }`
|
|
1955
|
-
|
|
1956
|
-
`ProductSkinSideTransition`: `{ name?: string, from: ProductSkinSurfaceCoordinate, to: ProductSkinSurfaceCoordinate }`
|
|
1957
|
-
|
|
1958
|
-
#### `sideTransitionChain()` — Return a sequence of matching side-local coordinates for an explicit multi-side split-member route.
|
|
1959
|
-
|
|
1960
|
-
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.
|
|
1961
|
-
|
|
1962
|
-
```ts
|
|
1963
|
-
sideTransitionChain(sides: ProductSkinSide[], input?: ProductSkinSideTransitionInput): ProductSkinSideTransition[]
|
|
1964
|
-
```
|
|
1965
|
-
|
|
1966
|
-
#### `sideRoute()` — Return side-local member segments for a generated multi-side split-member route.
|
|
1967
|
-
|
|
1968
|
-
The route still compiles as explicit members plus named-anchor joins. This helper only generates the per-side segment endpoints and transition names.
|
|
1969
|
-
|
|
1970
|
-
```ts
|
|
1971
|
-
sideRoute(input: ProductSkinSideRouteInput): ProductSkinSideRoute
|
|
1972
|
-
```
|
|
1973
|
-
|
|
1974
|
-
**`ProductSkinSideRouteInput`**: `name?: string`, `sides: ProductSkinSide[]`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `v?: number`, `offset?: number`
|
|
1975
|
-
|
|
1976
|
-
`ProductSkinSideRoute`: `{ name?: string, transitions: ProductSkinSideTransition[], segments: ProductSkinSideRouteSegment[] }`
|
|
1977
|
-
|
|
1978
|
-
**`ProductSkinSideRouteSegment`**: `name: string`, `side: ProductSkinSide`, `from: ProductSkinSurfaceCoordinate`, `to: ProductSkinSurfaceCoordinate`, `startAnchorName?: string`, `endAnchorName?: string`
|
|
1979
|
-
|
|
1980
|
-
#### `pointAt()`
|
|
1981
|
-
|
|
1982
|
-
```ts
|
|
1983
|
-
pointAt(coordinate: ProductSkinSurfaceCoordinate): Vec3
|
|
1984
|
-
```
|
|
1985
|
-
|
|
1986
|
-
#### `mirrorPoint()`
|
|
1987
|
-
|
|
1988
|
-
```ts
|
|
1989
|
-
mirrorPoint(point: Vec3): Vec3
|
|
1990
|
-
```
|
|
1991
|
-
|
|
1992
|
-
#### `normalAt()`
|
|
1993
|
-
|
|
1994
|
-
```ts
|
|
1995
|
-
normalAt(coordinate: ProductSkinSurfaceCoordinate): Vec3
|
|
1996
|
-
```
|
|
1997
|
-
|
|
1998
|
-
#### `tangentAt()`
|
|
1999
|
-
|
|
2000
|
-
```ts
|
|
2001
|
-
tangentAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): Vec3
|
|
2002
|
-
```
|
|
2003
|
-
|
|
2004
|
-
#### `frameAt()`
|
|
2005
|
-
|
|
2006
|
-
```ts
|
|
2007
|
-
frameAt(coordinate: ProductSkinSurfaceCoordinate, tangentHint?: Vec3): SurfaceFrame
|
|
2008
|
-
```
|
|
2009
|
-
|
|
2010
|
-
**`SurfaceFrame`**: `point: Vec3`, `normal: Vec3`, `tangentAlong: Vec3`, `tangentAcross: Vec3`, `matrix: Mat4`, `carrier: string`, `representation: SurfaceCarrierKind | string`, `coordinate: SurfaceCoordinate`
|
|
2011
|
-
|
|
2012
|
-
#### `bounds()`
|
|
2013
|
-
|
|
2014
|
-
```ts
|
|
2015
|
-
bounds(): SurfaceBounds
|
|
2016
|
-
```
|
|
2017
|
-
|
|
2018
|
-
**`SurfaceBounds`**: `u?: [ number, number ]`, `v?: [ number, number ]`, `angle?: [ number, number ]`, `z?: [ number, number ]`, `x?: [ number, number ]`, `y?: [ number, number ]`
|
|
2019
|
-
|
|
2020
|
-
#### `offset()`
|
|
2021
|
-
|
|
2022
|
-
```ts
|
|
2023
|
-
offset(distance: number): ProductSkinCarrier
|
|
2024
|
-
```
|
|
2025
|
-
|
|
2026
|
-
#### `mirrorCoordinate()`
|
|
2027
|
-
|
|
2028
|
-
```ts
|
|
2029
|
-
mirrorCoordinate(coordinate: ProductSkinSurfaceCoordinate): ProductSkinSurfaceCoordinate
|
|
2030
|
-
```
|
|
2031
|
-
|
|
2032
|
-
### `SurfacePath`
|
|
2033
|
-
|
|
2034
|
-
**Properties:**
|
|
2035
|
-
|
|
2036
|
-
| Property | Type | Description |
|
|
2037
|
-
|----------|------|-------------|
|
|
2038
|
-
| `carrier` | `CarrierSurface<C>` | — |
|
|
2039
|
-
| `points` | `C[]` | — |
|
|
2040
|
-
| `closedValue` | `boolean` | — |
|
|
2041
|
-
|
|
2042
|
-
**Methods:**
|
|
2043
|
-
|
|
2044
|
-
#### `closed()`
|
|
2045
|
-
|
|
2046
|
-
```ts
|
|
2047
|
-
closed(): SurfacePath<C>
|
|
2048
|
-
```
|
|
2049
|
-
|
|
2050
|
-
#### `mirror()`
|
|
2051
|
-
|
|
2052
|
-
```ts
|
|
2053
|
-
mirror(): SurfacePath<C>
|
|
2054
|
-
```
|
|
2055
|
-
|
|
2056
|
-
#### `coordinateAt()`
|
|
2057
|
-
|
|
2058
|
-
```ts
|
|
2059
|
-
coordinateAt(t: number): C
|
|
2060
|
-
```
|
|
2061
|
-
|
|
2062
|
-
#### `sample()`
|
|
2063
|
-
|
|
2064
|
-
```ts
|
|
2065
|
-
sample(count?: number): SurfacePathSample<C>[]
|
|
2066
|
-
```
|
|
2067
|
-
|
|
2068
|
-
#### `length()`
|
|
2069
|
-
|
|
2070
|
-
```ts
|
|
2071
|
-
length(samples?: number): number
|
|
2072
|
-
```
|
|
2073
|
-
|
|
2074
|
-
### `SurfacePathBuilder`
|
|
2075
|
-
|
|
2076
|
-
**Properties:**
|
|
2077
|
-
|
|
2078
|
-
| Property | Type | Description |
|
|
2079
|
-
|----------|------|-------------|
|
|
2080
|
-
| `carrier` | `CarrierSurface<C>` | — |
|
|
2081
|
-
|
|
2082
|
-
**Methods:**
|
|
2083
|
-
|
|
2084
|
-
#### `from()`
|
|
2085
|
-
|
|
2086
|
-
```ts
|
|
2087
|
-
from(coordinate: C): this
|
|
2088
|
-
```
|
|
2089
|
-
|
|
2090
|
-
#### `through()`
|
|
2091
|
-
|
|
2092
|
-
```ts
|
|
2093
|
-
through(coordinate: C): this
|
|
2094
|
-
```
|
|
2095
|
-
|
|
2096
|
-
#### `to()`
|
|
2097
|
-
|
|
2098
|
-
```ts
|
|
2099
|
-
to(coordinate: C): this
|
|
2100
|
-
```
|
|
2101
|
-
|
|
2102
|
-
#### `around()`
|
|
2103
|
-
|
|
2104
|
-
```ts
|
|
2105
|
-
around(input: { z: number; fromAngle: number; toAngle: number; offset?: number; }): this
|
|
2106
|
-
```
|
|
2107
|
-
|
|
2108
|
-
#### `closed()`
|
|
2109
|
-
|
|
2110
|
-
```ts
|
|
2111
|
-
closed(): this
|
|
2112
|
-
```
|
|
2113
|
-
|
|
2114
|
-
#### `mirror()`
|
|
2115
|
-
|
|
2116
|
-
```ts
|
|
2117
|
-
mirror(): SurfacePath<C>
|
|
2118
|
-
```
|
|
2119
|
-
|
|
2120
|
-
#### `build()`
|
|
2121
|
-
|
|
2122
|
-
```ts
|
|
2123
|
-
build(): SurfacePath<C>
|
|
2124
|
-
```
|
|
2125
|
-
|
|
2126
|
-
#### `sample()`
|
|
2127
|
-
|
|
2128
|
-
```ts
|
|
2129
|
-
sample(count?: number): SurfacePathSample<C>[]
|
|
2130
|
-
```
|
|
1015
|
+
- `from(coordinate: C): this`
|
|
1016
|
+
- `through(coordinate: C): this`
|
|
1017
|
+
- `to(coordinate: C): this`
|
|
1018
|
+
- `around(input: { z: number; fromAngle: number; toAngle: number; offset?: number; }): this`
|
|
1019
|
+
- `closed(): this`
|
|
1020
|
+
- `mirror(): SurfacePath<C>`
|
|
1021
|
+
- `build(): SurfacePath<C>`
|
|
1022
|
+
- `sample(count?: number): SurfacePathSample<C>[]`
|
|
2131
1023
|
|
|
2132
1024
|
### `SurfaceBand`
|
|
2133
1025
|
|
|
@@ -2141,34 +1033,19 @@ sample(count?: number): SurfacePathSample<C>[]
|
|
|
2141
1033
|
|
|
2142
1034
|
**Methods:**
|
|
2143
1035
|
|
|
2144
|
-
#### `
|
|
2145
|
-
|
|
2146
|
-
```ts
|
|
2147
|
-
widthAt(t: number): number
|
|
2148
|
-
```
|
|
2149
|
-
|
|
2150
|
-
#### `boundaries()`
|
|
2151
|
-
|
|
2152
|
-
```ts
|
|
2153
|
-
boundaries(samples?: number): SurfaceBandBoundarySample[]
|
|
2154
|
-
```
|
|
2155
|
-
|
|
2156
|
-
#### `withHole()` — Return a new band with a named member-local rounded-slot hole region recorded as inspectable intent.
|
|
2157
|
-
|
|
2158
|
-
```ts
|
|
2159
|
-
withHole(name: string, input: SurfaceBandHoleInput): SurfaceBand<C>
|
|
2160
|
-
```
|
|
1036
|
+
#### `withHole(name: string, input: SurfaceBandHoleInput): SurfaceBand<C>` — Return a new band with a named member-local rounded-slot hole region recorded as inspectable intent.
|
|
2161
1037
|
|
|
2162
1038
|
`SurfaceBandHoleInput`: `{ length: number, width: number, along?: number, across?: number }`
|
|
2163
1039
|
|
|
2164
|
-
#### `holes()` — Resolve recorded hole regions into member-local across/along loops.
|
|
1040
|
+
#### `holes(): SurfaceBandHoleRegion[]` — Resolve recorded hole regions into member-local across/along loops.
|
|
2165
1041
|
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
```
|
|
1042
|
+
- `widthAt(t: number): number`
|
|
1043
|
+
- `boundaries(samples?: number): SurfaceBandBoundarySample[]`
|
|
2169
1044
|
|
|
2170
1045
|
### `SurfaceBodyBuilder`
|
|
2171
1046
|
|
|
1047
|
+
Builder for a named surface-member body. Owns named members — `band()` or `plate()` — and the joins between them. Features (slots, cutouts, lips, cups, ribs) attach to a member's local coordinate system before lowering; this is not a global boolean recipe.
|
|
1048
|
+
|
|
2172
1049
|
**Properties:**
|
|
2173
1050
|
|
|
2174
1051
|
| Property | Type | Description |
|
|
@@ -2177,215 +1054,65 @@ holes(): SurfaceBandHoleRegion[]
|
|
|
2177
1054
|
|
|
2178
1055
|
**Methods:**
|
|
2179
1056
|
|
|
2180
|
-
#### `
|
|
2181
|
-
|
|
2182
|
-
```ts
|
|
2183
|
-
carrier(carrier: CarrierSurface): this
|
|
2184
|
-
```
|
|
2185
|
-
|
|
2186
|
-
`CarrierSurface`: `{ name: string, kind: SurfaceCarrierKind }`
|
|
2187
|
-
|
|
2188
|
-
#### `member()`
|
|
2189
|
-
|
|
2190
|
-
```ts
|
|
2191
|
-
member(name: string): SurfaceMemberBuilder
|
|
2192
|
-
```
|
|
2193
|
-
|
|
2194
|
-
#### `join()`
|
|
1057
|
+
#### `join(from: string, to: string | string[]): SurfaceJoinBuilder` — Declare a join between named members. Only a limited join set lowers to real geometry: close endpoint pairs, selected named-anchor pairs (`.betweenAnchors()`), and sampled band/plate landing pads. Farther, missing-anchor, or ambiguous joins remain diagnostic-only intent — decompose the design into supported joins instead of expecting a fallback.
|
|
2195
1058
|
|
|
2196
|
-
|
|
2197
|
-
join(from: string, to: string | string[]): SurfaceJoinBuilder
|
|
2198
|
-
```
|
|
1059
|
+
#### `autoJoinAtSharedAnchors(): this` — Lower only unambiguous shared-endpoint pairs (exactly two members sharing a point) into junction geometry. Shared points with more than two members produce a warning diagnostic — declare explicit `.join(...)` relationships instead.
|
|
2199
1060
|
|
|
2200
|
-
#### `
|
|
2201
|
-
|
|
2202
|
-
```ts
|
|
2203
|
-
autoJoinAtSharedAnchors(): this
|
|
2204
|
-
```
|
|
1061
|
+
#### `build(): Shape | ShapeGroup` — Build and return only the member + junction geometry. Use `buildWithDiagnostics()` for the member graph and diagnostic codes.
|
|
2205
1062
|
|
|
2206
|
-
|
|
1063
|
+
- `carrier(carrier: CarrierSurface): this`
|
|
1064
|
+
- `member(name: string): SurfaceMemberBuilder`
|
|
2207
1065
|
|
|
2208
|
-
|
|
2209
|
-
build(): Shape | ShapeGroup
|
|
2210
|
-
```
|
|
1066
|
+
`CarrierSurface`: `{ name: string, kind: SurfaceCarrierKind }`
|
|
2211
1067
|
|
|
2212
1068
|
### `SurfaceMemberBuilder`
|
|
2213
1069
|
|
|
2214
|
-
#### `
|
|
2215
|
-
|
|
2216
|
-
```ts
|
|
2217
|
-
plate(): this
|
|
2218
|
-
```
|
|
2219
|
-
|
|
2220
|
-
#### `band()`
|
|
2221
|
-
|
|
2222
|
-
```ts
|
|
2223
|
-
band(): this
|
|
2224
|
-
```
|
|
2225
|
-
|
|
2226
|
-
#### `at()`
|
|
2227
|
-
|
|
2228
|
-
```ts
|
|
2229
|
-
at(anchor: SurfaceAnchor<C>): this
|
|
2230
|
-
```
|
|
1070
|
+
#### `anchorAt(name: string, coordinate: C | SurfaceAnchor<C>): this` — Add a named anchor at a carrier surface coordinate for explicit member joins.
|
|
2231
1071
|
|
|
2232
1072
|
`SurfaceAnchor`: `{ carrier: CarrierSurface<C>, coordinate: C }`
|
|
2233
1073
|
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
size(width: number, height: number): this
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
1074
|
+
- `plate(): this`
|
|
1075
|
+
- `band(): this`
|
|
1076
|
+
- `at(anchor: SurfaceAnchor<C>): this`
|
|
1077
|
+
- `size(width: number, height: number): this`
|
|
1078
|
+
- `path(path: SurfacePath<C> | SurfacePathBuilder<C>): this`
|
|
1079
|
+
- `section(section: MemberSectionInput): this`
|
|
1080
|
+
- `cap(style: SurfaceBandCap): this`
|
|
1081
|
+
- `slot(name: string, feature: MemberFeature | RoundedSlotBuilder): this`
|
|
1082
|
+
- `cutout(name: string, feature: MemberFeature | RoundedSlotBuilder): this`
|
|
1083
|
+
- `counterbore(name: string, feature: MemberFeature | CounterboreBuilder): this`
|
|
1084
|
+
- `features(features: MemberFeature | MemberFeature[]): this`
|
|
1085
|
+
- `profile(name: string, options?: { depth?: number; height?: number; }): this`
|
|
1086
|
+
- `mirrorOf(memberName: string): SurfaceBodyBuilder`
|
|
1087
|
+
- `member(name: string): SurfaceMemberBuilder`
|
|
1088
|
+
- `join(from: string, to: string | string[]): SurfaceJoinBuilder`
|
|
1089
|
+
- `autoJoinAtSharedAnchors(): SurfaceBodyBuilder`
|
|
1090
|
+
- `build(): Shape | ShapeGroup`
|
|
2251
1091
|
|
|
2252
1092
|
**`MemberSectionInput`**: `width?: number`, `thickness: number`, `edgeRadius?: number`, `direction?: MemberOutwardDirection`, `material?: ProductMaterial`, `stations?: MemberSectionStation[]`
|
|
2253
1093
|
|
|
2254
1094
|
`MemberSectionStation`: `{ t: number, width?: number, thickness?: number }`
|
|
2255
1095
|
|
|
2256
|
-
#### `cap()`
|
|
2257
|
-
|
|
2258
|
-
```ts
|
|
2259
|
-
cap(style: SurfaceBandCap): this
|
|
2260
|
-
```
|
|
2261
|
-
|
|
2262
|
-
#### [`slot()`](/docs/sketch#slot)
|
|
2263
|
-
|
|
2264
|
-
```ts
|
|
2265
|
-
slot(name: string, feature: MemberFeature | RoundedSlotBuilder): this
|
|
2266
|
-
```
|
|
2267
|
-
|
|
2268
1096
|
**`MemberFeature`**: `type: MemberFeatureType`, `name?: string`, `length?: number`, `width?: number`, `diameter?: number`, `counterboreDiameter?: number`, `clearanceDiameter?: number`, `height?: number`, `depth?: number`, `count?: number`, `along?: number`, `across?: number`, `verticalTravel?: number`
|
|
2269
1097
|
|
|
2270
|
-
#### `cutout()`
|
|
2271
|
-
|
|
2272
|
-
```ts
|
|
2273
|
-
cutout(name: string, feature: MemberFeature | RoundedSlotBuilder): this
|
|
2274
|
-
```
|
|
2275
|
-
|
|
2276
|
-
#### `counterbore()`
|
|
2277
|
-
|
|
2278
|
-
```ts
|
|
2279
|
-
counterbore(name: string, feature: MemberFeature | CounterboreBuilder): this
|
|
2280
|
-
```
|
|
2281
|
-
|
|
2282
|
-
#### `anchorAt()` — Add a named anchor at a carrier surface coordinate for explicit member joins.
|
|
2283
|
-
|
|
2284
|
-
```ts
|
|
2285
|
-
anchorAt(name: string, coordinate: C | SurfaceAnchor<C>): this
|
|
2286
|
-
```
|
|
2287
|
-
|
|
2288
|
-
#### `features()`
|
|
2289
|
-
|
|
2290
|
-
```ts
|
|
2291
|
-
features(features: MemberFeature | MemberFeature[]): this
|
|
2292
|
-
```
|
|
2293
|
-
|
|
2294
|
-
#### `profile()`
|
|
2295
|
-
|
|
2296
|
-
```ts
|
|
2297
|
-
profile(name: string, options?: { depth?: number; height?: number; }): this
|
|
2298
|
-
```
|
|
2299
|
-
|
|
2300
|
-
#### `mirrorOf()`
|
|
2301
|
-
|
|
2302
|
-
```ts
|
|
2303
|
-
mirrorOf(memberName: string): SurfaceBodyBuilder
|
|
2304
|
-
```
|
|
2305
|
-
|
|
2306
|
-
#### `member()`
|
|
2307
|
-
|
|
2308
|
-
```ts
|
|
2309
|
-
member(name: string): SurfaceMemberBuilder
|
|
2310
|
-
```
|
|
2311
|
-
|
|
2312
|
-
#### `join()`
|
|
2313
|
-
|
|
2314
|
-
```ts
|
|
2315
|
-
join(from: string, to: string | string[]): SurfaceJoinBuilder
|
|
2316
|
-
```
|
|
2317
|
-
|
|
2318
|
-
#### `autoJoinAtSharedAnchors()`
|
|
2319
|
-
|
|
2320
|
-
```ts
|
|
2321
|
-
autoJoinAtSharedAnchors(): SurfaceBodyBuilder
|
|
2322
|
-
```
|
|
2323
|
-
|
|
2324
|
-
#### `build()`
|
|
2325
|
-
|
|
2326
|
-
```ts
|
|
2327
|
-
build(): Shape | ShapeGroup
|
|
2328
|
-
```
|
|
2329
|
-
|
|
2330
1098
|
### `SurfaceJoinBuilder`
|
|
2331
1099
|
|
|
2332
|
-
#### `betweenAnchors()` — Select named anchors on the source and target members before lowering this join.
|
|
2333
|
-
|
|
2334
|
-
```ts
|
|
2335
|
-
betweenAnchors(fromAnchor: string, toAnchor: string): this
|
|
2336
|
-
```
|
|
2337
|
-
|
|
2338
|
-
#### `blend()`
|
|
1100
|
+
#### `betweenAnchors(fromAnchor: string, toAnchor: string): this` — Select named anchors on the source and target members before lowering this join.
|
|
2339
1101
|
|
|
2340
|
-
|
|
2341
|
-
blend(input?: { radius?: number; style?: string; priority?: number; continuity?: string; }): SurfaceBodyBuilder
|
|
2342
|
-
```
|
|
1102
|
+
- `blend(input?: { radius?: number; style?: string; priority?: number; continuity?: string; }): SurfaceBodyBuilder`
|
|
2343
1103
|
|
|
2344
1104
|
### `CounterboreBuilder`
|
|
2345
1105
|
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
at(input: { along?: number; across?: number; z?: number; }): this
|
|
2350
|
-
```
|
|
2351
|
-
|
|
2352
|
-
#### `named()`
|
|
2353
|
-
|
|
2354
|
-
```ts
|
|
2355
|
-
named(name: string): MemberFeature
|
|
2356
|
-
```
|
|
2357
|
-
|
|
2358
|
-
#### `toFeature()`
|
|
2359
|
-
|
|
2360
|
-
```ts
|
|
2361
|
-
toFeature(name?: string): MemberFeature
|
|
2362
|
-
```
|
|
1106
|
+
- `at(input: { along?: number; across?: number; z?: number; }): this`
|
|
1107
|
+
- `named(name: string): MemberFeature`
|
|
1108
|
+
- `toFeature(name?: string): MemberFeature`
|
|
2363
1109
|
|
|
2364
1110
|
### `RoundedSlotBuilder`
|
|
2365
1111
|
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
```
|
|
2371
|
-
|
|
2372
|
-
#### `at()`
|
|
2373
|
-
|
|
2374
|
-
```ts
|
|
2375
|
-
at(input: { along?: number; across?: number; z?: number; }): this
|
|
2376
|
-
```
|
|
2377
|
-
|
|
2378
|
-
#### `named()`
|
|
2379
|
-
|
|
2380
|
-
```ts
|
|
2381
|
-
named(name: string): MemberFeature
|
|
2382
|
-
```
|
|
2383
|
-
|
|
2384
|
-
#### `toFeature()`
|
|
2385
|
-
|
|
2386
|
-
```ts
|
|
2387
|
-
toFeature(name?: string): MemberFeature
|
|
2388
|
-
```
|
|
1112
|
+
- `verticalTravel(value: number): this`
|
|
1113
|
+
- `at(input: { along?: number; across?: number; z?: number; }): this`
|
|
1114
|
+
- `named(name: string): MemberFeature`
|
|
1115
|
+
- `toFeature(name?: string): MemberFeature`
|
|
2389
1116
|
|
|
2390
1117
|
---
|
|
2391
1118
|
|
|
@@ -2397,18 +1124,7 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
2397
1124
|
|
|
2398
1125
|
`Curve.*` is the public home for reference curves and route centerlines that feed `sweep`, `variableSweep`, route visualization, and future path consumers. Standalone 3D curve constructors have been collapsed into this namespace.
|
|
2399
1126
|
|
|
2400
|
-
|
|
2401
|
-
- `BlendG2(start: CurveBlendG2Endpoint, end: CurveBlendG2Endpoint): NurbsCurve3D` — Create an exact G2 blend curve between two directed endpoints. This is the curvature-aware companion to `Curve.Blend()`. It returns a degree-5 non-rational `NurbsCurve3D` that matches endpoint position, tangent direction, and optional curvature/second-derivative vectors.
|
|
2402
|
-
- `Arc(options: CurveArcOptions): NurbsCurve3D` — Create an exact circular 3D arc from start, end, and start tangent. The returned curve is a rational quadratic `NurbsCurve3D`, split into stable spans when needed, so it can feed `sweep` without sampling the authoring intent away.
|
|
2403
|
-
- `Line(start: Vec3, end: Vec3): NurbsCurve3D` — Create an exact straight 3D NURBS line segment.
|
|
2404
|
-
- `Polyline(points: Vec3[]): Vec3[]` — Create a polyline path as cloned 3D points. Polylines are exact as route/path input to `sweep`. Use `Curve.Route` when the centerline needs bend and endpoint-frame metadata.
|
|
2405
|
-
- `Spline(points: Vec3[], options?: Spline3DOptions): Curve3D` — Create a smooth Catmull-Rom spline path. This is a smooth sampled curve object. Use `Curve.Nurbs` when the path must preserve exact control-point and knot data.
|
|
2406
|
-
- `Nurbs(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D` — Create an exact NURBS 3D curve from control points, weights, knots, and degree.
|
|
2407
|
-
- `Fit(points: Vec3[], options?: CurveFitOptions): NurbsCurve3D` — Fit a non-rational NURBS curve that interpolates every input point. This is global B-spline interpolation, not approximate curve reduction: ForgeCAD computes chord-length parameters, averaged clamped knots, solves the control points, then verifies the interpolation residual against `tolerance`.
|
|
2408
|
-
- `Trim<T extends CurveTrimInput>(curve: T, start: number, end: number): CurveTrimOutput<T>` — Extract an exact curve segment from normalized parameter `start` to `end`. `NurbsCurve3D` inputs are trimmed with exact knot insertion/subdomain extraction. Polyline point arrays are trimmed by arclength over their exact line segments. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
2409
|
-
- `Reverse<T extends CurveTrimInput>(curve: T): CurveTrimOutput<T>` — Reverse an exact curve without changing its geometry. `NurbsCurve3D` inputs reverse control points, weights, and knots. Polyline point arrays are cloned and reversed. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
2410
|
-
- `Route: typeof Route3D` — Build analytic 3D line/arc routes for sweeps. `Curve.Route.fromPolyline()` is the canonical route API. It returns a `Route3D` value object, preserving exact route segments, named port frames, and the lowerable `route3d` sweep compile plan.
|
|
2411
|
-
- `Helix: { path(options: HelixOptions): CurveHelixPath; coil: CurveHelixCoil; }` — Build helical paths and swept coils. `Curve.Helix` is the canonical namespace for helical paths and coils. It uses the same sweep-based lowering as other curve paths.
|
|
1127
|
+
Members (full entries under [Curves & Surfacing](#curves-surfacing)): `Curve.Blend`, `Curve.BlendG2`, `Curve.Arc`, `Curve.Line`, `Curve.Nurbs`, `Curve.Fit`, `Curve.Trim`, `Curve.Reverse`, `Curve.Route`, `Curve.Helix`.
|
|
2412
1128
|
|
|
2413
1129
|
### `Surface`
|
|
2414
1130
|
|
|
@@ -2417,9 +1133,30 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
2417
1133
|
- `Cone(options: SurfaceConeOptions): Shape` — Create a finite analytic conical or frustum sheet, optionally bounded by start/end angles.
|
|
2418
1134
|
- `Sphere(options: SurfaceSphereOptions): Shape` — Create a finite analytic spherical sheet bounded by longitude and latitude ranges.
|
|
2419
1135
|
- `Torus(options: SurfaceTorusOptions): Shape` — Create a finite analytic torus sheet bounded by major and tube angle ranges.
|
|
2420
|
-
- `Nurbs(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape`
|
|
1136
|
+
- `Nurbs(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape` — Create an exact NURBS surface from a grid of control points.
|
|
1137
|
+
|
|
1138
|
+
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. With default options this builds a bicubic non-rational B-spline sheet with uniform clamped knots; `NurbsSurfaceOptions` controls degrees, weights, knots, trim loops, tessellation, domain, and an optional `thickness` to return a thin solid instead of an open sheet.
|
|
1139
|
+
|
|
1140
|
+
```js
|
|
1141
|
+
// Simple 4×4 control grid — a gently curved surface
|
|
1142
|
+
const grid = [
|
|
1143
|
+
[[0,0,0], [10,0,2], [20,0,2], [30,0,0]],
|
|
1144
|
+
[[0,10,1], [10,10,5], [20,10,5], [30,10,1]],
|
|
1145
|
+
[[0,20,1], [10,20,5], [20,20,5], [30,20,1]],
|
|
1146
|
+
[[0,30,0], [10,30,2], [20,30,2], [30,30,0]],
|
|
1147
|
+
];
|
|
1148
|
+
const sheet = Surface.Nurbs(grid);
|
|
1149
|
+
const panel = Surface.Nurbs(grid, { thickness: 2 });
|
|
1150
|
+
```
|
|
2421
1151
|
- `Ruled(curveA: ExactCurveInput, curveB: ExactCurveInput, options?: SurfaceCommonOptions): Shape`
|
|
2422
|
-
- `Patch(curves: { bottom: ExactCurveInput; top: ExactCurveInput; left: ExactCurveInput; right: ExactCurveInput; }, options?: SurfacePatchOptions): Shape`
|
|
1152
|
+
- `Patch(curves: { bottom: ExactCurveInput; top: ExactCurveInput; left: ExactCurveInput; right: ExactCurveInput; }, options?: SurfacePatchOptions): Shape` — Create a smooth open surface sheet from 4 boundary curves (Coons patch).
|
|
1153
|
+
|
|
1154
|
+
The four curves form the boundary of a quadrilateral patch and should meet at corners (small gaps are tolerated). Boundaries are exact by default: pass `NurbsCurve3D` values or `Shape.edge()` refs, or set `{ approximate: true }` to accept sampled `Curve3D`/`Vec3[]` boundaries. The result is an open sheet — call `.thicken(t)` for a thin solid.
|
|
1155
|
+
|
|
1156
|
+
```js
|
|
1157
|
+
const sheet = Surface.Patch({ bottom, top, left, right });
|
|
1158
|
+
const panel = Surface.Patch({ bottom, top, left, right }).thicken(1.5);
|
|
1159
|
+
```
|
|
2423
1160
|
- `Boundary(input: SurfaceBoundaryInput): Shape`
|
|
2424
1161
|
- `Fill(input: SurfaceFillInput): Shape`
|
|
2425
1162
|
- `Sew(shapes: Shape[], options?: { tolerance?: number; }): Shape`
|
|
@@ -2428,7 +1165,6 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
2428
1165
|
- `Trim(shape: Shape, tool: Shape | SurfacePlaneOp): Shape`
|
|
2429
1166
|
- `Split(shape: Shape, tool: Shape | SurfacePlaneOp): [ Shape, Shape ]`
|
|
2430
1167
|
- `Match(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape`
|
|
2431
|
-
- `MatchEdge(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape`
|
|
2432
1168
|
|
|
2433
1169
|
### `Blend`
|
|
2434
1170
|
|
|
@@ -2447,29 +1183,40 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
2447
1183
|
|
|
2448
1184
|
- `skin(name: string): ProductSkinBuilder` — Start a named product skin builder.
|
|
2449
1185
|
- `station(name: string): ProductStationBuilder` — Start a named cross-section station for Product.skin(...).stations(...).
|
|
2450
|
-
- `rail: {
|
|
2451
|
-
- `profiles: { ... }` —
|
|
1186
|
+
- `rail: { ... }` — Namespaced rail builders for product skin guide rails and handle spines.
|
|
1187
|
+
- `profiles: { ... }` — Product profile helper namespace: oval, superEllipse, roundedRect, and circle — for stations, panels, trims, and openings.
|
|
2452
1188
|
- `materials: { ... }` — Namespaced product material presets for molded plastic, rubber, metal, and transparent parts.
|
|
2453
1189
|
- `applyMaterial(shape: Shape, preset: ProductMaterial | undefined): Shape` — Apply a product material preset to a Shape.
|
|
2454
1190
|
- `scenePreset(name: ProductScenePreset): void` — Apply an opinionated scene preset for product review renders.
|
|
2455
|
-
- `ovalProfile(width: number, depth: number, options?: ProductProfileOptions): Sketch` — Create a centered oval profile from full width/depth dimensions.
|
|
2456
|
-
- `roundedRectProfile(width: number, depth: number, radius: number): Sketch` — Create a centered rounded-rectangle profile.
|
|
2457
|
-
- `circleProfile(diameter: number, options?: ProductProfileOptions): Sketch` — Create a centered circular profile from full diameter.
|
|
2458
|
-
- `superEllipseProfile(width: number, depth: number, options?: ProductSuperEllipseOptions): Sketch` — Create a centered superellipse profile for soft-square product sections.
|
|
2459
1191
|
- `profileSize(sketch: Sketch): { width: number; depth: number; }` — Measure the width and depth of a 2D profile sketch.
|
|
2460
1192
|
- `describeProfile(sketch: Sketch, kind?: ProductProfileKind, radius?: number): ProductProfileDescriptor` — Describe a custom sketch as a product profile.
|
|
2461
1193
|
- `scaleProfileTo(sketch: Sketch, width: number, depth: number): Sketch` — Scale an existing profile sketch to a target width/depth.
|
|
2462
1194
|
- `ref(skin: ProductSkin, query: ProductSkinRefQuery): ProductSurfaceRef` — Create an ad-hoc ProductSurfaceRef from a skin and side/u/v query.
|
|
2463
|
-
- `surface(skin: ProductSkin, side: ProductSkinSide): ProductSurfaceBuilder` — Create a fluent surface helper for refs and conformal features on one side of a skin.
|
|
1195
|
+
- `surface(skin: ProductSkin, side: ProductSkinSide): ProductSurfaceBuilder` — Create a fluent surface helper for refs and conformal features on one side of a skin.
|
|
1196
|
+
|
|
1197
|
+
Equivalent to skin.surface(side), useful when writing in Product.* namespace style.
|
|
2464
1198
|
- `panel(name: string): ProductPanelBuilder` — Start a panel feature builder.
|
|
2465
|
-
- `ribbon(name: string): ProductRibbonBuilder` — Start a conformal ribbon/trim builder for details that should bend with a ProductSkin.
|
|
2466
|
-
|
|
2467
|
-
|
|
1199
|
+
- `ribbon(name: string): ProductRibbonBuilder` — Start a conformal ribbon/trim builder for details that should bend with a ProductSkin.
|
|
1200
|
+
|
|
1201
|
+
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().
|
|
2468
1202
|
- `place(detail: Shape | ShapeGroup, ref: ProductRefInput, options?: ProductAttachOptions): Shape | ShapeGroup` — Place a shape or group on a ProductSurfaceRef.
|
|
2469
1203
|
- `landing(name: string, radius?: number, material?: ProductMaterial): Shape` — Small blended landing volume for manual structural bridges and connection proofs.
|
|
2470
1204
|
|
|
2471
1205
|
### `Carrier`
|
|
2472
1206
|
|
|
1207
|
+
Factory for carrier surfaces — the coordinate-and-frame owners that surface members (`SurfaceBody`) live on.
|
|
1208
|
+
|
|
1209
|
+
A carrier owns surface-local coordinates and 3D frames; members and paths are authored in carrier coordinates, never in raw Cartesian math. Cylinder coordinates are `{ angle, z }` with `angle` in degrees — paths handle seam wrapping, so never compute positions with trig. `clearance()`/`offset()` lift geometry off the nominal surface. A ProductSkin carrier path stays on one side (`left`/`right`/`top`/`bottom`); for multi-side detail, split into one member per side and join them at the matching side-local coordinates from `sideTransition()` / `sideTransitionChain()` / `sideRoute()`.
|
|
1210
|
+
|
|
1211
|
+
```ts
|
|
1212
|
+
// Bottle-cage arm: a curved band on a cylinder, authored in degrees + mm
|
|
1213
|
+
const bottle = Carrier.cylinder('bottle').diameter(74).height(170).clearance(1.5);
|
|
1214
|
+
const arm = bottle.path()
|
|
1215
|
+
.from({ angle: -145, z: 18 })
|
|
1216
|
+
.through({ angle: -80, z: 72 })
|
|
1217
|
+
.to({ angle: -34, z: 112 });
|
|
1218
|
+
```
|
|
1219
|
+
|
|
2473
1220
|
- `cylinder(name: string): CylinderCarrier` — Create an analytic cylinder carrier for bottles, limbs, tubes, guards, and cuffs.
|
|
2474
1221
|
- `plane(name: string): PlaneCarrier` — Create an analytic plane carrier for plates and local flat construction surfaces.
|
|
2475
1222
|
- `productSkin(skin: ProductSkin): ProductSkinCarrier` — Adapt an existing ProductSkin into the general surface-member carrier protocol.
|
|
@@ -2477,17 +1224,48 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
2477
1224
|
### `SurfaceMembers`
|
|
2478
1225
|
|
|
2479
1226
|
- `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.
|
|
1227
|
+
|
|
1228
|
+
```js
|
|
1229
|
+
const carrier = Carrier.cylinder('guard-envelope').diameter(84).height(36).clearance(2);
|
|
1230
|
+
const guard = SurfaceBody('simple-guard')
|
|
1231
|
+
.carrier(carrier)
|
|
1232
|
+
.member('left-strut')
|
|
1233
|
+
.band()
|
|
1234
|
+
.path(carrier.path().from({ angle: -132, z: 6 }).to({ angle: -58, z: 18 }))
|
|
1235
|
+
.section({ width: 5.5, thickness: 2.8, edgeRadius: 0.6 })
|
|
1236
|
+
.member('right-strut')
|
|
1237
|
+
.mirrorOf('left-strut')
|
|
1238
|
+
.member('front-hoop')
|
|
1239
|
+
.band()
|
|
1240
|
+
.path(carrier.path().around({ z: 18, fromAngle: -58, toAngle: 58 }))
|
|
1241
|
+
.section({ width: 6.2, thickness: 3, edgeRadius: 0.7 })
|
|
1242
|
+
.join('left-strut', 'front-hoop').blend({ radius: 3.2 })
|
|
1243
|
+
.join('right-strut', 'front-hoop').blend({ radius: 3.2 })
|
|
1244
|
+
.build();
|
|
1245
|
+
```
|
|
2480
1246
|
- `Band: typeof SurfaceBand`
|
|
2481
1247
|
- `band<C extends SurfaceCoordinate>(path: SurfacePath<C> | SurfacePathBuilder<C>, width: WidthProfile, cap?: SurfaceBandCap): SurfaceBand<C>`
|
|
1248
|
+
- `roundedSlot(input: { length: number; width: number; }): RoundedSlotBuilder` — Create a rounded member-local slot feature for `SurfaceMemberBuilder.slot()`/`.cutout()`.
|
|
2482
1249
|
|
|
2483
|
-
|
|
1250
|
+
Returns a fluent `RoundedSlotBuilder`: chain `.verticalTravel(mm)` to extend the slot for vertical bottle-drop style insertion (travel is summed into the slot length) and `.at({ along, across })` (or `{ z }`) to position it in member-local coordinates.
|
|
2484
1251
|
|
|
2485
|
-
|
|
1252
|
+
```js
|
|
1253
|
+
const arm = body.member('arm', armPath)
|
|
1254
|
+
.slot('upper-mount-slot', SurfaceMembers.roundedSlot({ length: 12, width: 5.7 }).verticalTravel(6).at({ z: 82 }));
|
|
1255
|
+
```
|
|
1256
|
+
- `counterbore(input: { diameter: number; clearanceDiameter: number; depth: number; }): CounterboreBuilder` — Create a cylindrical member-local counterbore feature for `SurfaceMemberBuilder.counterbore()`.
|
|
2486
1257
|
|
|
2487
|
-
|
|
1258
|
+
`diameter` is the counterbore pocket diameter and must be larger than `clearanceDiameter`, the through-hole for the fastener shank. Chain `.at({ along, across })` (or `{ z }`) to position it in member-local coordinates.
|
|
2488
1259
|
|
|
2489
|
-
|
|
1260
|
+
```js
|
|
1261
|
+
const strap = body.member('strap', strapPath)
|
|
1262
|
+
.counterbore('head-pocket', SurfaceMembers.counterbore({ diameter: 9.8, clearanceDiameter: 5.7, depth: 3 }).at({ z: 58 }));
|
|
1263
|
+
```
|
|
1264
|
+
- `ribs(input: { count: number; height: number; }): MemberFeature` — Create a repeated-rib stiffening feature for `SurfaceMemberBuilder.features()`.
|
|
2490
1265
|
|
|
2491
|
-
|
|
1266
|
+
Ribs belong to the surface member and follow its carrier-surface lowering; `count` ribs of the given `height` are distributed along the member.
|
|
2492
1267
|
|
|
2493
|
-
|
|
1268
|
+
```js
|
|
1269
|
+
const grip = body.member('grip', gripPath)
|
|
1270
|
+
.features(SurfaceMembers.ribs({ count: 18, height: 0.35 }));
|
|
1271
|
+
```
|