forgecad 0.10.4 → 0.10.5
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-raksfnNA.js} +1 -1
- package/dist/assets/{BenchmarkPage-DXKVXMrJ.js → BenchmarkPage-DP3RxhPs.js} +2 -2
- package/dist/assets/{BlogPage-B7BWxOCg.js → BlogPage-D7Dos-vl.js} +1 -1
- package/dist/assets/{DocsPage-BPGGwht1.js → DocsPage-DO1kvBns.js} +7 -1
- package/dist/assets/{EditorApp-BWUGCdD5.js → EditorApp-DQJmcmRT.js} +9 -8
- package/dist/assets/{EmbedViewer-DygByZS2.js → EmbedViewer-DFDUhOma.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-BoVE7JGY.js → LandingPageProofDriven-DbE_tp8-.js} +2 -2
- package/dist/assets/{LegalPage-Din8wv8d.js → LegalPage-CominSso.js} +2 -2
- package/dist/assets/{PricingPage-C2PMzmDc.js → PricingPage-CcVIN9yj.js} +2 -2
- package/dist/assets/{SettingsPage-BlJDCRe8.js → SettingsPage-DLWcP289.js} +1 -1
- package/dist/assets/{app-BsRYSfxY.js → app-xW3hOdq9.js} +1135 -320
- package/dist/assets/{backendInit-6C0DLgH0.js → backendInit-mDHk97u7.js} +6630 -2493
- package/dist/assets/cli/{render-XXol_ET7.js → render--SIU27W_.js} +1263 -112
- package/dist/assets/{constructionHistoryWorker-cTHWRJEi.js → constructionHistoryWorker-uEe_Q7Kg.js} +1861 -610
- package/dist/assets/{evalWorker-BssDYW9u.js → evalWorker-BqyDHDcI.js} +6254 -2177
- 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-UXMxlcR8.js} +2738 -742
- package/dist/assets/{jointPose-B0blBj9A.js → jointPose-bYMlwU3v.js} +1 -1
- package/dist/assets/{landing-proof-driven-Cpf-MIbI.css → landing-proof-driven-_u4v_xQb.css} +2 -2
- package/dist/assets/{manifold-B_7QXpGB.js → manifold-BR7UYI4P.js} +1 -1
- package/dist/assets/{manifold-CYlIm-M6.js → manifold-CyOV5B9S.js} +2 -2
- package/dist/assets/{manifold-CNShmpEJ.js → manifold-D4d5NQst.js} +1 -1
- package/dist/assets/{reportWorker-Cb5eyM7D.js → reportWorker-DsaICZsn.js} +6010 -2032
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/CLI.md +4 -2
- package/dist/docs-raw/generated/assembly.md +76 -3
- package/dist/docs-raw/generated/concepts.md +31 -4
- package/dist/docs-raw/generated/core.md +159 -21
- package/dist/docs-raw/generated/curves.md +344 -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 +4 -2
- package/dist/docs-raw/guides/structural-fea.md +224 -0
- package/dist/docs-raw/skills/forgecad.md +1 -0
- package/dist/index.html +1 -1
- package/dist/sitemap.xml +15 -15
- package/dist-cli/{check-compiler-4RPB6SB5.js → check-compiler-7YAHVXYM.js} +1 -1
- package/dist-cli/{check-query-propagation-KN3DFQTX.js → check-query-propagation-ZRR6IOJW.js} +1 -1
- package/dist-cli/{chunk-UHBRMYA6.js → chunk-VNM67DIV.js} +6489 -2333
- package/dist-cli/forgecad.js +5258 -717
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +827 -45
- package/dist-skill/SKILL.md +1 -0
- package/dist-skill/docs/CLI.md +4 -2
- package/dist-skill/docs/generated/assembly.md +73 -3
- package/dist-skill/docs/generated/core.md +159 -21
- package/dist-skill/docs/generated/curves.md +343 -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 +4 -2
- package/dist-skill/docs/guides/structural-fea.md +224 -0
- package/dist-skill/website/skills/forgecad.md +1 -0
- 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/spoon-full-tang-handle.forge.js +148 -0
- package/examples/api/surface-boundarynet-dished-bowl.forge.js +63 -0
- package/examples/api/surface-fill-interior-constraints.forge.js +59 -0
- package/package.json +4 -1
- /package/dist/assets/{landing-proof-driven-BxZZh5r5.js → landing-proof-driven-DNPRKL_p.js} +0 -0
package/dist-skill/SKILL.md
CHANGED
|
@@ -107,6 +107,7 @@ Test-run, export pipelines, debug flags.
|
|
|
107
107
|
|
|
108
108
|
- `{{SKILL_DIR}}/docs/CLI.md`
|
|
109
109
|
- `{{SKILL_DIR}}/docs/guides/inspection-bundles.md`
|
|
110
|
+
- `{{SKILL_DIR}}/docs/guides/structural-fea.md`
|
|
110
111
|
|
|
111
112
|
### SDF Modeling (smooth booleans, TPMS, deformations, fromFunction)
|
|
112
113
|
|
package/dist-skill/docs/CLI.md
CHANGED
|
@@ -136,7 +136,8 @@ Inspect a model by asking for one explicit kind of evidence.
|
|
|
136
136
|
- `inspect surface zebra|roughness` — surface continuity and roughness evidence
|
|
137
137
|
- `inspect physical components|floating|gaps` — physical component graph evidence
|
|
138
138
|
- `inspect fit interference` — positive-volume overlap evidence
|
|
139
|
-
- `inspect manufacture thickness` — wall-thickness evidence
|
|
139
|
+
- `inspect manufacture thickness|through-thickness` — wall-thickness and minimum solid span evidence
|
|
140
|
+
- `inspect structural stress` — solver-produced structural stress scalar-field evidence
|
|
140
141
|
- `inspect compare overlay` — candidate-vs-reference visual mismatch evidence
|
|
141
142
|
- `inspect sections at|stack|sample` — exact section evidence for precise cuts, dense scans, or sparse samples
|
|
142
143
|
- `inspect mechanical-integrity` — model-focused integrity audit for generated assemblies
|
|
@@ -292,6 +293,7 @@ Export to every format you need.
|
|
|
292
293
|
| `export svg` | SVG | 2D vector output from sketches |
|
|
293
294
|
| `export sketch-pdf` **\[Production\]** | PDF | Sketch with dimensions and constraints |
|
|
294
295
|
| `export step` **\[Production\]** | STEP | CAD interchange (exact geometry) |
|
|
296
|
+
| `export fea` **\[Production\]** | FEA package | Exact STEP plus authored structural load-case metadata |
|
|
295
297
|
| `export brep` **\[Production\]** | BREP | Boundary representation |
|
|
296
298
|
| `export 3mf` | 3MF | 3D printing (color, multi-part) |
|
|
297
299
|
| `export stl` | STL | 3D printing |
|
|
@@ -543,7 +545,7 @@ The CLI is free for personal non-commercial use. Pro covers human-operated comme
|
|
|
543
545
|
|
|
544
546
|
| Free | Production outputs | Pro | Enterprise |
|
|
545
547
|
|------|--------------------|-----|------------|
|
|
546
|
-
| `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `compare 3d`, `check print`, `inspect fit interference`, `inspect mechanical-integrity` for personal non-commercial use | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export implicit`, `export sdf`, `export mjcf`, `export urdf`, `export usd`, `export report`, `export cutting-layout` are free to run for personal non-commercial use; Pro covers human-operated commercial CAD work | `render hq`, `capture gif`, `capture mp4` plus commercial coverage for client/customer work | Backend, hosted, embedded, or application workflows that call ForgeCAD automatically |
|
|
548
|
+
| `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `compare 3d`, `check print`, `inspect fit interference`, `inspect mechanical-integrity` for personal non-commercial use | `cut-list`, `export sketch-pdf`, `export step`, `export fea`, `export brep`, `export gcode`, `export implicit`, `export sdf`, `export mjcf`, `export urdf`, `export usd`, `export report`, `export cutting-layout` are free to run for personal non-commercial use; Pro covers human-operated commercial CAD work | `render hq`, `capture gif`, `capture mp4` plus commercial coverage for client/customer work | Backend, hosted, embedded, or application workflows that call ForgeCAD automatically |
|
|
547
549
|
|
|
548
550
|
```bash
|
|
549
551
|
forgecad license # Check local license status
|
|
@@ -26,12 +26,14 @@ Assembly-owned links, constraints, connectors, solved poses, and source-level si
|
|
|
26
26
|
|
|
27
27
|
#### `Sim.body(options: SimBodyOptions): SimBodyDef` — Describe one assembly part as a physical body with mass/density, material, collider intent, and optional contact surfaces.
|
|
28
28
|
|
|
29
|
-
**`SimBodyOptions`**: `massKg?: number`, `densityKgM3?: number`, `material?: SimMaterialDef`, `collider?: SimColliderDef`, `contacts?: Record<string, SimContactDef
|
|
29
|
+
**`SimBodyOptions`**: `massKg?: number`, `densityKgM3?: number`, `material?: SimMaterialDef`, `collider?: SimColliderDef`, `contacts?: Record<string, SimContactDef>`, `motion?: SimMotionDef`
|
|
30
30
|
|
|
31
|
-
`SimColliderDef`: `{ kind: "collider", mode: SimColliderMode, reason?: string }`
|
|
31
|
+
`SimColliderDef`: `{ kind: "collider", mode: SimColliderMode, reason?: string, sdfResolution?: number }`
|
|
32
32
|
|
|
33
33
|
`SimContactDef`: `{ kind: "wheelSurface" | "gripperSurface", connectorName: string }`
|
|
34
34
|
|
|
35
|
+
`SimMotionDef`: `{ kind: "motion", mode: SimMotionMode }`
|
|
36
|
+
|
|
35
37
|
`SimBodyDef`: `{ kind: "body" }`
|
|
36
38
|
|
|
37
39
|
#### `Sim.collider` — Collision-geometry intent constructors for physical parts.
|
|
@@ -39,8 +41,15 @@ Assembly-owned links, constraints, connectors, solved poses, and source-level si
|
|
|
39
41
|
- `Sim.collider.convexHull(): SimColliderDef` — Use a generated collision mesh for the part. This is the default fast rigid-body collider for irregular parts.
|
|
40
42
|
- `Sim.collider.boundingBox(): SimColliderDef` — Use the part bounding box as the collision geometry. This is fastest and works well for chassis and simple blocks.
|
|
41
43
|
- `Sim.collider.visualMesh(): SimColliderDef` — Use the visual mesh as collision geometry. This is exact but usually slower in physics engines.
|
|
44
|
+
- `Sim.collider.sdfMesh: (options?: { resolution?: number` — Use an SDF mesh collider for complex concave contact geometry. Exporters warn when their target cannot encode it.
|
|
42
45
|
- `Sim.collider.none(reason: string): SimColliderDef` — Disable collision for a part with an explicit reason, such as a sensor-only or decorative object.
|
|
43
46
|
|
|
47
|
+
#### `Sim.motion` — Body motion-state intent for simulation export. Dynamic is the default when omitted.
|
|
48
|
+
|
|
49
|
+
- `Sim.motion.dynamic(): SimMotionDef` — Simulate this body as a normal dynamic rigid body with mass and inertia.
|
|
50
|
+
- `Sim.motion.kinematic(): SimMotionDef` — Simulate this body as kinematic: moved by the simulator/user, but not force-integrated.
|
|
51
|
+
- `Sim.motion.static(): SimMotionDef` — Keep this body fixed in the world as a static collision/environment body.
|
|
52
|
+
|
|
44
53
|
#### `Sim.drive` — Joint-drive intent constructors for passive or powered assembly joints.
|
|
45
54
|
|
|
46
55
|
- `Sim.drive.passive(options?: SimPassiveDriveOptions): SimDriveDef` — Mark a joint as passive while preserving damping and friction metadata for simulation export.
|
|
@@ -71,6 +80,57 @@ Assembly-owned links, constraints, connectors, solved poses, and source-level si
|
|
|
71
80
|
|
|
72
81
|
`SimDiffDriveControllerDef`: `{ kind: "diffDrive" }`
|
|
73
82
|
|
|
83
|
+
#### `Fea.material(name: string, options: FeaMaterialOptions): FeaMaterialDef` — Create a named linear-elastic structural material for static stress studies.
|
|
84
|
+
|
|
85
|
+
#### `Fea.body(options: FeaBodyOptions): FeaBodyDef` — Mark one assembly part as a structural body with a `Fea.material(...)` value.
|
|
86
|
+
|
|
87
|
+
#### `Fea.region` — Stable explicit region references for solver package manifests.
|
|
88
|
+
|
|
89
|
+
- `Fea.region.face(partName: string, faceName: string): FeaPartFaceRegionRef` — Reference a named face on a named assembly part without relying on object identity.
|
|
90
|
+
- `Fea.region.plane(partName: string, faceName: string, options: FeaPlaneRegionOptions): FeaPartPlaneRegionRef` — Reference a planar face by a point on the face and its outward normal in part-local coordinates.
|
|
91
|
+
|
|
92
|
+
`FeaPartFaceRegionRef`: `{ kind: "fea-region-face", partName: string, faceName: string }`
|
|
93
|
+
|
|
94
|
+
`FeaPlaneRegionOptions`: `{ center: Vec3, normal: Vec3 }`
|
|
95
|
+
|
|
96
|
+
`FeaPartPlaneRegionRef`: `{ kind: "fea-region-plane", partName: string, faceName: string, center: Vec3, normal: Vec3 }`
|
|
97
|
+
|
|
98
|
+
#### `Fea.fix` — Fixture constructors over authored face/region references.
|
|
99
|
+
|
|
100
|
+
- `Fea.fix.fixed(region: FeaRegionRef): FeaFixedFixtureDef` — Fully fix all translational degrees of freedom on a face/region.
|
|
101
|
+
|
|
102
|
+
`FeaFixedFixtureDef`: `{ kind: "fixed", region: FeaRegionRef }`
|
|
103
|
+
|
|
104
|
+
#### `Fea.load` — Load constructors over authored face/region references.
|
|
105
|
+
|
|
106
|
+
- `Fea.load.force(region: FeaRegionRef, options: FeaForceLoadOptions): FeaForceLoadDef` — Apply a force with magnitude in newtons along the given direction vector.
|
|
107
|
+
|
|
108
|
+
`FeaForceLoadOptions`: `{ newtons: number, direction: Vec3 }`
|
|
109
|
+
|
|
110
|
+
`FeaForceLoadDef`: `{ kind: "force", region: FeaRegionRef }`
|
|
111
|
+
|
|
112
|
+
#### `Fea.target` — Study target constructors used by feedback and pass/fail gates.
|
|
113
|
+
|
|
114
|
+
- `Fea.target.minSafetyFactor(value: number): FeaMinSafetyFactorTargetDef` — Require the solved minimum safety factor to be at least `value`.
|
|
115
|
+
|
|
116
|
+
`FeaMinSafetyFactorTargetDef`: `{ kind: "minSafetyFactor", value: number }`
|
|
117
|
+
|
|
118
|
+
#### `Fea.mesh` — Volume mesh intent. V1 structural stress uses second-order tetrahedra only.
|
|
119
|
+
|
|
120
|
+
- `Fea.mesh.quadraticTets(options: FeaQuadraticTetMeshOptions): FeaQuadraticTetMeshDef` — Request quadratic tetrahedral C3D10 elements with a maximum size in mm.
|
|
121
|
+
|
|
122
|
+
`FeaQuadraticTetMeshOptions`: `{ maxSizeMm: number, minQuality?: number }`
|
|
123
|
+
|
|
124
|
+
`FeaQuadraticTetMeshDef`: `{ kind: "quadraticTets", order: 2, element: "C3D10" }`
|
|
125
|
+
|
|
126
|
+
#### `Fea.study` — Study constructors.
|
|
127
|
+
|
|
128
|
+
- `Fea.study.staticStress(name: string, options: FeaStaticStressStudyOptions): FeaStaticStressStudyDef` — Create a linear static structural stress study.
|
|
129
|
+
|
|
130
|
+
`FeaStaticStressStudyOptions`: `{ fixtures: FeaFixtureDef[], loads: FeaLoadDef[], target?: FeaTargetDef, mesh: FeaMeshDef }`
|
|
131
|
+
|
|
132
|
+
`FeaStaticStressStudyDef`: `{ kind: "staticStress", name: string }`
|
|
133
|
+
|
|
74
134
|
#### `assembly(name?: string): Assembly` — Create an assembly container with named parts, connectors, and kinematic links.
|
|
75
135
|
|
|
76
136
|
**Use this from iteration 1 for any model with moving parts.** Do not build one static pose and retrofit motion later.
|
|
@@ -204,7 +264,7 @@ const housing = group(
|
|
|
204
264
|
assembly.addPart("Base Assembly", housing);
|
|
205
265
|
```
|
|
206
266
|
|
|
207
|
-
**`PartOptions`**: `transform?: TransformInput`, `metadata?: PartMetadata`, `sim?: SimBodyDef`, `mate?: AssemblyPartMateInput | AssemblyPartMateInput[]`, `bindToFrame?: string`
|
|
267
|
+
**`PartOptions`**: `transform?: TransformInput`, `metadata?: PartMetadata`, `sim?: SimBodyDef`, `fea?: FeaBodyDef`, `mate?: AssemblyPartMateInput | AssemblyPartMateInput[]`, `bindToFrame?: string`
|
|
208
268
|
|
|
209
269
|
**`PartMetadata`**
|
|
210
270
|
|
|
@@ -214,6 +274,12 @@ assembly.addPart("Base Assembly", housing);
|
|
|
214
274
|
|
|
215
275
|
Also: `material?: string`, `process?: string`, `tolerance?: string`, `qty?: number`, `notes?: string`, `densityKgM3?: number`, `massKg?: number`.
|
|
216
276
|
|
|
277
|
+
`FeaBodyDef`: `{ kind: "fea-body", material: FeaMaterialDef }`
|
|
278
|
+
|
|
279
|
+
`FeaMaterialOptions`: `{ densityKgM3: number, youngsModulusMPa: number, poissonRatio: number, yieldStrengthMPa: number }`
|
|
280
|
+
|
|
281
|
+
`FeaMaterialDef`: `{ kind: "fea-material", name: string }`
|
|
282
|
+
|
|
217
283
|
**`AssemblyPartMateInput`**
|
|
218
284
|
- `connector: string` — Name of a connector declared on the part (via `withConnectors()`).
|
|
219
285
|
- `toLink: string` — Name of the link this connector's origin is pinned to.
|
|
@@ -360,6 +426,10 @@ Use this after adding physical parts and joints. Robot-body profiles require `ro
|
|
|
360
426
|
|
|
361
427
|
`SimAssemblySimulationOptions`: `{ profile: SimProfileDef, rootPart?: string, controllers?: SimControllerDef[] }`
|
|
362
428
|
|
|
429
|
+
#### `withFeaStudy(study: FeaStudyDef): Assembly` — Attach a structural FEA study to this assembly.
|
|
430
|
+
|
|
431
|
+
The study is authored with `Fea.study.staticStress(...)` and consumed by `forgecad export fea`. This records load-case intent only; ForgeCAD refuses to invent fixtures, loads, mesh order, or region tags during export.
|
|
432
|
+
|
|
363
433
|
#### `edgeBetweenFrames(a: string, b: string, options?: AssemblyFrameEdgeOptions): Assembly` — Add a visual skeleton edge between two rig frame origins.
|
|
364
434
|
|
|
365
435
|
Frame edges follow the solved frame poses produced by `fixedJoint()`, `revoluteJoint()`, and `prismaticJoint()`. They do not add constraints, degrees of freedom, parts, or geometry; use them to make a frame-only rig readable in the Motion/rig inspection overlay.
|
|
@@ -18,13 +18,12 @@ skill-order: 100
|
|
|
18
18
|
- [Grouping & Local Coordinates](#grouping-local-coordinates)
|
|
19
19
|
- [Section & Projection](#section-projection)
|
|
20
20
|
- [Verification](#verification)
|
|
21
|
-
- [Shape](#shape) — Appearance, Face Topology, Edge Topology, Transforms, Booleans & Cutting, Features, Placement, Connectors, References, Measurement
|
|
21
|
+
- [Shape](#shape) — Freeform Construction, Appearance, Face Topology, Edge Topology, Transforms, Booleans & Cutting, Features, Placement, Connectors, References, Measurement
|
|
22
22
|
- [Transform](#transform)
|
|
23
23
|
- [ShapeGroup](#shapegroup) — Children, Transforms, Placement, Connectors, References
|
|
24
24
|
- [SurfacePattern](#surfacepattern)
|
|
25
25
|
- [Pattern2D](#pattern2d)
|
|
26
26
|
- [Pattern2DBuilder](#pattern2dbuilder)
|
|
27
|
-
- [Sheet](#sheet)
|
|
28
27
|
- [CurveNetBuilder](#curvenetbuilder)
|
|
29
28
|
- [MatchEdgeBuilder](#matchedgebuilder)
|
|
30
29
|
- [BridgeBuilder](#bridgebuilder)
|
|
@@ -705,6 +704,96 @@ Supports transforms (translate, rotate, scale, mirror, transform, rotateAround,
|
|
|
705
704
|
|----------|------|-------------|
|
|
706
705
|
| `materialProps` | `ShapeMaterialProps \| undefined` | — |
|
|
707
706
|
|
|
707
|
+
**Freeform Construction**
|
|
708
|
+
|
|
709
|
+
#### `slicePerpendicularToX(x: number, profile: Sketch, options?: FromSlicesAxisSliceOptions): FromSlicesSlice` — Create a slice descriptor perpendicular to the X axis.
|
|
710
|
+
|
|
711
|
+
The profile is drawn in the YZ plane. `options.center` is `[y, z]`, so authors can place changing section centers without manually translating sketches in ForgeCAD's internal plane axes.
|
|
712
|
+
|
|
713
|
+
```js
|
|
714
|
+
Shape.fromSlices([
|
|
715
|
+
Shape.slicePerpendicularToX(-20, ellipse(10, 2), { center: [0, 3] }),
|
|
716
|
+
Shape.slicePerpendicularToX(20, ellipse(8, 1.5), { center: [0, 6] }),
|
|
717
|
+
]);
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
**`FromSlicesAxisSliceOptions`**
|
|
721
|
+
- `center?: FromSlicesVec2` — Plane-local profile center. XY uses [x, y], XZ uses [x, z], YZ uses [y, z].
|
|
722
|
+
|
|
723
|
+
#### `slicePerpendicularToY(y: number, profile: Sketch, options?: FromSlicesAxisSliceOptions): FromSlicesSlice` — Create a slice descriptor perpendicular to the Y axis.
|
|
724
|
+
|
|
725
|
+
The profile is drawn in the XZ plane. `options.center` is `[x, z]`.
|
|
726
|
+
|
|
727
|
+
#### `slicePerpendicularToZ(z: number, profile: Sketch, options?: FromSlicesAxisSliceOptions): FromSlicesSlice` — Create a slice descriptor perpendicular to the Z axis.
|
|
728
|
+
|
|
729
|
+
The profile is drawn in the XY plane. `options.center` is `[x, y]`.
|
|
730
|
+
|
|
731
|
+
#### `sliceThrough(center: FromSlicesVec3, normal: FromSlicesVec3, profile: Sketch): FromSlicesSlice` — Create a slice descriptor through a world point with an arbitrary plane normal.
|
|
732
|
+
|
|
733
|
+
The profile origin lands at `center`. Use this when the section plane is not one of the world XY/XZ/YZ planes.
|
|
734
|
+
|
|
735
|
+
#### `sliceOnFrame(frame: FromSlicesFrameInput, profile: Sketch): FromSlicesSlice` — Create a slice descriptor on a full 3D work frame.
|
|
736
|
+
|
|
737
|
+
Sheet frame helpers return the right shape for `frame`. Use `Sheet.frameAt()` for tangent construction planes, or `Sheet.framePerpendicularToU()` / `Sheet.framePerpendicularToV()` for cross-sections normal to a surface path. On the Manifold backend, framed slices are lofted in input order when every slice comes from a frame.
|
|
738
|
+
|
|
739
|
+
**`FromSlicesFrameInput`**
|
|
740
|
+
|
|
741
|
+
| Option | Type | Description |
|
|
742
|
+
|--------|------|-------------|
|
|
743
|
+
| `point?` | `FromSlicesVec3` | World-space frame origin. Sheet frame helpers return this as `point`. |
|
|
744
|
+
| `origin?` | `FromSlicesVec3` | Alias for `point` when using generic CAD frame terminology. |
|
|
745
|
+
| `normal` | `FromSlicesVec3` | World-space frame normal. |
|
|
746
|
+
| `tangentU?` | `FromSlicesVec3` | World-space direction for the profile's local X axis. Sheet frame helpers return this as `tangentU`. |
|
|
747
|
+
| `tangentV?` | `FromSlicesVec3` | Optional world-space direction for the profile's local Y axis. Sheet frame helpers return this as `tangentV`. |
|
|
748
|
+
| `xAxis?` | `FromSlicesVec3` | Alias for `tangentU`. |
|
|
749
|
+
| `yAxis?` | `FromSlicesVec3` | Alias for `tangentV`. |
|
|
750
|
+
|
|
751
|
+
#### `fromSlices(slices: FromSlicesSlice[], options?: FromSlicesOptions): Shape` — Construct a 3D shape from cross-section slices on one or more planes.
|
|
752
|
+
|
|
753
|
+
On the Manifold backend, slices created with `Shape.sliceOnFrame()` are lofted in their input order while preserving each full 3D frame. Other slices with the same normal direction are lofted together. Slices with different normals are combined via smooth radial blending — each silhouette constrains the shape's extent, producing smooth ellipsoidal cross-sections.
|
|
754
|
+
|
|
755
|
+
```js
|
|
756
|
+
// Egg from two orthogonal silhouettes
|
|
757
|
+
const eggProfile = ellipse(15, 25);
|
|
758
|
+
return Shape.fromSlices([
|
|
759
|
+
{ on: 'xz', at: 0, profile: eggProfile },
|
|
760
|
+
{ on: 'yz', at: 0, profile: eggProfile },
|
|
761
|
+
]);
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
```js
|
|
765
|
+
// Vase with cross-section transitions
|
|
766
|
+
return Shape.fromSlices([
|
|
767
|
+
Shape.slicePerpendicularToZ(0, circle2d(20)),
|
|
768
|
+
Shape.slicePerpendicularToZ(40, rect(25, 25)),
|
|
769
|
+
Shape.slicePerpendicularToZ(80, circle2d(8)),
|
|
770
|
+
Shape.slicePerpendicularToY(0, vaseOutline),
|
|
771
|
+
]);
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
**`FromSlicesSlice`**
|
|
775
|
+
|
|
776
|
+
| Option | Type | Description |
|
|
777
|
+
|--------|------|-------------|
|
|
778
|
+
| `on` | `SlicePlane` | Plane normal: axis name or arbitrary unit vector. |
|
|
779
|
+
| `at?` | `number` | Signed offset along the normal from the origin. Omit when `center` defines the plane. |
|
|
780
|
+
| `center?` | `FromSlicesVec3` | World-space point where the 2D profile origin should land on the slice plane. |
|
|
781
|
+
| `profile` | `Sketch` | 2D cross-section profile on that plane. |
|
|
782
|
+
| `frame?` | `FromSlicesFramePlacement` | Full 3D section frame, preserved for ordered lofts through rotating planes. |
|
|
783
|
+
|
|
784
|
+
**`FromSlicesFramePlacement`**
|
|
785
|
+
|
|
786
|
+
| Option | Type | Description |
|
|
787
|
+
|--------|------|-------------|
|
|
788
|
+
| `point` | `FromSlicesVec3` | World-space frame origin. |
|
|
789
|
+
| `normal` | `FromSlicesVec3` | World-space section normal. |
|
|
790
|
+
| `tangentU` | `FromSlicesVec3` | World-space direction for the profile's local X axis. |
|
|
791
|
+
| `tangentV` | `FromSlicesVec3` | World-space direction for the profile's local Y axis. |
|
|
792
|
+
|
|
793
|
+
**`FromSlicesOptions`**
|
|
794
|
+
- `edgeLength?: number` — Marching-grid edge length for level-set meshing (Manifold only).
|
|
795
|
+
- `boundsPadding?: number` — Extra bounding-box padding (Manifold only).
|
|
796
|
+
|
|
708
797
|
**Appearance**
|
|
709
798
|
|
|
710
799
|
#### `color(value: string | undefined): Shape` — Set the color of this shape (hex string, e.g. "#ff0000"). Returns a new Shape with the color applied.
|
|
@@ -1355,57 +1444,106 @@ const bracket = group(
|
|
|
1355
1444
|
| `depth?` | `number` | Thread groove depth in millimeters. Default: 0.8. |
|
|
1356
1445
|
| `underScale?` | `number` | Relative height of the under-crossing thread. Default: 0.15. |
|
|
1357
1446
|
|
|
1358
|
-
### `
|
|
1447
|
+
### `CurveNetBuilder`
|
|
1359
1448
|
|
|
1360
|
-
|
|
1449
|
+
#### `alongRails(railA: CurveInput, railB: CurveInput): this` — Use two lengthwise boundary curves as guide rails.
|
|
1361
1450
|
|
|
1362
|
-
|
|
1451
|
+
Chain `.sections(...)` to create a bi-rail surface: the rails define the sheet edges while each section curve shapes the cross-span at its station.
|
|
1363
1452
|
|
|
1364
|
-
|
|
1365
|
-
|----------|------|-------------|
|
|
1366
|
-
| `surface` | `BSplineSurface` | — |
|
|
1453
|
+
#### `sections(...curves: CurveInput[]): this` — Add crosswise section curves.
|
|
1367
1454
|
|
|
1368
|
-
|
|
1455
|
+
By itself this skins the sections into a surface. After `.alongRails(...)`, the sections are fitted between the two rails so the surface follows both the boundary guide curves and the section profiles.
|
|
1369
1456
|
|
|
1370
|
-
#### `
|
|
1457
|
+
#### `resolution(samples: number): this` — Set the sampling resolution used to build curve-family surface grids.
|
|
1371
1458
|
|
|
1372
|
-
|
|
1459
|
+
This affects `.lengthwise(...)`, `.crosswise(...)`, and `.alongRails(...).sections(...)` surfaces. It does not resample explicit `.cage(grid)` input because the cage already is the authored control net.
|
|
1373
1460
|
|
|
1374
|
-
#### `
|
|
1461
|
+
#### `matchStartU(condition: BoundaryCondition): this` — Enforce a continuity condition on the `u = 0` (left) boundary.
|
|
1462
|
+
|
|
1463
|
+
Pass `{ edge }` to match an adjacent sheet's tangent (G1) or curvature (G2), or `{ tangent }` to impose an explicit cross-boundary direction. See `BoundaryCondition`.
|
|
1464
|
+
|
|
1465
|
+
**`BoundaryCondition`**
|
|
1466
|
+
|
|
1467
|
+
| Option | Type | Description |
|
|
1468
|
+
|--------|------|-------------|
|
|
1469
|
+
| `edge?` | `SheetEdge` | Match the tangent (G1) and curvature (G2) of an existing sheet edge across this boundary. |
|
|
1470
|
+
| `tangent?` | `Vec3` | Or impose an explicit cross-boundary tangent direction in world space (auto-normalized). |
|
|
1471
|
+
| `tangentScale?` | `number` | Scalar magnitude for the imposed `tangent` ramp, in model units. Ignored when `edge` is given. Default: the local cross-boundary control-span length (chord-scaled), so the imposed tangent has the same strength as the surface already carries — no magic number. |
|
|
1472
|
+
| `continuity?` | `0 \| 1 \| 2` | Continuity order to enforce on this side. Default inferred: 1 if a tangent or edge is given, else 0. G2 (curvature) requires an `edge` to copy the neighbor's second difference. |
|
|
1375
1473
|
|
|
1376
1474
|
**`SheetEdge`**
|
|
1377
1475
|
- `fixed: "u" | "v"` — Which parameter is held fixed along this edge.
|
|
1378
1476
|
- `value: 0 | 1` — The fixed value (0 or 1).
|
|
1379
1477
|
- Also: `sheet: Sheet`.
|
|
1380
1478
|
|
|
1381
|
-
|
|
1382
|
-
- `get leftEdge(): SheetEdge`
|
|
1383
|
-
- `get rightEdge(): SheetEdge`
|
|
1384
|
-
- `pointAt(u: number, v: number): Vec3`
|
|
1385
|
-
- `normalAt(u: number, v: number): Vec3`
|
|
1386
|
-
- `curvatureAt(u: number, v: number): SurfaceCurvature`
|
|
1479
|
+
#### `matchEndU(condition: BoundaryCondition): this` — Enforce a continuity condition on the `u = 1` (right) boundary. See `matchStartU`.
|
|
1387
1480
|
|
|
1388
|
-
|
|
1481
|
+
#### `matchStartV(condition: BoundaryCondition): this` — Enforce a continuity condition on the `v = 0` (front) boundary. See `matchStartU`.
|
|
1482
|
+
|
|
1483
|
+
#### `matchEndV(condition: BoundaryCondition): this` — Enforce a continuity condition on the `v = 1` (rear) boundary. See `matchStartU`.
|
|
1484
|
+
|
|
1485
|
+
#### `closedU(): this` — Weld the two ends of the U direction into a tangent-continuous periodic loop, so the `u = 0` and `u = 1` boundaries coincide with NO G0 kink (a closed tube/ring in U — e.g. a bowl's around-rim seam). The cage's first and last U rows must already be coincident (the loop must close in position).
|
|
1486
|
+
|
|
1487
|
+
#### `closedV(): this` — Weld the two ends of the V direction into a tangent-continuous periodic loop. See `closedU`.
|
|
1389
1488
|
|
|
1390
1489
|
#### `toSheet(): Sheet` — Build (once) and return the Sheet.
|
|
1391
1490
|
|
|
1392
1491
|
- `lengthwise(...curves: CurveInput[]): this`
|
|
1393
1492
|
- `crosswise(...curves: CurveInput[]): this`
|
|
1394
|
-
- `alongRails(railA: CurveInput, railB: CurveInput): this`
|
|
1395
|
-
- `sections(...curves: CurveInput[]): this`
|
|
1396
1493
|
- `cage(grid: Vec3[][]): this`
|
|
1397
1494
|
- `degree(u: number, v: number): this`
|
|
1398
1495
|
- `get frontEdge(): SheetEdge`
|
|
1399
1496
|
- `get rearEdge(): SheetEdge`
|
|
1400
1497
|
- `get leftEdge(): SheetEdge`
|
|
1401
1498
|
- `get rightEdge(): SheetEdge`
|
|
1499
|
+
- `get frontCurve(): NurbsCurve3D`
|
|
1500
|
+
- `get rearCurve(): NurbsCurve3D`
|
|
1501
|
+
- `get leftCurve(): NurbsCurve3D`
|
|
1502
|
+
- `get rightCurve(): NurbsCurve3D`
|
|
1402
1503
|
- `get surface(): BSplineSurface`
|
|
1403
1504
|
- `pointAt(u: number, v: number): Vec3`
|
|
1404
1505
|
- `normalAt(u: number, v: number): Vec3`
|
|
1506
|
+
- `frameAt(u: number, v: number, options?: SheetFrameOptions): SheetFrame`
|
|
1507
|
+
- `framePerpendicularToU(u: number, v: number, options?: SheetFrameOptions): SheetFrame`
|
|
1508
|
+
- `framePerpendicularToV(u: number, v: number, options?: SheetFrameOptions): SheetFrame`
|
|
1405
1509
|
- `curvatureAt(u: number, v: number): SurfaceCurvature`
|
|
1510
|
+
- `curveAlong(edge: SheetEdge): NurbsCurve3D`
|
|
1511
|
+
- `curveAlongU(v: number): NurbsCurve3D`
|
|
1512
|
+
- `curveAlongV(u: number): NurbsCurve3D`
|
|
1513
|
+
- `pathAlong(edge: SheetEdge, options?: SheetPathAlongOptions): Vec3[]`
|
|
1514
|
+
- `pathAlongBoundary(spans: SheetBoundaryPathSpan[], options?: SheetBoundaryPathOptions): Vec3[]`
|
|
1515
|
+
- `pathAlongU(v: number, options?: SheetPathAlongOptions): Vec3[]`
|
|
1516
|
+
- `pathAlongV(u: number, options?: SheetPathAlongOptions): Vec3[]`
|
|
1406
1517
|
- `thicken(wall: number, options?: { resolution?: number; }): Shape`
|
|
1407
1518
|
- `matchEdge(edge: SheetEdge): MatchEdgeBuilder`
|
|
1408
1519
|
|
|
1520
|
+
**`SheetFrameOptions`**
|
|
1521
|
+
- `normalOffset?: number` — Offset the frame origin along the analytic surface normal. Default 0.
|
|
1522
|
+
|
|
1523
|
+
**`SheetPathAlongOptions`**
|
|
1524
|
+
|
|
1525
|
+
| Option | Type | Description |
|
|
1526
|
+
|--------|------|-------------|
|
|
1527
|
+
| `samples?` | `number` | Samples along the path span. Default 32. |
|
|
1528
|
+
| `start?` | `number` | Normalized start parameter along the path. Default 0. |
|
|
1529
|
+
| `end?` | `number` | Normalized end parameter along the path. Default 1. |
|
|
1530
|
+
| `reverse?` | `boolean` | Return points from end to start after sampling the span. Default false. |
|
|
1531
|
+
| `normalOffset?` | `number` | Offset each path point along the analytic surface normal. Default 0. |
|
|
1532
|
+
|
|
1533
|
+
**`SheetBoundaryPathSpan`**
|
|
1534
|
+
|
|
1535
|
+
| Option | Type | Description |
|
|
1536
|
+
|--------|------|-------------|
|
|
1537
|
+
| `edge` | `SheetEdge` | Boundary edge to sample for this span. |
|
|
1538
|
+
| `start?` | `SheetPathParameter` | Normalized edge parameter or world point projected to the closest edge parameter. Default 0. |
|
|
1539
|
+
| `end?` | `SheetPathParameter` | Normalized edge parameter or world point projected to the closest edge parameter. Default 1. |
|
|
1540
|
+
| `samples?` | `number` | Samples along this edge span. Defaults to options.samplesPerEdge or 32. |
|
|
1541
|
+
|
|
1542
|
+
**`SheetBoundaryPathOptions`**
|
|
1543
|
+
- `samplesPerEdge?: number` — Samples for spans that do not specify their own count. Default 32.
|
|
1544
|
+
- `normalOffset?: number` — Offset each path point along the analytic surface normal. Default 0.
|
|
1545
|
+
- `tolerance?: number` — Maximum allowed gap between adjacent sampled spans. Default 1e-6.
|
|
1546
|
+
|
|
1409
1547
|
### `MatchEdgeBuilder`
|
|
1410
1548
|
|
|
1411
1549
|
- `toG0(neighbor: SheetEdge): Sheet`
|