forgecad 0.10.4 → 0.11.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-B3L3W1Uo.js → AdminPage-B1nIvqLS.js} +1 -1
- package/dist/assets/{BenchmarkPage-DXKVXMrJ.js → BenchmarkPage-YZJbw5nd.js} +2 -2
- package/dist/assets/{BlogPage-B7BWxOCg.js → BlogPage-DIWRApKS.js} +1 -1
- package/dist/assets/{DocsPage-BPGGwht1.js → DocsPage-ClL6X1hR.js} +8 -22
- package/dist/assets/EditorApp-CYBDvSyT.js +17067 -0
- package/dist/assets/{EmbedViewer-DygByZS2.js → EmbedViewer-Dmfu_LIw.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-BoVE7JGY.js → LandingPageProofDriven-XYTiYxfM.js} +2 -2
- package/dist/assets/{LegalPage-Din8wv8d.js → LegalPage-D5Z3CscF.js} +2 -2
- package/dist/assets/{PricingPage-C2PMzmDc.js → PricingPage-BP4lIGio.js} +2 -2
- package/dist/assets/{SettingsPage-BlJDCRe8.js → SettingsPage-D3bcPBsC.js} +1 -1
- package/dist/assets/{app-BsRYSfxY.js → app-BKjogwIZ.js} +3288 -512
- package/dist/assets/{backendInit-6C0DLgH0.js → backendInit-6a9-ilom.js} +80498 -74979
- package/dist/assets/cli/{render-XXol_ET7.js → render-CMNudGb0.js} +1264 -113
- package/dist/assets/{constructionHistoryWorker-cTHWRJEi.js → constructionHistoryWorker-BuZgc606.js} +8369 -6839
- package/dist/assets/{evalWorker-BssDYW9u.js → evalWorker-DQ82ueGu.js} +45438 -39996
- package/dist/assets/{forgecad_geometry-CZ_IfuvA.js → forgecad_geometry-D8rWX7nQ.js} +1 -1
- package/dist/assets/{forgecad_geometry_bg-C3rQHfwg.wasm → forgecad_geometry_bg-ObqfqjJT.wasm} +0 -0
- package/dist/assets/{inspectWorker-ymhBV4Ll.js → inspectWorker-Cuby2qfT.js} +4899 -1303
- package/dist/assets/{jointPose-B0blBj9A.js → jointPose-CFql5I-u.js} +1 -1
- package/dist/assets/{landing-proof-driven-Cpf-MIbI.css → landing-proof-driven-_u4v_xQb.css} +2 -2
- package/dist/assets/{manifold-CYlIm-M6.js → manifold-02pmr7O7.js} +2 -2
- package/dist/assets/{manifold-B_7QXpGB.js → manifold-C6KU0oII.js} +1 -1
- package/dist/assets/{manifold-CNShmpEJ.js → manifold-P1yF3GKn.js} +1 -1
- package/dist/assets/{reportWorker-Cb5eyM7D.js → reportWorker-kg065BVL.js} +76583 -65731
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/usage.md +6 -8
- package/dist/docs-raw/CLI.md +14 -12
- package/dist/docs-raw/component-model.md +28 -9
- package/dist/docs-raw/generated/assembly.md +76 -3
- package/dist/docs-raw/generated/concepts.md +43 -7
- package/dist/docs-raw/generated/core.md +399 -73
- package/dist/docs-raw/generated/curves.md +357 -6
- package/dist/docs-raw/generated/runtime-names.md +12 -12
- package/dist/docs-raw/generated/sketch.md +16 -3
- package/dist/docs-raw/guides/inspection-bundles.md +5 -3
- package/dist/docs-raw/guides/structural-fea.md +235 -0
- package/dist/docs-raw/skills/forgecad-build-model.md +70 -147
- package/dist/docs-raw/skills/forgecad-image-prompt.md +1 -1
- package/dist/docs-raw/skills/forgecad-project-sync.md +3 -3
- package/dist/docs-raw/skills/forgecad-reconstruct-cad-file.md +2 -2
- package/dist/docs-raw/skills/forgecad-reconstruct-from-images.md +4 -5
- package/dist/docs-raw/skills/forgecad.md +4 -1
- package/dist/docs-raw/skills/index.md +1 -5
- package/dist/docs-raw/welcome.md +3 -4
- package/dist/index.html +1 -1
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +15 -15
- package/dist-cli/{check-compiler-4RPB6SB5.js → check-compiler-UJWUEIDC.js} +1 -1
- package/dist-cli/{check-query-propagation-KN3DFQTX.js → check-query-propagation-O2EPDJSY.js} +1 -1
- package/dist-cli/{chunk-UHBRMYA6.js → chunk-MNDROM7T.js} +78926 -73392
- package/dist-cli/forgecad.js +6306 -1061
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +1257 -110
- package/dist-skill/SKILL.md +4 -1
- package/dist-skill/docs/API/core/concepts.md +31 -4
- package/dist-skill/docs/CLI.md +14 -12
- package/dist-skill/docs/generated/assembly.md +73 -3
- package/dist-skill/docs/generated/core.md +395 -74
- package/dist-skill/docs/generated/curves.md +356 -6
- package/dist-skill/docs/generated/runtime-names.md +12 -12
- package/dist-skill/docs/generated/sketch.md +16 -3
- package/dist-skill/docs/guides/inspection-bundles.md +5 -3
- package/dist-skill/docs/guides/manual-parameters.md +130 -0
- package/dist-skill/docs/guides/structural-fea.md +235 -0
- package/dist-skill/library/README.md +0 -4
- package/dist-skill/library/forgecad-build-model/SKILL.md +57 -150
- package/dist-skill/library/forgecad-build-model/references/inspection-feedback.md +58 -0
- package/dist-skill/library/forgecad-build-model/references/module-contracts.md +53 -0
- package/dist-skill/library/forgecad-build-model/references/parameter-controls.md +22 -0
- package/dist-skill/library/forgecad-build-model/references/readiness-review.md +43 -0
- package/dist-skill/library/forgecad-build-model/references/simulation-feedback.md +49 -0
- package/dist-skill/library/forgecad-build-model/references/stage-1-design-intent.md +21 -0
- package/dist-skill/library/forgecad-build-model/references/stage-2-architecture-plan.md +23 -0
- package/dist-skill/library/forgecad-build-model/references/stage-3-build-slices.md +39 -0
- package/dist-skill/library/forgecad-build-model/references/stage-4-feedback-iteration.md +24 -0
- package/dist-skill/library/forgecad-build-model/references/stage-5-readiness-package.md +34 -0
- package/dist-skill/library/forgecad-image-prompt/SKILL.md +1 -1
- package/dist-skill/library/forgecad-project-sync/SKILL.md +3 -3
- package/dist-skill/library/forgecad-reconstruct-cad-file/SKILL.md +2 -2
- package/dist-skill/library/forgecad-reconstruct-from-images/SKILL.md +4 -5
- package/dist-skill/website/skills/forgecad-build-model.md +70 -147
- package/dist-skill/website/skills/forgecad-image-prompt.md +1 -1
- package/dist-skill/website/skills/forgecad-project-sync.md +3 -3
- package/dist-skill/website/skills/forgecad-reconstruct-cad-file.md +2 -2
- package/dist-skill/website/skills/forgecad-reconstruct-from-images.md +4 -5
- package/dist-skill/website/skills/forgecad.md +4 -1
- package/dist-skill/website/skills/index.md +1 -5
- package/examples/analysis/structural-stress-fea.forge.js +19 -0
- package/examples/api/blend-full-round.forge.js +37 -0
- package/examples/api/blend-variable-radius.forge.js +51 -0
- package/examples/api/curve-project-and-intersect.forge.js +59 -0
- package/examples/api/extrude-up-to-face.forge.js +47 -0
- package/examples/api/param-path2d.forge.js +65 -0
- package/examples/api/param-placement2d.forge.js +80 -0
- package/examples/api/param-spline2d-g-continuity.forge.js +57 -0
- package/examples/api/spoon-full-tang-handle.forge.js +188 -0
- package/examples/api/surface-boundarynet-dished-bowl.forge.js +63 -0
- package/examples/api/surface-fill-interior-constraints.forge.js +59 -0
- package/examples/api/surface-variable-thickness-panel.forge.js +62 -0
- package/examples/mechanical/airplane-propeller.forge.js +81 -28
- package/package.json +5 -2
- package/dist/assets/EditorApp-BWUGCdD5.js +0 -16610
- package/dist/docs-raw/skills/forgecad-design-spec.md +0 -145
- package/dist/docs-raw/skills/forgecad-grade-model.md +0 -84
- package/dist/docs-raw/skills/forgecad-inspect-model.md +0 -80
- package/dist/docs-raw/skills/forgecad-verify-mujoco.md +0 -78
- package/dist-skill/library/forgecad-design-spec/SKILL.md +0 -132
- package/dist-skill/library/forgecad-design-spec/references/default-profiles.md +0 -99
- package/dist-skill/library/forgecad-design-spec/references/master-prompt.md +0 -73
- package/dist-skill/library/forgecad-grade-model/SKILL.md +0 -72
- package/dist-skill/library/forgecad-grade-model/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-inspect-model/SKILL.md +0 -68
- package/dist-skill/library/forgecad-verify-mujoco/SKILL.md +0 -66
- package/dist-skill/website/skills/forgecad-design-spec.md +0 -145
- package/dist-skill/website/skills/forgecad-grade-model.md +0 -84
- package/dist-skill/website/skills/forgecad-inspect-model.md +0 -80
- package/dist-skill/website/skills/forgecad-verify-mujoco.md +0 -78
- /package/dist/assets/{landing-proof-driven-BxZZh5r5.js → landing-proof-driven-DNPRKL_p.js} +0 -0
- /package/dist-skill/library/{forgecad-verify-mujoco → forgecad-build-model}/scripts/mujoco_verify.py +0 -0
- /package/dist-skill/library/{forgecad-inspect-model → forgecad-build-model/scripts}/summarize_manifest.py +0 -0
|
@@ -15,6 +15,7 @@ Smooth curves, lofted surfaces, swept solids, splines, and high-level product sk
|
|
|
15
15
|
- [Route3D](#route3d)
|
|
16
16
|
- [NurbsCurve3D](#nurbscurve3d)
|
|
17
17
|
- [NurbsSurface](#nurbssurface)
|
|
18
|
+
- [Sheet](#sheet)
|
|
18
19
|
- [PathBuilder](#pathbuilder) — Line Segments, Arcs, Curves, Closing & Output
|
|
19
20
|
- [ProductSkin](#productskin)
|
|
20
21
|
- [ProductSurfaceRef](#productsurfaceref)
|
|
@@ -38,6 +39,7 @@ Smooth curves, lofted surfaces, swept solids, splines, and high-level product sk
|
|
|
38
39
|
- [Surface](#surface)
|
|
39
40
|
- [Blend](#blend)
|
|
40
41
|
- [Analysis](#analysis)
|
|
42
|
+
- [Thickness](#thickness)
|
|
41
43
|
- [Product](#product)
|
|
42
44
|
- [Carrier](#carrier)
|
|
43
45
|
- [SurfaceMembers](#surfacemembers)
|
|
@@ -78,6 +80,34 @@ const rail = Curve.BlendG2(
|
|
|
78
80
|
**`CurveBlendG2Endpoint`** extends CurveBlendEndpoint
|
|
79
81
|
- `curvature?: Vec3` — Optional endpoint curvature/second-derivative vector. Default is zero.
|
|
80
82
|
|
|
83
|
+
#### `Curve.Bridge(options: CurveBridgeOptions): NurbsCurve3D` — Bridge two existing curve endpoints with inferred tangent or curvature continuity.
|
|
84
|
+
|
|
85
|
+
This is the Onshape-style "select two curves and bridge them" primitive: ForgeCAD reads the endpoint positions, tangent directions, and NURBS curvature from the selected curves so callers do not hand-author tangent vectors. Use `continuity: 'G1'` for a cubic tangent bridge or the default `G2` for a quintic curvature bridge.
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const leftRim = Curve.Fit([[20, -12, 0], [0, -18, 2], [-30, -14, 1]]);
|
|
89
|
+
const rightRim = Curve.Fit([[20, 12, 0], [0, 18, 2], [-30, 14, 1]]);
|
|
90
|
+
const roundedNose = Curve.Bridge({
|
|
91
|
+
from: { curve: leftRim, at: 'end' },
|
|
92
|
+
to: { curve: rightRim, at: 'end' },
|
|
93
|
+
continuity: 'G2',
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**`CurveBridgeOptions`**
|
|
98
|
+
|
|
99
|
+
| Option | Type | Description |
|
|
100
|
+
|--------|------|-------------|
|
|
101
|
+
| `from` | `CurveBridgeEndpoint` | Endpoint where the bridge starts. |
|
|
102
|
+
| `to` | `CurveBridgeEndpoint` | Endpoint where the bridge ends. |
|
|
103
|
+
| `continuity?` | `CurveBridgeContinuity` | Continuity target. Default `G2`. |
|
|
104
|
+
| `weight?` | `number` | Tangent reach relative to bridge chord. Default 0.6. |
|
|
105
|
+
|
|
106
|
+
**`CurveBridgeEndpoint`**
|
|
107
|
+
- `curve: CurveTrimInput` — Existing curve endpoint to bridge from or to.
|
|
108
|
+
- `at?: CurveBridgeEndpointAt` — Which endpoint of the curve to use. Default is `end`.
|
|
109
|
+
- `weight?: number` — Tangent reach relative to bridge chord. Overrides `CurveBridgeOptions.weight` for this side.
|
|
110
|
+
|
|
81
111
|
#### `Curve.Arc(options: CurveArcOptions): NurbsCurve3D` — Create an exact circular 3D arc from start, end, and start tangent.
|
|
82
112
|
|
|
83
113
|
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.
|
|
@@ -142,6 +172,52 @@ const loop = Curve.Fit(
|
|
|
142
172
|
- `tolerance?: number` — Maximum allowed interpolation residual in model units. Default 1e-7.
|
|
143
173
|
- `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.
|
|
144
174
|
|
|
175
|
+
#### `Curve.ProjectOnSurface(curve: NurbsCurve3D | Vec3[], sheet: Sheet, options?: CurveProjectOnSurfaceOptions): NurbsCurve3D` — Project a curve onto a `Sheet` along the surface normal and return the exact NURBS foot curve.
|
|
176
|
+
|
|
177
|
+
This is the "drape a curve onto a surface" primitive: each sampled point of the source curve is inverted onto the sheet (closest surface point via the analytic jet), and the foot points are fitted with `Curve.Fit`. Use it to trace a planned trim line, seam, or graphic onto a freeform panel, then sweep or trim from the real on-surface curve.
|
|
178
|
+
|
|
179
|
+
The source may be an exact `NurbsCurve3D` or a `Vec3[]` polyline (for example a placed 2D path). With `{ closed: true }` the result is a periodic loop, for draping a closed boundary onto the sheet. Set `maxGap` to require that every sample lands within a distance of the surface; the call throws if any sample misses (no silent fallback).
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
const panel = Surface.Net().cage(cage);
|
|
183
|
+
const guide = Curve.Line([-20, 0, 30], [20, 0, 30]);
|
|
184
|
+
const seam = Curve.ProjectOnSurface(guide, panel);
|
|
185
|
+
const bead = sweep(circle2d(0.6), seam);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**`CurveProjectOnSurfaceOptions`**
|
|
189
|
+
|
|
190
|
+
| Option | Type | Description |
|
|
191
|
+
|--------|------|-------------|
|
|
192
|
+
| `samples?` | `number` | Coarse samples taken along the source curve before per-sample projection. Default 64. |
|
|
193
|
+
| `refineIterations?` | `number` | Newton refinement iterations of the (u, v) foot-point per sample. Default 8. |
|
|
194
|
+
| `tolerance?` | `number` | Interpolation tolerance passed to Curve.Fit for the result. Default 1e-4. |
|
|
195
|
+
| `closed?` | `boolean` | Fit a closed periodic loop (use when the source curve is a closed loop). Default false. |
|
|
196
|
+
| `maxGap?` | `number` | Max allowed projection gap; throws if any sample lands farther than this from the surface foot. Default Infinity (no gate). |
|
|
197
|
+
|
|
198
|
+
#### `Curve.Intersect(sheetA: Sheet, sheetB: Sheet, options?: CurveIntersectOptions): NurbsCurve3D[]` — Intersect two `Sheet` surfaces and return the exact NURBS intersection branches.
|
|
199
|
+
|
|
200
|
+
This is curve-following surface-surface intersection (SSI): a transversal marcher follows each intersection branch using the analytic surface jets (the intersection tangent is `cross(normalA, normalB)`), converging every step onto both surfaces, then fits each branch with `Curve.Fit`. A single pair of sheets can intersect in several disjoint curves, so the result is an array (empty when the sheets do not meet).
|
|
201
|
+
|
|
202
|
+
Only transversal intersections (where the surfaces cross and the intersection tangent `cross(normalA, normalB)` is well defined) are detected. A tangential / grazing contact (where the surface normals are parallel and the tangent is undefined) is not marched and may be reported as no-intersection (an empty array) — tangential SSI is a documented follow-on, not a silent fallback.
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
const wing = Surface.Net().cage(wingCage);
|
|
206
|
+
const rib = Surface.Net().cage(ribCage);
|
|
207
|
+
const [seam] = Curve.Intersect(wing, rib);
|
|
208
|
+
const weld = sweep(circle2d(0.5), seam);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**`CurveIntersectOptions`**
|
|
212
|
+
|
|
213
|
+
| Option | Type | Description |
|
|
214
|
+
|--------|------|-------------|
|
|
215
|
+
| `samples?` | `number` | Grid resolution per axis for seeding the marcher (samples x samples on sheetA). Default 48. |
|
|
216
|
+
| `step?` | `number` | Marching step as a fraction of sheetA's average sample spacing. Default 0.5. |
|
|
217
|
+
| `refineIterations?` | `number` | Newton iterations to converge each marched point onto both surfaces. Default 12. |
|
|
218
|
+
| `tolerance?` | `number` | Convergence/coincidence tolerance in model units. Default 1e-4. |
|
|
219
|
+
| `fitTolerance?` | `number` | Fit tolerance passed to Curve.Fit. Default 1e-3. |
|
|
220
|
+
|
|
145
221
|
#### `Curve.Trim<T extends CurveTrimInput>(curve: T, start: number, end: number): CurveTrimOutput<T>` — Extract an exact curve segment from normalized parameter `start` to `end`.
|
|
146
222
|
|
|
147
223
|
`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.
|
|
@@ -150,6 +226,68 @@ const loop = Curve.Fit(
|
|
|
150
226
|
|
|
151
227
|
`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.
|
|
152
228
|
|
|
229
|
+
#### `Curve.closestParameter(curve: CurveClosestParameterInput, point: Vec3, options?: CurveClosestParameterOptions): number` — Find the normalized parameter on an exact curve closest to a world point.
|
|
230
|
+
|
|
231
|
+
This is the query companion to `Curve.Trim()`: use it to locate where a construction point lands on an existing rail, surface boundary, or edge curve, then trim/sweep from that real geometric station instead of copying the original construction points.
|
|
232
|
+
|
|
233
|
+
`NurbsCurve3D` inputs are searched by curve parameter with coarse sampling plus local refinement. Polyline point arrays are projected onto their exact line segments and return an arclength-normalized parameter.
|
|
234
|
+
|
|
235
|
+
```js
|
|
236
|
+
const start = Curve.closestParameter(sheet.frontCurve, [-20, -12, 4]);
|
|
237
|
+
const end = Curve.closestParameter(sheet.frontCurve, [20, -12, 4]);
|
|
238
|
+
const rimRail = Curve.Trim(sheet.frontCurve, start, end);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**`CurveClosestParameterOptions`**
|
|
242
|
+
- `samples?: number` — Coarse samples before local refinement. Default 96.
|
|
243
|
+
|
|
244
|
+
#### `Curve.join(curves: CurveJoinInput[], options?: CurveJoinOptions): Vec3[]` — Join touching curve segments into one sampled sweep path.
|
|
245
|
+
|
|
246
|
+
This is the composite-curve primitive for downstream features that need to follow several real edges as one path: rolled rims, seam beads, trim strips, weld beads, and surface-boundary inlays. ForgeCAD validates that adjacent segment endpoints touch; it will not silently reverse or bridge gaps.
|
|
247
|
+
|
|
248
|
+
```js
|
|
249
|
+
const rimPath = Curve.join([
|
|
250
|
+
Curve.Reverse(Curve.Trim(sheet.frontCurve, 0, u)),
|
|
251
|
+
sheet.leftCurve,
|
|
252
|
+
Curve.Trim(sheet.rearCurve, 0, u),
|
|
253
|
+
]);
|
|
254
|
+
const rim = sweep(ellipse(0.8, 0.35), rimPath);
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**`CurveJoinOptions`**
|
|
258
|
+
- `samples?: number` — Points sampled per exact curve segment. Default 32.
|
|
259
|
+
- `tolerance?: number` — Maximum allowed gap between adjacent segment endpoints. Default 1e-6.
|
|
260
|
+
|
|
261
|
+
#### `Curve.placeOnXY(path: CurvePath2D, z?: number, options?: CurvePathPlacementOptions): Vec3[]` — Place a 2D path onto the XY plane at world Z.
|
|
262
|
+
|
|
263
|
+
The returned 3D point array can feed `Surface.Net`, `Curve.Fit`, `sweep`, `Curve.Trim`, and any other curve consumer that accepts points.
|
|
264
|
+
|
|
265
|
+
```js
|
|
266
|
+
const rail = Curve.placeOnXY(path().moveTo(0, 0).bezierTo(30, 8, 60, -4, 90, 0), 12);
|
|
267
|
+
const smoothRail = Curve.Fit(rail);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**`CurvePathPlacementOptions`**
|
|
271
|
+
- `samples?: number` — Optional sample count when [`path`](/docs/sketch#path) is a path-like object.
|
|
272
|
+
|
|
273
|
+
#### `Curve.placeOnXZ(path: CurvePath2D, y?: number, options?: CurvePathPlacementOptions): Vec3[]` — Place a 2D path onto the XZ plane at world Y.
|
|
274
|
+
|
|
275
|
+
The path's first coordinate becomes X and the second becomes Z.
|
|
276
|
+
|
|
277
|
+
#### `Curve.placeOnYZ(path: CurvePath2D, x?: number, options?: CurvePathPlacementOptions): Vec3[]` — Place a 2D path onto the YZ plane at world X.
|
|
278
|
+
|
|
279
|
+
The path's first coordinate becomes Y and the second becomes Z. This is the direct "sketch cross-sections on offset planes" primitive for surface nets.
|
|
280
|
+
|
|
281
|
+
#### `Curve.placeOnPlane(path: CurvePath2D, options: CurvePlanePlacementOptions): Vec3[]` — Place a 2D path onto an arbitrary world plane.
|
|
282
|
+
|
|
283
|
+
`origin` is the 2D sketch origin in world space. `xAxis` and `yAxis` are perpendicular world directions for the local sketch axes.
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
**`CurvePlanePlacementOptions`** extends CurvePathPlacementOptions
|
|
287
|
+
- `origin: Vec3` — World-space origin of the 2D sketch plane.
|
|
288
|
+
- `xAxis: Vec3` — World-space direction for the sketch X axis.
|
|
289
|
+
- `yAxis: Vec3` — World-space direction for the sketch Y axis.
|
|
290
|
+
|
|
153
291
|
#### `Curve.Route: typeof Route3D` — Build analytic 3D line/arc routes for sweeps.
|
|
154
292
|
|
|
155
293
|
`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.
|
|
@@ -250,7 +388,7 @@ A closed spline (default) returns a filled profile. An open spline requires a st
|
|
|
250
388
|
| `strokeWidth?` | `number` | For open splines, provide stroke width to return a solid Sketch. If omitted for open splines, an error is thrown. |
|
|
251
389
|
| `join?` | `"Round" \| "Square"` | Stroke join for open splines. Default 'Round'. |
|
|
252
390
|
|
|
253
|
-
#### `loft(profiles: Sketch[], heights: number[], options?: LoftOptions): Shape` — Loft between multiple sketches along Z stations.
|
|
391
|
+
#### `loft(profiles: Sketch[], heights: (number | EndCondition)[], options?: LoftOptions): Shape` — Loft between multiple sketches along Z stations.
|
|
254
392
|
|
|
255
393
|
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.
|
|
256
394
|
|
|
@@ -258,6 +396,8 @@ The surface is smooth through 3+ stations (C1 spanwise interpolation, like CAD l
|
|
|
258
396
|
|
|
259
397
|
Performance note: loft is significantly heavier than primitive/extrude/revolve. If the part is axis-symmetric (bottles, vases, knobs), prefer revolve().
|
|
260
398
|
|
|
399
|
+
`EndCondition` — defined in [sketch](/docs/sketch).
|
|
400
|
+
|
|
261
401
|
#### `sweep(profile: Sketch, path: SweepPathInput, options?: SweepOptions): Shape`
|
|
262
402
|
|
|
263
403
|
**`SweepOptions`**
|
|
@@ -437,6 +577,95 @@ Uses Algorithm A2.3 basis-function derivatives with the rational quotient rule,
|
|
|
437
577
|
|
|
438
578
|
#### `tessellate(resU?: number, resV?: number): { positions: Vec3[]; normals: Vec3[]; indices: number[]; }` — Tessellate the surface into a triangle mesh. Returns positions, normals, and triangle indices.
|
|
439
579
|
|
|
580
|
+
### `Sheet`
|
|
581
|
+
|
|
582
|
+
A parametric open surface value (control grid + knots + analytic differential geometry).
|
|
583
|
+
|
|
584
|
+
**Properties:**
|
|
585
|
+
|
|
586
|
+
| Property | Type | Description |
|
|
587
|
+
|----------|------|-------------|
|
|
588
|
+
| `surface` | `BSplineSurface` | — |
|
|
589
|
+
|
|
590
|
+
**Methods:**
|
|
591
|
+
|
|
592
|
+
#### `get frontEdge(): SheetEdge` — Edge naming follows parameter direction (documented): front=v0, rear=v1, left=u0, right=u1.
|
|
593
|
+
|
|
594
|
+
#### `get frontCurve(): NurbsCurve3D` — Exact curve along the front boundary (`v = 0`).
|
|
595
|
+
|
|
596
|
+
#### `get rearCurve(): NurbsCurve3D` — Exact curve along the rear boundary (`v = 1`).
|
|
597
|
+
|
|
598
|
+
#### `get leftCurve(): NurbsCurve3D` — Exact curve along the left boundary (`u = 0`).
|
|
599
|
+
|
|
600
|
+
#### `get rightCurve(): NurbsCurve3D` — Exact curve along the right boundary (`u = 1`).
|
|
601
|
+
|
|
602
|
+
#### `curveAlong(edge: SheetEdge): NurbsCurve3D` — Extract an exact NURBS iso-curve from one of this sheet's boundary edges.
|
|
603
|
+
|
|
604
|
+
Use this when a downstream feature should be driven by the actual sheet boundary, such as a swept rim, seam bead, trim strip, or adjacent blend.
|
|
605
|
+
|
|
606
|
+
`SheetEdge` — defined in [core](/docs/core).
|
|
607
|
+
|
|
608
|
+
#### `curveAlongU(vInput: number): NurbsCurve3D` — Extract an exact NURBS iso-curve in the sheet U direction at fixed `v`.
|
|
609
|
+
|
|
610
|
+
Use this for centerline rails, ribs, beads, and trim features that live on the interior of a freeform sheet instead of on a boundary edge.
|
|
611
|
+
|
|
612
|
+
#### `curveAlongV(uInput: number): NurbsCurve3D` — Extract an exact NURBS iso-curve in the sheet V direction at fixed `u`.
|
|
613
|
+
|
|
614
|
+
Use this for cross-surface rails, seam lines, straps, and inspection paths that should be driven by the sheet parameterization rather than global axes.
|
|
615
|
+
|
|
616
|
+
#### `pathAlong(edge: SheetEdge, options?: SheetPathAlongOptions): Vec3[]` — Sample a world-space path along a sheet boundary edge.
|
|
617
|
+
|
|
618
|
+
Use this when a downstream feature should follow the real surface edge but does not need to stay an exact NURBS curve, for example a lip, gasket bead, trim strip, weld seam, or inlay lifted off the surface by `normalOffset`.
|
|
619
|
+
|
|
620
|
+
`SheetPathAlongOptions` — defined in [core](/docs/core).
|
|
621
|
+
|
|
622
|
+
#### `pathAlongBoundary(spans: SheetBoundaryPathSpan[], options?: SheetBoundaryPathOptions): Vec3[]` — Sample one connected path across ordered sheet boundary edge spans.
|
|
623
|
+
|
|
624
|
+
This is the composite-boundary primitive for rolled rims, weld beads, gaskets, trim strips, and inlays that follow several sheet edges as one continuous rail. Span `start` / `end` values may be normalized parameters or world points; world points are resolved to the closest point on that edge so callers do not have to manually invoke `Curve.closestParameter()`.
|
|
625
|
+
|
|
626
|
+
`SheetBoundaryPathSpan` — defined in [core](/docs/core).
|
|
627
|
+
|
|
628
|
+
`SheetBoundaryPathOptions` — defined in [core](/docs/core).
|
|
629
|
+
|
|
630
|
+
#### `pathAlongU(vInput: number, options?: SheetPathAlongOptions): Vec3[]` — Sample a world-space path in the sheet U direction at fixed `v`.
|
|
631
|
+
|
|
632
|
+
Unlike `curveAlongU()`, this can lift points along the analytic normal with `normalOffset`, which is the common path for swept ribs, inlays, and raised details on a freeform carrier surface.
|
|
633
|
+
|
|
634
|
+
#### `pathAlongV(uInput: number, options?: SheetPathAlongOptions): Vec3[]` — Sample a world-space path in the sheet V direction at fixed `u`.
|
|
635
|
+
|
|
636
|
+
Use this for lifted cross-surface features where a sampled path is more useful than an exact iso-curve, for example straps, grooves, or probes.
|
|
637
|
+
|
|
638
|
+
#### `frameAt(uInput: number, vInput: number, options?: SheetFrameOptions): SheetFrame` — Build an orthonormal local work frame on the sheet.
|
|
639
|
+
|
|
640
|
+
This is the "construct tangent plane/frame on a surface" primitive for downstream sketches, profiles, fixtures, inspection probes, and features that must be oriented from the sheet itself rather than global axes.
|
|
641
|
+
|
|
642
|
+
`SheetFrameOptions` — defined in [core](/docs/core).
|
|
643
|
+
|
|
644
|
+
#### `framePerpendicularToU(uInput: number, vInput: number, options?: SheetFrameOptions): SheetFrame` — Build a section work frame perpendicular to the sheet's U direction.
|
|
645
|
+
|
|
646
|
+
This is the "plane normal to path" primitive for ribs, raised handles, bosses, and other details whose cross-sections should be sketched across a carrier surface while marching along the surface U direction. The returned frame can be passed directly to `Shape.sliceOnFrame()`.
|
|
647
|
+
|
|
648
|
+
#### `framePerpendicularToV(uInput: number, vInput: number, options?: SheetFrameOptions): SheetFrame` — Build a section work frame perpendicular to the sheet's V direction.
|
|
649
|
+
|
|
650
|
+
Use this when the guide path runs in the surface V direction and the sketch profile should span the U direction while its height follows the surface normal. The returned frame can be passed directly to `Shape.sliceOnFrame()`.
|
|
651
|
+
|
|
652
|
+
#### `toShape(options?: { resolution?: number; }): Shape` — Return this open sheet as a renderable surface Shape.
|
|
653
|
+
|
|
654
|
+
#### `thicken(wall: number, options?: { resolution?: number; }): Shape` — Offset the sheet along its analytic normals into a watertight solid shell of the given wall thickness. Throws if the wall would self-intersect on a concave region (no silent degenerate solid).
|
|
655
|
+
|
|
656
|
+
#### `thickenInsideBy(thickness: ThicknessInput, options?: { resolution?: number; }): Shape` — Thicken this sheet inward by a scalar UV thickness field.
|
|
657
|
+
|
|
658
|
+
Numeric input delegates to `Sheet.thicken()`. `Thickness.*` fields produce a sampled solid because a variable normal offset is not generally an exact NURBS surface.
|
|
659
|
+
|
|
660
|
+
#### `matchEdge(edge: SheetEdge): MatchEdgeBuilder` — Per-edge continuity match against a neighbor (returns a NEW Sheet).
|
|
661
|
+
|
|
662
|
+
- `get rearEdge(): SheetEdge`
|
|
663
|
+
- `get leftEdge(): SheetEdge`
|
|
664
|
+
- `get rightEdge(): SheetEdge`
|
|
665
|
+
- `pointAt(u: number, v: number): Vec3`
|
|
666
|
+
- `normalAt(u: number, v: number): Vec3`
|
|
667
|
+
- `curvatureAt(u: number, v: number): SurfaceCurvature`
|
|
668
|
+
|
|
440
669
|
### `PathBuilder`
|
|
441
670
|
|
|
442
671
|
**Line Segments**
|
|
@@ -1132,7 +1361,7 @@ Canonical exact/smooth 3D curve constructors.
|
|
|
1132
1361
|
|
|
1133
1362
|
`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.
|
|
1134
1363
|
|
|
1135
|
-
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`.
|
|
1364
|
+
Members (full entries under [Curves & Surfacing](#curves-surfacing)): `Curve.Blend`, `Curve.BlendG2`, `Curve.Bridge`, `Curve.Arc`, `Curve.Line`, `Curve.Nurbs`, `Curve.Fit`, `Curve.ProjectOnSurface`, `Curve.Intersect`, `Curve.Trim`, `Curve.Reverse`, `Curve.closestParameter`, `Curve.join`, `Curve.placeOnXY`, `Curve.placeOnXZ`, `Curve.placeOnYZ`, `Curve.placeOnPlane`, `Curve.Route`, `Curve.Helix`.
|
|
1136
1365
|
|
|
1137
1366
|
### `Surface`
|
|
1138
1367
|
|
|
@@ -1141,6 +1370,31 @@ Members (full entries under [Curves & Surfacing](#curves-surfacing)): `Curve.Ble
|
|
|
1141
1370
|
- `Cone(options: SurfaceConeOptions): Shape` — Create a finite analytic conical or frustum sheet, optionally bounded by start/end angles.
|
|
1142
1371
|
- `Sphere(options: SurfaceSphereOptions): Shape` — Create a finite analytic spherical sheet bounded by longitude and latitude ranges.
|
|
1143
1372
|
- `Torus(options: SurfaceTorusOptions): Shape` — Create a finite analytic torus sheet bounded by major and tube angle ranges.
|
|
1373
|
+
- `Sweep(profile: SurfaceSweepProfileInput, spine: SweepPathInput, options?: SurfaceSweepOptions): Sheet` — Sweep an open 2D profile path along a 3D spine to create an open surface sheet.
|
|
1374
|
+
|
|
1375
|
+
This is the surface-first counterpart to the solid `sweep()` function. Use it for class-A/product workflows where the shape starts as an infinitely thin carrier sheet, then becomes physical material with `.thicken(...)`. The profile's local X axis maps across the sheet, local Y maps along the swept frame's up/normal direction, and the spine direction becomes sheet U.
|
|
1376
|
+
|
|
1377
|
+
```js
|
|
1378
|
+
const sideProfile = Curve.Fit(Curve.placeOnXZ(path().moveTo(0, 0).bezierTo(40, -8, 90, 8, 140, 3)));
|
|
1379
|
+
const crossSection = path().moveTo(-20, 2).bezierTo(-8, -4, 8, -4, 20, 2);
|
|
1380
|
+
const sheet = Surface.Sweep(crossSection, sideProfile);
|
|
1381
|
+
const thinPart = sheet.thicken(1.2);
|
|
1382
|
+
```
|
|
1383
|
+
- `Loft(input: SurfaceLoftInput): Sheet` — Loft an open surface sheet through ordered profile stations.
|
|
1384
|
+
|
|
1385
|
+
This is the surface-first counterpart to solid lofts: profiles are open 2D section curves, point stations intentionally collapse a smooth tip, and guide curves can pin named connection landmarks such as rims or low points. The result is an open `Sheet`; call `.thicken(...)` to make physical material.
|
|
1386
|
+
|
|
1387
|
+
```js
|
|
1388
|
+
const sheet = Surface.Loft({
|
|
1389
|
+
axis: 'X',
|
|
1390
|
+
profiles: [
|
|
1391
|
+
{ at: -40, point: [-40, 0, 0] },
|
|
1392
|
+
{ at: 0, profile: path().moveTo(-12, 2).bezierTo(-4, -4, 4, -4, 12, 2) },
|
|
1393
|
+
{ at: 40, profile: path().moveTo(-5, 0).lineTo(5, 0) },
|
|
1394
|
+
],
|
|
1395
|
+
connections: [{ name: 'lowPoint', profileParameter: 0.5 }],
|
|
1396
|
+
});
|
|
1397
|
+
```
|
|
1144
1398
|
- `Nurbs(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape` — Create an exact NURBS surface from a grid of control points.
|
|
1145
1399
|
|
|
1146
1400
|
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.
|
|
@@ -1166,20 +1420,109 @@ Members (full entries under [Curves & Surfacing](#curves-surfacing)): `Curve.Ble
|
|
|
1166
1420
|
const panel = Surface.Patch({ bottom, top, left, right }).thicken(1.5);
|
|
1167
1421
|
```
|
|
1168
1422
|
- `Boundary(input: SurfaceBoundaryInput): Shape`
|
|
1169
|
-
- `Fill(input: SurfaceFillInput): Shape`
|
|
1423
|
+
- `Fill(input: SurfaceFillInput): Shape` — Create an n-sided open surface sheet from 3 or more boundary curves (energy-minimizing constrained fill).
|
|
1424
|
+
|
|
1425
|
+
Boundaries form a closed loop of any size (n >= 3). They are exact by default: pass `NurbsCurve3D` values or `Shape.edge()` refs, or set `{ approximate: true }` to accept sampled `Curve3D`/`Vec3[]` boundaries. Use `match` to make a named boundary G0/G1/G2-tangent to a neighboring face. The result is an open sheet — call `.thicken(t)` for a thin solid.
|
|
1426
|
+
|
|
1427
|
+
Two optional fields pull the fill onto interior features (OCCT backend only; the Truck/SDF backends reject them):
|
|
1428
|
+
|
|
1429
|
+
- `through` — interior constraint curves the surface must pass through (not part of the boundary loop). These are matched positionally (G0) only; G1/G2 on a free interior curve is not honored, so a non-`'G0'` `continuity` throws.
|
|
1430
|
+
- `points` — isolated interior points the surface must interpolate.
|
|
1431
|
+
|
|
1432
|
+
```js
|
|
1433
|
+
const skin = Surface.Fill({
|
|
1434
|
+
boundaries: [
|
|
1435
|
+
{ name: 'a', curve: edgeA }, { name: 'b', curve: edgeB },
|
|
1436
|
+
{ name: 'c', curve: edgeC }, { name: 'd', curve: edgeD }, { name: 'e', curve: edgeE },
|
|
1437
|
+
],
|
|
1438
|
+
match: { a: { target: neighbor.edge('top'), continuity: 'G1' } },
|
|
1439
|
+
through: [{ curve: interiorSpine }], // pull the fill onto an internal feature line
|
|
1440
|
+
points: [[10, 10, 4]], // pin an interior bump
|
|
1441
|
+
});
|
|
1442
|
+
```
|
|
1170
1443
|
- `Sew(shapes: Shape[], options?: { tolerance?: number; }): Shape`
|
|
1171
1444
|
- `Solid(input: Shape | Shape[], options?: SurfaceSolidOptions): Shape` — Sew surface faces or consume an existing sewn shell and make a solid B-rep.
|
|
1172
1445
|
- `Extend(shape: Shape, options: SurfaceExtendOptions): Shape`
|
|
1173
1446
|
- `Trim(shape: Shape, tool: Shape | SurfacePlaneOp): Shape`
|
|
1174
1447
|
- `Split(shape: Shape, tool: Shape | SurfacePlaneOp): [ Shape, Shape ]`
|
|
1175
1448
|
- `Match(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape`
|
|
1176
|
-
- `Net(): CurveNet` — Begin a curve-network (Gordon) surface — the class-A keystone. Chain `.lengthwise(...)/.crosswise(...)` (or `.alongRails(a,b).sections(...)`, or `.cage(grid)`), then `.thicken(wall)` to get a solid Shape. Returns a fluent
|
|
1449
|
+
- `Net(): CurveNet` — Begin a curve-network (Gordon) surface — the class-A keystone. Chain `.lengthwise(...)/.crosswise(...)` (or `.alongRails(a,b).sections(...)`, or `.cage(grid)`), then `.thicken(wall)` to get a solid Shape. Returns a fluent `Sheet` builder with analytic point/normal/curvature queries and named edges.
|
|
1450
|
+
- `BoundaryNet(): CurveNet` — Begin a **Boundary Surface** — the canonical class-A surfacing primitive (SolidWorks "Boundary Boss/Base", Onshape "Boundary surface", Rhino NetworkSrf). It fills a curve cage exactly like `Net` (same Gordon interior), then adds the two foundational boundary capabilities a real boundary surface has:
|
|
1451
|
+
|
|
1452
|
+
1. **Per-side continuity** — `.matchStartU/.matchEndU/.matchStartV/.matchEndV` enforce G0/G1/G2 across a side, either matching an adjacent sheet's edge (tangent/curvature) or imposing an explicit cross-boundary tangent.
|
|
1453
|
+
2. **Closed / periodic form** — `.closedU()/.closedV()` weld a direction's two ends into a tangent-continuous loop, so a closed-rim surface (e.g. a bowl's around-rim seam) is smooth with NO G0 kink.
|
|
1454
|
+
|
|
1455
|
+
Returns the same fluent builder as `Net` (cage/families/degree plus the new boundary methods); finish with `.toSheet()` or `.thicken(wall)`. Verify a matched seam with `Analysis.EdgeMatch`.
|
|
1456
|
+
|
|
1457
|
+
```js
|
|
1458
|
+
// Smooth closed-rim dished bowl: a closed rim + radial sections, welded.
|
|
1459
|
+
const bowl = Surface.BoundaryNet()
|
|
1460
|
+
.lengthwise(...radialSections) // rim -> center, one per around-rim station
|
|
1461
|
+
.closedV() // weld the around-rim seam (no kink)
|
|
1462
|
+
.thicken(1.2);
|
|
1463
|
+
```
|
|
1464
|
+
|
|
1465
|
+
```js
|
|
1466
|
+
// Match a fender panel to the hood with curvature (G2) continuity.
|
|
1467
|
+
const fender = Surface.BoundaryNet()
|
|
1468
|
+
.lengthwise(sill, belt, crown)
|
|
1469
|
+
.crosswise(nose, aPillar)
|
|
1470
|
+
.matchStartV({ edge: hood.rearEdge, continuity: 2 })
|
|
1471
|
+
.toSheet();
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
U-sides then V-sides, so clean continuity is guaranteed along edge interiors, not exactly at the four corners (same limitation as `Sheet.matchEdge`).
|
|
1177
1475
|
|
|
1178
1476
|
### `Blend`
|
|
1179
1477
|
|
|
1180
|
-
- `Edge(options: BlendEdgeOptions): Shape`
|
|
1478
|
+
- `Edge(options: BlendEdgeOptions): Shape` — Fillet one or more edges with constant or variable radius.
|
|
1479
|
+
|
|
1480
|
+
Pass `variableRadius` for a tapered or station-law blend — it overrides the constant `radius`. Variable radius requires `--backend occt`.
|
|
1481
|
+
|
|
1482
|
+
Orientation caveat: for a linear `{ start, end }` taper, `start` maps to the matched edge's first vertex (u=0), whose orientation is not guaranteed to match the named edge's start. If the taper runs the wrong way, pass a `stations` law (explicit `at` positions) or swap `start`/`end`.
|
|
1483
|
+
|
|
1484
|
+
```js
|
|
1485
|
+
// Constant radius
|
|
1486
|
+
let b = box(40, 20, 10)
|
|
1487
|
+
b = Blend.Edge({ edges: [b.edge('top-front')], radius: 3 })
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
```js
|
|
1491
|
+
// Linear taper from 1mm to 5mm along the edge
|
|
1492
|
+
b = Blend.Edge({ edges: [b.edge('top-front')], variableRadius: { start: 1, end: 5 } })
|
|
1493
|
+
```
|
|
1494
|
+
|
|
1495
|
+
```js
|
|
1496
|
+
// Station law — bulge in the middle
|
|
1497
|
+
b = Blend.Edge({ edges: [b.edge('top-front')], variableRadius: {
|
|
1498
|
+
stations: [{ at: 0, radius: 1 }, { at: 0.5, radius: 4 }, { at: 1, radius: 1 }] } })
|
|
1499
|
+
```
|
|
1181
1500
|
- `Surface(options: BlendSurfaceOptions): Shape`
|
|
1182
|
-
- `Bridge(edgeA: SheetEdge, edgeB: SheetEdge): BridgeBuilder` — Build a transition strip between two `Surface.Net` sheet edges. Chain `.bulge(a, b)` then `.g0()/.g1()/.g2()` for the continuity order. Returns a
|
|
1501
|
+
- `Bridge(edgeA: SheetEdge, edgeB: SheetEdge): BridgeBuilder` — Build a transition strip between two `Surface.Net` sheet edges. Chain `.bulge(a, b)` then `.g0()/.g1()/.g2()` for the continuity order. Returns a `Sheet`; verify the seam with `Analysis.EdgeMatch`.
|
|
1502
|
+
- `Face(options: BlendFaceOptions): Shape` — Fillet every edge SHARED by a pair of faces — a "face fillet". Resolves the shared edges of the two faces and rolls a constant or variable-radius blend along all of them. Requires `--backend occt`.
|
|
1503
|
+
|
|
1504
|
+
```js
|
|
1505
|
+
let body = box(80, 50, 30).faces({ lid: 'top', wall: 'side-left' })
|
|
1506
|
+
body = Blend.Face({ faces: [body.face('lid'), body.face('wall')], radius: 4 })
|
|
1507
|
+
```
|
|
1508
|
+
|
|
1509
|
+
```js
|
|
1510
|
+
// Variable radius along the shared edges
|
|
1511
|
+
body = Blend.Face({ faces: [body.face('lid'), body.face('wall')],
|
|
1512
|
+
variableRadius: { start: 2, end: 6 } })
|
|
1513
|
+
```
|
|
1514
|
+
- `FullRound(options: BlendFullRoundOptions): Shape` — Full round — roll a blend over a narrow center face so it is consumed and its two neighbouring faces meet tangentially (classic 3-face full round). The radius defaults to half the center-face span. Requires `--backend occt`.
|
|
1515
|
+
|
|
1516
|
+
```js
|
|
1517
|
+
let bar = box(60, 8, 20).faces({ topRail: 'top', left: 'side-left', right: 'side-right' })
|
|
1518
|
+
bar = Blend.FullRound({ centerFace: bar.face('topRail') })
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
```js
|
|
1522
|
+
// Explicit neighbours
|
|
1523
|
+
bar = Blend.FullRound({ centerFace: bar.face('topRail'),
|
|
1524
|
+
sideFaces: [bar.face('left'), bar.face('right')] })
|
|
1525
|
+
```
|
|
1183
1526
|
|
|
1184
1527
|
### `Analysis`
|
|
1185
1528
|
|
|
@@ -1190,6 +1533,14 @@ Members (full entries under [Curves & Surfacing](#curves-surfacing)): `Curve.Ble
|
|
|
1190
1533
|
- `SurfaceHealth(shape: Shape, options?: { tinyEdgeThreshold?: number; sliverThreshold?: number; }): SurfaceHealthReport`
|
|
1191
1534
|
- `BRepValidity(shape: Shape, options?: BRepValidityOptions): BRepValidityReport` — Validate B-rep/shell/solid structure and return closedness, manifoldness, orientation, and issue diagnostics.
|
|
1192
1535
|
|
|
1536
|
+
### `Thickness`
|
|
1537
|
+
|
|
1538
|
+
- `constant: (thickness: number) => ThicknessField` — Use the same wall thickness everywhere on the sheet.
|
|
1539
|
+
- `alongU: (profile: ThicknessStation[] | ThicknessStationProfile) => ThicknessField` — Vary wall thickness across the sheet U direction.
|
|
1540
|
+
- `alongV: (profile: ThicknessStation[] | ThicknessStationProfile) => ThicknessField` — Vary wall thickness across the sheet V direction.
|
|
1541
|
+
- `grid: (values: number[][], options?: ThicknessGridOptions) => ThicknessField` — Bilinearly interpolate wall thickness from a rectangular UV grid.
|
|
1542
|
+
- `nurbs: (values: number[][], options?: ThicknessNurbsOptions) => ThicknessField` — Interpolate wall thickness from a scalar tensor-product B-spline over sheet UV.
|
|
1543
|
+
|
|
1193
1544
|
### `Product`
|
|
1194
1545
|
|
|
1195
1546
|
- `skin(name: string): ProductSkinBuilder` — Start a named product skin builder.
|
|
@@ -18,18 +18,18 @@ activateBackend, Analysis, arcSlot, assembly, Assembly, Blend, bom, box
|
|
|
18
18
|
cameraTrajectory, Carrier, chamfer, circle2d, Circle2D, circularLayout, circularPattern, circularPattern2d
|
|
19
19
|
coalesceEdges, compareWith, connector, console, constrainedSketch, Curve, Curve3D, cutPlane
|
|
20
20
|
cylinder, difference, difference2d, dim, draft, ellipse, explodeView, faceProfile
|
|
21
|
-
fillet, Function, gcode, GCodeBuilder, getActiveBackend, global, globalThis
|
|
22
|
-
Import, ImportedAssembly, initKernel, intersection, intersection2d, intersectWithPlane, joint
|
|
23
|
-
lib, Line2D, linearPattern, linearPattern2d, loadFont, loft, Loft
|
|
24
|
-
mock, ngon, NurbsCurve3D, NurbsSurface, offsetSolid, param, Param
|
|
25
|
-
Point2D, Points, polygon, polygonVertices, port, Product, ProductPanelBuilder
|
|
26
|
-
ProductSkin, ProductSkinBuilder, ProductStationBuilder, ProductSurfaceBuilder, ProductSurfaceRef, projectToPlane, queueMicrotask
|
|
27
|
-
Rectangle2D, roundedRect, Route3D, scene, Sculpt, sdf, SdfShape
|
|
28
|
-
selectEdges, self, setActiveBackend, setImmediate, setInterval, setTimeout, Shape
|
|
29
|
-
sheetMetal, SheetMetalPart, sheetStock, Sim, Sketch, sketchToDxf, sketchToSvg
|
|
30
|
-
SolvedAssembly, spec, sphere, spline2d, stroke, Surface, SurfaceBody
|
|
31
|
-
sweep, text2d, textWidth, torus, toShape, Transform
|
|
32
|
-
variableSweep, verify, Viewport, window, Wood, Wrap
|
|
21
|
+
Fea, fillet, Function, gcode, GCodeBuilder, getActiveBackend, global, globalThis
|
|
22
|
+
group, Import, ImportedAssembly, initKernel, intersection, intersection2d, intersectWithPlane, joint
|
|
23
|
+
Laser, lib, Line2D, linearPattern, linearPattern2d, loadFont, loft, Loft
|
|
24
|
+
mirrorCopy, mock, ngon, NurbsCurve3D, NurbsSurface, offsetSolid, param, Param
|
|
25
|
+
path, Point2D, Points, polygon, polygonVertices, port, Product, ProductPanelBuilder
|
|
26
|
+
ProductRibbonBuilder, ProductSkin, ProductSkinBuilder, ProductStationBuilder, ProductSurfaceBuilder, ProductSurfaceRef, projectToPlane, queueMicrotask
|
|
27
|
+
rect, Rectangle2D, roundedRect, Route3D, scene, Sculpt, sdf, SdfShape
|
|
28
|
+
selectEdge, selectEdges, self, setActiveBackend, setImmediate, setInterval, setTimeout, Shape
|
|
29
|
+
ShapeGroup, sheetMetal, SheetMetalPart, sheetStock, Sim, Sketch, sketchToDxf, sketchToSvg
|
|
30
|
+
slot, SolvedAssembly, spec, sphere, spline2d, stroke, Surface, SurfaceBody
|
|
31
|
+
SurfaceMembers, sweep, text2d, textWidth, Thickness, torus, toShape, Transform
|
|
32
|
+
union, union2d, variableSweep, verify, Viewport, window, Wood, Wrap
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
<!-- forgecad-skill:exclude-start symbol="compatibility runtime names" reason="Compatibility-only renamed runtime globals." -->
|
|
@@ -391,7 +391,22 @@ donut.region([40, 0]).extrude(10); // seed at radius 40, inside the ring
|
|
|
391
391
|
|
|
392
392
|
**Promotion**
|
|
393
393
|
|
|
394
|
-
#### `extrude(
|
|
394
|
+
#### `extrude(extent: number | EndCondition, opts?: { twist?: number; divisions?: number; scaleTop?: number | Vec2; }): Shape` — Extrude this 2D sketch along Z to create a 3D solid. Supports twist and scale tapering. The extent may be a numeric height or an `EndCondition` (up to a face, plane, or vertex).
|
|
395
|
+
|
|
396
|
+
**`EndCondition`**
|
|
397
|
+
|
|
398
|
+
| Option | Type | Description |
|
|
399
|
+
|--------|------|-------------|
|
|
400
|
+
| `upToFace?` | `FaceRef \| SketchFaceTarget` | Terminate flush with a planar face perpendicular to the feature direction. |
|
|
401
|
+
| `upToPlane?` | `PlaneOp` | Terminate at an arbitrary plane (ray-plane intersection along the direction). |
|
|
402
|
+
| `upToVertex?` | `Vec3` | Terminate at the plane through this point, perpendicular to the direction. |
|
|
403
|
+
| `offset?` | `number` | Signed offset PAST the resolved surface in the travel direction (default 0). |
|
|
404
|
+
|
|
405
|
+
`FaceRef` — defined in [core](/docs/core).
|
|
406
|
+
|
|
407
|
+
**`PlaneOp`**
|
|
408
|
+
- `normal: Vec3` — Plane normal. Need not be unit length; it is normalized internally.
|
|
409
|
+
- `offset?: number` — Signed offset of the plane along its normal from the world origin (default 0).
|
|
395
410
|
|
|
396
411
|
#### `revolve(degrees?: number, segments?: number): Shape` — Revolve this 2D sketch around the world Z axis. Sketch X is radius; sketch Y becomes world Z height. Keep the profile at X > 0 unless it intentionally touches the axis.
|
|
397
412
|
|
|
@@ -412,8 +427,6 @@ const shifted = rect(4, 70).attachTo(plate, 'bottom-left', 'top-left', [5, 0]);
|
|
|
412
427
|
|
|
413
428
|
Use this when a 2D profile should be oriented onto a 3D face before extrusion or other downstream operations.
|
|
414
429
|
|
|
415
|
-
`FaceRef` — defined in [core](/docs/core).
|
|
416
|
-
|
|
417
430
|
**Labels**
|
|
418
431
|
|
|
419
432
|
#### `labelEdge(name: string): Sketch` — Label the single boundary edge (for circles, single-loop profiles). Returns a new sketch.
|
|
@@ -5,21 +5,21 @@ skill-order: 2
|
|
|
5
5
|
|
|
6
6
|
# Inspection Bundles — Evidence Contract
|
|
7
7
|
|
|
8
|
-
`forgecad inspect <family> <mode>` writes a deterministic bundle: evidence PNGs under `evidence/<type>/` plus a root `manifest.json`. **The manifest is the authoritative contract** — take file paths, encodings, per-view ranges, thresholds, tolerances, and identity maps from it; never hard-code bundle layout or infer object identity from object order. The PNGs are a visual index for locating findings, not standalone artifacts. Command tree, flags, and `--focus`/`--hide` filtering live in `docs/skill/CLI.md` and `forgecad inspect evidence`; the inspection workflow lives in
|
|
8
|
+
`forgecad inspect <family> <mode>` writes a deterministic bundle: evidence PNGs under `evidence/<type>/` plus a root `manifest.json`. **The manifest is the authoritative contract** — take file paths, encodings, per-view ranges, thresholds, tolerances, and identity maps from it; never hard-code bundle layout or infer object identity from object order. The PNGs are a visual index for locating findings, not standalone artifacts. Command tree, flags, and `--focus`/`--hide` filtering live in `docs/skill/CLI.md` and `forgecad inspect evidence`; the model-building inspection workflow lives in `forgecad-build-model/references/inspection-feedback.md`. Model-authored `scene()` background, lights, fog, and exposure are ignored for inspection captures so evidence stays stable; named scene views remain available via `--view`.
|
|
9
9
|
|
|
10
10
|
Manifest evidence keys are evidence-oriented and stable for bundle readers: e.g. `fit interference` writes `manifest.evidence.collisions`, `physical components` writes `manifest.evidence.connectivity`.
|
|
11
11
|
|
|
12
12
|
## Reading Rules
|
|
13
13
|
|
|
14
14
|
- **Identity evidence** (`objects`, `connectivity`, `distance`, `collisions`): colors are bundle-local labels. Resolve every color through the manifest; the same color never carries universal meaning across bundles. Edge pixels may be antialiased blends — match solid interior colors.
|
|
15
|
-
- **Metric evidence** (`depth`, `thickness`, `roughness`, `distance`, `comparison`): read manifest thresholds, ranges, object summaries, and warnings before judging a PNG by eye.
|
|
15
|
+
- **Metric evidence** (`depth`, `thickness`, `throughThickness`, `roughness`, `distance`, `comparison`): read manifest thresholds, ranges, object summaries, and warnings before judging a PNG by eye.
|
|
16
16
|
- Black pixels are background = `null` (in `floating`, black also means ground-reachable geometry).
|
|
17
17
|
- Treat unexpected collisions, critical thin regions, high unresolved thickness, wrong component counts, floating bodies, or surprising gaps as **model bugs to fix and reinspect** — not rendering noise.
|
|
18
18
|
- Use section evidence to inspect hidden internals; never turn the production model into a permanent cutaway.
|
|
19
19
|
|
|
20
20
|
## The Physical-Contact Model
|
|
21
21
|
|
|
22
|
-
Connectivity, floating, distance, and
|
|
22
|
+
Connectivity, floating, distance, thickness, and minimum-solid-span (`throughThickness`) all share one contact model:
|
|
23
23
|
|
|
24
24
|
- **Bbox is broadphase only.** Bbox overlap or bbox face contact never merges separate scene objects and is never support evidence.
|
|
25
25
|
- Mesh surfaces within the contact tolerance (see manifest) count as **physically connected**.
|
|
@@ -62,6 +62,8 @@ normal = normalize((rgb / 255) * 2 - 1)
|
|
|
62
62
|
|
|
63
63
|
**thickness** — area-weighted surface point samples cast through the object along their normals; red = below min, orange = below warn, green = acceptable, blue = above max (thresholds in manifest; override via CLI flags). Contact-seam rule: rays crossing into a direct physical-contact neighbor skip hits within contact tolerance and continue to the next surface, so a modeled micro-gap between touching parts doesn't read as a paper-thin wall. **Gray/unresolved area means the heatmap is incomplete, NOT that the model is safe** — open meshes, concave geometry, coarse tessellation, or low sample counts leave unresolved regions. A mesh/raycast approximation, not FEA. Also writes `evidence/thickness/point-cloud.json` with per-sample object identity, local position, normal, thickness, class, color, and represented area.
|
|
64
64
|
|
|
65
|
+
**throughThickness** — minimum solid span from each surface point. Instead of casting only along the local normal, it searches for the closest opposite boundary reachable by a segment that leaves the surface into occupied material; nearby exterior air gaps are rejected. This catches diagonal choke points and edge-near weak zones that normal thickness can miss. Uses the same threshold/color options as `thickness` in v1 and writes `evidence/through-thickness/point-cloud.json`.
|
|
66
|
+
|
|
65
67
|
**sections** — exact 2D contour slices, three explicit modes:
|
|
66
68
|
|
|
67
69
|
- `sections at` — one exact cut through a localized feature (`--plane yz --offset 12.5`).
|