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,28 +9,24 @@ skill-order: 100
|
|
|
9
9
|
|
|
10
10
|
## Contents
|
|
11
11
|
|
|
12
|
-
- [3D Primitives](#3d-primitives)
|
|
13
|
-
- [Boolean Operations](#boolean-operations)
|
|
14
|
-
- [Edge Features](#edge-features)
|
|
15
|
-
- [Patterns & Layout](#patterns-layout)
|
|
16
|
-
- [Imports & Composition](#imports-composition)
|
|
17
|
-
- [Parameters](#parameters)
|
|
18
|
-
- [Grouping & Local Coordinates](#grouping-local-coordinates)
|
|
19
|
-
- [Section & Projection](#section-projection)
|
|
20
|
-
- [
|
|
21
|
-
- [Verification](#verification) — `verify.that`, `verify.equal`, `verify.notEqual`, `verify.greaterThan`, `verify.lessThan`, `verify.inRange`, `verify.centersCoincide`, `verify.connectorDistance`, `verify.physicalComponentCount`, `verify.intentionalOverlap`, `verify.notColliding`, `verify.minClearance`, `verify.clearanceBetween`, `verify.parallel`, `verify.perpendicular`, `verify.coplanar`, `verify.faceAt`, `verify.sameDirection`, `verify.isEmpty`, `verify.notEmpty`, `verify.volumeApprox`, `verify.areaApprox`, `verify.boundingBoxSize`, `verify.edgeContinuity`, `verify.noTinyEdges`, `verify.noSliverFaces`, `verify.noSelfIntersection`, `spec`
|
|
12
|
+
- [3D Primitives](#3d-primitives)
|
|
13
|
+
- [Boolean Operations](#boolean-operations)
|
|
14
|
+
- [Edge Features](#edge-features)
|
|
15
|
+
- [Patterns & Layout](#patterns-layout)
|
|
16
|
+
- [Imports & Composition](#imports-composition)
|
|
17
|
+
- [Parameters](#parameters)
|
|
18
|
+
- [Grouping & Local Coordinates](#grouping-local-coordinates)
|
|
19
|
+
- [Section & Projection](#section-projection)
|
|
20
|
+
- [Verification](#verification)
|
|
22
21
|
- [Shape](#shape) — Appearance, Face Topology, Edge Topology, Transforms, Booleans & Cutting, Features, Placement, Connectors, References, Measurement
|
|
23
22
|
- [Transform](#transform)
|
|
24
23
|
- [ShapeGroup](#shapegroup) — Children, Transforms, Placement, Connectors, References
|
|
25
24
|
- [SurfacePattern](#surfacepattern)
|
|
26
25
|
- [Pattern2D](#pattern2d)
|
|
27
26
|
- [Pattern2DBuilder](#pattern2dbuilder)
|
|
28
|
-
- [HermiteCurve3D](#hermitecurve3d)
|
|
29
|
-
- [QuinticHermiteCurve3D](#quintichermitecurve3d)
|
|
30
27
|
- [ShapeRef](#shaperef)
|
|
31
28
|
- [ANCHOR3D_NAMES](#anchor3d-names)
|
|
32
29
|
- [verify](#verify)
|
|
33
|
-
- [Constraint](#constraint)
|
|
34
30
|
- [Points](#points)
|
|
35
31
|
- [connector](#connector)
|
|
36
32
|
- [Import](#import)
|
|
@@ -39,7 +35,9 @@ skill-order: 100
|
|
|
39
35
|
|
|
40
36
|
### 3D Primitives
|
|
41
37
|
|
|
42
|
-
#### `box()` — Create a rectangular box. Centered on XY, base at Z=0.
|
|
38
|
+
#### `box(width: number, depth: number, height: number): Shape` — Create a rectangular box. Centered on XY, base at Z=0.
|
|
39
|
+
|
|
40
|
+
All ForgeCAD dimensions are millimeters; all angles are degrees (applies to every API, not just `box`).
|
|
43
41
|
|
|
44
42
|
Extents:
|
|
45
43
|
|
|
@@ -47,13 +45,11 @@ Extents:
|
|
|
47
45
|
- Y: `[-depth/2, depth/2]`
|
|
48
46
|
- Z: `[0, height]`
|
|
49
47
|
|
|
50
|
-
|
|
48
|
+
This origin convention (centered on XY, base at Z=0) applies to all volumetric primitives that have a base. There is no `center: true` option — recenter with `.translate(0, 0, -height/2)` or `.placeReference('center', [0, 0, 0])`.
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
box(width: number, depth: number, height: number): Shape
|
|
54
|
-
```
|
|
50
|
+
For named faces, build from a labeled sketch: `rect(width, depth).labelEdges('s', 'e', 'n', 'w').extrude(height, { labels: { start: 'bottom', end: 'top' } })`.
|
|
55
51
|
|
|
56
|
-
#### `cylinder()` — Create a cylinder or cone with named faces and edges. Centered on XY, base at Z=0.
|
|
52
|
+
#### `cylinder(height: number, radius: number, radiusTop?: number, segments?: number): Shape` — Create a cylinder or cone with named faces and edges. Centered on XY, base at Z=0.
|
|
57
53
|
|
|
58
54
|
Extents:
|
|
59
55
|
|
|
@@ -64,11 +60,7 @@ Extents:
|
|
|
64
60
|
|
|
65
61
|
Named faces: `top`, `bottom`, `side` Named edges: `top-rim`, `bottom-rim`
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
cylinder(height: number, radius: number, radiusTop?: number, segments?: number): Shape
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
#### `sphere()` — Create a sphere centered at the origin.
|
|
63
|
+
#### `sphere(radius: number, segments?: number): Shape` — Create a sphere centered at the origin.
|
|
72
64
|
|
|
73
65
|
Extents:
|
|
74
66
|
|
|
@@ -78,11 +70,7 @@ Extents:
|
|
|
78
70
|
|
|
79
71
|
Use `segments` for lower-poly approximations.
|
|
80
72
|
|
|
81
|
-
|
|
82
|
-
sphere(radius: number, segments?: number): Shape
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### `torus()` — Create a torus (donut shape) lying in the XY plane. Centered on all axes.
|
|
73
|
+
#### `torus(majorRadius: number, minorRadius: number, segments?: number): Shape` — Create a torus (donut shape) lying in the XY plane. Centered on all axes.
|
|
86
74
|
|
|
87
75
|
Extents:
|
|
88
76
|
|
|
@@ -92,41 +80,25 @@ Extents:
|
|
|
92
80
|
|
|
93
81
|
The origin is the center of the ring.
|
|
94
82
|
|
|
95
|
-
```ts
|
|
96
|
-
torus(majorRadius: number, minorRadius: number, segments?: number): Shape
|
|
97
|
-
```
|
|
98
|
-
|
|
99
83
|
### Boolean Operations
|
|
100
84
|
|
|
101
|
-
#### `union()` — Combine shapes into a single solid (additive boolean).
|
|
85
|
+
#### `union(...inputs: ShapeOperandInput[]): Shape` — Combine shapes into a single solid (additive boolean).
|
|
102
86
|
|
|
103
87
|
Accepts individual shapes, or an array of shapes. `union()` returns one solid, so only the first operand's color is preserved in the result. Use `group()` when you want separate child colors or identities.
|
|
104
88
|
|
|
105
|
-
|
|
106
|
-
union(...inputs: ShapeOperandInput[]): Shape
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
#### `difference()` — Subtract shapes from a base shape (subtractive boolean).
|
|
89
|
+
#### `difference(...inputs: ShapeOperandInput[]): Shape` — Subtract shapes from a base shape (subtractive boolean).
|
|
110
90
|
|
|
111
91
|
The first shape is the base; all subsequent shapes are subtracted from it. Accepts individual shapes, or an array of shapes.
|
|
112
92
|
|
|
113
|
-
|
|
114
|
-
difference(...inputs: ShapeOperandInput[]): Shape
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
#### `intersection()` — Keep only the overlapping volume of the input shapes (intersection boolean).
|
|
93
|
+
#### `intersection(...inputs: ShapeOperandInput[]): Shape` — Keep only the overlapping volume of the input shapes (intersection boolean).
|
|
118
94
|
|
|
119
95
|
Requires at least two shapes. Accepts individual shapes, or an array.
|
|
120
96
|
|
|
121
|
-
```ts
|
|
122
|
-
intersection(...inputs: ShapeOperandInput[]): Shape
|
|
123
|
-
```
|
|
124
|
-
|
|
125
97
|
### Edge Features
|
|
126
98
|
|
|
127
|
-
#### `fillet()` — Apply experimental fillets (rounded edges) to one or more edges of a shape.
|
|
99
|
+
#### `fillet(shape: Shape, radius: number, edges?: EdgeSelector, segments?: number): Shape` — Apply experimental fillets (rounded edges) to one or more edges of a shape.
|
|
128
100
|
|
|
129
|
-
**Experimental**:
|
|
101
|
+
**Experimental**: edge finishes (fillet and chamfer) are backend-sensitive. The Manifold backend is known to produce incorrect results for some edge-finish cases, and the OCCT backend can be very slow, especially with broad edge selections. Prefer profile-level rounding where the design allows (`sketch.filletCorners(radius)` before extruding — exact and fast); otherwise use targeted edge selectors and inspect the result before treating it as production-ready geometry.
|
|
130
102
|
|
|
131
103
|
Edge selections compile into backend operations; unsupported selections fail as explicit kernel gaps instead of using TypeScript geometry fallbacks.
|
|
132
104
|
|
|
@@ -135,6 +107,7 @@ The `edges` parameter is flexible:
|
|
|
135
107
|
- Omit to fillet **all** sharp edges
|
|
136
108
|
- Pass an `EdgeQuery` for an inline filter (most common)
|
|
137
109
|
- Pass an `EdgeSegment` or `EdgeSegment[]` from `selectEdges()` for pre-selected edges
|
|
110
|
+
- Pass a tracked `EdgeRef` from `shape.edge('vert-br')` (vertical edges of `box()` / [`Rectangle2D`](/docs/sketch#rectangle2d) extrusions) — this takes the **exact** compiler-owned path, not the mesh-approximate one
|
|
138
111
|
|
|
139
112
|
Throws if no edges match the selection, or if `radius` is not a positive finite number.
|
|
140
113
|
|
|
@@ -148,19 +121,19 @@ fillet(myShape, 1.5, { atZ: 20, convex: true })
|
|
|
148
121
|
// Fillet vertical edges selected beforehand
|
|
149
122
|
const edges = selectEdges(myShape, { parallel: [0, 0, 1] })
|
|
150
123
|
fillet(myShape, 3, edges)
|
|
151
|
-
```
|
|
152
124
|
|
|
153
|
-
|
|
154
|
-
|
|
125
|
+
// Exact compiler-owned fillet on a tracked box edge
|
|
126
|
+
const base = box(50, 50, 20)
|
|
127
|
+
fillet(base, 5, base.edge('vert-br'))
|
|
155
128
|
```
|
|
156
129
|
|
|
157
|
-
#### `chamfer()` — Apply experimental chamfers (beveled edges) to one or more edges of a shape.
|
|
130
|
+
#### `chamfer(shape: Shape, size: number, edges?: EdgeSelector): Shape` — Apply experimental chamfers (beveled edges) to one or more edges of a shape.
|
|
158
131
|
|
|
159
|
-
**Experimental**:
|
|
132
|
+
**Experimental**: same backend caveats as `fillet` — Manifold may be incorrect for some edge-finish cases, OCCT can be very slow on broad selections; prefer profile-level rounding or targeted selectors and inspect the result.
|
|
160
133
|
|
|
161
134
|
Produces a 45° bevel at the specified `size` (distance from edge). Edge selections compile into backend operations; unsupported selections fail as explicit kernel gaps instead of using TypeScript geometry fallbacks.
|
|
162
135
|
|
|
163
|
-
The `edges` parameter accepts the same options as `fillet()`: inline `EdgeQuery`, pre-selected `EdgeSegment`/`EdgeSegment[]`, or `undefined` (all sharp edges).
|
|
136
|
+
The `edges` parameter accepts the same options as `fillet()`: inline `EdgeQuery`, pre-selected `EdgeSegment`/`EdgeSegment[]`, a tracked `EdgeRef` from `shape.edge('vert-br')` (exact compiler-owned path), or `undefined` (all sharp edges).
|
|
164
137
|
|
|
165
138
|
```ts
|
|
166
139
|
// Chamfer all edges
|
|
@@ -168,13 +141,13 @@ chamfer(myShape, 1)
|
|
|
168
141
|
|
|
169
142
|
// Chamfer only vertical edges
|
|
170
143
|
chamfer(myShape, 2, { parallel: [0, 0, 1] })
|
|
171
|
-
```
|
|
172
144
|
|
|
173
|
-
|
|
174
|
-
|
|
145
|
+
// Exact compiler-owned chamfer on a tracked box edge
|
|
146
|
+
const base = box(50, 50, 20)
|
|
147
|
+
chamfer(base, 3, base.edge('vert-br'))
|
|
175
148
|
```
|
|
176
149
|
|
|
177
|
-
#### `draft()` — Apply a draft angle (taper) to vertical faces for mold extraction.
|
|
150
|
+
#### `draft(shape: Shape, angleDeg: number, pullDirection?: Vec3, neutralPlaneOffset?: number): Shape` — Apply a draft angle (taper) to vertical faces for mold extraction.
|
|
178
151
|
|
|
179
152
|
Adds a taper angle to the vertical faces of a solid so that it can be extracted from a mold. The neutral plane is the Z position where the draft angle is zero — faces above and below are tapered symmetrically. Typical values for injection molding are 1–5°.
|
|
180
153
|
|
|
@@ -188,11 +161,7 @@ draft(myBox, 3)
|
|
|
188
161
|
draft(myShape, 2, [0, 0, 1], 10)
|
|
189
162
|
```
|
|
190
163
|
|
|
191
|
-
|
|
192
|
-
draft(shape: Shape, angleDeg: number, pullDirection?: [ number, number, number ], neutralPlaneOffset?: number): Shape
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
#### `offsetSolid()` — Uniformly offset all surfaces of a solid inward or outward.
|
|
164
|
+
#### `offsetSolid(shape: Shape, thickness: number): Shape` — Uniformly offset all surfaces of a solid inward or outward.
|
|
196
165
|
|
|
197
166
|
Unlike `shell()`, which hollows a solid by removing one face, `offsetSolid()` produces a new solid whose every surface is shifted by `thickness`. Positive values grow the shape outward; negative values shrink it inward.
|
|
198
167
|
|
|
@@ -206,13 +175,9 @@ offsetSolid(myBox, 1)
|
|
|
206
175
|
offsetSolid(myShape, -0.5)
|
|
207
176
|
```
|
|
208
177
|
|
|
209
|
-
```ts
|
|
210
|
-
offsetSolid(shape: Shape, thickness: number): Shape
|
|
211
|
-
```
|
|
212
|
-
|
|
213
178
|
### Patterns & Layout
|
|
214
179
|
|
|
215
|
-
#### `circularLayout()` — Compute evenly-spaced positions around a circle.
|
|
180
|
+
#### `circularLayout(count: number, radius: number, options?: CircularLayoutOptions): LayoutPoint[]` — Compute evenly-spaced positions around a circle.
|
|
216
181
|
|
|
217
182
|
Eliminates the most common trig pattern in CAD scripts:
|
|
218
183
|
|
|
@@ -229,10 +194,6 @@ for (const {x, y} of circularLayout(12, r)) {
|
|
|
229
194
|
}
|
|
230
195
|
```
|
|
231
196
|
|
|
232
|
-
```ts
|
|
233
|
-
circularLayout(count: number, radius: number, options?: CircularLayoutOptions): LayoutPoint[]
|
|
234
|
-
```
|
|
235
|
-
|
|
236
197
|
**`CircularLayoutOptions`**
|
|
237
198
|
- `startDeg?: number` — Angle of the first element in degrees (default: 0 = +X axis).
|
|
238
199
|
- `centerX?: number` — Center X coordinate (default: 0).
|
|
@@ -240,7 +201,7 @@ circularLayout(count: number, radius: number, options?: CircularLayoutOptions):
|
|
|
240
201
|
|
|
241
202
|
`LayoutPoint`: `{ x: number, y: number }`
|
|
242
203
|
|
|
243
|
-
#### `polygonVertices()` — Compute the vertex positions of a regular polygon.
|
|
204
|
+
#### `polygonVertices(sides: number, radius: number, options?: PolygonVerticesOptions): LayoutPoint[]` — Compute the vertex positions of a regular polygon.
|
|
244
205
|
|
|
245
206
|
Default orientation places the first vertex at the top (90 degrees), matching the convention used by [`ngon()`](/docs/sketch#ngon).
|
|
246
207
|
|
|
@@ -256,16 +217,12 @@ const v3 = [center.x + r, center.y];
|
|
|
256
217
|
const [v1, v2, v3] = polygonVertices(3, r);
|
|
257
218
|
```
|
|
258
219
|
|
|
259
|
-
```ts
|
|
260
|
-
polygonVertices(sides: number, radius: number, options?: PolygonVerticesOptions): LayoutPoint[]
|
|
261
|
-
```
|
|
262
|
-
|
|
263
220
|
**`PolygonVerticesOptions`**
|
|
264
221
|
- `startDeg?: number` — Angle of the first vertex in degrees (default: 90 = top).
|
|
265
222
|
- `centerX?: number` — Center X coordinate (default: 0).
|
|
266
223
|
- `centerY?: number` — Center Y coordinate (default: 0).
|
|
267
224
|
|
|
268
|
-
#### `linearPattern()` — Repeat a shape in a linear pattern along a direction vector and union the copies.
|
|
225
|
+
#### `linearPattern(shape: Shape, count: number, dx: number, dy: number, dz?: number): Shape` — Repeat a shape in a linear pattern along a direction vector and union the copies.
|
|
269
226
|
|
|
270
227
|
Creates `count` copies of `shape`, each offset by `(dx*i, dy*i, dz*i)` from the original. All copies are unioned into a single `Shape`. Distinct compiler ownership is assigned to each copy so face identity via owner-scoped canonical queries still works post-merge.
|
|
271
228
|
|
|
@@ -274,11 +231,7 @@ Creates `count` copies of `shape`, each offset by `(dx*i, dy*i, dz*i)` from the
|
|
|
274
231
|
linearPattern(cylinder(10, 3), 5, 20, 0)
|
|
275
232
|
```
|
|
276
233
|
|
|
277
|
-
|
|
278
|
-
linearPattern(shape: Shape, count: number, dx: number, dy: number, dz?: number): Shape
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
#### `circularPattern()` — Repeat a shape in a circular pattern around an axis and union the copies.
|
|
234
|
+
#### `circularPattern(shape: Shape, count: number, centerXOrOpts?: number | CircularPatternOptions, centerY?: number): Shape` — Repeat a shape in a circular pattern around an axis and union the copies.
|
|
282
235
|
|
|
283
236
|
Distributes `count` copies evenly around the rotation axis (360° / count per step). All copies are unioned into a single `Shape`. Distinct compiler ownership is assigned to each copy — post-merge face identity via owner-scoped canonical queries still works for pattern descendants.
|
|
284
237
|
|
|
@@ -295,32 +248,20 @@ circularPattern(cylinder(12, 4).translate(30, 0, -1), 8)
|
|
|
295
248
|
circularPattern(myFeature, 4, { axis: [1, 0, 0], origin: [0, 0, 50] })
|
|
296
249
|
```
|
|
297
250
|
|
|
298
|
-
```ts
|
|
299
|
-
circularPattern(shape: Shape, count: number, centerXOrOpts?: number | CircularPatternOptions, centerY?: number): Shape
|
|
300
|
-
```
|
|
301
|
-
|
|
302
251
|
**`CircularPatternOptions`**
|
|
303
252
|
|
|
304
253
|
| Option | Type | Description |
|
|
305
254
|
|--------|------|-------------|
|
|
306
255
|
| `centerX?` | `number` | Center X of the rotation (default: 0). Used when the rotation axis is Z. |
|
|
307
256
|
| `centerY?` | `number` | Center Y of the rotation (default: 0). Used when the rotation axis is Z. |
|
|
308
|
-
| `axis?` | `
|
|
309
|
-
| `origin?` | `
|
|
310
|
-
|
|
311
|
-
#### `linearPattern2d()` — Repeat a 2D sketch in a linear pattern and union the copies.
|
|
312
|
-
|
|
313
|
-
```ts
|
|
314
|
-
linearPattern2d(sketch: Sketch, count: number, dx: number, dy?: number): Sketch
|
|
315
|
-
```
|
|
257
|
+
| `axis?` | `Vec3` | Rotation axis direction (default: [0, 0, 1] = Z axis). |
|
|
258
|
+
| `origin?` | `Vec3` | Pivot point for the rotation (default: [0, 0, 0]). Overrides centerX/centerY when set. |
|
|
316
259
|
|
|
317
|
-
#### `
|
|
260
|
+
#### `linearPattern2d(sketch: Sketch, count: number, dx: number, dy?: number): Sketch` — Repeat a 2D sketch in a linear pattern and union the copies.
|
|
318
261
|
|
|
319
|
-
|
|
320
|
-
circularPattern2d(sketch: Sketch, count: number, centerXOrOpts?: number | { centerX?: number; centerY?: number; startDeg?: number; }, centerY?: number): Sketch
|
|
321
|
-
```
|
|
262
|
+
#### `circularPattern2d(sketch: Sketch, count: number, centerXOrOpts?: number | { centerX?: number; centerY?: number; startDeg?: number; }, centerY?: number): Sketch` — Repeat a 2D sketch in a circular pattern around a center point and union the copies.
|
|
322
263
|
|
|
323
|
-
#### `mirrorCopy()` — Mirror a shape across a plane and union the mirror with the original.
|
|
264
|
+
#### `mirrorCopy(shape: Shape, normal: Vec3): Shape` — Mirror a shape across a plane and union the mirror with the original.
|
|
324
265
|
|
|
325
266
|
The mirror plane passes through the origin and is defined by its normal vector. The mirrored copy is unioned with the original to produce a single symmetric Shape.
|
|
326
267
|
|
|
@@ -329,11 +270,7 @@ The mirror plane passes through the origin and is defined by its normal vector.
|
|
|
329
270
|
mirrorCopy(box(50, 30, 10), [1, 0, 0])
|
|
330
271
|
```
|
|
331
272
|
|
|
332
|
-
|
|
333
|
-
mirrorCopy(shape: Shape, normal: [ number, number, number ]): Shape
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
#### `selectEdges()` — Select all edges from a shape that match the given query.
|
|
273
|
+
#### `selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]` — Select all edges from a shape that match the given query.
|
|
337
274
|
|
|
338
275
|
Uses the active kernel's native topology query when available (Truck), otherwise extracts sharp edges from the mesh (dihedral angle > 1°), applies all filters in the query, and returns the matching `EdgeSegment[]`. When `near` is specified the results are sorted closest-first.
|
|
339
276
|
|
|
@@ -348,10 +285,6 @@ for (const edge of coalesceEdges(topEdges)) {
|
|
|
348
285
|
}
|
|
349
286
|
```
|
|
350
287
|
|
|
351
|
-
```ts
|
|
352
|
-
selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]
|
|
353
|
-
```
|
|
354
|
-
|
|
355
288
|
**`EdgeQuery`**
|
|
356
289
|
|
|
357
290
|
| Option | Type | Description |
|
|
@@ -383,9 +316,10 @@ selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]
|
|
|
383
316
|
| `normalA` | `Vec3` | Normal of first adjacent face. |
|
|
384
317
|
| `normalB` | `Vec3` | Normal of second adjacent face (same as normalA for boundary edges). |
|
|
385
318
|
| `boundary` | `boolean` | true if this is a boundary (unmatched) edge — unusual for closed solids. |
|
|
386
|
-
| `start`, `end`, `midpoint`, `length` | | — |
|
|
387
319
|
|
|
388
|
-
|
|
320
|
+
Also: `start: Vec3`, `end: Vec3`, `midpoint: Vec3`, `length: number`.
|
|
321
|
+
|
|
322
|
+
#### `selectEdge(shape: Shape, query?: EdgeQuery): EdgeSegment` — Select the single best-matching edge from a shape.
|
|
389
323
|
|
|
390
324
|
When `near` is specified, returns the edge whose midpoint is closest to that point. Otherwise returns the first matching edge in mesh order. Throws if no edges match the query — useful as a guard when you expect exactly one result.
|
|
391
325
|
|
|
@@ -395,11 +329,7 @@ const bottomEdge = selectEdge(part, { near: [25, 0, 0], atZ: 0 });
|
|
|
395
329
|
result = chamfer(result, 1.5, bottomEdge);
|
|
396
330
|
```
|
|
397
331
|
|
|
398
|
-
|
|
399
|
-
selectEdge(shape: Shape, query?: EdgeQuery): EdgeSegment
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
#### `coalesceEdges()` — Merge collinear edge segments into longer logical edges.
|
|
332
|
+
#### `coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]` — Merge collinear edge segments into longer logical edges.
|
|
403
333
|
|
|
404
334
|
Tessellation often splits one geometric edge into multiple short segments. `coalesceEdges` groups adjacent collinear segments and merges each group into a single `EdgeSegment` spanning the full extent. This is usually needed before passing edges to `fillet()` or `chamfer()` on non-primitive shapes.
|
|
405
335
|
|
|
@@ -412,16 +342,14 @@ for (const edge of coalesceEdges(topEdges)) {
|
|
|
412
342
|
}
|
|
413
343
|
```
|
|
414
344
|
|
|
415
|
-
```ts
|
|
416
|
-
coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]
|
|
417
|
-
```
|
|
418
|
-
|
|
419
345
|
### Imports & Composition
|
|
420
346
|
|
|
421
|
-
#### `require()` — Import a module with optional ForgeCAD parameter overrides. Returns the module's exports.
|
|
347
|
+
#### `require(path: string, paramOverrides?: Record<string, number | string>): any` — Import a module with optional ForgeCAD parameter overrides. Returns the module's exports.
|
|
422
348
|
|
|
423
349
|
When importing a `.forge.js` file, most return values are passed through exactly as the script returns them. Assembly returns have one extra composition rule: an unsolved [`Assembly`](/docs/assembly#assembly) is wrapped as an [`ImportedAssembly`](/docs/assembly#importedassembly), preserving `solve(state)` and `mergeInto()` across file boundaries, while a returned [`SolvedAssembly`](/docs/assembly#solvedassembly) stays a [`SolvedAssembly`](/docs/assembly#solvedassembly). If the script returns a metadata object (e.g. `{ shape: myShape, bolts: {...} }`), the caller receives the full object — renderable values and metadata together.
|
|
424
350
|
|
|
351
|
+
**Script return contract:** a `.forge.js` script returns one of three shapes: a single renderable (Shape, ShapeGroup, Sketch, SdfShape, Assembly), an array of renderables or named descriptors (`{ name, shape|sketch|group }`), or a metadata object mixing renderable values with plain data. When a script runs directly, renderable entries of a metadata object are rendered under their key names and non-renderable entries are silently skipped — both halves of the metadata contract: one return value serves the viewport and `require()` callers.
|
|
352
|
+
|
|
425
353
|
**Assembly return contract**
|
|
426
354
|
|
|
427
355
|
| `.forge.js` return value | `require()` result |
|
|
@@ -480,57 +408,20 @@ const wheel = profiles.make.wheelProfile().extrude(8);
|
|
|
480
408
|
|
|
481
409
|
Keep exported builders pure over top-level constants, top-level `param()` values, or explicit function arguments. Do not declare new `param()` values inside an exported builder if callers need `require('./profiles.forge.js', { Width: 80 })` overrides: import overrides are validated while the module loads, before any exported builder is called. Use plain `.js` modules only for pure constants, tables, math helpers, and formatting code that does not construct ForgeCAD geometry.
|
|
482
410
|
|
|
483
|
-
|
|
484
|
-
require(path: string, paramOverrides?: Record<string, number | string>): any
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
#### `importSvgSketch()` — Parse an SVG file and return it as a Sketch with options for region filtering, scaling, and simplification.
|
|
488
|
-
|
|
489
|
-
```ts
|
|
490
|
-
importSvgSketch(fileName: string, options?: SvgImportOptions): Sketch
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
**`SvgImportOptions`**
|
|
494
|
-
|
|
495
|
-
| Option | Type | Description |
|
|
496
|
-
|--------|------|-------------|
|
|
497
|
-
| `include?` | `"auto" \| "fill" \| "stroke" \| "fill-and-stroke"` | Which geometry channels to include: - `auto`: prefer fills; if no fill geometry exists, fall back to strokes - `fill`: import only filled regions - `stroke`: import only stroke geometry - `fill-and-stroke`: include both |
|
|
498
|
-
| `regionSelection?` | `"all" \| "largest"` | Keep all disconnected regions, or only the largest. |
|
|
499
|
-
| `maxRegions?` | `number` | Keep at most this many regions (largest-first). |
|
|
500
|
-
| `minRegionArea?` | `number` | Drop regions below this absolute area threshold. |
|
|
501
|
-
| `minRegionAreaRatio?` | `number` | Drop regions below this ratio of largest-region area. |
|
|
502
|
-
| `flattenTolerance?` | `number` | Curve flattening tolerance in SVG user units. Smaller = more segments, higher fidelity. |
|
|
503
|
-
| `arcSegments?` | `number` | Minimum segment count for arc discretization. |
|
|
504
|
-
| `scale?` | `number` | Global scale applied after SVG parsing. |
|
|
505
|
-
| `maxWidth?` | `number` | Maximum imported sketch width. If exceeded, geometry is uniformly downscaled to fit. |
|
|
506
|
-
| `maxHeight?` | `number` | Maximum imported sketch height. If exceeded, geometry is uniformly downscaled to fit. |
|
|
507
|
-
| `centerOnOrigin?` | `boolean` | Recenter imported geometry so its 2D bounds center is at CAD origin. |
|
|
508
|
-
| `simplify?` | `number` | Simplification tolerance for final sketch cleanup. |
|
|
509
|
-
| `invertY?` | `boolean` | Flip SVG Y-down coordinates to CAD Y-up. Enabled by default. |
|
|
510
|
-
|
|
511
|
-
#### `importMesh()` — Import an external mesh file (STL, OBJ, 3MF).
|
|
512
|
-
|
|
513
|
-
By default, 3MF build items are flattened into one Shape for compatibility. Use `separateObjects: true` to import 3MF build items/resource objects as a named ShapeGroup whose children are targetable by `forgecad ls`. Use `object` to import one item by the stable ref/name reported by `forgecad run`.
|
|
411
|
+
**Entry detection (Node semantics):** `require.main` is the entry script's module object, so `require.main === module` is true only in the file being run directly. Part files use it to build standalone preview geometry only when opened directly — importers then skip that work entirely:
|
|
514
412
|
|
|
515
413
|
```js
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
importMesh(fileName: string, options?: { scale?: number; center?: boolean; object?: string; separateObjects?: boolean; }): Shape | ShapeGroup
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
#### `importStep()` — Import a STEP file (.step, .stp) as an exact OCCT-backed Shape. Preserves NURBS curves, B-spline surfaces, and exact topology. Requires running with the OCCT backend.
|
|
526
|
-
|
|
527
|
-
```ts
|
|
528
|
-
importStep(fileName: string): Shape
|
|
414
|
+
// part.forge.js
|
|
415
|
+
function bracket() { ... }
|
|
416
|
+
if (require.main === module) {
|
|
417
|
+
return { preview: [{ name: 'Bracket', shape: bracket() }] }; // direct run: render it
|
|
418
|
+
}
|
|
419
|
+
return { make: { bracket } }; // imported: builders only
|
|
529
420
|
```
|
|
530
421
|
|
|
531
422
|
### Parameters
|
|
532
423
|
|
|
533
|
-
#### `Param.number()` — Declare a numeric parameter that renders as a slider in the UI.
|
|
424
|
+
#### `Param.number(name: string, defaultValue: number, opts?: { min?: number; max?: number; step?: number; unit?: string; integer?: boolean; reverse?: boolean; }): number` — Declare a numeric parameter that renders as a slider in the UI.
|
|
534
425
|
|
|
535
426
|
Each call registers a slider control. When the user moves the slider the entire script re-executes with the new value. Parameter values are also overridable from `require()` imports or the CLI `--param` flag — the `name` string is the key used in both cases.
|
|
536
427
|
|
|
@@ -560,11 +451,7 @@ const bracket = require("./bracket.forge.js", { Width: 80 });
|
|
|
560
451
|
|
|
561
452
|
Also available as the shorthand alias `param()`.
|
|
562
453
|
|
|
563
|
-
|
|
564
|
-
Param.number(name: string, defaultValue: number, opts?: { min?: number; max?: number; step?: number; unit?: string; integer?: boolean; reverse?: boolean; }): number
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
#### `Param.string()` — Declare a string parameter that renders as a text input in the UI.
|
|
454
|
+
#### `Param.string(name: string, defaultValue: string, opts?: { maxLength?: number; }): string` — Declare a string parameter that renders as a text input in the UI.
|
|
568
455
|
|
|
569
456
|
String parameters let users type free-form text — labels, names, inscriptions, file paths, etc. The `name` string is the override key.
|
|
570
457
|
|
|
@@ -581,11 +468,7 @@ const tag = require("./tag.forge.js", { Label: "Custom Text" });
|
|
|
581
468
|
|
|
582
469
|
Only available as `Param.string()` — no standalone alias.
|
|
583
470
|
|
|
584
|
-
|
|
585
|
-
Param.string(name: string, defaultValue: string, opts?: { maxLength?: number; }): string
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
#### `Param.bool()` — Declare a boolean parameter that renders as a checkbox in the UI.
|
|
471
|
+
#### `Param.bool(name: string, defaultValue: boolean): boolean` — Declare a boolean parameter that renders as a checkbox in the UI.
|
|
589
472
|
|
|
590
473
|
Internally stored as `0`/`1`. When overriding from CLI or `require()`, pass `1` for true and `0` for false. The `name` string is the override key.
|
|
591
474
|
|
|
@@ -601,13 +484,7 @@ Override via import:
|
|
|
601
484
|
const pan = require("./pan.forge.js", { "Show Lid": 0 });
|
|
602
485
|
```
|
|
603
486
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
```ts
|
|
607
|
-
Param.bool(name: string, defaultValue: boolean): boolean
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
#### `Param.choice()` — Declare a choice parameter that renders as a dropdown in the UI.
|
|
487
|
+
#### `Param.choice(name: string, defaultValue: string, choices: string[]): string` — Declare a choice parameter that renders as a dropdown in the UI.
|
|
611
488
|
|
|
612
489
|
`defaultValue` must exactly match one entry in `choices`. Returns the selected string label. Prefer `Param.choice` over `Param.number` when a slider would hide intent — named choices like `"wok"` are self-describing.
|
|
613
490
|
|
|
@@ -630,13 +507,7 @@ Override via CLI:
|
|
|
630
507
|
forgecad run model.forge.js --param "Pan Style=wok"
|
|
631
508
|
```
|
|
632
509
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
```ts
|
|
636
|
-
Param.choice(name: string, defaultValue: string, choices: string[]): string
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
#### `Param.list()` — Declare a list parameter — an array of struct items with per-field UI controls.
|
|
510
|
+
#### `Param.list<T extends Record<string, number | boolean | string>>(name: string, defaultItems: T[], opts: { ... }): T[]` — Declare a list parameter — an array of struct items with per-field UI controls.
|
|
640
511
|
|
|
641
512
|
Each item in the list is a struct whose fields each render as their own control (slider, checkbox, or dropdown). The user can add/remove rows up to `minItems`/`maxItems` bounds.
|
|
642
513
|
|
|
@@ -646,15 +517,11 @@ Field types:
|
|
|
646
517
|
- Choice fields (`choices: [...]` in field defs) return as `string`
|
|
647
518
|
- All other fields return as `number`
|
|
648
519
|
|
|
649
|
-
```ts
|
|
650
|
-
Param.list<T extends Record<string, number | boolean | string>>(name: string, defaultItems: T[], opts: { ... }): T[]
|
|
651
|
-
```
|
|
652
|
-
|
|
653
520
|
`ListParamFieldDef`: `{ min?: number, max?: number, step?: number, unit?: string, integer?: boolean, boolean?: boolean, choices?: string[] }`
|
|
654
521
|
|
|
655
522
|
### Grouping & Local Coordinates
|
|
656
523
|
|
|
657
|
-
#### `group()` — Group multiple shapes/sketches for joint transforms without merging into a single mesh.
|
|
524
|
+
#### `group(...items: GroupInput[]): ShapeGroup` — Group multiple shapes/sketches for joint transforms without merging into a single mesh.
|
|
658
525
|
|
|
659
526
|
Unlike union(), child colors and individual identities are preserved. Children can be plain shapes, named descriptors ({ name, shape/sketch/group }), or nested groups. The returned ShapeGroup supports all Shape transforms (translate, rotate, etc.).
|
|
660
527
|
|
|
@@ -673,87 +540,35 @@ const indoorUnit = group(
|
|
|
673
540
|
).translate(0, -18, 70);
|
|
674
541
|
```
|
|
675
542
|
|
|
676
|
-
```ts
|
|
677
|
-
group(...items: GroupInput[]): ShapeGroup
|
|
678
|
-
```
|
|
679
|
-
|
|
680
543
|
### Section & Projection
|
|
681
544
|
|
|
682
|
-
#### `intersectWithPlane()` — Cross-section: slice a 3D shape with a plane and return the intersection as a 2D Sketch.
|
|
683
|
-
|
|
684
|
-
```ts
|
|
685
|
-
intersectWithPlane(shape: Shape, plane: PlaneSpec): Sketch
|
|
686
|
-
```
|
|
545
|
+
#### `intersectWithPlane(shape: Shape, plane: PlaneSpec): Sketch` — Cross-section: slice a 3D shape with a plane and return the intersection as a 2D Sketch.
|
|
687
546
|
|
|
688
|
-
#### `faceProfile()` — Extract the boundary profile of a named face as a 2D sketch.
|
|
547
|
+
#### `faceProfile(shape: Shape, face: FaceSelector): Sketch` — Extract the boundary profile of a named face as a 2D sketch.
|
|
689
548
|
|
|
690
549
|
The result is returned in the face's local 2D coordinate system, making it convenient for offsets, pocket profiles, or follow-up sketch operations driven by an existing face.
|
|
691
550
|
|
|
692
|
-
|
|
693
|
-
faceProfile(shape: Shape, face: FaceSelector): Sketch
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
#### `projectToPlane()` — Orthographically project a 3D shape onto a plane and return the silhouette as a 2D Sketch.
|
|
697
|
-
|
|
698
|
-
```ts
|
|
699
|
-
projectToPlane(shape: Shape, plane: PlaneSpec): Sketch
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Transforms
|
|
703
|
-
|
|
704
|
-
#### `composeChain()` — Compose transforms in chain order. Equivalent to Transform.identity().mul(a).mul(b).mul(c)...
|
|
705
|
-
|
|
706
|
-
```ts
|
|
707
|
-
composeChain(...steps: TransformInput[]): Transform
|
|
708
|
-
```
|
|
551
|
+
#### `projectToPlane(shape: Shape, plane: PlaneSpec): Sketch` — Orthographically project a 3D shape onto a plane and return the silhouette as a 2D Sketch.
|
|
709
552
|
|
|
710
553
|
### Verification
|
|
711
554
|
|
|
712
|
-
#### `verify.that()` — Custom predicate check.
|
|
713
|
-
|
|
714
|
-
```ts
|
|
715
|
-
verify.that(label: string, check: () => boolean, message?: string): void
|
|
716
|
-
```
|
|
717
|
-
|
|
718
|
-
#### `verify.equal()` — Check that two numbers are approximately equal (within tolerance).
|
|
719
|
-
|
|
720
|
-
```ts
|
|
721
|
-
verify.equal(label: string, actual: number, expected: number, tolerance?: number, message?: string): void
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
#### `verify.notEqual()` — Check that two numbers are NOT equal (differ by more than tolerance).
|
|
725
|
-
|
|
726
|
-
```ts
|
|
727
|
-
verify.notEqual(label: string, actual: number, unexpected: number, tolerance?: number, message?: string): void
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
#### `verify.greaterThan()` — Check that actual > min.
|
|
731
|
-
|
|
732
|
-
```ts
|
|
733
|
-
verify.greaterThan(label: string, actual: number, min: number, message?: string): void
|
|
734
|
-
```
|
|
555
|
+
#### `verify.that(label: string, check: () => boolean, message?: string): void` — Custom predicate check.
|
|
735
556
|
|
|
736
|
-
#### `verify.
|
|
557
|
+
#### `verify.equal(label: string, actual: number, expected: number, tolerance?: number, message?: string): void` — Check that two numbers are approximately equal (within tolerance).
|
|
737
558
|
|
|
738
|
-
|
|
739
|
-
verify.lessThan(label: string, actual: number, max: number, message?: string): void
|
|
740
|
-
```
|
|
559
|
+
#### `verify.notEqual(label: string, actual: number, unexpected: number, tolerance?: number, message?: string): void` — Check that two numbers are NOT equal (differ by more than tolerance).
|
|
741
560
|
|
|
742
|
-
#### `verify.
|
|
561
|
+
#### `verify.greaterThan(label: string, actual: number, min: number, message?: string): void` — Check that actual > min.
|
|
743
562
|
|
|
744
|
-
|
|
745
|
-
verify.inRange(label: string, actual: number, min: number, max: number, message?: string): void
|
|
746
|
-
```
|
|
563
|
+
#### `verify.lessThan(label: string, actual: number, max: number, message?: string): void` — Check that actual < max.
|
|
747
564
|
|
|
748
|
-
#### `verify.
|
|
565
|
+
#### `verify.inRange(label: string, actual: number, min: number, max: number, message?: string): void` — Check that min <= actual <= max.
|
|
749
566
|
|
|
750
|
-
|
|
751
|
-
verify.centersCoincide(label: string, a: ShapeLike, b: ShapeLike, tolerance?: number): void
|
|
752
|
-
```
|
|
567
|
+
#### `verify.centersCoincide(label: string, a: ShapeLike, b: ShapeLike, tolerance?: number): void` — Check that the bounding-box centers of two shapes coincide within tolerance (mm).
|
|
753
568
|
|
|
754
569
|
`ShapeLike`: `{ min: number[], max: number[] }`
|
|
755
570
|
|
|
756
|
-
#### `verify.connectorDistance()` — Check the distance between two named connectors on a shape or group.
|
|
571
|
+
#### `verify.connectorDistance(label: string, target: ConnectorDistanceLike, connectorA: string, connectorB: string, expected?: number, tolerance?: number): void` — Check the distance between two named connectors on a shape or group.
|
|
757
572
|
|
|
758
573
|
Use this when connectors + `matchTo()` define a static assembly interface. It proves the mate at runtime, unlike a plain source-level connector declaration. The common case is `expected = 0`, meaning the two connector origins should coincide after placement.
|
|
759
574
|
|
|
@@ -761,11 +576,7 @@ Use this when connectors + `matchTo()` define a static assembly interface. It pr
|
|
|
761
576
|
verify.connectorDistance("leg is seated", bench, "Rail.leg_0", "Leg0.head", 0, 0.01);
|
|
762
577
|
```
|
|
763
578
|
|
|
764
|
-
|
|
765
|
-
verify.connectorDistance(label: string, target: ConnectorDistanceLike, connectorA: string, connectorB: string, expected?: number, tolerance?: number): void
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
#### `verify.physicalComponentCount()` — Declare the expected physical connectivity component count for the returned visible model.
|
|
579
|
+
#### `verify.physicalComponentCount(label: string, expected: number): void` — Declare the expected physical connectivity component count for the returned visible model.
|
|
769
580
|
|
|
770
581
|
Use this for generated mechanical models that should have a clear component graph: one connected fixture, a purchased part plus a removable cartridge, a root assembly plus named intentional ghosts, and so on. `forgecad inspect mechanical-integrity` resolves the returned visible objects with the same physical-connectivity analysis used in the quality gate and fails if the actual component count differs.
|
|
771
582
|
|
|
@@ -775,11 +586,7 @@ This catches the common generated-CAD failure where a script returns a visually
|
|
|
775
586
|
verify.physicalComponentCount("vise is one connected installed assembly", 1);
|
|
776
587
|
```
|
|
777
588
|
|
|
778
|
-
|
|
779
|
-
verify.physicalComponentCount(label: string, expected: number): void
|
|
780
|
-
```
|
|
781
|
-
|
|
782
|
-
#### `verify.intentionalOverlap()` — Declare that two visible objects intentionally overlap because the overlap is real manufacturing intent.
|
|
589
|
+
#### `verify.intentionalOverlap(label: string, a: ShapeLike, b: ShapeLike, reason: string): void` — Declare that two visible objects intentionally overlap because the overlap is real manufacturing intent.
|
|
783
590
|
|
|
784
591
|
Use this only for overlaps that a mechanical reviewer would accept as actual matter sharing volume: welded/fused regions, overmolded inserts, potted electronics, cast-in hardware, or deliberately bonded laminations. This is not a shortcut for screws without holes, shafts without bores, covers without pockets, or parts placed with collision as a positioning hack.
|
|
785
592
|
|
|
@@ -789,25 +596,13 @@ Use this only for overlaps that a mechanical reviewer would accept as actual mat
|
|
|
789
596
|
verify.intentionalOverlap("rubber grip is overmolded on handle", rubberGrip, handleCore, "overmolded insert");
|
|
790
597
|
```
|
|
791
598
|
|
|
792
|
-
|
|
793
|
-
verify.intentionalOverlap(label: string, a: ShapeLike, b: ShapeLike, reason: string): void
|
|
794
|
-
```
|
|
795
|
-
|
|
796
|
-
#### `verify.notColliding()` — Check that two shapes do not share positive volume.
|
|
599
|
+
#### `verify.notColliding(label: string, a: ShapeLike, b: ShapeLike, searchLength?: number): void` — Check that two shapes do not share positive volume.
|
|
797
600
|
|
|
798
601
|
Face-to-face contact is allowed; use `verify.minClearance()` when an actual running gap is required.
|
|
799
602
|
|
|
800
|
-
|
|
801
|
-
verify.notColliding(label: string, a: ShapeLike, b: ShapeLike, searchLength?: number): void
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
#### `verify.minClearance()` — Check that a minimum clearance gap exists between two shapes.
|
|
805
|
-
|
|
806
|
-
```ts
|
|
807
|
-
verify.minClearance(label: string, a: ShapeLike, b: ShapeLike, minGap: number, searchLength?: number): void
|
|
808
|
-
```
|
|
603
|
+
#### `verify.minClearance(label: string, a: ShapeLike, b: ShapeLike, minGap: number, searchLength?: number): void` — Check that a minimum clearance gap exists between two shapes.
|
|
809
604
|
|
|
810
|
-
#### `verify.clearanceBetween()` — Check that the clearance gap between two shapes is inside an allowed range.
|
|
605
|
+
#### `verify.clearanceBetween(label: string, a: ShapeLike, b: ShapeLike, minGap: number, maxGap: number, searchLength?: number): void` — Check that the clearance gap between two shapes is inside an allowed range.
|
|
811
606
|
|
|
812
607
|
Use this for seated and retained interfaces where a part must be close enough to be mechanically accountable, but must not collide beyond the allowed minimum. It catches both failure modes that make generated CAD look fake: parts floating away from their receiver, and parts intersecting their receiver because the pocket, bore, or running clearance was not modeled.
|
|
813
608
|
|
|
@@ -820,99 +615,39 @@ verify.clearanceBetween("cover is seated on gasket", cover, gasket, -0.01, 0.05)
|
|
|
820
615
|
verify.clearanceBetween("carriage runs inside rail", carriage, rail, 0.2, 0.5);
|
|
821
616
|
```
|
|
822
617
|
|
|
823
|
-
|
|
824
|
-
verify.clearanceBetween(label: string, a: ShapeLike, b: ShapeLike, minGap: number, maxGap: number, searchLength?: number): void
|
|
825
|
-
```
|
|
826
|
-
|
|
827
|
-
#### `verify.parallel()` — Check that two face normals are parallel (within toleranceDeg degrees).
|
|
828
|
-
|
|
829
|
-
```ts
|
|
830
|
-
verify.parallel(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
`FaceRefLike`: `{ normal: [ number, number, number ], center: [ number, number, number ] }`
|
|
618
|
+
#### `verify.parallel(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are parallel (within toleranceDeg degrees).
|
|
834
619
|
|
|
835
|
-
|
|
620
|
+
`FaceRefLike`: `{ normal: Vec3, center: Vec3 }`
|
|
836
621
|
|
|
837
|
-
|
|
838
|
-
verify.perpendicular(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void
|
|
839
|
-
```
|
|
840
|
-
|
|
841
|
-
#### `verify.coplanar()` — Check that a face is coplanar with (same plane as) another face, meaning they are parallel AND their centers lie on the same plane.
|
|
842
|
-
|
|
843
|
-
```ts
|
|
844
|
-
verify.coplanar(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number, toleranceMm?: number): void
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
#### `verify.faceAt()` — Check that a face center lies at a specific position (within toleranceMm).
|
|
848
|
-
|
|
849
|
-
```ts
|
|
850
|
-
verify.faceAt(label: string, face: FaceRefLike, expectedPos: [ number, number, number ], toleranceMm?: number): void
|
|
851
|
-
```
|
|
852
|
-
|
|
853
|
-
#### `verify.sameDirection()` — Check that two face normals point in the same direction (not antiparallel). Stricter than parallel — both |angle| AND sign must match.
|
|
854
|
-
|
|
855
|
-
```ts
|
|
856
|
-
verify.sameDirection(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void
|
|
857
|
-
```
|
|
858
|
-
|
|
859
|
-
#### `verify.isEmpty()` — Check that a shape is empty.
|
|
860
|
-
|
|
861
|
-
```ts
|
|
862
|
-
verify.isEmpty(label: string, shape: ShapeLike, message?: string): void
|
|
863
|
-
```
|
|
622
|
+
#### `verify.perpendicular(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are perpendicular (within toleranceDeg degrees).
|
|
864
623
|
|
|
865
|
-
#### `verify.
|
|
866
|
-
|
|
867
|
-
```ts
|
|
868
|
-
verify.notEmpty(label: string, shape: ShapeLike, message?: string): void
|
|
869
|
-
```
|
|
624
|
+
#### `verify.coplanar(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number, toleranceMm?: number): void` — Check that a face is coplanar with (same plane as) another face, meaning they are parallel AND their centers lie on the same plane.
|
|
870
625
|
|
|
871
|
-
#### `verify.
|
|
626
|
+
#### `verify.faceAt(label: string, face: FaceRefLike, expectedPos: Vec3, toleranceMm?: number): void` — Check that a face center lies at a specific position (within toleranceMm).
|
|
872
627
|
|
|
873
|
-
|
|
874
|
-
verify.volumeApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void
|
|
875
|
-
```
|
|
628
|
+
#### `verify.sameDirection(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals point in the same direction (not antiparallel). Stricter than parallel — both |angle| AND sign must match.
|
|
876
629
|
|
|
877
|
-
#### `verify.
|
|
630
|
+
#### `verify.isEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is empty.
|
|
878
631
|
|
|
879
|
-
|
|
880
|
-
verify.areaApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void
|
|
881
|
-
```
|
|
632
|
+
#### `verify.notEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is NOT empty.
|
|
882
633
|
|
|
883
|
-
#### `verify.
|
|
634
|
+
#### `verify.volumeApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void` — Check that a shape's volume is approximately equal to expected (mm³).
|
|
884
635
|
|
|
885
|
-
|
|
886
|
-
verify.boundingBoxSize(label: string, shape: ShapeLike, expectedSize: [ number, number, number ], tolerance?: number): void
|
|
887
|
-
```
|
|
636
|
+
#### `verify.areaApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void` — Check that a shape's surface area is approximately equal to expected (mm²).
|
|
888
637
|
|
|
889
|
-
#### `verify.
|
|
638
|
+
#### `verify.boundingBoxSize(label: string, shape: ShapeLike, expectedSize: Vec3, tolerance?: number): void` — Check that a shape's bounding box has approximately the given size.
|
|
890
639
|
|
|
891
|
-
|
|
892
|
-
verify.edgeContinuity(label: string, shape: ShapeLike, options?: EdgeContinuityThresholds): void
|
|
893
|
-
```
|
|
640
|
+
#### `verify.edgeContinuity(label: string, shape: ShapeLike, options?: EdgeContinuityThresholds): void` — Check that every sampled seam on a shape meets a requested continuity threshold.
|
|
894
641
|
|
|
895
642
|
**`EdgeContinuityThresholds`**: `continuity?: SurfaceContinuity`, `samples?: number`, `positionTolerance?: number`, `tangentToleranceDeg?: number`, `curvatureTolerance?: number`
|
|
896
643
|
|
|
897
|
-
#### `verify.noTinyEdges()` — Check that a shape has no tiny edges below the requested threshold.
|
|
898
|
-
|
|
899
|
-
```ts
|
|
900
|
-
verify.noTinyEdges(label: string, shape: ShapeLike, threshold?: number): void
|
|
901
|
-
```
|
|
902
|
-
|
|
903
|
-
#### `verify.noSliverFaces()` — Check that a shape has no sliver faces below the requested score threshold.
|
|
904
|
-
|
|
905
|
-
```ts
|
|
906
|
-
verify.noSliverFaces(label: string, shape: ShapeLike, threshold?: number): void
|
|
907
|
-
```
|
|
644
|
+
#### `verify.noTinyEdges(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no tiny edges below the requested threshold.
|
|
908
645
|
|
|
909
|
-
#### `verify.
|
|
646
|
+
#### `verify.noSliverFaces(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no sliver faces below the requested score threshold.
|
|
910
647
|
|
|
911
|
-
|
|
912
|
-
verify.noSelfIntersection(label: string, shape: ShapeLike): void
|
|
913
|
-
```
|
|
648
|
+
#### `verify.noSelfIntersection(label: string, shape: ShapeLike): void` — Best-effort exact-shape validity guard for self-intersections or broken B-Rep topology.
|
|
914
649
|
|
|
915
|
-
#### `spec()` — Create a named, reusable bundle of verification checks.
|
|
650
|
+
#### `spec(name: string, checkFn: (...args: any[]) => void): Spec` — Create a named, reusable bundle of verification checks.
|
|
916
651
|
|
|
917
652
|
A spec groups related `verify.*` calls under a collapsible header in the Checks panel. This makes large check suites scannable. Specs can be applied to multiple shapes and can check relationships between parts.
|
|
918
653
|
|
|
@@ -942,10 +677,6 @@ fitSpec.check(bracket, standoff);
|
|
|
942
677
|
|
|
943
678
|
**Spec-first workflow:** Write specs before building geometry. Checks go from red to green as you build — effectively TDD for CAD.
|
|
944
679
|
|
|
945
|
-
```ts
|
|
946
|
-
spec(name: string, checkFn: (...args: any[]) => void): Spec
|
|
947
|
-
```
|
|
948
|
-
|
|
949
680
|
**`Spec`**
|
|
950
681
|
- `name: string` — The display name of this spec
|
|
951
682
|
|
|
@@ -963,17 +694,13 @@ Supports transforms (translate, rotate, scale, mirror, transform, rotateAround,
|
|
|
963
694
|
|
|
964
695
|
| Property | Type | Description |
|
|
965
696
|
|----------|------|-------------|
|
|
966
|
-
| `materialProps` | `ShapeMaterialProps
|
|
697
|
+
| `materialProps` | `ShapeMaterialProps \| undefined` | — |
|
|
967
698
|
|
|
968
699
|
**Appearance**
|
|
969
700
|
|
|
970
|
-
#### `color()` — Set the color of this shape (hex string, e.g. "#ff0000"). Returns a new Shape with the color applied.
|
|
971
|
-
|
|
972
|
-
```ts
|
|
973
|
-
color(value: string | undefined): Shape
|
|
974
|
-
```
|
|
701
|
+
#### `color(value: string | undefined): Shape` — Set the color of this shape (hex string, e.g. "#ff0000"). Returns a new Shape with the color applied.
|
|
975
702
|
|
|
976
|
-
#### `material()` — Set PBR material properties for this shape's visual appearance.
|
|
703
|
+
#### `material(props: ShapeMaterialProps): Shape` — Set PBR material properties for this shape's visual appearance.
|
|
977
704
|
|
|
978
705
|
Returns a new Shape with the specified material properties merged on top of any previously set properties. All properties are optional — omitted keys retain their current value. Material properties survive transforms and boolean operations.
|
|
979
706
|
|
|
@@ -988,10 +715,6 @@ cylinder(40, 20).material({ opacity: 0.4, clearcoat: 1.0, clearcoatRoughness: 0.
|
|
|
988
715
|
box(100, 100, 10).color('#gold').material({ metalness: 0.95, roughness: 0.05 }).translate(0, 0, 50);
|
|
989
716
|
```
|
|
990
717
|
|
|
991
|
-
```ts
|
|
992
|
-
material(props: ShapeMaterialProps): Shape
|
|
993
|
-
```
|
|
994
|
-
|
|
995
718
|
**`ShapeMaterialProps`**
|
|
996
719
|
|
|
997
720
|
| Option | Type | Description |
|
|
@@ -1013,12 +736,14 @@ material(props: ShapeMaterialProps): Shape
|
|
|
1013
736
|
|
|
1014
737
|
**Face Topology**
|
|
1015
738
|
|
|
1016
|
-
#### `face()` — Resolve a face by user-authored label or compiler-owned name. Returns a `FaceRef` that can be passed to `.onFace()`, `projectToPlane()`, or used directly in placement.
|
|
739
|
+
#### `face(selector: FaceSelector): FaceRef` — Resolve a face by user-authored label or compiler-owned name. Returns a `FaceRef` that can be passed to `.onFace()`, `projectToPlane()`, or used directly in placement.
|
|
1017
740
|
|
|
1018
741
|
`.face(name)` is a pure label lookup — it finds faces by user-authored labels, not by geometric queries. Labels are born in sketches via `.label()` / `.labelEdges()` and grow into face names through extrude, loft, revolve, and sweep. They are stable references that travel with the geometry.
|
|
1019
742
|
|
|
1020
743
|
Labels must be unique within a shape. Use `.prefixLabels()` before combining shapes with `union()` / `difference()` to avoid collisions. Collision detection throws a clear error with a fix suggestion.
|
|
1021
744
|
|
|
745
|
+
Boolean survival: `union()` and `intersection()` carry labels from every operand; `difference()` carries only the base (first) operand's labels — cutter labels are dropped. A surviving label addresses whatever portion of its face survives the boolean; cutters may split or erase it, and a lineage shared by multiple union operands resolves as a face set rather than a single face.
|
|
746
|
+
|
|
1022
747
|
For compile-covered shapes (extrude, loft, etc.) the lookup resolves via the shape's compile plan. As a fallback, planar-faced mesh shapes (e.g. results of boolean ops) are resolved via coplanar triangle clustering.
|
|
1023
748
|
|
|
1024
749
|
```ts
|
|
@@ -1045,69 +770,29 @@ const full = union(left, right);
|
|
|
1045
770
|
full.face('l/upper'); // left wing upper surface
|
|
1046
771
|
```
|
|
1047
772
|
|
|
1048
|
-
|
|
1049
|
-
face(selector: FaceSelector): FaceRef
|
|
1050
|
-
```
|
|
1051
|
-
|
|
1052
|
-
#### `faces()` — Return faces matching a query, or label semantic faces when passed a mapping.
|
|
773
|
+
#### `faces(): FaceRef[]` — Return faces matching a query, or label semantic faces when passed a mapping.
|
|
1053
774
|
|
|
1054
775
|
Mapping form returns a new shape: `shape.faces({ lid: 'top', walls: ['front', 'back', 'left', 'right'] })`.
|
|
1055
776
|
|
|
1056
|
-
|
|
1057
|
-
faces(): FaceRef[]
|
|
1058
|
-
```
|
|
1059
|
-
|
|
1060
|
-
#### `faceNames()` — List defined semantic face names currently available on this shape.
|
|
1061
|
-
|
|
1062
|
-
```ts
|
|
1063
|
-
faceNames(): string[]
|
|
1064
|
-
```
|
|
1065
|
-
|
|
1066
|
-
#### `prefixLabels()` — Prefix all user-authored face labels, including semantic labels from `faces(mapping)`. Returns a new shape with modified labels.
|
|
1067
|
-
|
|
1068
|
-
```ts
|
|
1069
|
-
prefixLabels(prefix: string): Shape
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
#### `renameLabel()` — Rename a single face label. Returns a new shape.
|
|
1073
|
-
|
|
1074
|
-
```ts
|
|
1075
|
-
renameLabel(from: string, to: string): Shape
|
|
1076
|
-
```
|
|
1077
|
-
|
|
1078
|
-
#### `dropLabels()` — Remove specific face labels. Returns a new shape.
|
|
777
|
+
#### `faceNames(): string[]` — List defined semantic face names currently available on this shape.
|
|
1079
778
|
|
|
1080
|
-
|
|
1081
|
-
dropLabels(...names: string[]): Shape
|
|
1082
|
-
```
|
|
779
|
+
#### `prefixLabels(prefix: string): Shape` — Prefix all user-authored face labels, including semantic labels from `faces(mapping)`. Returns a new shape with modified labels.
|
|
1083
780
|
|
|
1084
|
-
#### `
|
|
781
|
+
#### `renameLabel(from: string, to: string): Shape` — Rename a single face label. Returns a new shape.
|
|
1085
782
|
|
|
1086
|
-
|
|
1087
|
-
dropAllLabels(): Shape
|
|
1088
|
-
```
|
|
783
|
+
#### `dropLabels(...names: string[]): Shape` — Remove specific face labels. Returns a new shape.
|
|
1089
784
|
|
|
1090
|
-
#### `
|
|
785
|
+
#### `dropAllLabels(): Shape` — Remove all face labels. Returns a new shape.
|
|
1091
786
|
|
|
1092
|
-
|
|
1093
|
-
faceHistory(name: string): FaceTransformationHistory
|
|
1094
|
-
```
|
|
787
|
+
#### `faceHistory(name: string): FaceTransformationHistory` — Get the transformation history for a specific face.
|
|
1095
788
|
|
|
1096
789
|
**Edge Topology**
|
|
1097
790
|
|
|
1098
|
-
#### `edge()` — Get a named topology edge. Only available on shapes with tracked topology (from box/cylinder/extrude).
|
|
791
|
+
#### `edge(name: string): EdgeRef` — Get a named topology edge. Only available on shapes with tracked topology (from box/cylinder/extrude).
|
|
1099
792
|
|
|
1100
|
-
|
|
1101
|
-
edge(name: string): EdgeRef
|
|
1102
|
-
```
|
|
1103
|
-
|
|
1104
|
-
#### `edgeNames()` — List named topology edge names. Returns empty array if shape has no tracked topology.
|
|
1105
|
-
|
|
1106
|
-
```ts
|
|
1107
|
-
edgeNames(): string[]
|
|
1108
|
-
```
|
|
793
|
+
#### `edgeNames(): string[]` — List named topology edge names. Returns empty array if shape has no tracked topology.
|
|
1109
794
|
|
|
1110
|
-
#### `edgesOf()` — Return all boundary edges of a named face.
|
|
795
|
+
#### `edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]` — Return all boundary edges of a named face.
|
|
1111
796
|
|
|
1112
797
|
Finds edges where one adjacent mesh face belongs to the target face and the other belongs to a different face. The result is coalesced (tessellation fragments merged) and can be passed directly to `fillet()` or `chamfer()`.
|
|
1113
798
|
|
|
@@ -1127,10 +812,6 @@ body = fillet(body, 1.5, body.edgesOf('opening'))
|
|
|
1127
812
|
body.edgesOf('top', { concave: true })
|
|
1128
813
|
```
|
|
1129
814
|
|
|
1130
|
-
```ts
|
|
1131
|
-
edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]
|
|
1132
|
-
```
|
|
1133
|
-
|
|
1134
815
|
**`EdgesOfOptions`**
|
|
1135
816
|
|
|
1136
817
|
| Option | Type | Description |
|
|
@@ -1140,7 +821,7 @@ edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]
|
|
|
1140
821
|
| `concave?` | `boolean` | Additional geometric filter: only concave edges. |
|
|
1141
822
|
| `minLength?` | `number` | Minimum edge length filter. |
|
|
1142
823
|
|
|
1143
|
-
#### `edgesBetween()` — Return edges shared between two named faces.
|
|
824
|
+
#### `edgesBetween(faceA: string, faceB: string | string[]): EdgeSegment[]` — Return edges shared between two named faces.
|
|
1144
825
|
|
|
1145
826
|
An edge is "between" faces A and B when one of its adjacent mesh triangles belongs to A and the other belongs to B. This is the most precise topological edge selection — "fillet the edges where the top meets the wall."
|
|
1146
827
|
|
|
@@ -1159,155 +840,63 @@ tube = fillet(tube, 1, tube.edgesBetween('cap', 'barrel'))
|
|
|
1159
840
|
body.edgesBetween('lid', ['left-wall', 'right-wall', 'front-wall', 'back-wall'])
|
|
1160
841
|
```
|
|
1161
842
|
|
|
1162
|
-
```ts
|
|
1163
|
-
edgesBetween(faceA: string, faceB: string | string[]): EdgeSegment[]
|
|
1164
|
-
```
|
|
1165
|
-
|
|
1166
843
|
**Transforms**
|
|
1167
844
|
|
|
1168
|
-
#### `translate()` — Move the shape relative to its current position. All transforms are immutable and return new shapes.
|
|
845
|
+
#### `translate(x: number, y: number, z: number): Shape` — Move the shape relative to its current position. All transforms are immutable and return new shapes.
|
|
1169
846
|
|
|
1170
|
-
|
|
1171
|
-
translate(x: number, y: number, z: number): Shape
|
|
1172
|
-
```
|
|
1173
|
-
|
|
1174
|
-
#### `translatePolar()` — Translate using polar coordinates (radius + angle in degrees). Eliminates manual `r * Math.cos(angle * PI/180)` calculations.
|
|
847
|
+
#### `translatePolar(radius: number, angleDeg: number, z?: number): Shape` — Translate using polar coordinates (radius + angle in degrees). Eliminates manual `r * Math.cos(angle * PI/180)` calculations.
|
|
1175
848
|
|
|
1176
849
|
Example: `shape.translatePolar(50, 30)` moves 50mm at 30 degrees from +X.
|
|
1177
850
|
|
|
1178
|
-
|
|
1179
|
-
translatePolar(radius: number, angleDeg: number, z?: number): Shape
|
|
1180
|
-
```
|
|
851
|
+
#### `moveTo(x: number, y: number, z: number): Shape` — Position the shape so its bounding box min corner is at the given global coordinate.
|
|
1181
852
|
|
|
1182
|
-
#### `
|
|
853
|
+
#### `moveToLocal(target: Shape | { toShape(): Shape; }, x: number, y: number, z: number): Shape` — Position the shape relative to another shape's local coordinate system (bounding box min corner).
|
|
1183
854
|
|
|
1184
|
-
|
|
1185
|
-
moveTo(x: number, y: number, z: number): Shape
|
|
1186
|
-
```
|
|
855
|
+
#### `rotate(axis: Vec3, angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around an arbitrary axis through the origin. Unlike `Sketch.rotate()` (bounding-box center), this pivots at the world origin — pass `options.pivot` to rotate in place.
|
|
1187
856
|
|
|
1188
|
-
#### `
|
|
857
|
+
#### `rotateX(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the X axis by the given angle in degrees.
|
|
1189
858
|
|
|
1190
|
-
|
|
1191
|
-
moveToLocal(target: Shape | { toShape(): Shape; }, x: number, y: number, z: number): Shape
|
|
1192
|
-
```
|
|
859
|
+
#### `rotateY(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the Y axis by the given angle in degrees.
|
|
1193
860
|
|
|
1194
|
-
#### `
|
|
861
|
+
#### `rotateZ(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the Z axis by the given angle in degrees.
|
|
1195
862
|
|
|
1196
|
-
|
|
1197
|
-
rotate(axis: [ number, number, number ], angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1198
|
-
```
|
|
863
|
+
#### `rotateAroundTo(axis: Vec3, pivot: Vec3, movingPoint: RotationPointLike, targetPoint: RotationPointLike, options?: RotateAroundToOptions): Shape` — Rotate around an axis until a moving point reaches the target line/plane defined by the axis and target point. `movingPoint` / `targetPoint` may be raw world points or this shape's anchors/references.
|
|
1199
864
|
|
|
1200
|
-
|
|
865
|
+
`RotateAroundToOptions`: `{ mode?: RotateAroundToMode }`
|
|
1201
866
|
|
|
1202
|
-
|
|
1203
|
-
rotateX(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1204
|
-
```
|
|
867
|
+
#### `transform(m: Mat4 | Transform): Shape` — Apply a 4x4 affine transform matrix (column-major) or a Transform object.
|
|
1205
868
|
|
|
1206
|
-
#### `
|
|
1207
|
-
|
|
1208
|
-
```ts
|
|
1209
|
-
rotateY(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1210
|
-
```
|
|
869
|
+
#### `scale(v: number | Vec3): Shape` — Scale the shape uniformly or per-axis from the shape's bounding box center. Accepts a single number or [x, y, z] array.
|
|
1211
870
|
|
|
1212
|
-
#### `
|
|
871
|
+
#### `scaleAround(pivot: Vec3, v: number | Vec3): Shape` — Scale the shape uniformly or per-axis from an explicit pivot point.
|
|
1213
872
|
|
|
1214
|
-
|
|
1215
|
-
rotateZ(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1216
|
-
```
|
|
873
|
+
#### `mirror(normal: Vec3): Shape` — Mirror across a plane through the shape's bounding box center, defined by its normal vector.
|
|
1217
874
|
|
|
1218
|
-
#### `
|
|
875
|
+
#### `mirrorThrough(point: Vec3, normal: Vec3): Shape` — Mirror across a plane through an explicit point, defined by its normal vector.
|
|
1219
876
|
|
|
1220
|
-
|
|
1221
|
-
rotateAroundTo(axis: [ number, number, number ], pivot: [ number, number, number ], movingPoint: RotationPointLike, targetPoint: RotationPointLike, options?: RotateAroundToOptions): Shape
|
|
1222
|
-
```
|
|
1223
|
-
|
|
1224
|
-
`RotateAroundToOptions`: `{ mode?: RotateAroundToMode }`
|
|
1225
|
-
|
|
1226
|
-
#### `transform()` — Apply a 4x4 affine transform matrix (column-major) or a Transform object.
|
|
1227
|
-
|
|
1228
|
-
```ts
|
|
1229
|
-
transform(m: Mat4 | Transform): Shape
|
|
1230
|
-
```
|
|
1231
|
-
|
|
1232
|
-
#### `scale()` — Scale the shape uniformly or per-axis from the shape's bounding box center. Accepts a single number or [x, y, z] array.
|
|
1233
|
-
|
|
1234
|
-
```ts
|
|
1235
|
-
scale(v: number | [ number, number, number ]): Shape
|
|
1236
|
-
```
|
|
1237
|
-
|
|
1238
|
-
#### `scaleAround()` — Scale the shape uniformly or per-axis from an explicit pivot point.
|
|
1239
|
-
|
|
1240
|
-
```ts
|
|
1241
|
-
scaleAround(pivot: [ number, number, number ], v: number | [ number, number, number ]): Shape
|
|
1242
|
-
```
|
|
1243
|
-
|
|
1244
|
-
#### `mirror()` — Mirror across a plane through the shape's bounding box center, defined by its normal vector.
|
|
1245
|
-
|
|
1246
|
-
```ts
|
|
1247
|
-
mirror(normal: [ number, number, number ]): Shape
|
|
1248
|
-
```
|
|
1249
|
-
|
|
1250
|
-
#### `mirrorThrough()` — Mirror across a plane through an explicit point, defined by its normal vector.
|
|
1251
|
-
|
|
1252
|
-
```ts
|
|
1253
|
-
mirrorThrough(point: [ number, number, number ], normal: [ number, number, number ]): Shape
|
|
1254
|
-
```
|
|
1255
|
-
|
|
1256
|
-
#### `pointAlong()` — Reorient a shape so its primary axis (Z) points along the given direction. Useful for laying cylinders/extrusions along X or Y without thinking about Euler angles. The shape's origin stays at [0,0,0] — translate after pointAlong to position it.
|
|
877
|
+
#### `pointAlong(direction: Vec3): Shape` — Reorient a shape so its primary axis (Z) points along the given direction. Useful for laying cylinders/extrusions along X or Y without thinking about Euler angles. The shape's origin stays at [0,0,0] — translate after pointAlong to position it.
|
|
1257
878
|
|
|
1258
879
|
Example: cylinder(40, 5).pointAlong([1, 0, 0]) — lays cylinder along X, starting at origin
|
|
1259
880
|
|
|
1260
|
-
```ts
|
|
1261
|
-
pointAlong(direction: [ number, number, number ]): Shape
|
|
1262
|
-
```
|
|
1263
|
-
|
|
1264
881
|
**Booleans & Cutting**
|
|
1265
882
|
|
|
1266
|
-
#### `add()` — Union this shape with others (additive boolean). Method form of union().
|
|
1267
|
-
|
|
1268
|
-
```ts
|
|
1269
|
-
add(...others: ShapeOperandInput[]): Shape
|
|
1270
|
-
```
|
|
1271
|
-
|
|
1272
|
-
#### `subtract()` — Subtract other shapes from this one. Method form of difference().
|
|
1273
|
-
|
|
1274
|
-
```ts
|
|
1275
|
-
subtract(...others: ShapeOperandInput[]): Shape
|
|
1276
|
-
```
|
|
1277
|
-
|
|
1278
|
-
#### `intersect()` — Keep only the overlap with other shapes. Method form of intersection().
|
|
883
|
+
#### `add(...others: ShapeOperandInput[]): Shape` — Union this shape with others (additive boolean). Method form of union().
|
|
1279
884
|
|
|
1280
|
-
|
|
1281
|
-
intersect(...others: ShapeOperandInput[]): Shape
|
|
1282
|
-
```
|
|
885
|
+
#### `subtract(...others: ShapeOperandInput[]): Shape` — Subtract other shapes from this one. Method form of difference().
|
|
1283
886
|
|
|
1284
|
-
#### `
|
|
887
|
+
#### `intersect(...others: ShapeOperandInput[]): Shape` — Keep only the overlap with other shapes. Method form of intersection().
|
|
1285
888
|
|
|
1286
|
-
|
|
1287
|
-
split(cutter: Shape | { toShape(): Shape; }): [ Shape, Shape ]
|
|
1288
|
-
```
|
|
1289
|
-
|
|
1290
|
-
#### `splitByPlane()` — Split by infinite plane. Returns [positive-side, negative-side].
|
|
1291
|
-
|
|
1292
|
-
```ts
|
|
1293
|
-
splitByPlane(normal: [ number, number, number ], originOffset?: number): [ Shape, Shape ]
|
|
1294
|
-
```
|
|
889
|
+
#### `split(cutter: Shape | { toShape(): Shape; }): [ Shape, Shape ]` — Split into [inside, outside] by another shape.
|
|
1295
890
|
|
|
1296
|
-
#### `
|
|
891
|
+
#### `splitByPlane(normal: Vec3, originOffset?: number): [ Shape, Shape ]` — Split by infinite plane. Returns [positive-side, negative-side].
|
|
1297
892
|
|
|
1298
|
-
|
|
1299
|
-
trimByPlane(normal: [ number, number, number ], originOffset?: number): Shape
|
|
1300
|
-
```
|
|
893
|
+
#### `trimByPlane(normal: Vec3, originOffset?: number): Shape` — Keep the positive side of the plane and discard the opposite side.
|
|
1301
894
|
|
|
1302
895
|
**Features**
|
|
1303
896
|
|
|
1304
|
-
#### `shell()` — Hollow out compile-covered boxes, cylinders, and straight extrudes. `openFaces` names any subset of the base shape's labeled faces to leave open (no wall).
|
|
897
|
+
#### `shell(thickness: number, opts?: { openFaces?: string[]; }): Shape` — Hollow out compile-covered boxes, cylinders, and straight extrudes. `openFaces` names any subset of the base shape's labeled faces to leave open (no wall).
|
|
1305
898
|
|
|
1306
|
-
|
|
1307
|
-
shell(thickness: number, opts?: { openFaces?: string[]; }): Shape
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
|
-
#### `pocket()` — Cut a pocket (cavity) into this solid through the named face.
|
|
899
|
+
#### `pocket(face: FaceSelector, depth: number, opts?: PocketOptions): Shape` — Cut a pocket (cavity) into this solid through the named face.
|
|
1311
900
|
|
|
1312
901
|
```js
|
|
1313
902
|
box(100, 100, 20).pocket('top', 8)
|
|
@@ -1315,50 +904,39 @@ box(100, 100, 20).pocket('top', 8, { inset: 5 })
|
|
|
1315
904
|
box(100, 100, 20).pocket('top', 8, { scale: 0.8 })
|
|
1316
905
|
```
|
|
1317
906
|
|
|
1318
|
-
```ts
|
|
1319
|
-
pocket(face: FaceSelector, depth: number, opts?: PocketOptions): Shape
|
|
1320
|
-
```
|
|
1321
|
-
|
|
1322
907
|
**`PocketOptions`**
|
|
1323
908
|
- `inset?: number` — Shrink the face boundary inward by this many mm before extruding. Produces angled walls when combined with depth. Default: 0 (full face).
|
|
1324
909
|
- `scale?: number` — Scale the face profile uniformly (e.g. 0.8 = 80% of the face area). Mutually exclusive with `inset`; `inset` takes precedence if both are set.
|
|
1325
910
|
- `join?: "Square" | "Round" | "Miter"` — Corner join style when using `inset`. Default: 'Round'.
|
|
1326
911
|
|
|
1327
|
-
#### `boss()` — Add a boss (protrusion) from the named face.
|
|
912
|
+
#### `boss(face: FaceSelector, height: number, opts?: BossOptions): Shape` — Add a boss (protrusion) from the named face.
|
|
1328
913
|
|
|
1329
914
|
```js
|
|
1330
915
|
box(100, 100, 20).boss('top', 5)
|
|
1331
916
|
box(100, 100, 20).boss('top', 10, { scale: 0.6 })
|
|
1332
917
|
```
|
|
1333
918
|
|
|
1334
|
-
|
|
1335
|
-
boss(face: FaceSelector, height: number, opts?: BossOptions): Shape
|
|
1336
|
-
```
|
|
1337
|
-
|
|
1338
|
-
#### `hole()` — Drill a hole into this solid at a face.
|
|
919
|
+
#### `hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape` — Drill a hole into this solid at a face.
|
|
1339
920
|
|
|
1340
921
|
```js
|
|
1341
922
|
box(50, 50, 20).hole('top', { diameter: 8, depth: 10 })
|
|
1342
923
|
box(50, 50, 20).hole('top', { diameter: 6, counterbore: { diameter: 12, depth: 3 } })
|
|
1343
924
|
```
|
|
1344
925
|
|
|
1345
|
-
```ts
|
|
1346
|
-
hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape
|
|
1347
|
-
```
|
|
1348
|
-
|
|
1349
926
|
**`FaceRef`**
|
|
1350
927
|
|
|
1351
928
|
| Option | Type | Description |
|
|
1352
929
|
|--------|------|-------------|
|
|
1353
|
-
| `normal` | `
|
|
1354
|
-
| `center` | `
|
|
930
|
+
| `normal` | `Vec3` | Normal direction of the face |
|
|
931
|
+
| `center` | `Vec3` | Center point of the face |
|
|
1355
932
|
| `query?` | `FaceQueryRef` | Compiler-owned face query when available. |
|
|
1356
933
|
| `planar?` | `boolean` | True when the face can host a 2D sketch placement frame |
|
|
1357
|
-
| `uAxis?` | `
|
|
1358
|
-
| `vAxis?` | `
|
|
934
|
+
| `uAxis?` | `Vec3` | Face-local horizontal axis for planar faces |
|
|
935
|
+
| `vAxis?` | `Vec3` | Face-local vertical axis for planar faces |
|
|
1359
936
|
| `surface?` | `FaceSurface` | Analytic surface family when the backend can identify one. |
|
|
1360
937
|
| `descendant?` | `FaceDescendantMetadata` | Shared descendant-resolution metadata when this face is a semantic region/set. |
|
|
1361
|
-
|
|
938
|
+
|
|
939
|
+
Also: `name: FaceName`.
|
|
1362
940
|
|
|
1363
941
|
**`FaceDescendantMetadata`**: `kind: "single" | "face-set"`, `semantic: FaceDescendantSemantic`, `memberCount: number`, `memberNames: string[]`, `coplanar: boolean`
|
|
1364
942
|
|
|
@@ -1370,7 +948,7 @@ hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape
|
|
|
1370
948
|
|
|
1371
949
|
**`ShapeHoleThreadOptions`**: `designation?: string`, `pitch?: number`, `class?: string`, `handedness?: "right" | "left"`, `depth?: number`, `modeled?: boolean`
|
|
1372
950
|
|
|
1373
|
-
#### `cutout()` — Cut a profile-shaped pocket through a face using a placed sketch.
|
|
951
|
+
#### `cutout(sketch: Sketch, opts?: ShapeCutoutOptions): Shape` — Cut a profile-shaped pocket through a face using a placed sketch.
|
|
1374
952
|
|
|
1375
953
|
The sketch must be placed on a face with `Sketch.onFace(...)`. The cut follows the sketch's 2D profile.
|
|
1376
954
|
|
|
@@ -1379,15 +957,11 @@ const profile = circle2d(10).onFace(body, 'top');
|
|
|
1379
957
|
body.cutout(profile, { depth: 5 })
|
|
1380
958
|
```
|
|
1381
959
|
|
|
1382
|
-
|
|
1383
|
-
cutout(sketch: Sketch, opts?: ShapeCutoutOptions): Shape
|
|
1384
|
-
```
|
|
1385
|
-
|
|
1386
|
-
**`ShapeCutoutOptions`**: `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `taperScale?: number | [ number, number ]`
|
|
960
|
+
**`ShapeCutoutOptions`**: `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `taperScale?: number | Vec2`
|
|
1387
961
|
|
|
1388
962
|
**Placement**
|
|
1389
963
|
|
|
1390
|
-
#### `placeReference()` — Translate the shape so the given anchor or reference lands on the target coordinate.
|
|
964
|
+
#### `placeReference(ref: PlacementAnchorLike, target: Vec3, offset?: Vec3): Shape` — Translate the shape so the given anchor or reference lands on the target coordinate.
|
|
1391
965
|
|
|
1392
966
|
Accepts any built-in anchor name (`'bottom'`, `'center'`, `'top-front-left'`, etc.) or a custom placement reference attached via `withReferences()`.
|
|
1393
967
|
|
|
@@ -1402,19 +976,11 @@ shape.placeReference('center', [0, 0, 0])
|
|
|
1402
976
|
shape.placeReference('left', [10, 0, 0])
|
|
1403
977
|
```
|
|
1404
978
|
|
|
1405
|
-
|
|
1406
|
-
placeReference(ref: PlacementAnchorLike, target: [ number, number, number ], offset?: [ number, number, number ]): Shape
|
|
1407
|
-
```
|
|
1408
|
-
|
|
1409
|
-
#### `attachTo()` — Position this shape relative to another using named 3D anchor points.
|
|
979
|
+
#### `attachTo(target: ShapeAnchorTarget, targetAnchor: PlacementAnchorLike, selfAnchor?: PlacementAnchorLike, offset?: Vec3): Shape` — Position this shape relative to another using named 3D anchor points.
|
|
1410
980
|
|
|
1411
981
|
Anchors are bounding-box-relative: 'center', face centers ('top', 'front', ...), edge midpoints ('top-front', 'back-left', ...), and corners ('top-front-left', ...). Anchor word order is flexible: 'front-left' and 'left-front' are equivalent. Named placement references (from withReferences) can also be used as anchors.
|
|
1412
982
|
|
|
1413
|
-
|
|
1414
|
-
attachTo(target: ShapeAnchorTarget, targetAnchor: PlacementAnchorLike, selfAnchor?: PlacementAnchorLike, offset?: [ number, number, number ]): Shape
|
|
1415
|
-
```
|
|
1416
|
-
|
|
1417
|
-
#### `onFace()` — Place this shape on a face of a parent shape.
|
|
983
|
+
#### `onFace(parent: ShapeAnchorTarget, face: "front" | "back" | "left" | "right" | "top" | "bottom", opts?: { u?: number; v?: number; protrude?: number; }): Shape` — Place this shape on a face of a parent shape.
|
|
1418
984
|
|
|
1419
985
|
Think of it like sticking a label on a box surface:
|
|
1420
986
|
|
|
@@ -1425,11 +991,7 @@ Think of it like sticking a label on a box surface:
|
|
|
1425
991
|
- top/bottom: u = left/right (X), v = forward/back (Y)
|
|
1426
992
|
- `protrude` = how far the child sticks out (positive = outward from face)
|
|
1427
993
|
|
|
1428
|
-
|
|
1429
|
-
onFace(parent: ShapeAnchorTarget, face: "front" | "back" | "left" | "right" | "top" | "bottom", opts?: { u?: number; v?: number; protrude?: number; }): Shape
|
|
1430
|
-
```
|
|
1431
|
-
|
|
1432
|
-
#### `seatInto()` — Slide this shape along an axis until a labeled face is embedded in the target body.
|
|
994
|
+
#### `seatInto(target: Shape, surface: string, options?: SeatIntoOptions): Shape` — Slide this shape along an axis until a labeled face is embedded in the target body.
|
|
1433
995
|
|
|
1434
996
|
Position the shape roughly first (translate/rotate), then call seatInto to auto-adjust the penetration depth. No manual coordinate math needed.
|
|
1435
997
|
|
|
@@ -1444,16 +1006,12 @@ pod.translate(0, station, radius + 20).seatInto(fuselage, 'base', { depth: 'flus
|
|
|
1444
1006
|
mast.translate(0, station, radius + 50).seatInto(fuselage, 'mount', { depth: 'flush', gap: 3 });
|
|
1445
1007
|
```
|
|
1446
1008
|
|
|
1447
|
-
```ts
|
|
1448
|
-
seatInto(target: Shape, surface: string, options?: SeatIntoOptions): Shape
|
|
1449
|
-
```
|
|
1450
|
-
|
|
1451
1009
|
**`SeatIntoOptions`**
|
|
1452
|
-
- `along?:
|
|
1010
|
+
- `along?: Vec3` — Movement axis. Default: inverted face normal (points into target).
|
|
1453
1011
|
- `depth?: "full" | "flush" | number` — How deep to embed. 'full' = entire face inside. 'flush' = nearest point touches. number = mm past flush. Default: 'full'.
|
|
1454
1012
|
- `gap?: number` — Standoff gap in mm. Positive = gap between face and target. Negative = extra penetration. Default: 0.
|
|
1455
1013
|
|
|
1456
|
-
#### `seatOver()` — Slide this shape until a target's labeled face is fully covered (inside this shape).
|
|
1014
|
+
#### `seatOver(target: Shape, targetSurface: string, options?: SeatIntoOptions): Shape` — Slide this shape until a target's labeled face is fully covered (inside this shape).
|
|
1457
1015
|
|
|
1458
1016
|
The inverse of `seatInto`: instead of embedding *your* face into the target, you move until the *target's* face is embedded inside you.
|
|
1459
1017
|
|
|
@@ -1465,47 +1023,25 @@ nacelle.translate(rough).seatOver(pylon, 'bottom');
|
|
|
1465
1023
|
cap.translate(rough).seatOver(post, 'top');
|
|
1466
1024
|
```
|
|
1467
1025
|
|
|
1468
|
-
```ts
|
|
1469
|
-
seatOver(target: Shape, targetSurface: string, options?: SeatIntoOptions): Shape
|
|
1470
|
-
```
|
|
1471
|
-
|
|
1472
1026
|
**Connectors**
|
|
1473
1027
|
|
|
1474
|
-
#### `withConnectors()` — Attach named connectors — attachment points that survive transforms and imports. Connectors can be bare (position + orientation) or typed (with connectorType/gender for compatibility matching).
|
|
1475
|
-
|
|
1476
|
-
```ts
|
|
1477
|
-
withConnectors(connectors: Record<string, ConnectorInput>): Shape
|
|
1478
|
-
```
|
|
1028
|
+
#### `withConnectors(connectors: Record<string, ConnectorInput>): Shape` — Attach named connectors — attachment points that survive transforms and imports. Connectors can be bare (position + orientation) or typed (with connectorType/gender for compatibility matching).
|
|
1479
1029
|
|
|
1480
|
-
|
|
1030
|
+
`PortInput`: `{ origin?: Vec3, axis?: Vec3, start?: Vec3, end?: Vec3, up?: Vec3, kind?: JointType, min?: number, max?: number }`
|
|
1481
1031
|
|
|
1482
1032
|
`ConnectorInput`: `{ connectorType?: string, gender?: ConnectorGender, measurements?: Record<string, number | string> }`
|
|
1483
1033
|
|
|
1484
|
-
#### `connectorNames()` — List all connector names on this shape.
|
|
1485
|
-
|
|
1486
|
-
```ts
|
|
1487
|
-
connectorNames(): string[]
|
|
1488
|
-
```
|
|
1489
|
-
|
|
1490
|
-
#### `connectorsByType()` — Get all connectors of a given type.
|
|
1491
|
-
|
|
1492
|
-
```ts
|
|
1493
|
-
connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>
|
|
1494
|
-
```
|
|
1034
|
+
#### `connectorNames(): string[]` — List all connector names on this shape.
|
|
1495
1035
|
|
|
1496
|
-
#### `
|
|
1036
|
+
#### `connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>` — Get all connectors of a given type.
|
|
1497
1037
|
|
|
1498
|
-
|
|
1499
|
-
connectorDistance(nameA: string, nameB: string): number
|
|
1500
|
-
```
|
|
1038
|
+
#### `connectorDistance(nameA: string, nameB: string): number` — Distance between two connector origins on this shape.
|
|
1501
1039
|
|
|
1502
|
-
#### `connectorMeasurements()
|
|
1040
|
+
#### `connectorMeasurements(name: string): Record<string, number | string>` — Get measurements metadata from a connector.
|
|
1503
1041
|
|
|
1504
|
-
|
|
1505
|
-
connectorMeasurements(name: string): Record<string, number | string>
|
|
1506
|
-
```
|
|
1042
|
+
#### `matchTo(targetOrPairs: Shape | MatchTarget | Array<[ Shape | MatchTarget, string, string ]>, selfConnOrDict?: string | Record<string, string>, targetConnOrOptions?: string | MatchToOptions, maybeOptions?: MatchToOptions): Shape` — Position this shape by matching connectors to a target.
|
|
1507
1043
|
|
|
1508
|
-
|
|
1044
|
+
Alignment: with a single connector pair, the shape translates and rotates so the connector origins coincide and the axes oppose (plug-in model); `up` pins the roll. With multiple pairs, the connector origins define the rigid transform — still author meaningful `axis`/`up` values so the same connectors remain useful for `connect()`, audits, and future matching.
|
|
1509
1045
|
|
|
1510
1046
|
Overloads:
|
|
1511
1047
|
|
|
@@ -1513,125 +1049,53 @@ Overloads:
|
|
|
1513
1049
|
- Dictionary (same target): `matchTo(target, { selfConn: targetConn, ... }, options?)`
|
|
1514
1050
|
- Multi-target: `matchTo([ [target1, selfConn1, targetConn1], ... ], options?)`
|
|
1515
1051
|
|
|
1516
|
-
```ts
|
|
1517
|
-
matchTo(targetOrPairs: Shape | MatchTarget | Array<[ Shape | MatchTarget, string, string ]>, selfConnOrDict?: string | Record<string, string>, targetConnOrOptions?: string | MatchToOptions, maybeOptions?: MatchToOptions): Shape
|
|
1518
|
-
```
|
|
1519
|
-
|
|
1520
1052
|
`MatchToOptions`: `{ force?: boolean, angle?: number, distance?: number }`
|
|
1521
1053
|
|
|
1522
1054
|
**References**
|
|
1523
1055
|
|
|
1524
|
-
#### `withReferences()` — Attach named placement references that survive normal transforms and imports.
|
|
1056
|
+
#### `withReferences(refs: PlacementReferenceInput): Shape` — Attach named placement references that survive normal transforms and imports.
|
|
1525
1057
|
|
|
1526
|
-
|
|
1527
|
-
withReferences(refs: PlacementReferenceInput): Shape
|
|
1528
|
-
```
|
|
1529
|
-
|
|
1530
|
-
**`PlacementReferenceInput`**: `points?: Record<string, [ number, number, number ]>`, `edges?: Record<string, PlacementEdgeRef>`, `surfaces?: Record<string, PlacementSurfaceRef>`, `objects?: Record<string, PlacementObjectInput>`
|
|
1058
|
+
**`PlacementReferenceInput`**: `points?: Record<string, Vec3>`, `edges?: Record<string, PlacementEdgeRef>`, `surfaces?: Record<string, PlacementSurfaceRef>`, `objects?: Record<string, PlacementObjectInput>`
|
|
1531
1059
|
|
|
1532
1060
|
`PlacementEdgeRef`: `{ start: Vec3, end: Vec3 }`
|
|
1533
1061
|
|
|
1534
1062
|
`PlacementSurfaceRef`: `{ center: Vec3, normal: Vec3 }`
|
|
1535
1063
|
|
|
1536
|
-
#### `referenceNames()` — List named placement references carried by this shape.
|
|
1537
|
-
|
|
1538
|
-
```ts
|
|
1539
|
-
referenceNames(kind?: PlacementReferenceKind): string[]
|
|
1540
|
-
```
|
|
1541
|
-
|
|
1542
|
-
#### `referencePoint()` — Resolve a named placement reference or built-in anchor to a 3D point.
|
|
1064
|
+
#### `referenceNames(kind?: PlacementReferenceKind): string[]` — List named placement references carried by this shape.
|
|
1543
1065
|
|
|
1544
|
-
|
|
1545
|
-
referencePoint(ref: PlacementAnchorLike): [ number, number, number ]
|
|
1546
|
-
```
|
|
1066
|
+
#### `referencePoint(ref: PlacementAnchorLike): Vec3` — Resolve a named placement reference or built-in anchor to a 3D point.
|
|
1547
1067
|
|
|
1548
1068
|
**Measurement**
|
|
1549
1069
|
|
|
1550
|
-
#### `boundingBox()` — Get the axis-aligned bounding box as { min: [x,y,z], max: [x,y,z] }.
|
|
1551
|
-
|
|
1552
|
-
```ts
|
|
1553
|
-
boundingBox(): ShapeRuntimeBounds
|
|
1554
|
-
```
|
|
1555
|
-
|
|
1556
|
-
#### `volume()` — Volume in mm cubed.
|
|
1557
|
-
|
|
1558
|
-
```ts
|
|
1559
|
-
volume(): number
|
|
1560
|
-
```
|
|
1070
|
+
#### `boundingBox(): ShapeRuntimeBounds` — Get the axis-aligned bounding box as { min: [x,y,z], max: [x,y,z] }.
|
|
1561
1071
|
|
|
1562
|
-
#### `
|
|
1072
|
+
#### `volume(): number` — Volume in mm cubed.
|
|
1563
1073
|
|
|
1564
|
-
|
|
1565
|
-
surfaceArea(): number
|
|
1566
|
-
```
|
|
1074
|
+
#### `surfaceArea(): number` — Surface area in mm squared.
|
|
1567
1075
|
|
|
1568
|
-
#### `isEmpty()` — True if the shape contains no geometry.
|
|
1076
|
+
#### `isEmpty(): boolean` — True if the shape contains no geometry.
|
|
1569
1077
|
|
|
1570
|
-
|
|
1571
|
-
isEmpty(): boolean
|
|
1572
|
-
```
|
|
1078
|
+
#### `numBodies(): number` — Number of disconnected solid bodies in this shape.
|
|
1573
1079
|
|
|
1574
|
-
#### `
|
|
1575
|
-
|
|
1576
|
-
```ts
|
|
1577
|
-
numBodies(): number
|
|
1578
|
-
```
|
|
1579
|
-
|
|
1580
|
-
#### `numTri()` — Triangle count of the mesh representation.
|
|
1581
|
-
|
|
1582
|
-
```ts
|
|
1583
|
-
numTri(): number
|
|
1584
|
-
```
|
|
1080
|
+
#### `numTri(): number` — Triangle count of the mesh representation.
|
|
1585
1081
|
|
|
1586
1082
|
**Other**
|
|
1587
1083
|
|
|
1588
|
-
#### `clone()` — Return a new Shape wrapper for explicit duplication in scripts.
|
|
1084
|
+
#### `clone(): Shape` — Return a new Shape wrapper for explicit duplication in scripts.
|
|
1589
1085
|
|
|
1590
|
-
|
|
1591
|
-
clone(): Shape
|
|
1592
|
-
```
|
|
1593
|
-
|
|
1594
|
-
#### `geometryInfo()` — Inspect which backend/representation produced this solid.
|
|
1595
|
-
|
|
1596
|
-
```ts
|
|
1597
|
-
geometryInfo(): GeometryInfo
|
|
1598
|
-
```
|
|
1599
|
-
|
|
1600
|
-
#### `as()` — Name this shape as a reference namespace for diagnostics and future published refs.
|
|
1086
|
+
#### `geometryInfo(): GeometryInfo` — Inspect which backend/representation produced this solid.
|
|
1601
1087
|
|
|
1602
|
-
|
|
1603
|
-
as(name: string): Shape
|
|
1604
|
-
```
|
|
1088
|
+
#### `as(name: string): Shape` — Name this shape as a reference namespace for diagnostics and future published refs.
|
|
1605
1089
|
|
|
1606
|
-
#### `ref()` — Resolve a semantic reference path like `lid`, `lid/back`, or a midpoint selector on `lid/back`.
|
|
1090
|
+
#### `ref(path: string): ShapeRef` — Resolve a semantic reference path like `lid`, `lid/back`, or a midpoint selector on `lid/back`.
|
|
1607
1091
|
|
|
1608
|
-
|
|
1609
|
-
ref(path: string): ShapeRef
|
|
1610
|
-
```
|
|
1092
|
+
#### `thicken(thickness: number): Shape` — Offset-thicken an exact open surface or shell into a solid.
|
|
1611
1093
|
|
|
1612
|
-
#### `
|
|
1094
|
+
#### `getMesh(): ShapeRuntimeMesh` — Extract triangle mesh for Three.js rendering
|
|
1613
1095
|
|
|
1614
|
-
|
|
1615
|
-
thicken(thickness: number): Shape
|
|
1616
|
-
```
|
|
1096
|
+
#### `slice(offset?: number): any` — Slice the runtime solid by a plane normal to local Z at the given offset.
|
|
1617
1097
|
|
|
1618
|
-
#### `
|
|
1619
|
-
|
|
1620
|
-
```ts
|
|
1621
|
-
getMesh(): ShapeRuntimeMesh
|
|
1622
|
-
```
|
|
1623
|
-
|
|
1624
|
-
#### `slice()` — Slice the runtime solid by a plane normal to local Z at the given offset.
|
|
1625
|
-
|
|
1626
|
-
```ts
|
|
1627
|
-
slice(offset?: number): any
|
|
1628
|
-
```
|
|
1629
|
-
|
|
1630
|
-
#### `project()` — Orthographically project the runtime solid onto the local XY plane.
|
|
1631
|
-
|
|
1632
|
-
```ts
|
|
1633
|
-
project(): any
|
|
1634
|
-
```
|
|
1098
|
+
#### `project(): any` — Orthographically project the runtime solid onto the local XY plane.
|
|
1635
1099
|
|
|
1636
1100
|
**Compatibility Aliases**
|
|
1637
1101
|
|
|
@@ -1640,101 +1104,45 @@ project(): any
|
|
|
1640
1104
|
|
|
1641
1105
|
### `Transform`
|
|
1642
1106
|
|
|
1643
|
-
#### `identity()` — Return the identity transform.
|
|
1107
|
+
#### `static identity(): Transform` — Return the identity transform.
|
|
1644
1108
|
|
|
1645
|
-
|
|
1646
|
-
static identity(): Transform
|
|
1647
|
-
```
|
|
1648
|
-
|
|
1649
|
-
#### `from()` — Wrap an existing `Transform` or raw 4x4 matrix as a `Transform`.
|
|
1109
|
+
#### `static from(input: TransformInput): Transform` — Wrap an existing `Transform` or raw 4x4 matrix as a `Transform`.
|
|
1650
1110
|
|
|
1651
|
-
|
|
1652
|
-
static from(input: TransformInput): Transform
|
|
1653
|
-
```
|
|
1111
|
+
#### `static compose(...steps: TransformInput[]): Transform` — Compose transforms in chain order: `Transform.compose(a, b, c)` applies `a`, then `b`, then `c` — the same left-to-right order as `Transform.from(a).mul(b).mul(c)`.
|
|
1654
1112
|
|
|
1655
|
-
|
|
1113
|
+
Prefer this over manual `.mul()` chains when composing 3+ transforms (e.g. kinematics: `local -> childBase -> jointMotion -> jointFrame -> parentWorld`); the variadic form makes the application order explicit and prevents order mistakes.
|
|
1656
1114
|
|
|
1657
1115
|
```ts
|
|
1658
|
-
|
|
1116
|
+
const world = Transform.compose(childBase, jointMotion, jointFrame, parentWorld);
|
|
1659
1117
|
```
|
|
1660
1118
|
|
|
1661
|
-
#### `
|
|
1119
|
+
#### `static translation(x: number, y: number, z: number): Transform` — Create a translation transform.
|
|
1662
1120
|
|
|
1663
|
-
|
|
1664
|
-
static scale(v: number | Vec3): Transform
|
|
1665
|
-
```
|
|
1121
|
+
#### `static scale(v: number | Vec3): Transform` — Create a uniform or per-axis scale transform.
|
|
1666
1122
|
|
|
1667
|
-
#### `rotationAxis()` — Create a rotation around an arbitrary axis, optionally about a pivot.
|
|
1123
|
+
#### `static rotationAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform` — Create a rotation around an arbitrary axis, optionally about a pivot.
|
|
1668
1124
|
|
|
1669
|
-
|
|
1670
|
-
static rotationAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform
|
|
1671
|
-
```
|
|
1125
|
+
#### `static rotateAroundTo(axis: Vec3, pivot: Vec3, movingPoint: Vec3, targetPoint: Vec3, options?: RotateAroundToOptions): Transform` — Solve the rotation needed to move one point onto a target line or plane.
|
|
1672
1126
|
|
|
1673
|
-
#### `
|
|
1127
|
+
#### `mul(other: TransformInput): Transform` — Compose transforms in chain order: `a.mul(b)` applies `a`, then `b`.
|
|
1674
1128
|
|
|
1675
|
-
|
|
1676
|
-
static rotateAroundTo(axis: Vec3, pivot: Vec3, movingPoint: Vec3, targetPoint: Vec3, options?: RotateAroundToOptions): Transform
|
|
1677
|
-
```
|
|
1129
|
+
#### `translate(x: number, y: number, z: number): Transform` — Translate after the current transform.
|
|
1678
1130
|
|
|
1679
|
-
#### `
|
|
1131
|
+
#### `rotateAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform` — Rotate after the current transform.
|
|
1680
1132
|
|
|
1681
|
-
|
|
1682
|
-
mul(other: TransformInput): Transform
|
|
1683
|
-
```
|
|
1133
|
+
#### `rotateX(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the X axis after the current transform (parity with `Shape.rotateX`).
|
|
1684
1134
|
|
|
1685
|
-
#### `
|
|
1135
|
+
#### `rotateY(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the Y axis after the current transform (parity with `Shape.rotateY`).
|
|
1686
1136
|
|
|
1687
|
-
|
|
1688
|
-
translate(x: number, y: number, z: number): Transform
|
|
1689
|
-
```
|
|
1137
|
+
#### `rotateZ(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the Z axis after the current transform (parity with `Shape.rotateZ`).
|
|
1690
1138
|
|
|
1691
|
-
#### `
|
|
1139
|
+
#### `inverse(): Transform` — Return the inverse transform.
|
|
1692
1140
|
|
|
1693
|
-
|
|
1694
|
-
rotateAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform
|
|
1695
|
-
```
|
|
1141
|
+
#### `point(p: Vec3): Vec3` — Transform a point using homogeneous coordinates.
|
|
1696
1142
|
|
|
1697
|
-
#### `
|
|
1143
|
+
#### `vector(v: Vec3): Vec3` — Transform a direction vector without translation.
|
|
1698
1144
|
|
|
1699
|
-
|
|
1700
|
-
rotateX(angleDeg: number, pivot?: Vec3): Transform
|
|
1701
|
-
```
|
|
1702
|
-
|
|
1703
|
-
#### `rotateY()` — Rotate about the Y axis after the current transform (parity with `Shape.rotateY`).
|
|
1704
|
-
|
|
1705
|
-
```ts
|
|
1706
|
-
rotateY(angleDeg: number, pivot?: Vec3): Transform
|
|
1707
|
-
```
|
|
1708
|
-
|
|
1709
|
-
#### `rotateZ()` — Rotate about the Z axis after the current transform (parity with `Shape.rotateZ`).
|
|
1710
|
-
|
|
1711
|
-
```ts
|
|
1712
|
-
rotateZ(angleDeg: number, pivot?: Vec3): Transform
|
|
1713
|
-
```
|
|
1714
|
-
|
|
1715
|
-
#### `inverse()` — Return the inverse transform.
|
|
1716
|
-
|
|
1717
|
-
```ts
|
|
1718
|
-
inverse(): Transform
|
|
1719
|
-
```
|
|
1720
|
-
|
|
1721
|
-
#### [`point()`](/docs/sketch#point) — Transform a point using homogeneous coordinates.
|
|
1722
|
-
|
|
1723
|
-
```ts
|
|
1724
|
-
point(p: Vec3): Vec3
|
|
1725
|
-
```
|
|
1726
|
-
|
|
1727
|
-
#### `vector()` — Transform a direction vector without translation.
|
|
1728
|
-
|
|
1729
|
-
```ts
|
|
1730
|
-
vector(v: Vec3): Vec3
|
|
1731
|
-
```
|
|
1732
|
-
|
|
1733
|
-
#### `toArray()` — Return the transform as a raw 4x4 matrix array.
|
|
1734
|
-
|
|
1735
|
-
```ts
|
|
1736
|
-
toArray(): Mat4
|
|
1737
|
-
```
|
|
1145
|
+
#### `toArray(): Mat4` — Return the transform as a raw 4x4 matrix array.
|
|
1738
1146
|
|
|
1739
1147
|
### `ShapeGroup`
|
|
1740
1148
|
|
|
@@ -1743,117 +1151,49 @@ toArray(): Mat4
|
|
|
1743
1151
|
| Property | Type | Description |
|
|
1744
1152
|
|----------|------|-------------|
|
|
1745
1153
|
| `children` | `GroupChild[]` | — |
|
|
1746
|
-
| `childNames` | `Array<string
|
|
1154
|
+
| `childNames` | `Array<string \| undefined>` | — |
|
|
1747
1155
|
|
|
1748
1156
|
**Children**
|
|
1749
1157
|
|
|
1750
|
-
#### `child()` — Return the named child by name. Throws if not found. Useful when importing a multipart group and working on components individually.
|
|
1751
|
-
|
|
1752
|
-
```ts
|
|
1753
|
-
child(name: string): GroupChild
|
|
1754
|
-
```
|
|
1755
|
-
|
|
1756
|
-
#### `childName()` — Return the optional name of the child at `index`.
|
|
1158
|
+
#### `child(name: string): GroupChild` — Return the named child by name. Throws if not found. Useful when importing a multipart group and working on components individually.
|
|
1757
1159
|
|
|
1758
|
-
|
|
1759
|
-
childName(index: number): string | undefined
|
|
1760
|
-
```
|
|
1160
|
+
#### `childName(index: number): string | undefined` — Return the optional name of the child at `index`.
|
|
1761
1161
|
|
|
1762
1162
|
**Transforms**
|
|
1763
1163
|
|
|
1764
|
-
#### `translate()` — Move the entire group by (x, y, z). All children move together as a unit.
|
|
1765
|
-
|
|
1766
|
-
```ts
|
|
1767
|
-
translate(x: number, y: number, z: number): ShapeGroup
|
|
1768
|
-
```
|
|
1769
|
-
|
|
1770
|
-
#### `moveTo()` — Move the group so its bounding-box min corner lands at the given coordinate.
|
|
1771
|
-
|
|
1772
|
-
```ts
|
|
1773
|
-
moveTo(x: number, y: number, z: number): ShapeGroup
|
|
1774
|
-
```
|
|
1775
|
-
|
|
1776
|
-
#### `moveToLocal()` — Move the group relative to another part's bounding-box min corner.
|
|
1777
|
-
|
|
1778
|
-
```ts
|
|
1779
|
-
moveToLocal(target: Shape | ShapeGroup, x: number, y: number, z: number): ShapeGroup
|
|
1780
|
-
```
|
|
1781
|
-
|
|
1782
|
-
#### `rotate()` — Rotate the group around an arbitrary axis through the origin.
|
|
1783
|
-
|
|
1784
|
-
```ts
|
|
1785
|
-
rotate(axis: [ number, number, number ], angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1786
|
-
```
|
|
1787
|
-
|
|
1788
|
-
#### `rotateX()` — Rotate the group around the X axis.
|
|
1789
|
-
|
|
1790
|
-
```ts
|
|
1791
|
-
rotateX(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1792
|
-
```
|
|
1793
|
-
|
|
1794
|
-
#### `rotateY()` — Rotate the group around the Y axis.
|
|
1795
|
-
|
|
1796
|
-
```ts
|
|
1797
|
-
rotateY(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1798
|
-
```
|
|
1799
|
-
|
|
1800
|
-
#### `rotateZ()` — Rotate the group around the Z axis.
|
|
1801
|
-
|
|
1802
|
-
```ts
|
|
1803
|
-
rotateZ(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1804
|
-
```
|
|
1164
|
+
#### `translate(x: number, y: number, z: number): ShapeGroup` — Move the entire group by (x, y, z). All children move together as a unit.
|
|
1805
1165
|
|
|
1806
|
-
#### `
|
|
1166
|
+
#### `moveTo(x: number, y: number, z: number): ShapeGroup` — Move the group so its bounding-box min corner lands at the given coordinate.
|
|
1807
1167
|
|
|
1808
|
-
|
|
1809
|
-
rotateAroundAxis(axis: [ number, number, number ], angleDeg: number, pivot?: [ number, number, number ]): ShapeGroup
|
|
1810
|
-
```
|
|
1168
|
+
#### `moveToLocal(target: Shape | ShapeGroup, x: number, y: number, z: number): ShapeGroup` — Move the group relative to another part's bounding-box min corner.
|
|
1811
1169
|
|
|
1812
|
-
#### `
|
|
1170
|
+
#### `rotate(axis: Vec3, angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around an arbitrary axis through the origin. Unlike `scale()`/`mirror()` (bounding-box center) and `Sketch.rotate()`, this pivots at the world origin — pass `options.pivot` to rotate in place.
|
|
1813
1171
|
|
|
1814
|
-
|
|
1815
|
-
rotateAroundTo(axis: [ number, number, number ], pivot: [ number, number, number ], movingPoint: Anchor3D | [ number, number, number ], targetPoint: Anchor3D | [ number, number, number ], options?: RotateAroundToOptions): ShapeGroup
|
|
1816
|
-
```
|
|
1172
|
+
#### `rotateX(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the X axis.
|
|
1817
1173
|
|
|
1818
|
-
#### `
|
|
1174
|
+
#### `rotateY(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the Y axis.
|
|
1819
1175
|
|
|
1820
|
-
|
|
1821
|
-
pointAlong(direction: [ number, number, number ]): ShapeGroup
|
|
1822
|
-
```
|
|
1176
|
+
#### `rotateZ(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the Z axis.
|
|
1823
1177
|
|
|
1824
|
-
#### `
|
|
1178
|
+
#### `rotateAroundAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): ShapeGroup` — Rotate around an arbitrary axis, optionally through a pivot point.
|
|
1825
1179
|
|
|
1826
|
-
|
|
1827
|
-
transform(m: Mat4 | Transform): ShapeGroup
|
|
1828
|
-
```
|
|
1180
|
+
#### `rotateAroundTo(axis: Vec3, pivot: Vec3, movingPoint: Anchor3D | Vec3, targetPoint: Anchor3D | Vec3, options?: RotateAroundToOptions): ShapeGroup` — Rotate around an axis until a moving point reaches the target line/plane defined by the axis and target point. ShapeGroup string points use built-in anchors only.
|
|
1829
1181
|
|
|
1830
|
-
#### `
|
|
1182
|
+
#### `pointAlong(direction: Vec3): ShapeGroup` — Reorient the group so its local Z axis points along `direction`.
|
|
1831
1183
|
|
|
1832
|
-
|
|
1833
|
-
scale(v: number | [ number, number, number ]): ShapeGroup
|
|
1834
|
-
```
|
|
1184
|
+
#### `transform(m: Mat4 | Transform): ShapeGroup` — Apply a 4x4 transform matrix or `Transform` to all 3D children.
|
|
1835
1185
|
|
|
1836
|
-
#### `
|
|
1186
|
+
#### `scale(v: number | Vec3): ShapeGroup` — Scale uniformly or per-axis from the group's bounding-box center.
|
|
1837
1187
|
|
|
1838
|
-
|
|
1839
|
-
scaleAround(pivot: [ number, number, number ], v: number | [ number, number, number ]): ShapeGroup
|
|
1840
|
-
```
|
|
1188
|
+
#### `scaleAround(pivot: Vec3, v: number | Vec3): ShapeGroup` — Scale uniformly or per-axis from an explicit pivot point.
|
|
1841
1189
|
|
|
1842
|
-
#### `mirror()` — Mirror across a plane through the group's bounding-box center.
|
|
1190
|
+
#### `mirror(normal: Vec3): ShapeGroup` — Mirror across a plane through the group's bounding-box center.
|
|
1843
1191
|
|
|
1844
|
-
|
|
1845
|
-
mirror(normal: [ number, number, number ]): ShapeGroup
|
|
1846
|
-
```
|
|
1847
|
-
|
|
1848
|
-
#### `mirrorThrough()` — Mirror across a plane through an explicit point.
|
|
1849
|
-
|
|
1850
|
-
```ts
|
|
1851
|
-
mirrorThrough(point: [ number, number, number ], normal: [ number, number, number ]): ShapeGroup
|
|
1852
|
-
```
|
|
1192
|
+
#### `mirrorThrough(point: Vec3, normal: Vec3): ShapeGroup` — Mirror across a plane through an explicit point.
|
|
1853
1193
|
|
|
1854
1194
|
**Placement**
|
|
1855
1195
|
|
|
1856
|
-
#### `placeReference()` — Translate the group so the given anchor or reference lands on the target coordinate.
|
|
1196
|
+
#### `placeReference(ref: PlacementAnchorLike, target: Vec3, offset?: Vec3): ShapeGroup` — Translate the group so the given anchor or reference lands on the target coordinate.
|
|
1857
1197
|
|
|
1858
1198
|
Accepts any built-in anchor name (`'bottom'`, `'center'`, `'top-front-left'`, etc.) or a custom placement reference attached via `withReferences()`.
|
|
1859
1199
|
|
|
@@ -1866,57 +1206,27 @@ const placed = require('./bracket-assembly.forge.js').group
|
|
|
1866
1206
|
.placeReference('mountCenter', [0, 0, 50]);
|
|
1867
1207
|
```
|
|
1868
1208
|
|
|
1869
|
-
|
|
1870
|
-
placeReference(ref: PlacementAnchorLike, target: [ number, number, number ], offset?: [ number, number, number ]): ShapeGroup
|
|
1871
|
-
```
|
|
1872
|
-
|
|
1873
|
-
#### `attachTo()` — Attach this group to a face or anchor on another part.
|
|
1209
|
+
#### `attachTo(target: Shape | ShapeGroup, targetAnchor: Anchor3D | string, selfAnchor?: Anchor3D, offset?: Vec3): ShapeGroup` — Attach this group to a face or anchor on another part.
|
|
1874
1210
|
|
|
1875
1211
|
`targetAnchor` can be a built-in anchor name or a custom reference name on the target. `selfAnchor` selects the anchor on this group to align.
|
|
1876
1212
|
|
|
1877
|
-
|
|
1878
|
-
attachTo(target: Shape | ShapeGroup, targetAnchor: Anchor3D | string, selfAnchor?: Anchor3D, offset?: [ number, number, number ]): ShapeGroup
|
|
1879
|
-
```
|
|
1880
|
-
|
|
1881
|
-
#### `onFace()` — Place this group on a face of a parent shape. See Shape.onFace() for full documentation.
|
|
1882
|
-
|
|
1883
|
-
```ts
|
|
1884
|
-
onFace(parent: Shape | ShapeGroup, face: "front" | "back" | "left" | "right" | "top" | "bottom", opts?: { u?: number; v?: number; protrude?: number; }): ShapeGroup
|
|
1885
|
-
```
|
|
1213
|
+
#### `onFace(parent: Shape | ShapeGroup, face: "front" | "back" | "left" | "right" | "top" | "bottom", opts?: { u?: number; v?: number; protrude?: number; }): ShapeGroup` — Place this group on a face of a parent shape. See Shape.onFace() for full documentation.
|
|
1886
1214
|
|
|
1887
1215
|
**Connectors**
|
|
1888
1216
|
|
|
1889
|
-
#### `withConnectors()` — Attach named connectors — attachment points that survive transforms. Connectors can be bare (position + orientation) or typed (with connectorType/gender for compatibility matching).
|
|
1217
|
+
#### `withConnectors(connectors: Record<string, ConnectorInput>): ShapeGroup` — Attach named connectors — attachment points that survive transforms. Connectors can be bare (position + orientation) or typed (with connectorType/gender for compatibility matching).
|
|
1890
1218
|
|
|
1891
|
-
|
|
1892
|
-
withConnectors(connectors: Record<string, ConnectorInput>): ShapeGroup
|
|
1893
|
-
```
|
|
1894
|
-
|
|
1895
|
-
#### `connectorNames()` — List all connector names, including "ChildName.connectorName" from named children.
|
|
1896
|
-
|
|
1897
|
-
```ts
|
|
1898
|
-
connectorNames(): string[]
|
|
1899
|
-
```
|
|
1900
|
-
|
|
1901
|
-
#### `connectorsByType()` — Get all connectors of a given type, including from named children.
|
|
1219
|
+
#### `connectorNames(): string[]` — List all connector names, including "ChildName.connectorName" from named children.
|
|
1902
1220
|
|
|
1903
|
-
|
|
1904
|
-
connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>
|
|
1905
|
-
```
|
|
1221
|
+
#### `connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>` — Get all connectors of a given type, including from named children.
|
|
1906
1222
|
|
|
1907
|
-
#### `connectorDistance()` — Distance between two connector origins on this group (supports dotted child paths).
|
|
1223
|
+
#### `connectorDistance(nameA: string, nameB: string): number` — Distance between two connector origins on this group (supports dotted child paths).
|
|
1908
1224
|
|
|
1909
|
-
|
|
1910
|
-
connectorDistance(nameA: string, nameB: string): number
|
|
1911
|
-
```
|
|
1225
|
+
#### `connectorMeasurements(name: string): Record<string, number | string>` — Get measurements metadata from a connector (supports dotted child paths).
|
|
1912
1226
|
|
|
1913
|
-
#### `
|
|
1914
|
-
|
|
1915
|
-
```ts
|
|
1916
|
-
connectorMeasurements(name: string): Record<string, number | string>
|
|
1917
|
-
```
|
|
1227
|
+
#### `matchTo(targetOrPairs: Shape | ShapeGroup | Array<[ Shape | ShapeGroup, string, string ]>, selfConnOrDict?: string | Record<string, string>, targetConnOrOptions?: string | MatchToOptions, maybeOptions?: MatchToOptions): ShapeGroup` — Position this group by matching connectors to a target. Connector names support dotted paths into named children: "ChildName.connectorName".
|
|
1918
1228
|
|
|
1919
|
-
|
|
1229
|
+
Alignment: with a single connector pair, the group translates and rotates so the connector origins coincide and the axes oppose (plug-in model); `up` pins the roll. With multiple pairs, the connector origins define the rigid transform — still author meaningful `axis`/`up` values so the same connectors remain useful for `connect()`, audits, and future matching.
|
|
1920
1230
|
|
|
1921
1231
|
Overloads:
|
|
1922
1232
|
|
|
@@ -1924,13 +1234,9 @@ Overloads:
|
|
|
1924
1234
|
- Dictionary (same target): `matchTo(target, { selfConn: targetConn, ... }, options?)`
|
|
1925
1235
|
- Multi-target: `matchTo([ [target1, selfConn1, targetConn1], ... ], options?)`
|
|
1926
1236
|
|
|
1927
|
-
```ts
|
|
1928
|
-
matchTo(targetOrPairs: Shape | ShapeGroup | Array<[ Shape | ShapeGroup, string, string ]>, selfConnOrDict?: string | Record<string, string>, targetConnOrOptions?: string | MatchToOptions, maybeOptions?: MatchToOptions): ShapeGroup
|
|
1929
|
-
```
|
|
1930
|
-
|
|
1931
1237
|
**References**
|
|
1932
1238
|
|
|
1933
|
-
#### `withReferences()` — Attach named placement references to this group. References survive normal transforms (translate/rotate/scale/mirror/transform).
|
|
1239
|
+
#### `withReferences(refs: PlacementReferenceInput): ShapeGroup` — Attach named placement references to this group. References survive normal transforms (translate/rotate/scale/mirror/transform).
|
|
1934
1240
|
|
|
1935
1241
|
```javascript
|
|
1936
1242
|
const bracket = group(
|
|
@@ -1941,41 +1247,17 @@ const bracket = group(
|
|
|
1941
1247
|
});
|
|
1942
1248
|
```
|
|
1943
1249
|
|
|
1944
|
-
|
|
1945
|
-
withReferences(refs: PlacementReferenceInput): ShapeGroup
|
|
1946
|
-
```
|
|
1947
|
-
|
|
1948
|
-
#### `referenceNames()` — List named placement references carried by this group.
|
|
1949
|
-
|
|
1950
|
-
```ts
|
|
1951
|
-
referenceNames(kind?: PlacementReferenceKind): string[]
|
|
1952
|
-
```
|
|
1953
|
-
|
|
1954
|
-
#### `referencePoint()` — Resolve a named placement reference or built-in Anchor3D to a 3D point. Named refs take priority over built-in anchors.
|
|
1250
|
+
#### `referenceNames(kind?: PlacementReferenceKind): string[]` — List named placement references carried by this group.
|
|
1955
1251
|
|
|
1956
|
-
|
|
1957
|
-
referencePoint(ref: PlacementAnchorLike): [ number, number, number ]
|
|
1958
|
-
```
|
|
1252
|
+
#### `referencePoint(ref: PlacementAnchorLike): Vec3` — Resolve a named placement reference or built-in Anchor3D to a 3D point. Named refs take priority over built-in anchors.
|
|
1959
1253
|
|
|
1960
1254
|
**Other**
|
|
1961
1255
|
|
|
1962
|
-
#### `clone()` — Return a deep-cloned ShapeGroup tree (refs copied).
|
|
1256
|
+
#### `clone(): ShapeGroup` — Return a deep-cloned ShapeGroup tree (refs copied).
|
|
1963
1257
|
|
|
1964
|
-
|
|
1965
|
-
clone(): ShapeGroup
|
|
1966
|
-
```
|
|
1258
|
+
#### `boundingBox(): { min: Vec3; max: Vec3; }` — Return the combined 3D bounding box of all children.
|
|
1967
1259
|
|
|
1968
|
-
#### `
|
|
1969
|
-
|
|
1970
|
-
```ts
|
|
1971
|
-
boundingBox(): { min: [ number, number, number ]; max: [ number, number, number ]; }
|
|
1972
|
-
```
|
|
1973
|
-
|
|
1974
|
-
#### `color()` — Return a copy of the group with the given display color applied to each child.
|
|
1975
|
-
|
|
1976
|
-
```ts
|
|
1977
|
-
color(hex: string): ShapeGroup
|
|
1978
|
-
```
|
|
1260
|
+
#### `color(hex: string): ShapeGroup` — Return a copy of the group with the given display color applied to each child.
|
|
1979
1261
|
|
|
1980
1262
|
**Compatibility Aliases**
|
|
1981
1263
|
|
|
@@ -1993,67 +1275,27 @@ color(hex: string): ShapeGroup
|
|
|
1993
1275
|
|
|
1994
1276
|
### `Pattern2D`
|
|
1995
1277
|
|
|
1996
|
-
#### `add()` — Add this pattern to one or more patterns or constant height offsets.
|
|
1997
|
-
|
|
1998
|
-
```ts
|
|
1999
|
-
add(...patterns: Pattern2DInput[]): Pattern2D
|
|
2000
|
-
```
|
|
2001
|
-
|
|
2002
|
-
#### `subtract()` — Subtract another pattern or constant height offset from this pattern.
|
|
2003
|
-
|
|
2004
|
-
```ts
|
|
2005
|
-
subtract(pattern: Pattern2DInput): Pattern2D
|
|
2006
|
-
```
|
|
2007
|
-
|
|
2008
|
-
#### `multiply()` — Multiply this pattern by one or more patterns or numeric scale factors.
|
|
2009
|
-
|
|
2010
|
-
```ts
|
|
2011
|
-
multiply(...patterns: Pattern2DInput[]): Pattern2D
|
|
2012
|
-
```
|
|
2013
|
-
|
|
2014
|
-
#### `min()` — Keep the lower height between this pattern and one or more other patterns.
|
|
2015
|
-
|
|
2016
|
-
```ts
|
|
2017
|
-
min(...patterns: Pattern2DInput[]): Pattern2D
|
|
2018
|
-
```
|
|
2019
|
-
|
|
2020
|
-
#### `max()` — Keep the higher height between this pattern and one or more other patterns.
|
|
1278
|
+
#### `add(...patterns: Pattern2DInput[]): Pattern2D` — Add this pattern to one or more patterns or constant height offsets.
|
|
2021
1279
|
|
|
2022
|
-
|
|
2023
|
-
max(...patterns: Pattern2DInput[]): Pattern2D
|
|
2024
|
-
```
|
|
1280
|
+
#### `subtract(pattern: Pattern2DInput): Pattern2D` — Subtract another pattern or constant height offset from this pattern.
|
|
2025
1281
|
|
|
2026
|
-
#### `
|
|
1282
|
+
#### `multiply(...patterns: Pattern2DInput[]): Pattern2D` — Multiply this pattern by one or more patterns or numeric scale factors.
|
|
2027
1283
|
|
|
2028
|
-
|
|
2029
|
-
clamp(min: number, max: number): Pattern2D
|
|
2030
|
-
```
|
|
1284
|
+
#### `min(...patterns: Pattern2DInput[]): Pattern2D` — Keep the lower height between this pattern and one or more other patterns.
|
|
2031
1285
|
|
|
2032
|
-
#### `
|
|
1286
|
+
#### `max(...patterns: Pattern2DInput[]): Pattern2D` — Keep the higher height between this pattern and one or more other patterns.
|
|
2033
1287
|
|
|
2034
|
-
|
|
2035
|
-
abs(): Pattern2D
|
|
2036
|
-
```
|
|
1288
|
+
#### `clamp(min: number, max: number): Pattern2D` — Limit pattern height to the inclusive `[min, max]` range in millimeters.
|
|
2037
1289
|
|
|
2038
|
-
#### `
|
|
1290
|
+
#### `abs(): Pattern2D` — Convert negative heights to positive heights.
|
|
2039
1291
|
|
|
2040
|
-
|
|
2041
|
-
negate(): Pattern2D
|
|
2042
|
-
```
|
|
1292
|
+
#### `negate(): Pattern2D` — Flip the pattern height sign.
|
|
2043
1293
|
|
|
2044
1294
|
### `Pattern2DBuilder`
|
|
2045
1295
|
|
|
2046
|
-
#### `constant()` — Create a constant-height pattern in millimeters.
|
|
2047
|
-
|
|
2048
|
-
```ts
|
|
2049
|
-
constant(value?: number): Pattern2D
|
|
2050
|
-
```
|
|
2051
|
-
|
|
2052
|
-
#### `sineWave()` — Create a sinusoidal wave pattern in UV space.
|
|
1296
|
+
#### `constant(value?: number): Pattern2D` — Create a constant-height pattern in millimeters.
|
|
2053
1297
|
|
|
2054
|
-
|
|
2055
|
-
sineWave(options: Pattern2DSineWaveOptions): Pattern2D
|
|
2056
|
-
```
|
|
1298
|
+
#### `sineWave(options: Pattern2DSineWaveOptions): Pattern2D` — Create a sinusoidal wave pattern in UV space.
|
|
2057
1299
|
|
|
2058
1300
|
**`Pattern2DSineWaveOptions`**
|
|
2059
1301
|
|
|
@@ -2065,11 +1307,7 @@ sineWave(options: Pattern2DSineWaveOptions): Pattern2D
|
|
|
2065
1307
|
| `phase?` | `number` | Phase offset in radians. Default: 0. |
|
|
2066
1308
|
| `bias?` | `number` | Constant height offset in millimeters. Default: 0. |
|
|
2067
1309
|
|
|
2068
|
-
#### `stripes()` — Create recessed stripe bands in UV space.
|
|
2069
|
-
|
|
2070
|
-
```ts
|
|
2071
|
-
stripes(options: Pattern2DStripesOptions): Pattern2D
|
|
2072
|
-
```
|
|
1310
|
+
#### `stripes(options: Pattern2DStripesOptions): Pattern2D` — Create recessed stripe bands in UV space.
|
|
2073
1311
|
|
|
2074
1312
|
**`Pattern2DStripesOptions`**
|
|
2075
1313
|
|
|
@@ -2080,11 +1318,7 @@ stripes(options: Pattern2DStripesOptions): Pattern2D
|
|
|
2080
1318
|
| `width` | `number` | Stripe width in surface millimeters. |
|
|
2081
1319
|
| `depth?` | `number` | Stripe groove depth in millimeters. Default: 1. |
|
|
2082
1320
|
|
|
2083
|
-
#### `overUnderWeave()` — Create an over-under woven relief pattern in UV space.
|
|
2084
|
-
|
|
2085
|
-
```ts
|
|
2086
|
-
overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D
|
|
2087
|
-
```
|
|
1321
|
+
#### `overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D` — Create an over-under woven relief pattern in UV space.
|
|
2088
1322
|
|
|
2089
1323
|
**`Pattern2DOverUnderWeaveOptions`**
|
|
2090
1324
|
|
|
@@ -2095,120 +1329,6 @@ overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D
|
|
|
2095
1329
|
| `depth?` | `number` | Thread groove depth in millimeters. Default: 0.8. |
|
|
2096
1330
|
| `underScale?` | `number` | Relative height of the under-crossing thread. Default: 0.15. |
|
|
2097
1331
|
|
|
2098
|
-
### `HermiteCurve3D`
|
|
2099
|
-
|
|
2100
|
-
**Properties:**
|
|
2101
|
-
|
|
2102
|
-
| Property | Type | Description |
|
|
2103
|
-
|----------|------|-------------|
|
|
2104
|
-
| `p0` | `Vec3` | Start position |
|
|
2105
|
-
| `p1` | `Vec3` | End position |
|
|
2106
|
-
| `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
|
|
2107
|
-
| `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
|
|
2108
|
-
| `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
|
|
2109
|
-
|
|
2110
|
-
**Methods:**
|
|
2111
|
-
|
|
2112
|
-
#### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
|
|
2113
|
-
|
|
2114
|
-
```ts
|
|
2115
|
-
pointAt(t: number): Vec3
|
|
2116
|
-
```
|
|
2117
|
-
|
|
2118
|
-
#### `tangentAt()` — Evaluate tangent (first derivative) at parameter t ∈ [0, 1]
|
|
2119
|
-
|
|
2120
|
-
```ts
|
|
2121
|
-
tangentAt(t: number): Vec3
|
|
2122
|
-
```
|
|
2123
|
-
|
|
2124
|
-
#### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
|
|
2125
|
-
|
|
2126
|
-
```ts
|
|
2127
|
-
curvatureAt(t: number): Vec3
|
|
2128
|
-
```
|
|
2129
|
-
|
|
2130
|
-
#### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
|
|
2131
|
-
|
|
2132
|
-
```ts
|
|
2133
|
-
sample(count?: number): Vec3[]
|
|
2134
|
-
```
|
|
2135
|
-
|
|
2136
|
-
#### `length()` — Approximate arc length by sampling.
|
|
2137
|
-
|
|
2138
|
-
```ts
|
|
2139
|
-
length(samples?: number): number
|
|
2140
|
-
```
|
|
2141
|
-
|
|
2142
|
-
#### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
|
|
2143
|
-
|
|
2144
|
-
```ts
|
|
2145
|
-
sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
|
|
2146
|
-
```
|
|
2147
|
-
|
|
2148
|
-
#### `toPolyline()` — Convert to a format compatible with sweep() path input.
|
|
2149
|
-
|
|
2150
|
-
```ts
|
|
2151
|
-
toPolyline(samples?: number): Vec3[]
|
|
2152
|
-
```
|
|
2153
|
-
|
|
2154
|
-
### `QuinticHermiteCurve3D`
|
|
2155
|
-
|
|
2156
|
-
**Properties:**
|
|
2157
|
-
|
|
2158
|
-
| Property | Type | Description |
|
|
2159
|
-
|----------|------|-------------|
|
|
2160
|
-
| `p0` | `Vec3` | Start position |
|
|
2161
|
-
| `p1` | `Vec3` | End position |
|
|
2162
|
-
| `t0` | `Vec3` | Scaled tangent at start (direction * weight * chordLength) |
|
|
2163
|
-
| `t1` | `Vec3` | Scaled tangent at end (direction * weight * chordLength) |
|
|
2164
|
-
| `c0` | `Vec3` | Scaled second derivative at start (curvature * weight² * chordLength²) |
|
|
2165
|
-
| `c1` | `Vec3` | Scaled second derivative at end (curvature * weight² * chordLength²) |
|
|
2166
|
-
| `chordLength` | `number` | Chord length (straight-line distance between endpoints) |
|
|
2167
|
-
|
|
2168
|
-
**Methods:**
|
|
2169
|
-
|
|
2170
|
-
#### `pointAt()` — Evaluate position at parameter t ∈ [0, 1]
|
|
2171
|
-
|
|
2172
|
-
```ts
|
|
2173
|
-
pointAt(t: number): Vec3
|
|
2174
|
-
```
|
|
2175
|
-
|
|
2176
|
-
#### `tangentAt()` — Evaluate tangent (first derivative, normalized) at parameter t ∈ [0, 1]
|
|
2177
|
-
|
|
2178
|
-
```ts
|
|
2179
|
-
tangentAt(t: number): Vec3
|
|
2180
|
-
```
|
|
2181
|
-
|
|
2182
|
-
#### `curvatureAt()` — Evaluate curvature vector (second derivative) at parameter t ∈ [0, 1]
|
|
2183
|
-
|
|
2184
|
-
```ts
|
|
2185
|
-
curvatureAt(t: number): Vec3
|
|
2186
|
-
```
|
|
2187
|
-
|
|
2188
|
-
#### `sample()` — Sample the curve as a polyline of evenly-spaced parameter values.
|
|
2189
|
-
|
|
2190
|
-
```ts
|
|
2191
|
-
sample(count?: number): Vec3[]
|
|
2192
|
-
```
|
|
2193
|
-
|
|
2194
|
-
#### `length()` — Approximate arc length by sampling.
|
|
2195
|
-
|
|
2196
|
-
```ts
|
|
2197
|
-
length(samples?: number): number
|
|
2198
|
-
```
|
|
2199
|
-
|
|
2200
|
-
#### `sampleAdaptive()` — Sample with adaptive density — more points where curvature is higher. Returns at least `minCount` points, up to `maxCount`.
|
|
2201
|
-
|
|
2202
|
-
```ts
|
|
2203
|
-
sampleAdaptive(minCount?: number, maxCount?: number): Vec3[]
|
|
2204
|
-
```
|
|
2205
|
-
|
|
2206
|
-
#### `toPolyline()` — Convert to a format compatible with sweep() path input.
|
|
2207
|
-
|
|
2208
|
-
```ts
|
|
2209
|
-
toPolyline(samples?: number): Vec3[]
|
|
2210
|
-
```
|
|
2211
|
-
|
|
2212
1332
|
### `ShapeRef`
|
|
2213
1333
|
|
|
2214
1334
|
A first-class reference path over a shape's semantic faces and face relationships.
|
|
@@ -2223,107 +1343,39 @@ Created with `shape.ref("lid/back")`, then refined through methods such as `.poi
|
|
|
2223
1343
|
|
|
2224
1344
|
**Methods:**
|
|
2225
1345
|
|
|
2226
|
-
#### `resolve()` — Resolve this reference into its current faces, edges, or points.
|
|
2227
|
-
|
|
2228
|
-
```ts
|
|
2229
|
-
resolve(): ShapeReferenceResolution
|
|
2230
|
-
```
|
|
2231
|
-
|
|
2232
|
-
#### `kind()` — The resolved reference kind, such as `face`, `edge-set`, or [`point`](/docs/sketch#point).
|
|
2233
|
-
|
|
2234
|
-
```ts
|
|
2235
|
-
get kind(): ShapeReferenceKind
|
|
2236
|
-
```
|
|
2237
|
-
|
|
2238
|
-
#### `cardinality()` — Whether the reference currently resolves to zero, one, or many matches.
|
|
2239
|
-
|
|
2240
|
-
```ts
|
|
2241
|
-
get cardinality(): ShapeReferenceCardinality
|
|
2242
|
-
```
|
|
2243
|
-
|
|
2244
|
-
#### `status()` — Return the reference lifecycle status for the current shape state.
|
|
2245
|
-
|
|
2246
|
-
```ts
|
|
2247
|
-
status(): ShapeReferenceStatus
|
|
2248
|
-
```
|
|
2249
|
-
|
|
2250
|
-
#### `explain()` — Return a human-readable explanation of how this reference resolved.
|
|
2251
|
-
|
|
2252
|
-
```ts
|
|
2253
|
-
explain(): string
|
|
2254
|
-
```
|
|
2255
|
-
|
|
2256
|
-
#### `as()` — Name this derived reference so the same shape can resolve it by `shape.ref(name)`.
|
|
2257
|
-
|
|
2258
|
-
```ts
|
|
2259
|
-
as(name: string): ShapeRef
|
|
2260
|
-
```
|
|
2261
|
-
|
|
2262
|
-
#### `maybe()` — Return an optional reference that resolves to zero matches instead of throwing when missing.
|
|
2263
|
-
|
|
2264
|
-
```ts
|
|
2265
|
-
maybe(): ShapeRef
|
|
2266
|
-
```
|
|
2267
|
-
|
|
2268
|
-
#### `all()` — Mark that a multi-match reference is intentionally being used as a set.
|
|
2269
|
-
|
|
2270
|
-
```ts
|
|
2271
|
-
all(): ShapeRef
|
|
2272
|
-
```
|
|
2273
|
-
|
|
2274
|
-
#### `one()` — Require this reference to resolve to exactly one match.
|
|
2275
|
-
|
|
2276
|
-
```ts
|
|
2277
|
-
one(): ShapeRef
|
|
2278
|
-
```
|
|
1346
|
+
#### `resolve(): ShapeReferenceResolution` — Resolve this reference into its current faces, edges, or points.
|
|
2279
1347
|
|
|
2280
|
-
#### `
|
|
1348
|
+
#### `get kind(): ShapeReferenceKind` — The resolved reference kind, such as `face`, `edge-set`, or `point`.
|
|
2281
1349
|
|
|
2282
|
-
|
|
2283
|
-
faces(): FaceRef[]
|
|
2284
|
-
```
|
|
1350
|
+
#### `get cardinality(): ShapeReferenceCardinality` — Whether the reference currently resolves to zero, one, or many matches.
|
|
2285
1351
|
|
|
2286
|
-
#### `
|
|
1352
|
+
#### `status(): ShapeReferenceStatus` — Return the reference lifecycle status for the current shape state.
|
|
2287
1353
|
|
|
2288
|
-
|
|
2289
|
-
face(): FaceRef
|
|
2290
|
-
```
|
|
1354
|
+
#### `explain(): string` — Return a human-readable explanation of how this reference resolved.
|
|
2291
1355
|
|
|
2292
|
-
#### `
|
|
1356
|
+
#### `as(name: string): ShapeRef` — Name this derived reference so the same shape can resolve it by `shape.ref(name)`.
|
|
2293
1357
|
|
|
2294
|
-
|
|
2295
|
-
edges(): EdgeSegment[]
|
|
2296
|
-
```
|
|
1358
|
+
#### `maybe(): ShapeRef` — Return an optional reference that resolves to zero matches instead of throwing when missing.
|
|
2297
1359
|
|
|
2298
|
-
#### `
|
|
1360
|
+
#### `all(): ShapeRef` — Mark that a multi-match reference is intentionally being used as a set.
|
|
2299
1361
|
|
|
2300
|
-
|
|
2301
|
-
edge(): EdgeSegment
|
|
2302
|
-
```
|
|
1362
|
+
#### `one(): ShapeRef` — Require this reference to resolve to exactly one match.
|
|
2303
1363
|
|
|
2304
|
-
#### `
|
|
1364
|
+
#### `faces(): FaceRef[]` — Resolve this reference as one or more faces.
|
|
2305
1365
|
|
|
2306
|
-
|
|
2307
|
-
points(): Vec3[]
|
|
2308
|
-
```
|
|
1366
|
+
#### `face(): FaceRef` — Resolve this reference as exactly one face.
|
|
2309
1367
|
|
|
2310
|
-
####
|
|
1368
|
+
#### `edges(): EdgeSegment[]` — Resolve this reference as one or more edges. Face references return boundary edges.
|
|
2311
1369
|
|
|
2312
|
-
|
|
2313
|
-
point(): Vec3
|
|
2314
|
-
```
|
|
1370
|
+
#### `edge(): EdgeSegment` — Resolve this reference as exactly one edge.
|
|
2315
1371
|
|
|
2316
|
-
#### `
|
|
1372
|
+
#### `points(): Vec3[]` — Resolve this reference as one or more points. Faces use centers and edges use midpoints.
|
|
2317
1373
|
|
|
2318
|
-
|
|
2319
|
-
toJSON(): ShapeReferenceResolution
|
|
2320
|
-
```
|
|
1374
|
+
#### `point(): Vec3` — Resolve this reference as exactly one point.
|
|
2321
1375
|
|
|
2322
|
-
#### `
|
|
1376
|
+
#### `toJSON(): ShapeReferenceResolution` — Return the structured JSON-friendly reference resolution.
|
|
2323
1377
|
|
|
2324
|
-
|
|
2325
|
-
toString(): string
|
|
2326
|
-
```
|
|
1378
|
+
#### `toString(): string` — Return a compact display form for this reference path.
|
|
2327
1379
|
|
|
2328
1380
|
---
|
|
2329
1381
|
|
|
@@ -2333,46 +1385,7 @@ toString(): string
|
|
|
2333
1385
|
|
|
2334
1386
|
### `verify`
|
|
2335
1387
|
|
|
2336
|
-
|
|
2337
|
-
- `equal(label: string, actual: number, expected: number, tolerance?: number, message?: string): void` — Check that two numbers are approximately equal (within tolerance).
|
|
2338
|
-
- `notEqual(label: string, actual: number, unexpected: number, tolerance?: number, message?: string): void` — Check that two numbers are NOT equal (differ by more than tolerance).
|
|
2339
|
-
- `greaterThan(label: string, actual: number, min: number, message?: string): void` — Check that actual > min.
|
|
2340
|
-
- `lessThan(label: string, actual: number, max: number, message?: string): void` — Check that actual < max.
|
|
2341
|
-
- `inRange(label: string, actual: number, min: number, max: number, message?: string): void` — Check that min <= actual <= max.
|
|
2342
|
-
- `centersCoincide(label: string, a: ShapeLike, b: ShapeLike, tolerance?: number): void` — Check that the bounding-box centers of two shapes coincide within tolerance (mm).
|
|
2343
|
-
- `connectorDistance(label: string, target: ConnectorDistanceLike, connectorA: string, connectorB: string, expected?: number, tolerance?: number): void` — Check the distance between two named connectors on a shape or group. Use this when connectors + `matchTo()` define a static assembly interface. It proves the mate at runtime, unlike a plain source-level connector declaration. The common case is `expected = 0`, meaning the two connector origins should coincide after placement. **Example** ```ts verify.connectorDistance("leg is seated", bench, "Rail.leg_0", "Leg0.head", 0, 0.01); ```
|
|
2344
|
-
- `physicalComponentCount(label: string, expected: number): void` — Declare the expected physical connectivity component count for the returned visible model. **Details** Use this for generated mechanical models that should have a clear component graph: one connected fixture, a purchased part plus a removable cartridge, a root assembly plus named intentional ghosts, and so on. `forgecad inspect mechanical-integrity` resolves the returned visible objects with the same physical-connectivity analysis used in the quality gate and fails if the actual component count differs. This catches the common generated-CAD failure where a script returns a visually plausible artifact but the handle, screw, washer, cover, or terminal block is actually a separate island. **Example** ```ts verify.physicalComponentCount("vise is one connected installed assembly", 1); ```
|
|
2345
|
-
- `intentionalOverlap(label: string, a: ShapeLike, b: ShapeLike, reason: string): void` — Declare that two visible objects intentionally overlap because the overlap is real manufacturing intent. **Details** Use this only for overlaps that a mechanical reviewer would accept as actual matter sharing volume: welded/fused regions, overmolded inserts, potted electronics, cast-in hardware, or deliberately bonded laminations. This is not a shortcut for screws without holes, shafts without bores, covers without pockets, or parts placed with collision as a positioning hack. `forgecad inspect mechanical-integrity --collisions` only honors this declaration when both shapes are returned as visible objects and the exact collision report finds that same object pair. Unused or non-visible declarations fail the quality gate so annotations cannot hide unrelated collisions. **Example** ```ts verify.intentionalOverlap("rubber grip is overmolded on handle", rubberGrip, handleCore, "overmolded insert"); ```
|
|
2346
|
-
- `notColliding(label: string, a: ShapeLike, b: ShapeLike, searchLength?: number): void` — Check that two shapes do not share positive volume. Face-to-face contact is allowed; use `verify.minClearance()` when an actual running gap is required.
|
|
2347
|
-
- `minClearance(label: string, a: ShapeLike, b: ShapeLike, minGap: number, searchLength?: number): void` — Check that a minimum clearance gap exists between two shapes.
|
|
2348
|
-
- `clearanceBetween(label: string, a: ShapeLike, b: ShapeLike, minGap: number, maxGap: number, searchLength?: number): void` — Check that the clearance gap between two shapes is inside an allowed range. **Details** Use this for seated and retained interfaces where a part must be close enough to be mechanically accountable, but must not collide beyond the allowed minimum. It catches both failure modes that make generated CAD look fake: parts floating away from their receiver, and parts intersecting their receiver because the pocket, bore, or running clearance was not modeled. For contact, use a narrow range such as `[-0.01, 0.05]` to tolerate tiny numerical noise. For a running fit, use the intended clearance band. Manifold-backed shapes use exact min-gap distance. Other backends use a mesh-derived min-gap check and say so in the verification message; keep `forgecad inspect mechanical-integrity --collisions` in the acceptance gate for positive-volume interference. **Example** ```ts verify.clearanceBetween("cover is seated on gasket", cover, gasket, -0.01, 0.05); verify.clearanceBetween("carriage runs inside rail", carriage, rail, 0.2, 0.5); ```
|
|
2349
|
-
- `parallel(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are parallel (within toleranceDeg degrees).
|
|
2350
|
-
- `perpendicular(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are perpendicular (within toleranceDeg degrees).
|
|
2351
|
-
- `coplanar(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number, toleranceMm?: number): void` — Check that a face is coplanar with (same plane as) another face, meaning they are parallel AND their centers lie on the same plane.
|
|
2352
|
-
- `faceAt(label: string, face: FaceRefLike, expectedPos: [ number, number, number ], toleranceMm?: number): void` — Check that a face center lies at a specific position (within toleranceMm).
|
|
2353
|
-
- `sameDirection(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals point in the same direction (not antiparallel). Stricter than parallel — both |angle| AND sign must match.
|
|
2354
|
-
- `isEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is empty.
|
|
2355
|
-
- `notEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is NOT empty.
|
|
2356
|
-
- `volumeApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void` — Check that a shape's volume is approximately equal to expected (mm³).
|
|
2357
|
-
- `areaApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void` — Check that a shape's surface area is approximately equal to expected (mm²).
|
|
2358
|
-
- `boundingBoxSize(label: string, shape: ShapeLike, expectedSize: [ number, number, number ], tolerance?: number): void` — Check that a shape's bounding box has approximately the given size.
|
|
2359
|
-
- `edgeContinuity(label: string, shape: ShapeLike, options?: EdgeContinuityThresholds): void` — Check that every sampled seam on a shape meets a requested continuity threshold.
|
|
2360
|
-
- `noTinyEdges(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no tiny edges below the requested threshold.
|
|
2361
|
-
- `noSliverFaces(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no sliver faces below the requested score threshold.
|
|
2362
|
-
- `noSelfIntersection(label: string, shape: ShapeLike): void` — Best-effort exact-shape validity guard for self-intersections or broken B-Rep topology.
|
|
2363
|
-
|
|
2364
|
-
### `Constraint`
|
|
2365
|
-
|
|
2366
|
-
- `makeParallel(builder: ConstrainedSketchBuilder, a: LineArg, b: LineArg): ConstrainedSketchBuilder` — Constrain two lines to be parallel.
|
|
2367
|
-
- `enforceAngle(builder: ConstrainedSketchBuilder, a: LineArg, b: LineArg, angleDeg: number): ConstrainedSketchBuilder` — Constrain the signed angle from line `a` to line `b`.
|
|
2368
|
-
- `horizontal(builder: ConstrainedSketchBuilder, line: LineArg): ConstrainedSketchBuilder` — Constrain a line to be horizontal.
|
|
2369
|
-
- `vertical(builder: ConstrainedSketchBuilder, line: LineArg): ConstrainedSketchBuilder` — Constrain a line to be vertical.
|
|
2370
|
-
- `equalLength(builder: ConstrainedSketchBuilder, a: LineArg, b: LineArg): ConstrainedSketchBuilder` — Constrain two lines to have equal length.
|
|
2371
|
-
- `distance(builder: ConstrainedSketchBuilder, a: PointArg, b: PointArg, value: number): ConstrainedSketchBuilder` — Constrain the distance between two points.
|
|
2372
|
-
- `fix(builder: ConstrainedSketchBuilder, pt: PointArg, x: number, y: number): ConstrainedSketchBuilder` — Fix a point at a specific coordinate.
|
|
2373
|
-
- `coincident(builder: ConstrainedSketchBuilder, a: PointArg, b: PointArg): ConstrainedSketchBuilder` — Constrain two points to occupy the same location.
|
|
2374
|
-
- `perpendicular(builder: ConstrainedSketchBuilder, a: LineArg, b: LineArg): ConstrainedSketchBuilder` — Constrain two lines to be perpendicular.
|
|
2375
|
-
- `length(builder: ConstrainedSketchBuilder, line: LineArg, value: number): ConstrainedSketchBuilder` — Constrain the length of a line.
|
|
1388
|
+
Members (full entries under [Verification](#verification)): `verify.that`, `verify.equal`, `verify.notEqual`, `verify.greaterThan`, `verify.lessThan`, `verify.inRange`, `verify.centersCoincide`, `verify.connectorDistance`, `verify.physicalComponentCount`, `verify.intentionalOverlap`, `verify.notColliding`, `verify.minClearance`, `verify.clearanceBetween`, `verify.parallel`, `verify.perpendicular`, `verify.coplanar`, `verify.faceAt`, `verify.sameDirection`, `verify.isEmpty`, `verify.notEmpty`, `verify.volumeApprox`, `verify.areaApprox`, `verify.boundingBoxSize`, `verify.edgeContinuity`, `verify.noTinyEdges`, `verify.noSliverFaces`, `verify.noSelfIntersection`.
|
|
2376
1389
|
|
|
2377
1390
|
### `Points`
|
|
2378
1391
|
|
|
@@ -2381,7 +1394,7 @@ toString(): string
|
|
|
2381
1394
|
- `lerp(a: Vec3, b: Vec3, t: number): Vec3` — Linearly interpolate between two 3D points. t=0 returns a, t=1 returns b.
|
|
2382
1395
|
- `direction(a: Vec3, b: Vec3): Vec3` — Unit direction vector from a to b. Throws if a and b are the same point.
|
|
2383
1396
|
- `offset(point: Vec3, dir: Vec3, amount: number): Vec3` — Move a point along a direction vector by a given amount.
|
|
2384
|
-
- `polar(length: number, angleDeg: number, from?:
|
|
1397
|
+
- `polar(length: number, angleDeg: number, from?: Vec2): Vec2` — Compute a 2D point at distance and angle (degrees) from an optional origin.
|
|
2385
1398
|
|
|
2386
1399
|
### `connector`
|
|
2387
1400
|
|
|
@@ -2389,6 +1402,19 @@ Connector factory. Create attachment points: `connector({...})`, `connector.male
|
|
|
2389
1402
|
|
|
2390
1403
|
### `Import`
|
|
2391
1404
|
|
|
2392
|
-
Namespaced file import helpers for
|
|
1405
|
+
Namespaced file-format import helpers — the single vocabulary for bringing external geometry files into a model.
|
|
2393
1406
|
|
|
2394
1407
|
- `dxfSketch(fileName: string, options?: DxfImportOptions): Sketch` — Parse a DXF file and return closed 2D profile geometry as a Sketch. The result can be extruded directly.
|
|
1408
|
+
- `svgSketch(fileName: string, options?: SvgImportOptions): Sketch` — Parse an SVG file and return it as a Sketch with options for region filtering, scaling, and simplification.
|
|
1409
|
+
- `mesh(fileName: string, options?: { scale?: number; center?: boolean; object?: string; separateObjects?: boolean; }): Shape | ShapeGroup` — Import an external mesh file (STL, OBJ, 3MF).
|
|
1410
|
+
|
|
1411
|
+
By default, 3MF build items are flattened into one Shape for compatibility. Use `separateObjects: true` to import 3MF build items/resource objects as a named ShapeGroup whose children are targetable by `forgecad ls`. Use `object` to import one item by the stable ref/name reported by `forgecad run`.
|
|
1412
|
+
|
|
1413
|
+
For 3MF sources, `forgecad run` prints a source-structure table with one line per build item: `[3mf:build:NNN:object:N] name type=... verts=... tris=... bbox=[min] → [max]`. Build items are numbered from `001`; files with no build items list resource objects as `3mf:object:N` instead. Per-item bboxes reveal multi-part structure — account for every substantial item before flattening. Pass any listed stable ref or name as `object` to import that item alone.
|
|
1414
|
+
|
|
1415
|
+
```js
|
|
1416
|
+
const all = Import.mesh("./assembly.3mf", { separateObjects: true });
|
|
1417
|
+
const pin = all.child("Pin #001");
|
|
1418
|
+
const plate = Import.mesh("./assembly.3mf", { object: "3mf:build:001:object:7" });
|
|
1419
|
+
```
|
|
1420
|
+
- `step(fileName: string): Shape` — Import a STEP file (.step, .stp) as an exact OCCT-backed Shape. Preserves NURBS curves, B-spline surfaces, and exact topology. Requires running with the OCCT backend.
|