forgecad 0.9.16 → 0.10.1
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-DcCnj0qo.js} +1 -1
- package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-BVEpJSVk.js} +1 -1
- package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DHaGP50_.js} +1 -1
- package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-CDoxHkz8.js} +40 -859
- package/dist/assets/EditorApp-BJ0Dloyh.js +16446 -0
- package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-CRKZbY0y.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-BxHkYRE7.js} +1 -1
- package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-B-u6FrVv.js} +1 -1
- package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-CzpZ6-Ce.js} +1 -1
- package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-CIZSSAd0.js} +1 -1
- package/dist/assets/{app-CE3sYcV7.css → app-CjsbDlb7.css} +143 -0
- package/dist/assets/{app-T0pDcSX4.js → app-DaTMg3nH.js} +1310 -290
- package/dist/assets/cli/{render-C5pcIISc.js → render-DPf4AYJK.js} +55 -60
- package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
- package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-CjZZWRWW.js} +5209 -2643
- package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
- package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DzQOViQH.js} +1 -1
- package/dist/assets/{manifold-BWgsjmAM.js → manifold-BYlzU521.js} +1 -1
- package/dist/assets/{manifold-D6IFSkhH.js → manifold-DgXo0T5P.js} +2 -2
- package/dist/assets/{manifold-rZexZI0G.js → manifold-K1SkarlQ.js} +1 -1
- package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-B9nWwSrB.js} +8501 -3393
- package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-prBw_s8t.js} +6067 -3479
- 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 +77 -240
- package/dist/docs-raw/README.md +6 -0
- package/dist/docs-raw/component-model.md +17 -150
- package/dist/docs-raw/generated/assembly.md +188 -582
- package/dist/docs-raw/generated/concepts.md +259 -3501
- package/dist/docs-raw/generated/core.md +283 -1250
- 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 +35 -99
- 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/guides/simready-quickstart.md +171 -0
- package/dist/docs-raw/simulation-workflow.md +273 -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 +2 -2
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +25 -13
- package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-II7NLPAB.js} +1 -1
- package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-7462TR3R.js} +1 -1
- package/dist-cli/{chunk-SPZE3DUY.js → chunk-UWTJCGXF.js} +5848 -2915
- package/dist-cli/forgecad.js +3496 -703
- package/dist-skill/CONTEXT.md +1797 -7963
- package/dist-skill/SKILL.md +15 -15
- package/dist-skill/docs/API/core/concepts.md +27 -157
- package/dist-skill/docs/CLI.md +77 -240
- package/dist-skill/docs/generated/assembly.md +182 -532
- package/dist-skill/docs/generated/core.md +283 -1250
- 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 +35 -99
- 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/examples/robotics/README.md +46 -0
- package/examples/robotics/scout-cam-rover-simready/README.md +119 -0
- package/examples/robotics/scout-cam-rover-simready/lib/dims.js +140 -0
- package/examples/robotics/scout-cam-rover-simready/main.forge.js +343 -0
- package/examples/robotics/scout-cam-rover-simready/parts/body.forge.js +304 -0
- package/examples/robotics/scout-cam-rover-simready/parts/chassis.forge.js +320 -0
- package/examples/robotics/scout-cam-rover-simready/parts/hardware.forge.js +21 -0
- package/examples/robotics/scout-cam-rover-simready/parts/turret.forge.js +70 -0
- package/examples/robotics/scout-cam-rover-simready/parts/wheel.forge.js +116 -0
- package/examples/robotics/simready-asset-crate.forge.js +79 -0
- package/examples/robotics/simready-diff-drive-rover.forge.js +141 -0
- package/examples/robotics/simready-parallel-gripper.forge.js +102 -0
- 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,9 +107,12 @@ 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
|
|
|
114
|
+
Selectorless (all-edges) calls draw from a per-run broad edge-feature budget. Exceeding it throws — except in live preview, which skips the finish with a warning for responsiveness. Explicit edge selectors are never budgeted; `FORGECAD_BROAD_EDGE_FEATURE_BUDGET` / `FORGECAD_ALLOW_BROAD_EDGE_FEATURES=1` raise or lift the budget.
|
|
115
|
+
|
|
141
116
|
```ts
|
|
142
117
|
// Fillet all edges
|
|
143
118
|
fillet(myShape, 2)
|
|
@@ -148,19 +123,21 @@ fillet(myShape, 1.5, { atZ: 20, convex: true })
|
|
|
148
123
|
// Fillet vertical edges selected beforehand
|
|
149
124
|
const edges = selectEdges(myShape, { parallel: [0, 0, 1] })
|
|
150
125
|
fillet(myShape, 3, edges)
|
|
151
|
-
```
|
|
152
126
|
|
|
153
|
-
|
|
154
|
-
|
|
127
|
+
// Exact compiler-owned fillet on a tracked box edge
|
|
128
|
+
const base = box(50, 50, 20)
|
|
129
|
+
fillet(base, 5, base.edge('vert-br'))
|
|
155
130
|
```
|
|
156
131
|
|
|
157
|
-
#### `chamfer()` — Apply experimental chamfers (beveled edges) to one or more edges of a shape.
|
|
132
|
+
#### `chamfer(shape: Shape, size: number, edges?: EdgeSelector): Shape` — Apply experimental chamfers (beveled edges) to one or more edges of a shape.
|
|
158
133
|
|
|
159
|
-
**Experimental**:
|
|
134
|
+
**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
135
|
|
|
161
136
|
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
137
|
|
|
163
|
-
|
|
138
|
+
Selectorless (all-edges) calls draw from a per-run broad edge-feature budget. Exceeding it throws — except in live preview, which skips the finish with a warning for responsiveness. Explicit edge selectors are never budgeted; `FORGECAD_BROAD_EDGE_FEATURE_BUDGET` / `FORGECAD_ALLOW_BROAD_EDGE_FEATURES=1` raise or lift the budget.
|
|
139
|
+
|
|
140
|
+
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
141
|
|
|
165
142
|
```ts
|
|
166
143
|
// Chamfer all edges
|
|
@@ -168,13 +145,13 @@ chamfer(myShape, 1)
|
|
|
168
145
|
|
|
169
146
|
// Chamfer only vertical edges
|
|
170
147
|
chamfer(myShape, 2, { parallel: [0, 0, 1] })
|
|
171
|
-
```
|
|
172
148
|
|
|
173
|
-
|
|
174
|
-
|
|
149
|
+
// Exact compiler-owned chamfer on a tracked box edge
|
|
150
|
+
const base = box(50, 50, 20)
|
|
151
|
+
chamfer(base, 3, base.edge('vert-br'))
|
|
175
152
|
```
|
|
176
153
|
|
|
177
|
-
#### `draft()` — Apply a draft angle (taper) to vertical faces for mold extraction.
|
|
154
|
+
#### `draft(shape: Shape, angleDeg: number, pullDirection?: Vec3, neutralPlaneOffset?: number): Shape` — Apply a draft angle (taper) to vertical faces for mold extraction.
|
|
178
155
|
|
|
179
156
|
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
157
|
|
|
@@ -188,11 +165,7 @@ draft(myBox, 3)
|
|
|
188
165
|
draft(myShape, 2, [0, 0, 1], 10)
|
|
189
166
|
```
|
|
190
167
|
|
|
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.
|
|
168
|
+
#### `offsetSolid(shape: Shape, thickness: number): Shape` — Uniformly offset all surfaces of a solid inward or outward.
|
|
196
169
|
|
|
197
170
|
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
171
|
|
|
@@ -206,13 +179,9 @@ offsetSolid(myBox, 1)
|
|
|
206
179
|
offsetSolid(myShape, -0.5)
|
|
207
180
|
```
|
|
208
181
|
|
|
209
|
-
```ts
|
|
210
|
-
offsetSolid(shape: Shape, thickness: number): Shape
|
|
211
|
-
```
|
|
212
|
-
|
|
213
182
|
### Patterns & Layout
|
|
214
183
|
|
|
215
|
-
#### `circularLayout()` — Compute evenly-spaced positions around a circle.
|
|
184
|
+
#### `circularLayout(count: number, radius: number, options?: CircularLayoutOptions): LayoutPoint[]` — Compute evenly-spaced positions around a circle.
|
|
216
185
|
|
|
217
186
|
Eliminates the most common trig pattern in CAD scripts:
|
|
218
187
|
|
|
@@ -229,10 +198,6 @@ for (const {x, y} of circularLayout(12, r)) {
|
|
|
229
198
|
}
|
|
230
199
|
```
|
|
231
200
|
|
|
232
|
-
```ts
|
|
233
|
-
circularLayout(count: number, radius: number, options?: CircularLayoutOptions): LayoutPoint[]
|
|
234
|
-
```
|
|
235
|
-
|
|
236
201
|
**`CircularLayoutOptions`**
|
|
237
202
|
- `startDeg?: number` — Angle of the first element in degrees (default: 0 = +X axis).
|
|
238
203
|
- `centerX?: number` — Center X coordinate (default: 0).
|
|
@@ -240,7 +205,7 @@ circularLayout(count: number, radius: number, options?: CircularLayoutOptions):
|
|
|
240
205
|
|
|
241
206
|
`LayoutPoint`: `{ x: number, y: number }`
|
|
242
207
|
|
|
243
|
-
#### `polygonVertices()` — Compute the vertex positions of a regular polygon.
|
|
208
|
+
#### `polygonVertices(sides: number, radius: number, options?: PolygonVerticesOptions): LayoutPoint[]` — Compute the vertex positions of a regular polygon.
|
|
244
209
|
|
|
245
210
|
Default orientation places the first vertex at the top (90 degrees), matching the convention used by [`ngon()`](/docs/sketch#ngon).
|
|
246
211
|
|
|
@@ -256,16 +221,12 @@ const v3 = [center.x + r, center.y];
|
|
|
256
221
|
const [v1, v2, v3] = polygonVertices(3, r);
|
|
257
222
|
```
|
|
258
223
|
|
|
259
|
-
```ts
|
|
260
|
-
polygonVertices(sides: number, radius: number, options?: PolygonVerticesOptions): LayoutPoint[]
|
|
261
|
-
```
|
|
262
|
-
|
|
263
224
|
**`PolygonVerticesOptions`**
|
|
264
225
|
- `startDeg?: number` — Angle of the first vertex in degrees (default: 90 = top).
|
|
265
226
|
- `centerX?: number` — Center X coordinate (default: 0).
|
|
266
227
|
- `centerY?: number` — Center Y coordinate (default: 0).
|
|
267
228
|
|
|
268
|
-
#### `linearPattern()` — Repeat a shape in a linear pattern along a direction vector and union the copies.
|
|
229
|
+
#### `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
230
|
|
|
270
231
|
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
232
|
|
|
@@ -274,11 +235,7 @@ Creates `count` copies of `shape`, each offset by `(dx*i, dy*i, dz*i)` from the
|
|
|
274
235
|
linearPattern(cylinder(10, 3), 5, 20, 0)
|
|
275
236
|
```
|
|
276
237
|
|
|
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.
|
|
238
|
+
#### `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
239
|
|
|
283
240
|
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
241
|
|
|
@@ -295,32 +252,20 @@ circularPattern(cylinder(12, 4).translate(30, 0, -1), 8)
|
|
|
295
252
|
circularPattern(myFeature, 4, { axis: [1, 0, 0], origin: [0, 0, 50] })
|
|
296
253
|
```
|
|
297
254
|
|
|
298
|
-
```ts
|
|
299
|
-
circularPattern(shape: Shape, count: number, centerXOrOpts?: number | CircularPatternOptions, centerY?: number): Shape
|
|
300
|
-
```
|
|
301
|
-
|
|
302
255
|
**`CircularPatternOptions`**
|
|
303
256
|
|
|
304
257
|
| Option | Type | Description |
|
|
305
258
|
|--------|------|-------------|
|
|
306
259
|
| `centerX?` | `number` | Center X of the rotation (default: 0). Used when the rotation axis is Z. |
|
|
307
260
|
| `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.
|
|
261
|
+
| `axis?` | `Vec3` | Rotation axis direction (default: [0, 0, 1] = Z axis). |
|
|
262
|
+
| `origin?` | `Vec3` | Pivot point for the rotation (default: [0, 0, 0]). Overrides centerX/centerY when set. |
|
|
312
263
|
|
|
313
|
-
|
|
314
|
-
linearPattern2d(sketch: Sketch, count: number, dx: number, dy?: number): Sketch
|
|
315
|
-
```
|
|
264
|
+
#### `linearPattern2d(sketch: Sketch, count: number, dx: number, dy?: number): Sketch` — Repeat a 2D sketch in a linear pattern and union the copies.
|
|
316
265
|
|
|
317
|
-
#### `circularPattern2d()` — Repeat a 2D sketch in a circular pattern around a center point and union the copies.
|
|
318
|
-
|
|
319
|
-
```ts
|
|
320
|
-
circularPattern2d(sketch: Sketch, count: number, centerXOrOpts?: number | { centerX?: number; centerY?: number; startDeg?: number; }, centerY?: number): Sketch
|
|
321
|
-
```
|
|
266
|
+
#### `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
267
|
|
|
323
|
-
#### `mirrorCopy()` — Mirror a shape across a plane and union the mirror with the original.
|
|
268
|
+
#### `mirrorCopy(shape: Shape, normal: Vec3): Shape` — Mirror a shape across a plane and union the mirror with the original.
|
|
324
269
|
|
|
325
270
|
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
271
|
|
|
@@ -329,11 +274,7 @@ The mirror plane passes through the origin and is defined by its normal vector.
|
|
|
329
274
|
mirrorCopy(box(50, 30, 10), [1, 0, 0])
|
|
330
275
|
```
|
|
331
276
|
|
|
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.
|
|
277
|
+
#### `selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]` — Select all edges from a shape that match the given query.
|
|
337
278
|
|
|
338
279
|
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
280
|
|
|
@@ -348,10 +289,6 @@ for (const edge of coalesceEdges(topEdges)) {
|
|
|
348
289
|
}
|
|
349
290
|
```
|
|
350
291
|
|
|
351
|
-
```ts
|
|
352
|
-
selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]
|
|
353
|
-
```
|
|
354
|
-
|
|
355
292
|
**`EdgeQuery`**
|
|
356
293
|
|
|
357
294
|
| Option | Type | Description |
|
|
@@ -383,9 +320,10 @@ selectEdges(shape: Shape, query?: EdgeQuery): EdgeSegment[]
|
|
|
383
320
|
| `normalA` | `Vec3` | Normal of first adjacent face. |
|
|
384
321
|
| `normalB` | `Vec3` | Normal of second adjacent face (same as normalA for boundary edges). |
|
|
385
322
|
| `boundary` | `boolean` | true if this is a boundary (unmatched) edge — unusual for closed solids. |
|
|
386
|
-
| `start`, `end`, `midpoint`, `length` | | — |
|
|
387
323
|
|
|
388
|
-
|
|
324
|
+
Also: `start: Vec3`, `end: Vec3`, `midpoint: Vec3`, `length: number`.
|
|
325
|
+
|
|
326
|
+
#### `selectEdge(shape: Shape, query?: EdgeQuery): EdgeSegment` — Select the single best-matching edge from a shape.
|
|
389
327
|
|
|
390
328
|
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
329
|
|
|
@@ -395,11 +333,7 @@ const bottomEdge = selectEdge(part, { near: [25, 0, 0], atZ: 0 });
|
|
|
395
333
|
result = chamfer(result, 1.5, bottomEdge);
|
|
396
334
|
```
|
|
397
335
|
|
|
398
|
-
|
|
399
|
-
selectEdge(shape: Shape, query?: EdgeQuery): EdgeSegment
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
#### `coalesceEdges()` — Merge collinear edge segments into longer logical edges.
|
|
336
|
+
#### `coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]` — Merge collinear edge segments into longer logical edges.
|
|
403
337
|
|
|
404
338
|
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
339
|
|
|
@@ -412,16 +346,14 @@ for (const edge of coalesceEdges(topEdges)) {
|
|
|
412
346
|
}
|
|
413
347
|
```
|
|
414
348
|
|
|
415
|
-
```ts
|
|
416
|
-
coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]
|
|
417
|
-
```
|
|
418
|
-
|
|
419
349
|
### Imports & Composition
|
|
420
350
|
|
|
421
|
-
#### `require()` — Import a module with optional ForgeCAD parameter overrides. Returns the module's exports.
|
|
351
|
+
#### `require(path: string, paramOverrides?: Record<string, number | string>): any` — Import a module with optional ForgeCAD parameter overrides. Returns the module's exports.
|
|
422
352
|
|
|
423
353
|
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
354
|
|
|
355
|
+
**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.
|
|
356
|
+
|
|
425
357
|
**Assembly return contract**
|
|
426
358
|
|
|
427
359
|
| `.forge.js` return value | `require()` result |
|
|
@@ -480,57 +412,20 @@ const wheel = profiles.make.wheelProfile().extrude(8);
|
|
|
480
412
|
|
|
481
413
|
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
414
|
|
|
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`.
|
|
415
|
+
**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
416
|
|
|
515
417
|
```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
|
|
418
|
+
// part.forge.js
|
|
419
|
+
function bracket() { ... }
|
|
420
|
+
if (require.main === module) {
|
|
421
|
+
return { preview: [{ name: 'Bracket', shape: bracket() }] }; // direct run: render it
|
|
422
|
+
}
|
|
423
|
+
return { make: { bracket } }; // imported: builders only
|
|
529
424
|
```
|
|
530
425
|
|
|
531
426
|
### Parameters
|
|
532
427
|
|
|
533
|
-
#### `Param.number()` — Declare a numeric parameter that renders as a slider in the UI.
|
|
428
|
+
#### `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
429
|
|
|
535
430
|
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
431
|
|
|
@@ -560,11 +455,7 @@ const bracket = require("./bracket.forge.js", { Width: 80 });
|
|
|
560
455
|
|
|
561
456
|
Also available as the shorthand alias `param()`.
|
|
562
457
|
|
|
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.
|
|
458
|
+
#### `Param.string(name: string, defaultValue: string, opts?: { maxLength?: number; }): string` — Declare a string parameter that renders as a text input in the UI.
|
|
568
459
|
|
|
569
460
|
String parameters let users type free-form text — labels, names, inscriptions, file paths, etc. The `name` string is the override key.
|
|
570
461
|
|
|
@@ -581,11 +472,7 @@ const tag = require("./tag.forge.js", { Label: "Custom Text" });
|
|
|
581
472
|
|
|
582
473
|
Only available as `Param.string()` — no standalone alias.
|
|
583
474
|
|
|
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.
|
|
475
|
+
#### `Param.bool(name: string, defaultValue: boolean): boolean` — Declare a boolean parameter that renders as a checkbox in the UI.
|
|
589
476
|
|
|
590
477
|
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
478
|
|
|
@@ -601,13 +488,7 @@ Override via import:
|
|
|
601
488
|
const pan = require("./pan.forge.js", { "Show Lid": 0 });
|
|
602
489
|
```
|
|
603
490
|
|
|
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.
|
|
491
|
+
#### `Param.choice(name: string, defaultValue: string, choices: string[]): string` — Declare a choice parameter that renders as a dropdown in the UI.
|
|
611
492
|
|
|
612
493
|
`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
494
|
|
|
@@ -630,13 +511,7 @@ Override via CLI:
|
|
|
630
511
|
forgecad run model.forge.js --param "Pan Style=wok"
|
|
631
512
|
```
|
|
632
513
|
|
|
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.
|
|
514
|
+
#### `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
515
|
|
|
641
516
|
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
517
|
|
|
@@ -646,15 +521,11 @@ Field types:
|
|
|
646
521
|
- Choice fields (`choices: [...]` in field defs) return as `string`
|
|
647
522
|
- All other fields return as `number`
|
|
648
523
|
|
|
649
|
-
```ts
|
|
650
|
-
Param.list<T extends Record<string, number | boolean | string>>(name: string, defaultItems: T[], opts: { ... }): T[]
|
|
651
|
-
```
|
|
652
|
-
|
|
653
524
|
`ListParamFieldDef`: `{ min?: number, max?: number, step?: number, unit?: string, integer?: boolean, boolean?: boolean, choices?: string[] }`
|
|
654
525
|
|
|
655
526
|
### Grouping & Local Coordinates
|
|
656
527
|
|
|
657
|
-
#### `group()` — Group multiple shapes/sketches for joint transforms without merging into a single mesh.
|
|
528
|
+
#### `group(...items: GroupInput[]): ShapeGroup` — Group multiple shapes/sketches for joint transforms without merging into a single mesh.
|
|
658
529
|
|
|
659
530
|
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
531
|
|
|
@@ -673,87 +544,35 @@ const indoorUnit = group(
|
|
|
673
544
|
).translate(0, -18, 70);
|
|
674
545
|
```
|
|
675
546
|
|
|
676
|
-
```ts
|
|
677
|
-
group(...items: GroupInput[]): ShapeGroup
|
|
678
|
-
```
|
|
679
|
-
|
|
680
547
|
### Section & Projection
|
|
681
548
|
|
|
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
|
-
```
|
|
549
|
+
#### `intersectWithPlane(shape: Shape, plane: PlaneSpec): Sketch` — Cross-section: slice a 3D shape with a plane and return the intersection as a 2D Sketch.
|
|
687
550
|
|
|
688
|
-
#### `faceProfile()` — Extract the boundary profile of a named face as a 2D sketch.
|
|
551
|
+
#### `faceProfile(shape: Shape, face: FaceSelector): Sketch` — Extract the boundary profile of a named face as a 2D sketch.
|
|
689
552
|
|
|
690
553
|
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
554
|
|
|
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
|
-
```
|
|
555
|
+
#### `projectToPlane(shape: Shape, plane: PlaneSpec): Sketch` — Orthographically project a 3D shape onto a plane and return the silhouette as a 2D Sketch.
|
|
709
556
|
|
|
710
557
|
### Verification
|
|
711
558
|
|
|
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
|
-
```
|
|
559
|
+
#### `verify.that(label: string, check: () => boolean, message?: string): void` — Custom predicate check.
|
|
735
560
|
|
|
736
|
-
#### `verify.
|
|
561
|
+
#### `verify.equal(label: string, actual: number, expected: number, tolerance?: number, message?: string): void` — Check that two numbers are approximately equal (within tolerance).
|
|
737
562
|
|
|
738
|
-
|
|
739
|
-
verify.lessThan(label: string, actual: number, max: number, message?: string): void
|
|
740
|
-
```
|
|
563
|
+
#### `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
564
|
|
|
742
|
-
#### `verify.
|
|
565
|
+
#### `verify.greaterThan(label: string, actual: number, min: number, message?: string): void` — Check that actual > min.
|
|
743
566
|
|
|
744
|
-
|
|
745
|
-
verify.inRange(label: string, actual: number, min: number, max: number, message?: string): void
|
|
746
|
-
```
|
|
567
|
+
#### `verify.lessThan(label: string, actual: number, max: number, message?: string): void` — Check that actual < max.
|
|
747
568
|
|
|
748
|
-
#### `verify.
|
|
569
|
+
#### `verify.inRange(label: string, actual: number, min: number, max: number, message?: string): void` — Check that min <= actual <= max.
|
|
749
570
|
|
|
750
|
-
|
|
751
|
-
verify.centersCoincide(label: string, a: ShapeLike, b: ShapeLike, tolerance?: number): void
|
|
752
|
-
```
|
|
571
|
+
#### `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
572
|
|
|
754
573
|
`ShapeLike`: `{ min: number[], max: number[] }`
|
|
755
574
|
|
|
756
|
-
#### `verify.connectorDistance()` — Check the distance between two named connectors on a shape or group.
|
|
575
|
+
#### `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
576
|
|
|
758
577
|
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
578
|
|
|
@@ -761,11 +580,7 @@ Use this when connectors + `matchTo()` define a static assembly interface. It pr
|
|
|
761
580
|
verify.connectorDistance("leg is seated", bench, "Rail.leg_0", "Leg0.head", 0, 0.01);
|
|
762
581
|
```
|
|
763
582
|
|
|
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.
|
|
583
|
+
#### `verify.physicalComponentCount(label: string, expected: number): void` — Declare the expected physical connectivity component count for the returned visible model.
|
|
769
584
|
|
|
770
585
|
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
586
|
|
|
@@ -775,11 +590,7 @@ This catches the common generated-CAD failure where a script returns a visually
|
|
|
775
590
|
verify.physicalComponentCount("vise is one connected installed assembly", 1);
|
|
776
591
|
```
|
|
777
592
|
|
|
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.
|
|
593
|
+
#### `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
594
|
|
|
784
595
|
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
596
|
|
|
@@ -789,25 +600,13 @@ Use this only for overlaps that a mechanical reviewer would accept as actual mat
|
|
|
789
600
|
verify.intentionalOverlap("rubber grip is overmolded on handle", rubberGrip, handleCore, "overmolded insert");
|
|
790
601
|
```
|
|
791
602
|
|
|
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.
|
|
603
|
+
#### `verify.notColliding(label: string, a: ShapeLike, b: ShapeLike, searchLength?: number): void` — Check that two shapes do not share positive volume.
|
|
797
604
|
|
|
798
605
|
Face-to-face contact is allowed; use `verify.minClearance()` when an actual running gap is required.
|
|
799
606
|
|
|
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.
|
|
607
|
+
#### `verify.minClearance(label: string, a: ShapeLike, b: ShapeLike, minGap: number, searchLength?: number): void` — Check that a minimum clearance gap exists between two shapes.
|
|
805
608
|
|
|
806
|
-
|
|
807
|
-
verify.minClearance(label: string, a: ShapeLike, b: ShapeLike, minGap: number, searchLength?: number): void
|
|
808
|
-
```
|
|
809
|
-
|
|
810
|
-
#### `verify.clearanceBetween()` — Check that the clearance gap between two shapes is inside an allowed range.
|
|
609
|
+
#### `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
610
|
|
|
812
611
|
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
612
|
|
|
@@ -820,99 +619,39 @@ verify.clearanceBetween("cover is seated on gasket", cover, gasket, -0.01, 0.05)
|
|
|
820
619
|
verify.clearanceBetween("carriage runs inside rail", carriage, rail, 0.2, 0.5);
|
|
821
620
|
```
|
|
822
621
|
|
|
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 ] }`
|
|
834
|
-
|
|
835
|
-
#### `verify.perpendicular()` — Check that two face normals are perpendicular (within toleranceDeg degrees).
|
|
836
|
-
|
|
837
|
-
```ts
|
|
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.
|
|
622
|
+
#### `verify.parallel(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are parallel (within toleranceDeg degrees).
|
|
860
623
|
|
|
861
|
-
|
|
862
|
-
verify.isEmpty(label: string, shape: ShapeLike, message?: string): void
|
|
863
|
-
```
|
|
624
|
+
`FaceRefLike`: `{ normal: Vec3, center: Vec3 }`
|
|
864
625
|
|
|
865
|
-
#### `verify.
|
|
626
|
+
#### `verify.perpendicular(label: string, faceA: FaceRefLike, faceB: FaceRefLike, toleranceDeg?: number): void` — Check that two face normals are perpendicular (within toleranceDeg degrees).
|
|
866
627
|
|
|
867
|
-
|
|
868
|
-
verify.notEmpty(label: string, shape: ShapeLike, message?: string): void
|
|
869
|
-
```
|
|
628
|
+
#### `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
629
|
|
|
871
|
-
#### `verify.
|
|
630
|
+
#### `verify.faceAt(label: string, face: FaceRefLike, expectedPos: Vec3, toleranceMm?: number): void` — Check that a face center lies at a specific position (within toleranceMm).
|
|
872
631
|
|
|
873
|
-
|
|
874
|
-
verify.volumeApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void
|
|
875
|
-
```
|
|
632
|
+
#### `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
633
|
|
|
877
|
-
#### `verify.
|
|
634
|
+
#### `verify.isEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is empty.
|
|
878
635
|
|
|
879
|
-
|
|
880
|
-
verify.areaApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void
|
|
881
|
-
```
|
|
636
|
+
#### `verify.notEmpty(label: string, shape: ShapeLike, message?: string): void` — Check that a shape is NOT empty.
|
|
882
637
|
|
|
883
|
-
#### `verify.
|
|
638
|
+
#### `verify.volumeApprox(label: string, shape: ShapeLike, expected: number, tolerance?: number): void` — Check that a shape's volume is approximately equal to expected (mm³).
|
|
884
639
|
|
|
885
|
-
|
|
886
|
-
verify.boundingBoxSize(label: string, shape: ShapeLike, expectedSize: [ number, number, number ], tolerance?: number): void
|
|
887
|
-
```
|
|
640
|
+
#### `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
641
|
|
|
889
|
-
#### `verify.
|
|
642
|
+
#### `verify.boundingBoxSize(label: string, shape: ShapeLike, expectedSize: Vec3, tolerance?: number): void` — Check that a shape's bounding box has approximately the given size.
|
|
890
643
|
|
|
891
|
-
|
|
892
|
-
verify.edgeContinuity(label: string, shape: ShapeLike, options?: EdgeContinuityThresholds): void
|
|
893
|
-
```
|
|
644
|
+
#### `verify.edgeContinuity(label: string, shape: ShapeLike, options?: EdgeContinuityThresholds): void` — Check that every sampled seam on a shape meets a requested continuity threshold.
|
|
894
645
|
|
|
895
646
|
**`EdgeContinuityThresholds`**: `continuity?: SurfaceContinuity`, `samples?: number`, `positionTolerance?: number`, `tangentToleranceDeg?: number`, `curvatureTolerance?: number`
|
|
896
647
|
|
|
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
|
-
```
|
|
648
|
+
#### `verify.noTinyEdges(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no tiny edges below the requested threshold.
|
|
908
649
|
|
|
909
|
-
#### `verify.
|
|
650
|
+
#### `verify.noSliverFaces(label: string, shape: ShapeLike, threshold?: number): void` — Check that a shape has no sliver faces below the requested score threshold.
|
|
910
651
|
|
|
911
|
-
|
|
912
|
-
verify.noSelfIntersection(label: string, shape: ShapeLike): void
|
|
913
|
-
```
|
|
652
|
+
#### `verify.noSelfIntersection(label: string, shape: ShapeLike): void` — Best-effort exact-shape validity guard for self-intersections or broken B-Rep topology.
|
|
914
653
|
|
|
915
|
-
#### `spec()` — Create a named, reusable bundle of verification checks.
|
|
654
|
+
#### `spec(name: string, checkFn: (...args: any[]) => void): Spec` — Create a named, reusable bundle of verification checks.
|
|
916
655
|
|
|
917
656
|
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
657
|
|
|
@@ -942,10 +681,6 @@ fitSpec.check(bracket, standoff);
|
|
|
942
681
|
|
|
943
682
|
**Spec-first workflow:** Write specs before building geometry. Checks go from red to green as you build — effectively TDD for CAD.
|
|
944
683
|
|
|
945
|
-
```ts
|
|
946
|
-
spec(name: string, checkFn: (...args: any[]) => void): Spec
|
|
947
|
-
```
|
|
948
|
-
|
|
949
684
|
**`Spec`**
|
|
950
685
|
- `name: string` — The display name of this spec
|
|
951
686
|
|
|
@@ -963,17 +698,13 @@ Supports transforms (translate, rotate, scale, mirror, transform, rotateAround,
|
|
|
963
698
|
|
|
964
699
|
| Property | Type | Description |
|
|
965
700
|
|----------|------|-------------|
|
|
966
|
-
| `materialProps` | `ShapeMaterialProps
|
|
701
|
+
| `materialProps` | `ShapeMaterialProps \| undefined` | — |
|
|
967
702
|
|
|
968
703
|
**Appearance**
|
|
969
704
|
|
|
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
|
-
```
|
|
705
|
+
#### `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
706
|
|
|
976
|
-
#### `material()` — Set PBR material properties for this shape's visual appearance.
|
|
707
|
+
#### `material(props: ShapeMaterialProps): Shape` — Set PBR material properties for this shape's visual appearance.
|
|
977
708
|
|
|
978
709
|
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
710
|
|
|
@@ -988,10 +719,6 @@ cylinder(40, 20).material({ opacity: 0.4, clearcoat: 1.0, clearcoatRoughness: 0.
|
|
|
988
719
|
box(100, 100, 10).color('#gold').material({ metalness: 0.95, roughness: 0.05 }).translate(0, 0, 50);
|
|
989
720
|
```
|
|
990
721
|
|
|
991
|
-
```ts
|
|
992
|
-
material(props: ShapeMaterialProps): Shape
|
|
993
|
-
```
|
|
994
|
-
|
|
995
722
|
**`ShapeMaterialProps`**
|
|
996
723
|
|
|
997
724
|
| Option | Type | Description |
|
|
@@ -1013,12 +740,14 @@ material(props: ShapeMaterialProps): Shape
|
|
|
1013
740
|
|
|
1014
741
|
**Face Topology**
|
|
1015
742
|
|
|
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.
|
|
743
|
+
#### `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
744
|
|
|
1018
745
|
`.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
746
|
|
|
1020
747
|
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
748
|
|
|
749
|
+
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.
|
|
750
|
+
|
|
1022
751
|
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
752
|
|
|
1024
753
|
```ts
|
|
@@ -1045,69 +774,29 @@ const full = union(left, right);
|
|
|
1045
774
|
full.face('l/upper'); // left wing upper surface
|
|
1046
775
|
```
|
|
1047
776
|
|
|
1048
|
-
|
|
1049
|
-
face(selector: FaceSelector): FaceRef
|
|
1050
|
-
```
|
|
1051
|
-
|
|
1052
|
-
#### `faces()` — Return faces matching a query, or label semantic faces when passed a mapping.
|
|
777
|
+
#### `faces(): FaceRef[]` — Return faces matching a query, or label semantic faces when passed a mapping.
|
|
1053
778
|
|
|
1054
779
|
Mapping form returns a new shape: `shape.faces({ lid: 'top', walls: ['front', 'back', 'left', 'right'] })`.
|
|
1055
780
|
|
|
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.
|
|
781
|
+
#### `faceNames(): string[]` — List defined semantic face names currently available on this shape.
|
|
1073
782
|
|
|
1074
|
-
|
|
1075
|
-
renameLabel(from: string, to: string): Shape
|
|
1076
|
-
```
|
|
1077
|
-
|
|
1078
|
-
#### `dropLabels()` — Remove specific face labels. Returns a new shape.
|
|
1079
|
-
|
|
1080
|
-
```ts
|
|
1081
|
-
dropLabels(...names: string[]): Shape
|
|
1082
|
-
```
|
|
783
|
+
#### `prefixLabels(prefix: string): Shape` — Prefix all user-authored face labels, including semantic labels from `faces(mapping)`. Returns a new shape with modified labels.
|
|
1083
784
|
|
|
1084
|
-
#### `
|
|
785
|
+
#### `renameLabel(from: string, to: string): Shape` — Rename a single face label. Returns a new shape.
|
|
1085
786
|
|
|
1086
|
-
|
|
1087
|
-
dropAllLabels(): Shape
|
|
1088
|
-
```
|
|
787
|
+
#### `dropLabels(...names: string[]): Shape` — Remove specific face labels. Returns a new shape.
|
|
1089
788
|
|
|
1090
|
-
#### `
|
|
789
|
+
#### `dropAllLabels(): Shape` — Remove all face labels. Returns a new shape.
|
|
1091
790
|
|
|
1092
|
-
|
|
1093
|
-
faceHistory(name: string): FaceTransformationHistory
|
|
1094
|
-
```
|
|
791
|
+
#### `faceHistory(name: string): FaceTransformationHistory` — Get the transformation history for a specific face.
|
|
1095
792
|
|
|
1096
793
|
**Edge Topology**
|
|
1097
794
|
|
|
1098
|
-
#### `edge()` — Get a named topology edge. Only available on shapes with tracked topology (from box/cylinder/extrude).
|
|
1099
|
-
|
|
1100
|
-
```ts
|
|
1101
|
-
edge(name: string): EdgeRef
|
|
1102
|
-
```
|
|
1103
|
-
|
|
1104
|
-
#### `edgeNames()` — List named topology edge names. Returns empty array if shape has no tracked topology.
|
|
795
|
+
#### `edge(name: string): EdgeRef` — Get a named topology edge. Only available on shapes with tracked topology (from box/cylinder/extrude).
|
|
1105
796
|
|
|
1106
|
-
|
|
1107
|
-
edgeNames(): string[]
|
|
1108
|
-
```
|
|
797
|
+
#### `edgeNames(): string[]` — List named topology edge names. Returns empty array if shape has no tracked topology.
|
|
1109
798
|
|
|
1110
|
-
#### `edgesOf()` — Return all boundary edges of a named face.
|
|
799
|
+
#### `edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]` — Return all boundary edges of a named face.
|
|
1111
800
|
|
|
1112
801
|
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
802
|
|
|
@@ -1127,10 +816,6 @@ body = fillet(body, 1.5, body.edgesOf('opening'))
|
|
|
1127
816
|
body.edgesOf('top', { concave: true })
|
|
1128
817
|
```
|
|
1129
818
|
|
|
1130
|
-
```ts
|
|
1131
|
-
edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]
|
|
1132
|
-
```
|
|
1133
|
-
|
|
1134
819
|
**`EdgesOfOptions`**
|
|
1135
820
|
|
|
1136
821
|
| Option | Type | Description |
|
|
@@ -1140,7 +825,7 @@ edgesOf(faceLabel: string, options?: EdgesOfOptions): EdgeSegment[]
|
|
|
1140
825
|
| `concave?` | `boolean` | Additional geometric filter: only concave edges. |
|
|
1141
826
|
| `minLength?` | `number` | Minimum edge length filter. |
|
|
1142
827
|
|
|
1143
|
-
#### `edgesBetween()` — Return edges shared between two named faces.
|
|
828
|
+
#### `edgesBetween(faceA: string, faceB: string | string[]): EdgeSegment[]` — Return edges shared between two named faces.
|
|
1144
829
|
|
|
1145
830
|
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
831
|
|
|
@@ -1159,155 +844,63 @@ tube = fillet(tube, 1, tube.edgesBetween('cap', 'barrel'))
|
|
|
1159
844
|
body.edgesBetween('lid', ['left-wall', 'right-wall', 'front-wall', 'back-wall'])
|
|
1160
845
|
```
|
|
1161
846
|
|
|
1162
|
-
```ts
|
|
1163
|
-
edgesBetween(faceA: string, faceB: string | string[]): EdgeSegment[]
|
|
1164
|
-
```
|
|
1165
|
-
|
|
1166
847
|
**Transforms**
|
|
1167
848
|
|
|
1168
|
-
#### `translate()` — Move the shape relative to its current position. All transforms are immutable and return new shapes.
|
|
1169
|
-
|
|
1170
|
-
```ts
|
|
1171
|
-
translate(x: number, y: number, z: number): Shape
|
|
1172
|
-
```
|
|
849
|
+
#### `translate(x: number, y: number, z: number): Shape` — Move the shape relative to its current position. All transforms are immutable and return new shapes.
|
|
1173
850
|
|
|
1174
|
-
#### `translatePolar()` — Translate using polar coordinates (radius + angle in degrees). Eliminates manual `r * Math.cos(angle * PI/180)` calculations.
|
|
851
|
+
#### `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
852
|
|
|
1176
853
|
Example: `shape.translatePolar(50, 30)` moves 50mm at 30 degrees from +X.
|
|
1177
854
|
|
|
1178
|
-
|
|
1179
|
-
translatePolar(radius: number, angleDeg: number, z?: number): Shape
|
|
1180
|
-
```
|
|
855
|
+
#### `moveTo(x: number, y: number, z: number): Shape` — Position the shape so its bounding box min corner is at the given global coordinate.
|
|
1181
856
|
|
|
1182
|
-
#### `
|
|
857
|
+
#### `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
858
|
|
|
1184
|
-
|
|
1185
|
-
moveTo(x: number, y: number, z: number): Shape
|
|
1186
|
-
```
|
|
859
|
+
#### `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
860
|
|
|
1188
|
-
#### `
|
|
861
|
+
#### `rotateX(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the X axis by the given angle in degrees.
|
|
1189
862
|
|
|
1190
|
-
|
|
1191
|
-
moveToLocal(target: Shape | { toShape(): Shape; }, x: number, y: number, z: number): Shape
|
|
1192
|
-
```
|
|
863
|
+
#### `rotateY(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the Y axis by the given angle in degrees.
|
|
1193
864
|
|
|
1194
|
-
#### `
|
|
865
|
+
#### `rotateZ(angleDeg: number, options?: { pivot?: Vec3; }): Shape` — Rotate around the Z axis by the given angle in degrees.
|
|
1195
866
|
|
|
1196
|
-
|
|
1197
|
-
rotate(axis: [ number, number, number ], angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1198
|
-
```
|
|
1199
|
-
|
|
1200
|
-
#### `rotateX()` — Rotate around the X axis by the given angle in degrees.
|
|
1201
|
-
|
|
1202
|
-
```ts
|
|
1203
|
-
rotateX(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1204
|
-
```
|
|
1205
|
-
|
|
1206
|
-
#### `rotateY()` — Rotate around the Y axis by the given angle in degrees.
|
|
1207
|
-
|
|
1208
|
-
```ts
|
|
1209
|
-
rotateY(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1210
|
-
```
|
|
1211
|
-
|
|
1212
|
-
#### `rotateZ()` — Rotate around the Z axis by the given angle in degrees.
|
|
1213
|
-
|
|
1214
|
-
```ts
|
|
1215
|
-
rotateZ(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): Shape
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
#### `rotateAroundTo()` — 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.
|
|
1219
|
-
|
|
1220
|
-
```ts
|
|
1221
|
-
rotateAroundTo(axis: [ number, number, number ], pivot: [ number, number, number ], movingPoint: RotationPointLike, targetPoint: RotationPointLike, options?: RotateAroundToOptions): Shape
|
|
1222
|
-
```
|
|
867
|
+
#### `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.
|
|
1223
868
|
|
|
1224
869
|
`RotateAroundToOptions`: `{ mode?: RotateAroundToMode }`
|
|
1225
870
|
|
|
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
|
-
```
|
|
871
|
+
#### `transform(m: Mat4 | Transform): Shape` — Apply a 4x4 affine transform matrix (column-major) or a Transform object.
|
|
1237
872
|
|
|
1238
|
-
#### `
|
|
873
|
+
#### `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.
|
|
1239
874
|
|
|
1240
|
-
|
|
1241
|
-
scaleAround(pivot: [ number, number, number ], v: number | [ number, number, number ]): Shape
|
|
1242
|
-
```
|
|
875
|
+
#### `scaleAround(pivot: Vec3, v: number | Vec3): Shape` — Scale the shape uniformly or per-axis from an explicit pivot point.
|
|
1243
876
|
|
|
1244
|
-
#### `mirror()` — Mirror across a plane through the shape's bounding box center, defined by its normal vector.
|
|
877
|
+
#### `mirror(normal: Vec3): Shape` — Mirror across a plane through the shape's bounding box center, defined by its normal vector.
|
|
1245
878
|
|
|
1246
|
-
|
|
1247
|
-
mirror(normal: [ number, number, number ]): Shape
|
|
1248
|
-
```
|
|
879
|
+
#### `mirrorThrough(point: Vec3, normal: Vec3): Shape` — Mirror across a plane through an explicit point, defined by its normal vector.
|
|
1249
880
|
|
|
1250
|
-
#### `
|
|
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.
|
|
881
|
+
#### `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
882
|
|
|
1258
883
|
Example: cylinder(40, 5).pointAlong([1, 0, 0]) — lays cylinder along X, starting at origin
|
|
1259
884
|
|
|
1260
|
-
```ts
|
|
1261
|
-
pointAlong(direction: [ number, number, number ]): Shape
|
|
1262
|
-
```
|
|
1263
|
-
|
|
1264
885
|
**Booleans & Cutting**
|
|
1265
886
|
|
|
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().
|
|
887
|
+
#### `add(...others: ShapeOperandInput[]): Shape` — Union this shape with others (additive boolean). Method form of union().
|
|
1279
888
|
|
|
1280
|
-
|
|
1281
|
-
intersect(...others: ShapeOperandInput[]): Shape
|
|
1282
|
-
```
|
|
889
|
+
#### `subtract(...others: ShapeOperandInput[]): Shape` — Subtract other shapes from this one. Method form of difference().
|
|
1283
890
|
|
|
1284
|
-
#### `
|
|
891
|
+
#### `intersect(...others: ShapeOperandInput[]): Shape` — Keep only the overlap with other shapes. Method form of intersection().
|
|
1285
892
|
|
|
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
|
-
```
|
|
893
|
+
#### `split(cutter: Shape | { toShape(): Shape; }): [ Shape, Shape ]` — Split into [inside, outside] by another shape.
|
|
1295
894
|
|
|
1296
|
-
#### `
|
|
895
|
+
#### `splitByPlane(normal: Vec3, originOffset?: number): [ Shape, Shape ]` — Split by infinite plane. Returns [positive-side, negative-side].
|
|
1297
896
|
|
|
1298
|
-
|
|
1299
|
-
trimByPlane(normal: [ number, number, number ], originOffset?: number): Shape
|
|
1300
|
-
```
|
|
897
|
+
#### `trimByPlane(normal: Vec3, originOffset?: number): Shape` — Keep the positive side of the plane and discard the opposite side.
|
|
1301
898
|
|
|
1302
899
|
**Features**
|
|
1303
900
|
|
|
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).
|
|
901
|
+
#### `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
902
|
|
|
1306
|
-
|
|
1307
|
-
shell(thickness: number, opts?: { openFaces?: string[]; }): Shape
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
|
-
#### `pocket()` — Cut a pocket (cavity) into this solid through the named face.
|
|
903
|
+
#### `pocket(face: FaceSelector, depth: number, opts?: PocketOptions): Shape` — Cut a pocket (cavity) into this solid through the named face.
|
|
1311
904
|
|
|
1312
905
|
```js
|
|
1313
906
|
box(100, 100, 20).pocket('top', 8)
|
|
@@ -1315,50 +908,39 @@ box(100, 100, 20).pocket('top', 8, { inset: 5 })
|
|
|
1315
908
|
box(100, 100, 20).pocket('top', 8, { scale: 0.8 })
|
|
1316
909
|
```
|
|
1317
910
|
|
|
1318
|
-
```ts
|
|
1319
|
-
pocket(face: FaceSelector, depth: number, opts?: PocketOptions): Shape
|
|
1320
|
-
```
|
|
1321
|
-
|
|
1322
911
|
**`PocketOptions`**
|
|
1323
912
|
- `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
913
|
- `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
914
|
- `join?: "Square" | "Round" | "Miter"` — Corner join style when using `inset`. Default: 'Round'.
|
|
1326
915
|
|
|
1327
|
-
#### `boss()` — Add a boss (protrusion) from the named face.
|
|
916
|
+
#### `boss(face: FaceSelector, height: number, opts?: BossOptions): Shape` — Add a boss (protrusion) from the named face.
|
|
1328
917
|
|
|
1329
918
|
```js
|
|
1330
919
|
box(100, 100, 20).boss('top', 5)
|
|
1331
920
|
box(100, 100, 20).boss('top', 10, { scale: 0.6 })
|
|
1332
921
|
```
|
|
1333
922
|
|
|
1334
|
-
|
|
1335
|
-
boss(face: FaceSelector, height: number, opts?: BossOptions): Shape
|
|
1336
|
-
```
|
|
1337
|
-
|
|
1338
|
-
#### `hole()` — Drill a hole into this solid at a face.
|
|
923
|
+
#### `hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape` — Drill a hole into this solid at a face.
|
|
1339
924
|
|
|
1340
925
|
```js
|
|
1341
926
|
box(50, 50, 20).hole('top', { diameter: 8, depth: 10 })
|
|
1342
927
|
box(50, 50, 20).hole('top', { diameter: 6, counterbore: { diameter: 12, depth: 3 } })
|
|
1343
928
|
```
|
|
1344
929
|
|
|
1345
|
-
```ts
|
|
1346
|
-
hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape
|
|
1347
|
-
```
|
|
1348
|
-
|
|
1349
930
|
**`FaceRef`**
|
|
1350
931
|
|
|
1351
932
|
| Option | Type | Description |
|
|
1352
933
|
|--------|------|-------------|
|
|
1353
|
-
| `normal` | `
|
|
1354
|
-
| `center` | `
|
|
934
|
+
| `normal` | `Vec3` | Normal direction of the face |
|
|
935
|
+
| `center` | `Vec3` | Center point of the face |
|
|
1355
936
|
| `query?` | `FaceQueryRef` | Compiler-owned face query when available. |
|
|
1356
937
|
| `planar?` | `boolean` | True when the face can host a 2D sketch placement frame |
|
|
1357
|
-
| `uAxis?` | `
|
|
1358
|
-
| `vAxis?` | `
|
|
938
|
+
| `uAxis?` | `Vec3` | Face-local horizontal axis for planar faces |
|
|
939
|
+
| `vAxis?` | `Vec3` | Face-local vertical axis for planar faces |
|
|
1359
940
|
| `surface?` | `FaceSurface` | Analytic surface family when the backend can identify one. |
|
|
1360
941
|
| `descendant?` | `FaceDescendantMetadata` | Shared descendant-resolution metadata when this face is a semantic region/set. |
|
|
1361
|
-
|
|
942
|
+
|
|
943
|
+
Also: `name: FaceName`.
|
|
1362
944
|
|
|
1363
945
|
**`FaceDescendantMetadata`**: `kind: "single" | "face-set"`, `semantic: FaceDescendantSemantic`, `memberCount: number`, `memberNames: string[]`, `coplanar: boolean`
|
|
1364
946
|
|
|
@@ -1370,7 +952,7 @@ hole(faceOrRef: SketchFaceTarget | FaceRef, opts: ShapeHoleOptions): Shape
|
|
|
1370
952
|
|
|
1371
953
|
**`ShapeHoleThreadOptions`**: `designation?: string`, `pitch?: number`, `class?: string`, `handedness?: "right" | "left"`, `depth?: number`, `modeled?: boolean`
|
|
1372
954
|
|
|
1373
|
-
#### `cutout()` — Cut a profile-shaped pocket through a face using a placed sketch.
|
|
955
|
+
#### `cutout(sketch: Sketch, opts?: ShapeCutoutOptions): Shape` — Cut a profile-shaped pocket through a face using a placed sketch.
|
|
1374
956
|
|
|
1375
957
|
The sketch must be placed on a face with `Sketch.onFace(...)`. The cut follows the sketch's 2D profile.
|
|
1376
958
|
|
|
@@ -1379,15 +961,11 @@ const profile = circle2d(10).onFace(body, 'top');
|
|
|
1379
961
|
body.cutout(profile, { depth: 5 })
|
|
1380
962
|
```
|
|
1381
963
|
|
|
1382
|
-
|
|
1383
|
-
cutout(sketch: Sketch, opts?: ShapeCutoutOptions): Shape
|
|
1384
|
-
```
|
|
1385
|
-
|
|
1386
|
-
**`ShapeCutoutOptions`**: `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `taperScale?: number | [ number, number ]`
|
|
964
|
+
**`ShapeCutoutOptions`**: `depth?: number`, `upToFace?: SketchFaceTarget | FaceRef`, `extent?: ShapeFeatureExtentOptions`, `taperScale?: number | Vec2`
|
|
1387
965
|
|
|
1388
966
|
**Placement**
|
|
1389
967
|
|
|
1390
|
-
#### `placeReference()` — Translate the shape so the given anchor or reference lands on the target coordinate.
|
|
968
|
+
#### `placeReference(ref: PlacementAnchorLike, target: Vec3, offset?: Vec3): Shape` — Translate the shape so the given anchor or reference lands on the target coordinate.
|
|
1391
969
|
|
|
1392
970
|
Accepts any built-in anchor name (`'bottom'`, `'center'`, `'top-front-left'`, etc.) or a custom placement reference attached via `withReferences()`.
|
|
1393
971
|
|
|
@@ -1402,19 +980,11 @@ shape.placeReference('center', [0, 0, 0])
|
|
|
1402
980
|
shape.placeReference('left', [10, 0, 0])
|
|
1403
981
|
```
|
|
1404
982
|
|
|
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.
|
|
983
|
+
#### `attachTo(target: ShapeAnchorTarget, targetAnchor: PlacementAnchorLike, selfAnchor?: PlacementAnchorLike, offset?: Vec3): Shape` — Position this shape relative to another using named 3D anchor points.
|
|
1410
984
|
|
|
1411
985
|
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
986
|
|
|
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.
|
|
987
|
+
#### `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
988
|
|
|
1419
989
|
Think of it like sticking a label on a box surface:
|
|
1420
990
|
|
|
@@ -1425,11 +995,7 @@ Think of it like sticking a label on a box surface:
|
|
|
1425
995
|
- top/bottom: u = left/right (X), v = forward/back (Y)
|
|
1426
996
|
- `protrude` = how far the child sticks out (positive = outward from face)
|
|
1427
997
|
|
|
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.
|
|
998
|
+
#### `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
999
|
|
|
1434
1000
|
Position the shape roughly first (translate/rotate), then call seatInto to auto-adjust the penetration depth. No manual coordinate math needed.
|
|
1435
1001
|
|
|
@@ -1444,16 +1010,12 @@ pod.translate(0, station, radius + 20).seatInto(fuselage, 'base', { depth: 'flus
|
|
|
1444
1010
|
mast.translate(0, station, radius + 50).seatInto(fuselage, 'mount', { depth: 'flush', gap: 3 });
|
|
1445
1011
|
```
|
|
1446
1012
|
|
|
1447
|
-
```ts
|
|
1448
|
-
seatInto(target: Shape, surface: string, options?: SeatIntoOptions): Shape
|
|
1449
|
-
```
|
|
1450
|
-
|
|
1451
1013
|
**`SeatIntoOptions`**
|
|
1452
|
-
- `along?:
|
|
1014
|
+
- `along?: Vec3` — Movement axis. Default: inverted face normal (points into target).
|
|
1453
1015
|
- `depth?: "full" | "flush" | number` — How deep to embed. 'full' = entire face inside. 'flush' = nearest point touches. number = mm past flush. Default: 'full'.
|
|
1454
1016
|
- `gap?: number` — Standoff gap in mm. Positive = gap between face and target. Negative = extra penetration. Default: 0.
|
|
1455
1017
|
|
|
1456
|
-
#### `seatOver()` — Slide this shape until a target's labeled face is fully covered (inside this shape).
|
|
1018
|
+
#### `seatOver(target: Shape, targetSurface: string, options?: SeatIntoOptions): Shape` — Slide this shape until a target's labeled face is fully covered (inside this shape).
|
|
1457
1019
|
|
|
1458
1020
|
The inverse of `seatInto`: instead of embedding *your* face into the target, you move until the *target's* face is embedded inside you.
|
|
1459
1021
|
|
|
@@ -1465,47 +1027,25 @@ nacelle.translate(rough).seatOver(pylon, 'bottom');
|
|
|
1465
1027
|
cap.translate(rough).seatOver(post, 'top');
|
|
1466
1028
|
```
|
|
1467
1029
|
|
|
1468
|
-
```ts
|
|
1469
|
-
seatOver(target: Shape, targetSurface: string, options?: SeatIntoOptions): Shape
|
|
1470
|
-
```
|
|
1471
|
-
|
|
1472
1030
|
**Connectors**
|
|
1473
1031
|
|
|
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).
|
|
1032
|
+
#### `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).
|
|
1475
1033
|
|
|
1476
|
-
|
|
1477
|
-
withConnectors(connectors: Record<string, ConnectorInput>): Shape
|
|
1478
|
-
```
|
|
1479
|
-
|
|
1480
|
-
**`PortInput`**: `origin?: [ number, number, number ]`, `axis?: [ number, number, number ]`, `start?: [ number, number, number ]`, `end?: [ number, number, number ]`, `up?: [ number, number, number ]`, `kind?: JointType`, `min?: number`, `max?: number`
|
|
1034
|
+
`PortInput`: `{ origin?: Vec3, axis?: Vec3, start?: Vec3, end?: Vec3, up?: Vec3, kind?: JointType, min?: number, max?: number }`
|
|
1481
1035
|
|
|
1482
1036
|
`ConnectorInput`: `{ connectorType?: string, gender?: ConnectorGender, measurements?: Record<string, number | string> }`
|
|
1483
1037
|
|
|
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
|
-
```
|
|
1038
|
+
#### `connectorNames(): string[]` — List all connector names on this shape.
|
|
1495
1039
|
|
|
1496
|
-
#### `
|
|
1040
|
+
#### `connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>` — Get all connectors of a given type.
|
|
1497
1041
|
|
|
1498
|
-
|
|
1499
|
-
connectorDistance(nameA: string, nameB: string): number
|
|
1500
|
-
```
|
|
1042
|
+
#### `connectorDistance(nameA: string, nameB: string): number` — Distance between two connector origins on this shape.
|
|
1501
1043
|
|
|
1502
|
-
#### `connectorMeasurements()
|
|
1044
|
+
#### `connectorMeasurements(name: string): Record<string, number | string>` — Get measurements metadata from a connector.
|
|
1503
1045
|
|
|
1504
|
-
|
|
1505
|
-
connectorMeasurements(name: string): Record<string, number | string>
|
|
1506
|
-
```
|
|
1046
|
+
#### `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
1047
|
|
|
1508
|
-
|
|
1048
|
+
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
1049
|
|
|
1510
1050
|
Overloads:
|
|
1511
1051
|
|
|
@@ -1513,125 +1053,53 @@ Overloads:
|
|
|
1513
1053
|
- Dictionary (same target): `matchTo(target, { selfConn: targetConn, ... }, options?)`
|
|
1514
1054
|
- Multi-target: `matchTo([ [target1, selfConn1, targetConn1], ... ], options?)`
|
|
1515
1055
|
|
|
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
1056
|
`MatchToOptions`: `{ force?: boolean, angle?: number, distance?: number }`
|
|
1521
1057
|
|
|
1522
1058
|
**References**
|
|
1523
1059
|
|
|
1524
|
-
#### `withReferences()` — Attach named placement references that survive normal transforms and imports.
|
|
1525
|
-
|
|
1526
|
-
```ts
|
|
1527
|
-
withReferences(refs: PlacementReferenceInput): Shape
|
|
1528
|
-
```
|
|
1060
|
+
#### `withReferences(refs: PlacementReferenceInput): Shape` — Attach named placement references that survive normal transforms and imports.
|
|
1529
1061
|
|
|
1530
|
-
**`PlacementReferenceInput`**: `points?: Record<string,
|
|
1062
|
+
**`PlacementReferenceInput`**: `points?: Record<string, Vec3>`, `edges?: Record<string, PlacementEdgeRef>`, `surfaces?: Record<string, PlacementSurfaceRef>`, `objects?: Record<string, PlacementObjectInput>`
|
|
1531
1063
|
|
|
1532
1064
|
`PlacementEdgeRef`: `{ start: Vec3, end: Vec3 }`
|
|
1533
1065
|
|
|
1534
1066
|
`PlacementSurfaceRef`: `{ center: Vec3, normal: Vec3 }`
|
|
1535
1067
|
|
|
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.
|
|
1068
|
+
#### `referenceNames(kind?: PlacementReferenceKind): string[]` — List named placement references carried by this shape.
|
|
1543
1069
|
|
|
1544
|
-
|
|
1545
|
-
referencePoint(ref: PlacementAnchorLike): [ number, number, number ]
|
|
1546
|
-
```
|
|
1070
|
+
#### `referencePoint(ref: PlacementAnchorLike): Vec3` — Resolve a named placement reference or built-in anchor to a 3D point.
|
|
1547
1071
|
|
|
1548
1072
|
**Measurement**
|
|
1549
1073
|
|
|
1550
|
-
#### `boundingBox()` — Get the axis-aligned bounding box as { min: [x,y,z], max: [x,y,z] }.
|
|
1074
|
+
#### `boundingBox(): ShapeRuntimeBounds` — Get the axis-aligned bounding box as { min: [x,y,z], max: [x,y,z] }.
|
|
1551
1075
|
|
|
1552
|
-
|
|
1553
|
-
boundingBox(): ShapeRuntimeBounds
|
|
1554
|
-
```
|
|
1076
|
+
#### `volume(): number` — Volume in mm cubed.
|
|
1555
1077
|
|
|
1556
|
-
#### `
|
|
1078
|
+
#### `surfaceArea(): number` — Surface area in mm squared.
|
|
1557
1079
|
|
|
1558
|
-
|
|
1559
|
-
volume(): number
|
|
1560
|
-
```
|
|
1080
|
+
#### `isEmpty(): boolean` — True if the shape contains no geometry.
|
|
1561
1081
|
|
|
1562
|
-
#### `
|
|
1082
|
+
#### `numBodies(): number` — Number of disconnected solid bodies in this shape.
|
|
1563
1083
|
|
|
1564
|
-
|
|
1565
|
-
surfaceArea(): number
|
|
1566
|
-
```
|
|
1567
|
-
|
|
1568
|
-
#### `isEmpty()` — True if the shape contains no geometry.
|
|
1569
|
-
|
|
1570
|
-
```ts
|
|
1571
|
-
isEmpty(): boolean
|
|
1572
|
-
```
|
|
1573
|
-
|
|
1574
|
-
#### `numBodies()` — Number of disconnected solid bodies in this shape.
|
|
1575
|
-
|
|
1576
|
-
```ts
|
|
1577
|
-
numBodies(): number
|
|
1578
|
-
```
|
|
1579
|
-
|
|
1580
|
-
#### `numTri()` — Triangle count of the mesh representation.
|
|
1581
|
-
|
|
1582
|
-
```ts
|
|
1583
|
-
numTri(): number
|
|
1584
|
-
```
|
|
1084
|
+
#### `numTri(): number` — Triangle count of the mesh representation.
|
|
1585
1085
|
|
|
1586
1086
|
**Other**
|
|
1587
1087
|
|
|
1588
|
-
#### `clone()` — Return a new Shape wrapper for explicit duplication in scripts.
|
|
1088
|
+
#### `clone(): Shape` — Return a new Shape wrapper for explicit duplication in scripts.
|
|
1589
1089
|
|
|
1590
|
-
|
|
1591
|
-
clone(): Shape
|
|
1592
|
-
```
|
|
1593
|
-
|
|
1594
|
-
#### `geometryInfo()` — Inspect which backend/representation produced this solid.
|
|
1090
|
+
#### `geometryInfo(): GeometryInfo` — Inspect which backend/representation produced this solid.
|
|
1595
1091
|
|
|
1596
|
-
|
|
1597
|
-
geometryInfo(): GeometryInfo
|
|
1598
|
-
```
|
|
1599
|
-
|
|
1600
|
-
#### `as()` — Name this shape as a reference namespace for diagnostics and future published refs.
|
|
1601
|
-
|
|
1602
|
-
```ts
|
|
1603
|
-
as(name: string): Shape
|
|
1604
|
-
```
|
|
1092
|
+
#### `as(name: string): Shape` — Name this shape as a reference namespace for diagnostics and future published refs.
|
|
1605
1093
|
|
|
1606
|
-
#### `ref()` — Resolve a semantic reference path like `lid`, `lid/back`, or a midpoint selector on `lid/back`.
|
|
1094
|
+
#### `ref(path: string): ShapeRef` — Resolve a semantic reference path like `lid`, `lid/back`, or a midpoint selector on `lid/back`.
|
|
1607
1095
|
|
|
1608
|
-
|
|
1609
|
-
ref(path: string): ShapeRef
|
|
1610
|
-
```
|
|
1096
|
+
#### `thicken(thickness: number): Shape` — Offset-thicken an exact open surface or shell into a solid.
|
|
1611
1097
|
|
|
1612
|
-
#### `
|
|
1098
|
+
#### `getMesh(): ShapeRuntimeMesh` — Extract triangle mesh for Three.js rendering
|
|
1613
1099
|
|
|
1614
|
-
|
|
1615
|
-
thicken(thickness: number): Shape
|
|
1616
|
-
```
|
|
1100
|
+
#### `slice(offset?: number): any` — Slice the runtime solid by a plane normal to local Z at the given offset.
|
|
1617
1101
|
|
|
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
|
-
```
|
|
1102
|
+
#### `project(): any` — Orthographically project the runtime solid onto the local XY plane.
|
|
1635
1103
|
|
|
1636
1104
|
**Compatibility Aliases**
|
|
1637
1105
|
|
|
@@ -1640,101 +1108,45 @@ project(): any
|
|
|
1640
1108
|
|
|
1641
1109
|
### `Transform`
|
|
1642
1110
|
|
|
1643
|
-
#### `identity()` — Return the identity transform.
|
|
1111
|
+
#### `static identity(): Transform` — Return the identity transform.
|
|
1644
1112
|
|
|
1645
|
-
|
|
1646
|
-
static identity(): Transform
|
|
1647
|
-
```
|
|
1113
|
+
#### `static from(input: TransformInput): Transform` — Wrap an existing `Transform` or raw 4x4 matrix as a `Transform`.
|
|
1648
1114
|
|
|
1649
|
-
#### `
|
|
1650
|
-
|
|
1651
|
-
```ts
|
|
1652
|
-
static from(input: TransformInput): Transform
|
|
1653
|
-
```
|
|
1115
|
+
#### `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
1116
|
|
|
1655
|
-
|
|
1117
|
+
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
1118
|
|
|
1657
1119
|
```ts
|
|
1658
|
-
|
|
1120
|
+
const world = Transform.compose(childBase, jointMotion, jointFrame, parentWorld);
|
|
1659
1121
|
```
|
|
1660
1122
|
|
|
1661
|
-
#### `
|
|
1123
|
+
#### `static translation(x: number, y: number, z: number): Transform` — Create a translation transform.
|
|
1662
1124
|
|
|
1663
|
-
|
|
1664
|
-
static scale(v: number | Vec3): Transform
|
|
1665
|
-
```
|
|
1125
|
+
#### `static scale(v: number | Vec3): Transform` — Create a uniform or per-axis scale transform.
|
|
1666
1126
|
|
|
1667
|
-
#### `rotationAxis()` — Create a rotation around an arbitrary axis, optionally about a pivot.
|
|
1127
|
+
#### `static rotationAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform` — Create a rotation around an arbitrary axis, optionally about a pivot.
|
|
1668
1128
|
|
|
1669
|
-
|
|
1670
|
-
static rotationAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform
|
|
1671
|
-
```
|
|
1129
|
+
#### `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
1130
|
|
|
1673
|
-
#### `
|
|
1131
|
+
#### `mul(other: TransformInput): Transform` — Compose transforms in chain order: `a.mul(b)` applies `a`, then `b`.
|
|
1674
1132
|
|
|
1675
|
-
|
|
1676
|
-
static rotateAroundTo(axis: Vec3, pivot: Vec3, movingPoint: Vec3, targetPoint: Vec3, options?: RotateAroundToOptions): Transform
|
|
1677
|
-
```
|
|
1133
|
+
#### `translate(x: number, y: number, z: number): Transform` — Translate after the current transform.
|
|
1678
1134
|
|
|
1679
|
-
#### `
|
|
1135
|
+
#### `rotateAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform` — Rotate after the current transform.
|
|
1680
1136
|
|
|
1681
|
-
|
|
1682
|
-
mul(other: TransformInput): Transform
|
|
1683
|
-
```
|
|
1137
|
+
#### `rotateX(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the X axis after the current transform (parity with `Shape.rotateX`).
|
|
1684
1138
|
|
|
1685
|
-
#### `
|
|
1139
|
+
#### `rotateY(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the Y axis after the current transform (parity with `Shape.rotateY`).
|
|
1686
1140
|
|
|
1687
|
-
|
|
1688
|
-
translate(x: number, y: number, z: number): Transform
|
|
1689
|
-
```
|
|
1141
|
+
#### `rotateZ(angleDeg: number, pivot?: Vec3): Transform` — Rotate about the Z axis after the current transform (parity with `Shape.rotateZ`).
|
|
1690
1142
|
|
|
1691
|
-
#### `
|
|
1143
|
+
#### `inverse(): Transform` — Return the inverse transform.
|
|
1692
1144
|
|
|
1693
|
-
|
|
1694
|
-
rotateAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): Transform
|
|
1695
|
-
```
|
|
1145
|
+
#### `point(p: Vec3): Vec3` — Transform a point using homogeneous coordinates.
|
|
1696
1146
|
|
|
1697
|
-
#### `
|
|
1147
|
+
#### `vector(v: Vec3): Vec3` — Transform a direction vector without translation.
|
|
1698
1148
|
|
|
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
|
-
```
|
|
1149
|
+
#### `toArray(): Mat4` — Return the transform as a raw 4x4 matrix array.
|
|
1738
1150
|
|
|
1739
1151
|
### `ShapeGroup`
|
|
1740
1152
|
|
|
@@ -1743,117 +1155,49 @@ toArray(): Mat4
|
|
|
1743
1155
|
| Property | Type | Description |
|
|
1744
1156
|
|----------|------|-------------|
|
|
1745
1157
|
| `children` | `GroupChild[]` | — |
|
|
1746
|
-
| `childNames` | `Array<string
|
|
1158
|
+
| `childNames` | `Array<string \| undefined>` | — |
|
|
1747
1159
|
|
|
1748
1160
|
**Children**
|
|
1749
1161
|
|
|
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`.
|
|
1162
|
+
#### `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
1163
|
|
|
1758
|
-
|
|
1759
|
-
childName(index: number): string | undefined
|
|
1760
|
-
```
|
|
1164
|
+
#### `childName(index: number): string | undefined` — Return the optional name of the child at `index`.
|
|
1761
1165
|
|
|
1762
1166
|
**Transforms**
|
|
1763
1167
|
|
|
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.
|
|
1168
|
+
#### `translate(x: number, y: number, z: number): ShapeGroup` — Move the entire group by (x, y, z). All children move together as a unit.
|
|
1783
1169
|
|
|
1784
|
-
|
|
1785
|
-
rotate(axis: [ number, number, number ], angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1786
|
-
```
|
|
1170
|
+
#### `moveTo(x: number, y: number, z: number): ShapeGroup` — Move the group so its bounding-box min corner lands at the given coordinate.
|
|
1787
1171
|
|
|
1788
|
-
#### `
|
|
1172
|
+
#### `moveToLocal(target: Shape | ShapeGroup, x: number, y: number, z: number): ShapeGroup` — Move the group relative to another part's bounding-box min corner.
|
|
1789
1173
|
|
|
1790
|
-
|
|
1791
|
-
rotateX(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1792
|
-
```
|
|
1174
|
+
#### `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.
|
|
1793
1175
|
|
|
1794
|
-
#### `
|
|
1176
|
+
#### `rotateX(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the X axis.
|
|
1795
1177
|
|
|
1796
|
-
|
|
1797
|
-
rotateY(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1798
|
-
```
|
|
1178
|
+
#### `rotateY(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the Y axis.
|
|
1799
1179
|
|
|
1800
|
-
#### `rotateZ()` — Rotate the group around the Z axis.
|
|
1180
|
+
#### `rotateZ(angleDeg: number, options?: { pivot?: Vec3; }): ShapeGroup` — Rotate the group around the Z axis.
|
|
1801
1181
|
|
|
1802
|
-
|
|
1803
|
-
rotateZ(angleDeg: number, options?: { pivot?: [ number, number, number ]; }): ShapeGroup
|
|
1804
|
-
```
|
|
1182
|
+
#### `rotateAroundAxis(axis: Vec3, angleDeg: number, pivot?: Vec3): ShapeGroup` — Rotate around an arbitrary axis, optionally through a pivot point.
|
|
1805
1183
|
|
|
1806
|
-
#### `
|
|
1184
|
+
#### `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.
|
|
1807
1185
|
|
|
1808
|
-
|
|
1809
|
-
rotateAroundAxis(axis: [ number, number, number ], angleDeg: number, pivot?: [ number, number, number ]): ShapeGroup
|
|
1810
|
-
```
|
|
1186
|
+
#### `pointAlong(direction: Vec3): ShapeGroup` — Reorient the group so its local Z axis points along `direction`.
|
|
1811
1187
|
|
|
1812
|
-
#### `
|
|
1188
|
+
#### `transform(m: Mat4 | Transform): ShapeGroup` — Apply a 4x4 transform matrix or `Transform` to all 3D children.
|
|
1813
1189
|
|
|
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
|
-
```
|
|
1190
|
+
#### `scale(v: number | Vec3): ShapeGroup` — Scale uniformly or per-axis from the group's bounding-box center.
|
|
1817
1191
|
|
|
1818
|
-
#### `
|
|
1192
|
+
#### `scaleAround(pivot: Vec3, v: number | Vec3): ShapeGroup` — Scale uniformly or per-axis from an explicit pivot point.
|
|
1819
1193
|
|
|
1820
|
-
|
|
1821
|
-
pointAlong(direction: [ number, number, number ]): ShapeGroup
|
|
1822
|
-
```
|
|
1194
|
+
#### `mirror(normal: Vec3): ShapeGroup` — Mirror across a plane through the group's bounding-box center.
|
|
1823
1195
|
|
|
1824
|
-
#### `
|
|
1825
|
-
|
|
1826
|
-
```ts
|
|
1827
|
-
transform(m: Mat4 | Transform): ShapeGroup
|
|
1828
|
-
```
|
|
1829
|
-
|
|
1830
|
-
#### `scale()` — Scale uniformly or per-axis from the group's bounding-box center.
|
|
1831
|
-
|
|
1832
|
-
```ts
|
|
1833
|
-
scale(v: number | [ number, number, number ]): ShapeGroup
|
|
1834
|
-
```
|
|
1835
|
-
|
|
1836
|
-
#### `scaleAround()` — Scale uniformly or per-axis from an explicit pivot point.
|
|
1837
|
-
|
|
1838
|
-
```ts
|
|
1839
|
-
scaleAround(pivot: [ number, number, number ], v: number | [ number, number, number ]): ShapeGroup
|
|
1840
|
-
```
|
|
1841
|
-
|
|
1842
|
-
#### `mirror()` — Mirror across a plane through the group's bounding-box center.
|
|
1843
|
-
|
|
1844
|
-
```ts
|
|
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
|
-
```
|
|
1196
|
+
#### `mirrorThrough(point: Vec3, normal: Vec3): ShapeGroup` — Mirror across a plane through an explicit point.
|
|
1853
1197
|
|
|
1854
1198
|
**Placement**
|
|
1855
1199
|
|
|
1856
|
-
#### `placeReference()` — Translate the group so the given anchor or reference lands on the target coordinate.
|
|
1200
|
+
#### `placeReference(ref: PlacementAnchorLike, target: Vec3, offset?: Vec3): ShapeGroup` — Translate the group so the given anchor or reference lands on the target coordinate.
|
|
1857
1201
|
|
|
1858
1202
|
Accepts any built-in anchor name (`'bottom'`, `'center'`, `'top-front-left'`, etc.) or a custom placement reference attached via `withReferences()`.
|
|
1859
1203
|
|
|
@@ -1866,57 +1210,27 @@ const placed = require('./bracket-assembly.forge.js').group
|
|
|
1866
1210
|
.placeReference('mountCenter', [0, 0, 50]);
|
|
1867
1211
|
```
|
|
1868
1212
|
|
|
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.
|
|
1213
|
+
#### `attachTo(target: Shape | ShapeGroup, targetAnchor: Anchor3D | string, selfAnchor?: Anchor3D, offset?: Vec3): ShapeGroup` — Attach this group to a face or anchor on another part.
|
|
1874
1214
|
|
|
1875
1215
|
`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
1216
|
|
|
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
|
-
```
|
|
1217
|
+
#### `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
1218
|
|
|
1887
1219
|
**Connectors**
|
|
1888
1220
|
|
|
1889
|
-
#### `withConnectors()` — Attach named connectors — attachment points that survive transforms. Connectors can be bare (position + orientation) or typed (with connectorType/gender for compatibility matching).
|
|
1221
|
+
#### `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
1222
|
|
|
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.
|
|
1902
|
-
|
|
1903
|
-
```ts
|
|
1904
|
-
connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>
|
|
1905
|
-
```
|
|
1223
|
+
#### `connectorNames(): string[]` — List all connector names, including "ChildName.connectorName" from named children.
|
|
1906
1224
|
|
|
1907
|
-
#### `
|
|
1225
|
+
#### `connectorsByType(type: string): Array<{ name: string; port: ConnectorDef; }>` — Get all connectors of a given type, including from named children.
|
|
1908
1226
|
|
|
1909
|
-
|
|
1910
|
-
connectorDistance(nameA: string, nameB: string): number
|
|
1911
|
-
```
|
|
1227
|
+
#### `connectorDistance(nameA: string, nameB: string): number` — Distance between two connector origins on this group (supports dotted child paths).
|
|
1912
1228
|
|
|
1913
|
-
#### `connectorMeasurements()
|
|
1229
|
+
#### `connectorMeasurements(name: string): Record<string, number | string>` — Get measurements metadata from a connector (supports dotted child paths).
|
|
1914
1230
|
|
|
1915
|
-
|
|
1916
|
-
connectorMeasurements(name: string): Record<string, number | string>
|
|
1917
|
-
```
|
|
1231
|
+
#### `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
1232
|
|
|
1919
|
-
|
|
1233
|
+
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
1234
|
|
|
1921
1235
|
Overloads:
|
|
1922
1236
|
|
|
@@ -1924,13 +1238,9 @@ Overloads:
|
|
|
1924
1238
|
- Dictionary (same target): `matchTo(target, { selfConn: targetConn, ... }, options?)`
|
|
1925
1239
|
- Multi-target: `matchTo([ [target1, selfConn1, targetConn1], ... ], options?)`
|
|
1926
1240
|
|
|
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
1241
|
**References**
|
|
1932
1242
|
|
|
1933
|
-
#### `withReferences()` — Attach named placement references to this group. References survive normal transforms (translate/rotate/scale/mirror/transform).
|
|
1243
|
+
#### `withReferences(refs: PlacementReferenceInput): ShapeGroup` — Attach named placement references to this group. References survive normal transforms (translate/rotate/scale/mirror/transform).
|
|
1934
1244
|
|
|
1935
1245
|
```javascript
|
|
1936
1246
|
const bracket = group(
|
|
@@ -1941,41 +1251,17 @@ const bracket = group(
|
|
|
1941
1251
|
});
|
|
1942
1252
|
```
|
|
1943
1253
|
|
|
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.
|
|
1254
|
+
#### `referenceNames(kind?: PlacementReferenceKind): string[]` — List named placement references carried by this group.
|
|
1955
1255
|
|
|
1956
|
-
|
|
1957
|
-
referencePoint(ref: PlacementAnchorLike): [ number, number, number ]
|
|
1958
|
-
```
|
|
1256
|
+
#### `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
1257
|
|
|
1960
1258
|
**Other**
|
|
1961
1259
|
|
|
1962
|
-
#### `clone()` — Return a deep-cloned ShapeGroup tree (refs copied).
|
|
1260
|
+
#### `clone(): ShapeGroup` — Return a deep-cloned ShapeGroup tree (refs copied).
|
|
1963
1261
|
|
|
1964
|
-
|
|
1965
|
-
clone(): ShapeGroup
|
|
1966
|
-
```
|
|
1262
|
+
#### `boundingBox(): { min: Vec3; max: Vec3; }` — Return the combined 3D bounding box of all children.
|
|
1967
1263
|
|
|
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
|
-
```
|
|
1264
|
+
#### `color(hex: string): ShapeGroup` — Return a copy of the group with the given display color applied to each child.
|
|
1979
1265
|
|
|
1980
1266
|
**Compatibility Aliases**
|
|
1981
1267
|
|
|
@@ -1993,67 +1279,27 @@ color(hex: string): ShapeGroup
|
|
|
1993
1279
|
|
|
1994
1280
|
### `Pattern2D`
|
|
1995
1281
|
|
|
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.
|
|
1282
|
+
#### `add(...patterns: Pattern2DInput[]): Pattern2D` — Add this pattern to one or more patterns or constant height offsets.
|
|
2009
1283
|
|
|
2010
|
-
|
|
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.
|
|
1284
|
+
#### `subtract(pattern: Pattern2DInput): Pattern2D` — Subtract another pattern or constant height offset from this pattern.
|
|
2021
1285
|
|
|
2022
|
-
|
|
2023
|
-
max(...patterns: Pattern2DInput[]): Pattern2D
|
|
2024
|
-
```
|
|
1286
|
+
#### `multiply(...patterns: Pattern2DInput[]): Pattern2D` — Multiply this pattern by one or more patterns or numeric scale factors.
|
|
2025
1287
|
|
|
2026
|
-
#### `
|
|
1288
|
+
#### `min(...patterns: Pattern2DInput[]): Pattern2D` — Keep the lower height between this pattern and one or more other patterns.
|
|
2027
1289
|
|
|
2028
|
-
|
|
2029
|
-
clamp(min: number, max: number): Pattern2D
|
|
2030
|
-
```
|
|
1290
|
+
#### `max(...patterns: Pattern2DInput[]): Pattern2D` — Keep the higher height between this pattern and one or more other patterns.
|
|
2031
1291
|
|
|
2032
|
-
#### `
|
|
2033
|
-
|
|
2034
|
-
```ts
|
|
2035
|
-
abs(): Pattern2D
|
|
2036
|
-
```
|
|
1292
|
+
#### `clamp(min: number, max: number): Pattern2D` — Limit pattern height to the inclusive `[min, max]` range in millimeters.
|
|
2037
1293
|
|
|
2038
|
-
#### `
|
|
1294
|
+
#### `abs(): Pattern2D` — Convert negative heights to positive heights.
|
|
2039
1295
|
|
|
2040
|
-
|
|
2041
|
-
negate(): Pattern2D
|
|
2042
|
-
```
|
|
1296
|
+
#### `negate(): Pattern2D` — Flip the pattern height sign.
|
|
2043
1297
|
|
|
2044
1298
|
### `Pattern2DBuilder`
|
|
2045
1299
|
|
|
2046
|
-
#### `constant()` — Create a constant-height pattern in millimeters.
|
|
1300
|
+
#### `constant(value?: number): Pattern2D` — Create a constant-height pattern in millimeters.
|
|
2047
1301
|
|
|
2048
|
-
|
|
2049
|
-
constant(value?: number): Pattern2D
|
|
2050
|
-
```
|
|
2051
|
-
|
|
2052
|
-
#### `sineWave()` — Create a sinusoidal wave pattern in UV space.
|
|
2053
|
-
|
|
2054
|
-
```ts
|
|
2055
|
-
sineWave(options: Pattern2DSineWaveOptions): Pattern2D
|
|
2056
|
-
```
|
|
1302
|
+
#### `sineWave(options: Pattern2DSineWaveOptions): Pattern2D` — Create a sinusoidal wave pattern in UV space.
|
|
2057
1303
|
|
|
2058
1304
|
**`Pattern2DSineWaveOptions`**
|
|
2059
1305
|
|
|
@@ -2065,11 +1311,7 @@ sineWave(options: Pattern2DSineWaveOptions): Pattern2D
|
|
|
2065
1311
|
| `phase?` | `number` | Phase offset in radians. Default: 0. |
|
|
2066
1312
|
| `bias?` | `number` | Constant height offset in millimeters. Default: 0. |
|
|
2067
1313
|
|
|
2068
|
-
#### `stripes()` — Create recessed stripe bands in UV space.
|
|
2069
|
-
|
|
2070
|
-
```ts
|
|
2071
|
-
stripes(options: Pattern2DStripesOptions): Pattern2D
|
|
2072
|
-
```
|
|
1314
|
+
#### `stripes(options: Pattern2DStripesOptions): Pattern2D` — Create recessed stripe bands in UV space.
|
|
2073
1315
|
|
|
2074
1316
|
**`Pattern2DStripesOptions`**
|
|
2075
1317
|
|
|
@@ -2080,11 +1322,7 @@ stripes(options: Pattern2DStripesOptions): Pattern2D
|
|
|
2080
1322
|
| `width` | `number` | Stripe width in surface millimeters. |
|
|
2081
1323
|
| `depth?` | `number` | Stripe groove depth in millimeters. Default: 1. |
|
|
2082
1324
|
|
|
2083
|
-
#### `overUnderWeave()` — Create an over-under woven relief pattern in UV space.
|
|
2084
|
-
|
|
2085
|
-
```ts
|
|
2086
|
-
overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D
|
|
2087
|
-
```
|
|
1325
|
+
#### `overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D` — Create an over-under woven relief pattern in UV space.
|
|
2088
1326
|
|
|
2089
1327
|
**`Pattern2DOverUnderWeaveOptions`**
|
|
2090
1328
|
|
|
@@ -2095,120 +1333,6 @@ overUnderWeave(options: Pattern2DOverUnderWeaveOptions): Pattern2D
|
|
|
2095
1333
|
| `depth?` | `number` | Thread groove depth in millimeters. Default: 0.8. |
|
|
2096
1334
|
| `underScale?` | `number` | Relative height of the under-crossing thread. Default: 0.15. |
|
|
2097
1335
|
|
|
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
1336
|
### `ShapeRef`
|
|
2213
1337
|
|
|
2214
1338
|
A first-class reference path over a shape's semantic faces and face relationships.
|
|
@@ -2223,107 +1347,39 @@ Created with `shape.ref("lid/back")`, then refined through methods such as `.poi
|
|
|
2223
1347
|
|
|
2224
1348
|
**Methods:**
|
|
2225
1349
|
|
|
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
|
-
```
|
|
1350
|
+
#### `resolve(): ShapeReferenceResolution` — Resolve this reference into its current faces, edges, or points.
|
|
2279
1351
|
|
|
2280
|
-
#### `
|
|
1352
|
+
#### `get kind(): ShapeReferenceKind` — The resolved reference kind, such as `face`, `edge-set`, or `point`.
|
|
2281
1353
|
|
|
2282
|
-
|
|
2283
|
-
faces(): FaceRef[]
|
|
2284
|
-
```
|
|
1354
|
+
#### `get cardinality(): ShapeReferenceCardinality` — Whether the reference currently resolves to zero, one, or many matches.
|
|
2285
1355
|
|
|
2286
|
-
#### `
|
|
1356
|
+
#### `status(): ShapeReferenceStatus` — Return the reference lifecycle status for the current shape state.
|
|
2287
1357
|
|
|
2288
|
-
|
|
2289
|
-
face(): FaceRef
|
|
2290
|
-
```
|
|
1358
|
+
#### `explain(): string` — Return a human-readable explanation of how this reference resolved.
|
|
2291
1359
|
|
|
2292
|
-
#### `
|
|
1360
|
+
#### `as(name: string): ShapeRef` — Name this derived reference so the same shape can resolve it by `shape.ref(name)`.
|
|
2293
1361
|
|
|
2294
|
-
|
|
2295
|
-
edges(): EdgeSegment[]
|
|
2296
|
-
```
|
|
1362
|
+
#### `maybe(): ShapeRef` — Return an optional reference that resolves to zero matches instead of throwing when missing.
|
|
2297
1363
|
|
|
2298
|
-
#### `
|
|
1364
|
+
#### `all(): ShapeRef` — Mark that a multi-match reference is intentionally being used as a set.
|
|
2299
1365
|
|
|
2300
|
-
|
|
2301
|
-
edge(): EdgeSegment
|
|
2302
|
-
```
|
|
1366
|
+
#### `one(): ShapeRef` — Require this reference to resolve to exactly one match.
|
|
2303
1367
|
|
|
2304
|
-
#### `
|
|
1368
|
+
#### `faces(): FaceRef[]` — Resolve this reference as one or more faces.
|
|
2305
1369
|
|
|
2306
|
-
|
|
2307
|
-
points(): Vec3[]
|
|
2308
|
-
```
|
|
1370
|
+
#### `face(): FaceRef` — Resolve this reference as exactly one face.
|
|
2309
1371
|
|
|
2310
|
-
####
|
|
1372
|
+
#### `edges(): EdgeSegment[]` — Resolve this reference as one or more edges. Face references return boundary edges.
|
|
2311
1373
|
|
|
2312
|
-
|
|
2313
|
-
point(): Vec3
|
|
2314
|
-
```
|
|
1374
|
+
#### `edge(): EdgeSegment` — Resolve this reference as exactly one edge.
|
|
2315
1375
|
|
|
2316
|
-
#### `
|
|
1376
|
+
#### `points(): Vec3[]` — Resolve this reference as one or more points. Faces use centers and edges use midpoints.
|
|
2317
1377
|
|
|
2318
|
-
|
|
2319
|
-
toJSON(): ShapeReferenceResolution
|
|
2320
|
-
```
|
|
1378
|
+
#### `point(): Vec3` — Resolve this reference as exactly one point.
|
|
2321
1379
|
|
|
2322
|
-
#### `
|
|
1380
|
+
#### `toJSON(): ShapeReferenceResolution` — Return the structured JSON-friendly reference resolution.
|
|
2323
1381
|
|
|
2324
|
-
|
|
2325
|
-
toString(): string
|
|
2326
|
-
```
|
|
1382
|
+
#### `toString(): string` — Return a compact display form for this reference path.
|
|
2327
1383
|
|
|
2328
1384
|
---
|
|
2329
1385
|
|
|
@@ -2333,46 +1389,7 @@ toString(): string
|
|
|
2333
1389
|
|
|
2334
1390
|
### `verify`
|
|
2335
1391
|
|
|
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.
|
|
1392
|
+
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
1393
|
|
|
2377
1394
|
### `Points`
|
|
2378
1395
|
|
|
@@ -2381,7 +1398,7 @@ toString(): string
|
|
|
2381
1398
|
- `lerp(a: Vec3, b: Vec3, t: number): Vec3` — Linearly interpolate between two 3D points. t=0 returns a, t=1 returns b.
|
|
2382
1399
|
- `direction(a: Vec3, b: Vec3): Vec3` — Unit direction vector from a to b. Throws if a and b are the same point.
|
|
2383
1400
|
- `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?:
|
|
1401
|
+
- `polar(length: number, angleDeg: number, from?: Vec2): Vec2` — Compute a 2D point at distance and angle (degrees) from an optional origin.
|
|
2385
1402
|
|
|
2386
1403
|
### `connector`
|
|
2387
1404
|
|
|
@@ -2389,6 +1406,22 @@ Connector factory. Create attachment points: `connector({...})`, `connector.male
|
|
|
2389
1406
|
|
|
2390
1407
|
### `Import`
|
|
2391
1408
|
|
|
2392
|
-
Namespaced file import helpers for
|
|
1409
|
+
Namespaced file-format import helpers — the single vocabulary for bringing external geometry files into a model.
|
|
2393
1410
|
|
|
2394
1411
|
- `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.
|
|
1412
|
+
- `svgSketch(fileName: string, options?: SvgImportOptions): Sketch` — Parse an SVG file and return it as a Sketch with options for region filtering, scaling, and simplification.
|
|
1413
|
+
- `mesh(fileName: string, options?: MeshImportOptions): Shape | ShapeGroup` — Import an external mesh file (STL, OBJ, 3MF).
|
|
1414
|
+
|
|
1415
|
+
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`.
|
|
1416
|
+
|
|
1417
|
+
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.
|
|
1418
|
+
|
|
1419
|
+
Use `sourceFrame: { up: "+Y" }` when the file was authored in a non-Z-up coordinate system. ForgeCAD remains Z-up; the import is rotated so the named source axis becomes ForgeCAD +Z. Supported values: `"+X"`, `"-X"`, `"+Y"`, `"-Y"`, `"+Z"`, `"-Z"`.
|
|
1420
|
+
|
|
1421
|
+
```js
|
|
1422
|
+
const all = Import.mesh("./assembly.3mf", { separateObjects: true });
|
|
1423
|
+
const pin = all.child("Pin #001");
|
|
1424
|
+
const plate = Import.mesh("./assembly.3mf", { object: "3mf:build:001:object:7" });
|
|
1425
|
+
const yUpPart = Import.mesh("./part.obj", { sourceFrame: { up: "+Y" } });
|
|
1426
|
+
```
|
|
1427
|
+
- `step(fileName: string, options?: StepImportOptions): 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. Use `sourceFrame: { up: "+Y" }` to rotate Y-up source files into ForgeCAD's Z-up world.
|