forgecad 0.6.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -12
- package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-D4bocK4E.js} +250 -151
- package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
- package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-D3A_g8V3.js} +329 -163
- package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-BWYUSpUN.css} +590 -136
- package/dist/assets/EditorApp-Cihhqcsq.js +11692 -0
- package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-kWjKaC_t.js} +2 -4
- package/dist/assets/LandingPageProofDriven-Bg2IUc3l.css +856 -0
- package/dist/assets/LandingPageProofDriven-DXkKlyhI.js +601 -0
- package/dist/assets/PricingPage-BsU5vzEx.js +232 -0
- package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-PqvpAKIs.js} +129 -5
- package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-C-hzNUMy.js} +8949 -3161
- package/dist/assets/{Viewport-CoB46f5R.js → index-Pz321YAt.js} +38382 -7501
- package/dist/assets/{index-2hfs_ub0.css → index-ay13WNfa.css} +726 -53
- package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
- package/dist/assets/{manifold-CqNMHHKO.js → manifold-BcbjWLIo.js} +4 -3
- package/dist/assets/{manifold-Cce9wRFz.js → manifold-DBckbFgx.js} +1 -1
- package/dist/assets/{manifold-D6BeHIOo.js → manifold-O2AAGXyj.js} +1 -1
- package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-Dxr-5A7w.js} +8760 -3559
- package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/CLI.md +341 -718
- package/dist/docs-raw/generated/assembly.md +699 -112
- package/dist/docs-raw/generated/concepts.md +1834 -1346
- package/dist/docs-raw/generated/core.md +1012 -1059
- package/dist/docs-raw/generated/curves.md +759 -116
- package/dist/docs-raw/generated/lib.md +43 -748
- package/dist/docs-raw/generated/output.md +139 -245
- package/dist/docs-raw/generated/sdf.md +208 -0
- package/dist/docs-raw/generated/sheet-metal.md +473 -21
- package/dist/docs-raw/generated/sketch.md +1518 -362
- package/dist/docs-raw/generated/viewport.md +368 -299
- package/dist/docs-raw/generated/wood.md +104 -0
- package/dist/index.html +2 -2
- package/dist/landing/proof-ams-adapter.png +0 -0
- package/dist/landing/proof-bolt-and-nut.png +0 -0
- package/dist/landing/proof-fillet-enclosure.png +0 -0
- package/dist/landing/proof-glasses.png +0 -0
- package/dist/landing/proof-gyroid.png +0 -0
- package/dist/sitemap.xml +6 -6
- package/dist-cli/forgecad.js +12321 -5700
- package/dist-cli/forgecad.js.map +1 -0
- package/dist-cli/solver-46FFSK2U.js +363 -0
- package/dist-cli/solver-46FFSK2U.js.map +1 -0
- package/dist-skill/CONTEXT.md +4890 -6302
- package/dist-skill/SKILL-dev.md +22 -66
- package/dist-skill/SKILL.md +20 -59
- package/dist-skill/docs/API/core/concepts.md +37 -92
- package/dist-skill/docs/CLI.md +341 -718
- package/dist-skill/docs/generated/assembly.md +699 -112
- package/dist-skill/docs/generated/core.md +1012 -1059
- package/dist-skill/docs/generated/curves.md +759 -116
- package/dist-skill/docs/generated/lib.md +43 -748
- package/dist-skill/docs/generated/output.md +139 -245
- package/dist-skill/docs/generated/sdf.md +208 -0
- package/dist-skill/docs/generated/sheet-metal.md +473 -21
- package/dist-skill/docs/generated/sketch.md +1518 -362
- package/dist-skill/docs/generated/viewport.md +368 -299
- package/dist-skill/docs/generated/wood.md +104 -0
- package/dist-skill/docs/guides/coordinate-system.md +11 -17
- package/dist-skill/docs/guides/geometry-conventions.md +13 -70
- package/dist-skill/docs/guides/joint-design.md +78 -0
- package/dist-skill/docs/guides/modeling-recipes.md +22 -195
- package/dist-skill/docs/guides/positioning.md +88 -147
- package/dist-skill/docs-dev/API/core/concepts.md +78 -0
- package/dist-skill/docs-dev/CLI.md +488 -0
- package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
- package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
- package/dist-skill/{docs → docs-dev}/coding.md +2 -4
- package/dist-skill/docs-dev/component-model.md +164 -0
- package/dist-skill/docs-dev/generated/assembly.md +779 -0
- package/dist-skill/docs-dev/generated/core.md +1676 -0
- package/dist-skill/docs-dev/generated/curves.md +855 -0
- package/dist-skill/docs-dev/generated/lib.md +55 -0
- package/dist-skill/docs-dev/generated/output.md +234 -0
- package/dist-skill/docs-dev/generated/sdf.md +208 -0
- package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
- package/dist-skill/docs-dev/generated/sketch.md +1753 -0
- package/dist-skill/docs-dev/generated/viewport.md +513 -0
- package/dist-skill/docs-dev/generated/wood.md +104 -0
- package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
- package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
- package/dist-skill/docs-dev/guides/joint-design.md +78 -0
- package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
- package/dist-skill/docs-dev/guides/positioning.md +151 -0
- package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
- package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
- package/examples/api/attachTo-basics.forge.js +8 -8
- package/examples/api/bill-of-materials.forge.js +9 -9
- package/examples/api/bolt-pattern.forge.js +5 -5
- package/examples/api/boolean-operations.forge.js +5 -5
- package/examples/api/bounding-box-visualizer.forge.js +3 -3
- package/examples/api/clone-duplicate.forge.js +2 -2
- package/examples/api/colors-union-vs-array.forge.js +6 -6
- package/examples/api/connector-assembly.forge.js +8 -6
- package/examples/api/connector-basics.forge.js +7 -7
- package/examples/api/constrained-sketch-mechanical.forge.js +4 -4
- package/examples/api/elbow-test.forge.js +3 -3
- package/examples/api/extrude-options.forge.js +8 -14
- package/examples/api/feature-created-faces.forge.js +6 -10
- package/examples/api/fillet-showcase.forge.js +2 -2
- package/examples/api/folded-service-panel-cover.forge.js +2 -2
- package/examples/api/gears-tier1.forge.js +5 -5
- package/examples/api/group-test.forge.js +3 -3
- package/examples/api/group-vs-union.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +4 -0
- package/examples/api/js-module-pillars.js +1 -1
- package/examples/api/js-module-scene.js +2 -2
- package/examples/api/mesh-import-slats.forge.js +4 -4
- package/examples/api/patterns.forge.js +3 -3
- package/examples/api/pointAlong-orientation.forge.js +3 -3
- package/examples/api/profile-2020-b-slot6.forge.js +4 -5
- package/examples/api/route-perimeter-flange.forge.js +1 -1
- package/examples/api/sdf-rover-demo.forge.js +10 -10
- package/examples/api/sketch-on-face-demo.forge.js +2 -2
- package/examples/api/sketch-regions.forge.js +4 -4
- package/examples/api/sketch-rounding-strategies.forge.js +1 -1
- package/examples/api/smooth-curve-connections.forge.js +1 -1
- package/examples/api/transition-curves.forge.js +4 -4
- package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
- package/examples/api/variable-sweep-test.forge.js +2 -2
- package/examples/api/wood-joinery.forge.js +60 -0
- package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
- package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
- package/examples/constraints/01-fully-constrained-rect.forge.js +2 -2
- package/examples/constraints/02-underconstrained-triangle.forge.js +1 -1
- package/examples/constraints/03-redundant-constraints.forge.js +2 -2
- package/examples/constraints/05-parallel-with-linedistance.forge.js +2 -2
- package/examples/constraints/06-complex-spectrogram.forge.js +1 -1
- package/examples/constraints/07-perpendicular-chain.forge.js +4 -4
- package/examples/constraints/08-symmetric-bracket.forge.js +4 -4
- package/examples/constraints/09-stress-spiral.forge.js +1 -1
- package/examples/constraints/10-stress-honeycomb.forge.js +1 -1
- package/examples/constraints/11-surface-grid.forge.js +2 -2
- package/examples/constraints/12-surface-nested.forge.js +4 -4
- package/examples/constraints/13-surface-complex.forge.js +1 -1
- package/examples/exact-arc-housing.forge.js +12 -0
- package/examples/experiments/drone-arm.forge.js +53 -0
- package/examples/furniture/adjustable-table.forge.js +15 -15
- package/examples/furniture/bathroom.forge.js +26 -26
- package/examples/furniture/chair.forge.js +13 -13
- package/examples/furniture/picture-frame.forge.js +6 -6
- package/examples/furniture/shoe-rack-doors.forge.js +8 -8
- package/examples/furniture/shoe-rack.forge.js +7 -7
- package/examples/furniture/table-lamp.forge.js +8 -8
- package/examples/gcode/lissajous-vase.forge.js +4 -4
- package/examples/gcode/math-surface.forge.js +3 -3
- package/examples/gcode/parametric-vase.forge.js +4 -4
- package/examples/gcode/spiral-tower.forge.js +4 -4
- package/examples/generative/crystal-growth.forge.js +9 -9
- package/examples/generative/frost-spires.forge.js +9 -9
- package/examples/generative/golden-spiral-tower.forge.js +11 -11
- package/examples/generative/molten-forge.forge.js +6 -6
- package/examples/generative/neon-coral.forge.js +7 -7
- package/examples/mechanical/3d-printer.forge.js +37 -37
- package/examples/mechanical/5-finger-robot-hand.forge.js +19 -19
- package/examples/mechanical/airplane-propeller.forge.js +9 -9
- package/examples/mechanical/bolt-and-nut.forge.js +10 -10
- package/examples/mechanical/door-with-hinges.forge.js +7 -7
- package/examples/mechanical/fillet-enclosure.forge.js +15 -11
- package/examples/mechanical/headphone-hanger-v2.forge.js +11 -11
- package/examples/mechanical/robot_hand.forge.js +24 -24
- package/examples/mechanical/robot_hand_2.forge.js +26 -26
- package/examples/nurbs-surface.forge.js +8 -0
- package/examples/nurbs-tube.forge.js +7 -0
- package/examples/products/bottle.forge.js +8 -8
- package/examples/products/chess-set.forge.js +25 -25
- package/examples/products/classical-piano.forge.js +20 -20
- package/examples/products/clock.forge.js +33 -33
- package/examples/products/cup.forge.js +5 -5
- package/examples/products/iphone.forge.js +20 -20
- package/examples/products/laptop.forge.js +24 -24
- package/examples/products/laser-cut-box.forge.js +6 -6
- package/examples/products/laser-cut-tray.forge.js +6 -6
- package/examples/products/liquid-soap-dispenser.forge.js +23 -23
- package/examples/products/origami-fish.forge.js +14 -12
- package/examples/products/spiderman-cake.forge.js +6 -6
- package/examples/shelf/container.forge.js +5 -5
- package/examples/shelf/shelf-unit.forge.js +6 -6
- package/examples/toolbox/bolted-joint.forge.js +7 -7
- package/package.json +9 -4
- package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
- package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
- package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
- package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
- package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
- package/dist/assets/index-1CYp3zUp.js +0 -1455
- package/dist-skill/docs/API/API.md +0 -1666
- package/dist-skill/docs/API/README.md +0 -37
- package/dist-skill/docs/API/assembly/assembly.md +0 -617
- package/dist-skill/docs/API/core/edge-queries.md +0 -130
- package/dist-skill/docs/API/core/parameters.md +0 -122
- package/dist-skill/docs/API/core/reserved-terms.md +0 -137
- package/dist-skill/docs/API/core/sdf.md +0 -326
- package/dist-skill/docs/API/core/skill-cli.md +0 -194
- package/dist-skill/docs/API/core/skill-guide.md +0 -205
- package/dist-skill/docs/API/core/specs.md +0 -186
- package/dist-skill/docs/API/core/topology.md +0 -372
- package/dist-skill/docs/API/entities.md +0 -268
- package/dist-skill/docs/API/output/bom.md +0 -58
- package/dist-skill/docs/API/output/brep-export.md +0 -87
- package/dist-skill/docs/API/output/dimensions.md +0 -67
- package/dist-skill/docs/API/output/export.md +0 -110
- package/dist-skill/docs/API/output/gcode.md +0 -195
- package/dist-skill/docs/API/runtime/viewport.md +0 -420
- package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
- package/dist-skill/docs/API/sketch/anchor.md +0 -37
- package/dist-skill/docs/API/sketch/booleans.md +0 -91
- package/dist-skill/docs/API/sketch/core.md +0 -73
- package/dist-skill/docs/API/sketch/extrude.md +0 -62
- package/dist-skill/docs/API/sketch/on-face.md +0 -104
- package/dist-skill/docs/API/sketch/operations.md +0 -78
- package/dist-skill/docs/API/sketch/path.md +0 -75
- package/dist-skill/docs/API/sketch/primitives.md +0 -146
- package/dist-skill/docs/API/sketch/regions.md +0 -80
- package/dist-skill/docs/API/sketch/text.md +0 -108
- package/dist-skill/docs/API/sketch/transforms.md +0 -65
- package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
- package/dist-skill/docs/INDEX.md +0 -94
- package/dist-skill/docs/RELEASING.md +0 -55
- package/dist-skill/docs/cli-monetization.md +0 -111
- package/dist-skill/docs/deployment.md +0 -281
- package/dist-skill/docs/generated/concepts.md +0 -2112
- package/dist-skill/docs/internals/shape-from-slices.md +0 -152
- package/dist-skill/docs/platform/admin.md +0 -45
- package/dist-skill/docs/platform/architecture.md +0 -79
- package/dist-skill/docs/platform/auth.md +0 -110
- package/dist-skill/docs/platform/email.md +0 -67
- package/dist-skill/docs/platform/projects.md +0 -111
- package/dist-skill/docs/platform/sharing.md +0 -90
- package/dist-skill/docs/runbook.md +0 -345
|
@@ -5,440 +5,509 @@ skill-order: 100
|
|
|
5
5
|
|
|
6
6
|
# Viewport & Runtime
|
|
7
7
|
|
|
8
|
-
> **Auto-generated** from `src/forge/forge-public-api.ts`. Do not edit by hand — run `npm run gen:docs` to regenerate.
|
|
9
|
-
|
|
10
8
|
Cut planes, exploded views, joint animations, and scene configuration.
|
|
11
9
|
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [Viewport & Runtime](#viewport-runtime) — `jointsView`, `explodeView`, `cutPlane`, `cutPlane`, `mock`, `scene`, `viewConfig`, `showLabels`, `highlight`, `highlight`, `highlight`, `highlight`, `highlight`, `highlight`, `highlight`, `highlight`
|
|
13
|
+
- [RouteBuilder](#routebuilder)
|
|
14
|
+
- [route](#route)
|
|
15
|
+
|
|
12
16
|
## Functions
|
|
13
17
|
|
|
14
18
|
### Viewport & Runtime
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
#### `jointsView()` — Register viewport-only mechanism controls that animate returned objects without re-running the script.
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
Defines joints (revolute or prismatic), optional gear/rack couplings, and named animations. The viewport resolves transforms through the joint chain at display time — the script geometry is computed only once at rest pose.
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
**Critical:** Solve the assembly at **rest pose** (all animated joints = 0). The viewport applies `jointsView` transforms on top of the returned scene. If geometry is already solved at non-zero angles, animation will double-rotate everything.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// BAD — double rotation
|
|
28
|
+
const solved = mech.solve({ shoulder: 45, elbow: 30 });
|
|
29
|
+
jointsView({ joints: [{ name: 'shoulder', ... }] });
|
|
30
|
+
return solved;
|
|
31
|
+
|
|
32
|
+
// GOOD — rest pose, jointsView controls all posing
|
|
33
|
+
const solved = mech.solve({ shoulder: 0, elbow: 0 });
|
|
34
|
+
jointsView({
|
|
35
|
+
joints: [
|
|
36
|
+
{ name: 'shoulder', child: 'Upper Arm', default: 45, ... },
|
|
37
|
+
{ name: 'elbow', child: 'Forearm', parent: 'Upper Arm', default: 30, ... },
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
return solved;
|
|
22
41
|
```
|
|
23
42
|
|
|
24
|
-
|
|
43
|
+
**Pivot coordinates** are world-space positions of each joint origin at rest pose. For `addRevolute('shoulder', 'Base', 'Link', { frame: Transform.identity().translate(0, 0, 20) })` where "Base" is at world origin, the pivot is `[0, 0, 20]`.
|
|
25
44
|
|
|
26
|
-
|
|
45
|
+
**Fixed attachments** that must follow a parent during animation need a zero-angle revolute joint in the chain:
|
|
27
46
|
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
couplings?: JointViewCouplingInput[];
|
|
33
|
-
animations?: JointViewAnimationInput[];
|
|
34
|
-
defaultAnimation?: string;
|
|
35
|
-
}
|
|
47
|
+
```js
|
|
48
|
+
{ name: 'EE_Follow', child: 'End Effector', parent: 'Last Link',
|
|
49
|
+
type: 'revolute', axis: [0, 0, 1], pivot: [linkLength, 0, 0],
|
|
50
|
+
min: 0, max: 0, default: 0 }
|
|
36
51
|
```
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
Animation values are interpolated linearly between keyframes. ForgeCAD does **not** auto-wrap revolute values across `-180/180`. Keep keyframe values continuous — a `-180 -> 171` jump spins the part the long way around. Use `-180 -> -189` instead. Author high-speed multi-turn joints as accumulating angles (`0, 360, 720, ...`) with `continuous: true`.
|
|
39
54
|
|
|
40
|
-
|
|
55
|
+
**Tick-based keyframes:** Omit `at` from all keyframes to auto-distribute by tick weight:
|
|
41
56
|
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
min?: number;
|
|
50
|
-
max?: number;
|
|
51
|
-
default?: number;
|
|
52
|
-
unit?: string;
|
|
53
|
-
hidden?: boolean;
|
|
54
|
-
}
|
|
57
|
+
```js
|
|
58
|
+
keyframes: [
|
|
59
|
+
{ ticks: 3, values: { Shoulder: 20 } }, // slow segment (3x weight)
|
|
60
|
+
{ ticks: 1, values: { Shoulder: -10 } }, // fast segment (1x weight)
|
|
61
|
+
{ values: { Shoulder: 20 } }, // last keyframe; ticks ignored
|
|
62
|
+
]
|
|
63
|
+
// positions: 0, 0.75, 1.0
|
|
55
64
|
```
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
Mixing explicit `at` and omitted `at` in the same animation is not allowed.
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
jointsView({
|
|
70
|
+
joints: [{
|
|
71
|
+
name: 'Shoulder', child: 'Upper Arm', parent: 'Base',
|
|
72
|
+
type: 'revolute', axis: [0, -1, 0], pivot: [0, 0, 46],
|
|
73
|
+
min: -30, max: 110, default: 15,
|
|
74
|
+
}],
|
|
75
|
+
animations: [{
|
|
76
|
+
name: 'Walk Cycle', duration: 1.6, loop: true,
|
|
77
|
+
keyframes: [
|
|
78
|
+
{ values: { Shoulder: 20 } },
|
|
79
|
+
{ values: { Shoulder: -10 } },
|
|
80
|
+
{ values: { Shoulder: 20 } },
|
|
81
|
+
],
|
|
82
|
+
}],
|
|
83
|
+
});
|
|
84
|
+
```
|
|
60
85
|
|
|
61
86
|
```ts
|
|
62
|
-
|
|
63
|
-
joint: string;
|
|
64
|
-
terms: JointViewCouplingTermInput[];
|
|
65
|
-
offset?: number;
|
|
66
|
-
}
|
|
87
|
+
jointsView(options?: JointsViewOptions): void
|
|
67
88
|
```
|
|
68
89
|
|
|
69
|
-
|
|
90
|
+
**`JointsViewOptions`**: `enabled?: boolean`, `joints?: JointViewInput[]`, `couplings?: JointViewCouplingInput[]`, `animations?: JointViewAnimationInput[]`, `defaultAnimation?: string`
|
|
70
91
|
|
|
71
|
-
|
|
92
|
+
**`JointViewInput`**: `name: string`, `child: string`, `parent?: string`, `type?: JointViewType`, `axis?: JointViewAxis`, `min?: number`, `max?: number`, `default?: number`, `unit?: string`, `hidden?: boolean`
|
|
72
93
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
94
|
+
`JointViewCouplingInput`: `{ joint: string, terms: JointViewCouplingTermInput[], offset?: number }`
|
|
95
|
+
|
|
96
|
+
`JointViewCouplingTermInput`: `{ joint: string, ratio?: number }`
|
|
97
|
+
|
|
98
|
+
`JointViewAnimationInput`: `{ name: string, duration?: number, loop?: boolean, continuous?: boolean, keyframes: JointViewAnimationKeyframeInput[] }`
|
|
99
|
+
|
|
100
|
+
**`JointViewAnimationKeyframeInput`**
|
|
101
|
+
- `at?: number` — Timeline position [0, 1]. If omitted from ALL keyframes, positions are auto-computed from tick weights.
|
|
102
|
+
- `ticks?: number` — Relative weight of the segment from this keyframe to the next (default 1). Only used in tick-based mode (when `at` is omitted). Last keyframe's ticks value is ignored.
|
|
103
|
+
- Also: `values: Record<string, number>`
|
|
79
104
|
|
|
80
|
-
|
|
105
|
+
#### `explodeView()` — Configure how the viewport explode slider offsets returned objects.
|
|
81
106
|
|
|
82
|
-
|
|
107
|
+
Offsets are resolved from the returned object tree, not a flat list. In `radial` mode each node follows its parent branch direction, then fans locally from the immediate parent center — nested assemblies peel apart level by level. In fixed-axis or fixed-vector modes, the branch follows that axis/vector but nested descendants fan out perpendicular by default.
|
|
108
|
+
|
|
109
|
+
Multiple calls merge — later values override earlier ones on a per-key basis. `byName` and `byPath` maps are merged entry-by-entry.
|
|
110
|
+
|
|
111
|
+
For programmatic explode applied before returning (without the slider), use `lib.explode()` instead.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
explodeView({
|
|
115
|
+
amountScale: 1.2,
|
|
116
|
+
stages: [0.35, 0.8],
|
|
117
|
+
mode: 'radial',
|
|
118
|
+
byPath: { 'Drive/Shaft': { direction: [1, 0, 0], stage: 1.6 } },
|
|
119
|
+
});
|
|
120
|
+
```
|
|
83
121
|
|
|
84
122
|
```ts
|
|
85
|
-
|
|
86
|
-
name: string;
|
|
87
|
-
duration?: number;
|
|
88
|
-
loop?: boolean;
|
|
89
|
-
continuous?: boolean;
|
|
90
|
-
keyframes: JointViewAnimationKeyframeInput[];
|
|
91
|
-
}
|
|
123
|
+
explodeView(options?: ExplodeViewOptions): void
|
|
92
124
|
```
|
|
93
125
|
|
|
94
|
-
|
|
126
|
+
**`ExplodeViewOptions`**
|
|
127
|
+
|
|
128
|
+
| Option | Type | Description |
|
|
129
|
+
|--------|------|-------------|
|
|
130
|
+
| `enabled?` | `boolean` | Set false to disable viewport explode offsets for this script output. |
|
|
131
|
+
| `amountScale?` | `number` | Scales the UI explode amount. Default: 1 |
|
|
132
|
+
| `stages?` | `number[]` | Per-depth stage multipliers (depth 1 = first level). If depth exceeds this array, the last value is reused. Default when omitted: reciprocal depth (1, 1/2, 1/3, ...) |
|
|
133
|
+
| `mode?` | `ExplodeViewDirection` | Global direction mode fallback. Default: 'radial' |
|
|
134
|
+
| `axisLock?` | `ExplodeAxis` | Global axis lock fallback. |
|
|
135
|
+
| `byName?` | `Record<string, ExplodeViewDirective>` | Per-object overrides by final object name. |
|
|
136
|
+
| `byPath?` | `Record<string, ExplodeViewDirective>` | Per-tree-path overrides using slash-separated object tree segments. |
|
|
137
|
+
|
|
138
|
+
**`ExplodeDirective`**
|
|
139
|
+
- `stage?: number` — Multiplier applied to `amount` for this node
|
|
140
|
+
- `direction?: ExplodeDirection` — Direction mode for this node
|
|
141
|
+
- `axisLock?: ExplodeAxis` — Optional axis lock after direction is resolved
|
|
142
|
+
|
|
143
|
+
#### `cutPlane()` — Define a named section plane for inspecting internal geometry.
|
|
144
|
+
|
|
145
|
+
Registers a cut plane that appears as a toggle in the viewport View Panel. When enabled, geometry on the positive side of the plane (the side the normal points toward) is clipped away, revealing the internal cross-section. The newly exposed section faces render with a hatched overlay; pre-existing coplanar boundary faces are left unhatched.
|
|
95
146
|
|
|
96
|
-
|
|
147
|
+
Planes are registered once per script run. The viewport toggle state (on/off) persists across parameter changes without re-running the script. The `exclude` option only works correctly when the excluded object names are stable across parameter changes.
|
|
148
|
+
|
|
149
|
+
Accepts two overloads: `cutPlane(name, normal, offset?, options?)` or `cutPlane(name, normal, options?)` where options may include `offset`.
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
const cutZ = param('Cut Height', 10, { min: -50, max: 50, unit: 'mm' });
|
|
153
|
+
cutPlane('Inspection', [0, 0, 1], cutZ, { exclude: ['Probe', 'Fasteners'] });
|
|
154
|
+
```
|
|
97
155
|
|
|
98
156
|
```ts
|
|
99
|
-
|
|
100
|
-
/** Timeline position [0, 1]. If omitted from ALL keyframes, positions are auto-computed from tick weights. */
|
|
101
|
-
at?: number;
|
|
102
|
-
/** Relative weight of the segment from this keyframe to the next (default 1). Only used in tick-based mode (when `at` is omitted). Last keyframe's ticks value is ignored. */
|
|
103
|
-
ticks?: number;
|
|
104
|
-
values: Record<string, number>;
|
|
105
|
-
}
|
|
157
|
+
cutPlane(name: string, normal: [ number, number, number ], offset?: number, options?: CutPlaneOptions): void
|
|
106
158
|
```
|
|
107
159
|
|
|
108
|
-
|
|
160
|
+
**`CutPlaneOptions`**
|
|
161
|
+
- `offset?: number` — Optional offset along the plane normal (primarily for object-form overload).
|
|
162
|
+
- `exclude?: CutPlaneExcludeInput` — Object names to keep uncut for this plane.
|
|
109
163
|
|
|
110
|
-
#### `
|
|
164
|
+
#### `cutPlane()`
|
|
111
165
|
|
|
112
166
|
```ts
|
|
113
|
-
|
|
167
|
+
cutPlane(name: string, normal: [ number, number, number ], options?: CutPlaneOptions): void
|
|
114
168
|
```
|
|
115
169
|
|
|
116
|
-
|
|
170
|
+
#### `mock()` — Register a mock (context) object for visualization and collision checking.
|
|
117
171
|
|
|
118
|
-
|
|
172
|
+
Mock objects appear in the viewport and spatial analysis when you run a file directly, but are excluded when the file is imported via [`require()`](/docs/core#require). This lets you model the surrounding context — walls, bolts, mating parts — without polluting the module's exports.
|
|
173
|
+
|
|
174
|
+
The shape is returned unchanged, so you can reference it for alignment, dimensioning, and `verify` checks.
|
|
175
|
+
|
|
176
|
+
Mock objects participate in `forgecad run` collision detection and spatial analysis. Their names appear with a `(mock)` suffix in reports.
|
|
177
|
+
|
|
178
|
+
In the viewport, mock objects render at reduced opacity so they are visually distinct from real geometry.
|
|
119
179
|
|
|
120
180
|
```ts
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
axisLock?: ExplodeAxis;
|
|
132
|
-
/** Per-object overrides by final object name. */
|
|
133
|
-
byName?: Record<string, ExplodeViewDirective>;
|
|
134
|
-
/** Per-tree-path overrides using slash-separated object tree segments. */
|
|
135
|
-
byPath?: Record<string, ExplodeViewDirective>;
|
|
136
|
-
}
|
|
181
|
+
// bracket.forge.js
|
|
182
|
+
const wall = mock(box(100, 200, 10).translate(0, 0, -5), "wall");
|
|
183
|
+
const bolt = mock(cylinder(3, 15).translate(10, 15, 0), "bolt");
|
|
184
|
+
|
|
185
|
+
const bracket = box(20, 30, 5);
|
|
186
|
+
verify.notColliding("bracket vs wall", bracket, wall);
|
|
187
|
+
|
|
188
|
+
return bracket;
|
|
189
|
+
// When imported: only bracket is exported
|
|
190
|
+
// When run directly: bracket + wall + bolt all visible
|
|
137
191
|
```
|
|
138
192
|
|
|
139
|
-
|
|
193
|
+
```ts
|
|
194
|
+
mock<T extends Shape>(shape: T, name?: string): T
|
|
195
|
+
```
|
|
140
196
|
|
|
141
|
-
|
|
197
|
+
#### `scene()` — Configure the scene environment for the current script execution.
|
|
198
|
+
|
|
199
|
+
Controls camera position, lighting rig, background color or gradient, atmospheric fog, environment maps, post-processing effects, and capture parameters for the `forgecad capture` command. Multiple calls merge — later values override earlier ones on a per-key basis, so you can split configuration across multiple `scene()` calls.
|
|
200
|
+
|
|
201
|
+
When `lights` is specified, **all** default lights are removed. You must include your own ambient light or the scene will be fully dark.
|
|
202
|
+
|
|
203
|
+
Setting `camera.position` overrides auto-framing — the viewport will no longer auto-fit the geometry on script reload.
|
|
204
|
+
|
|
205
|
+
Post-processing effects (`bloom`, `vignette`, `grain`) work in the browser viewport only. The CLI applies camera, lights, background, fog, and `toneMappingExposure` but skips shader effects.
|
|
206
|
+
|
|
207
|
+
All numeric values accept `param()` expressions.
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
scene({
|
|
211
|
+
background: { top: '#000814', bottom: '#001d3d' },
|
|
212
|
+
camera: { position: [160, -120, 100], target: [0, 0, 50], fov: 52 },
|
|
213
|
+
lights: [
|
|
214
|
+
{ type: 'ambient', color: '#001233', intensity: 0.08 },
|
|
215
|
+
{ type: 'point', position: [120, -80, 130], color: '#00f5d4', intensity: 4, distance: 400, decay: 1 },
|
|
216
|
+
{ type: 'point', position: [-100, 60, 20], color: '#f72585', intensity: 3, distance: 350 },
|
|
217
|
+
{ type: 'directional', position: [50, -30, 200], color: '#ffd60a', intensity: 1.2 },
|
|
218
|
+
{ type: 'hemisphere', skyColor: '#003566', groundColor: '#000814', intensity: 0.2 },
|
|
219
|
+
],
|
|
220
|
+
fog: { color: '#000814', near: 100, far: 450 },
|
|
221
|
+
postProcessing: {
|
|
222
|
+
bloom: { intensity: param('bloom', 1.5, 0, 4), threshold: 0.5, radius: 0.7 },
|
|
223
|
+
vignette: { darkness: 0.8, offset: 0.25 },
|
|
224
|
+
grain: { intensity: 0.08 },
|
|
225
|
+
toneMappingExposure: param('exposure', 1.5, 0.5, 4),
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
```
|
|
142
229
|
|
|
143
230
|
```ts
|
|
144
|
-
|
|
145
|
-
/** Multiplier applied to `amount` for this node */
|
|
146
|
-
stage?: number;
|
|
147
|
-
/** Direction mode for this node */
|
|
148
|
-
direction?: ExplodeDirection;
|
|
149
|
-
/** Optional axis lock after direction is resolved */
|
|
150
|
-
axisLock?: ExplodeAxis;
|
|
151
|
-
}
|
|
231
|
+
scene(options: SceneOptions): void
|
|
152
232
|
```
|
|
153
233
|
|
|
154
|
-
|
|
234
|
+
**`SceneOptions`**
|
|
235
|
+
|
|
236
|
+
| Option | Type | Description |
|
|
237
|
+
|--------|------|-------------|
|
|
238
|
+
| `capture?` | `SceneCaptureConfig` | Default capture parameters for `forgecad capture` — CLI flags override these. |
|
|
239
|
+
| `background?`, `camera?`, `lights?`, `environment?`, `fog?`, `postProcessing?`, `ground?` | | — |
|
|
240
|
+
|
|
241
|
+
`SceneBackgroundGradient`: `{ top: string, bottom: string }`
|
|
242
|
+
|
|
243
|
+
`SceneCameraConfig`: `{ fov?: number, type?: "perspective" | "orthographic" }`
|
|
244
|
+
|
|
245
|
+
**`SceneLightConfig`**
|
|
246
|
+
|
|
247
|
+
| Option | Type | Description |
|
|
248
|
+
|--------|------|-------------|
|
|
249
|
+
| `groundColor?` | `string` | Ground color for hemisphere lights |
|
|
250
|
+
| `skyColor?` | `string` | Sky color alias for hemisphere lights (same as color) |
|
|
251
|
+
| `angle?` | `number` | Spot light cone angle in radians |
|
|
252
|
+
| `penumbra?` | `number` | Spot light penumbra (0–1) |
|
|
253
|
+
| `decay?` | `number` | Point/spot light decay |
|
|
254
|
+
| `distance?` | `number` | Point/spot light distance (0 = infinite) |
|
|
255
|
+
| `castShadow?` | `boolean` | Whether this light casts shadows |
|
|
256
|
+
| `type`, `color?`, `intensity?` | | — |
|
|
257
|
+
|
|
258
|
+
**`SceneEnvironmentConfig`**
|
|
259
|
+
- `preset?: "studio" | "sunset" | "dawn" | "warehouse" | "forest" | "apartment" | "lobby" | "city" | "park" | "night" | "none"` — Built-in preset name or 'none' to disable
|
|
260
|
+
- `intensity?: number` — Environment map intensity
|
|
261
|
+
- `background?: boolean` — Use environment map as scene background
|
|
262
|
+
|
|
263
|
+
**`SceneFogConfig`**
|
|
264
|
+
- `near?: number` — Linear fog near distance
|
|
265
|
+
- `far?: number` — Linear fog far distance
|
|
266
|
+
- `density?: number` — Exponential fog density (if set, uses FogExp2 instead of linear Fog)
|
|
267
|
+
- Also: `color?: string`
|
|
268
|
+
|
|
269
|
+
`ScenePostProcessingConfig`: `{ bloom?: SceneBloomConfig, vignette?: SceneVignetteConfig, grain?: SceneGrainConfig, toneMappingExposure?: number }`
|
|
270
|
+
|
|
271
|
+
`SceneBloomConfig`: `{ intensity?: number, threshold?: number, radius?: number }`
|
|
155
272
|
|
|
156
|
-
|
|
273
|
+
`SceneVignetteConfig`: `{ darkness?: number, offset?: number }`
|
|
274
|
+
|
|
275
|
+
`SceneGrainConfig`: `{ intensity?: number }`
|
|
276
|
+
|
|
277
|
+
**`SceneGroundConfig`**
|
|
278
|
+
|
|
279
|
+
| Option | Type | Description |
|
|
280
|
+
|--------|------|-------------|
|
|
281
|
+
| `visible?` | `boolean` | Show a ground plane |
|
|
282
|
+
| `color?` | `string` | Ground color |
|
|
283
|
+
| `offset?` | `number` | Offset below the model's bounding box minimum Z. Default 0 (flush with model bottom). |
|
|
284
|
+
| `receiveShadow?` | `boolean` | Receive shadows on the ground |
|
|
285
|
+
|
|
286
|
+
**`SceneCaptureConfig`**
|
|
287
|
+
|
|
288
|
+
| Option | Type | Description |
|
|
289
|
+
|--------|------|-------------|
|
|
290
|
+
| `framesPerTurn?` | `number` | Frames for one full orbit rotation (default: 72) |
|
|
291
|
+
| `holdFrames?` | `number` | Frozen frames before motion starts (default: 6) |
|
|
292
|
+
| `pitchDeg?` | `number` | Orbit pitch angle in degrees (default: auto from camera) |
|
|
293
|
+
| `fps?` | `number` | Output frame rate (default: 24) |
|
|
294
|
+
| `size?` | `number` | Output frame size in pixels (default: 960) |
|
|
295
|
+
| `background?` | `string` | Canvas background color for capture (default: '#252526') |
|
|
296
|
+
|
|
297
|
+
#### `viewConfig()` — Configure viewport helper visuals for the current script execution.
|
|
298
|
+
|
|
299
|
+
Controls renderer-only overlays that appear in the viewport but are not part of the geometry. Currently supports the joint overlay that renders axis arrows and arc indicators when `jointsView` is active. Multiple calls merge — later values override earlier ones per key.
|
|
300
|
+
|
|
301
|
+
This does **not** trigger a geometry recompute; it only affects the visual helpers drawn on top of the 3D scene.
|
|
302
|
+
|
|
303
|
+
```js
|
|
304
|
+
viewConfig({
|
|
305
|
+
jointOverlay: {
|
|
306
|
+
axisColor: '#13dfff',
|
|
307
|
+
arcColor: '#ff7a1a',
|
|
308
|
+
axisLineRadiusScale: 0.03,
|
|
309
|
+
arcLineRadiusScale: 0.022,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
```
|
|
157
313
|
|
|
158
314
|
```ts
|
|
159
|
-
|
|
160
|
-
}
|
|
315
|
+
viewConfig(options?: ViewConfigOptions): void
|
|
161
316
|
```
|
|
162
317
|
|
|
163
|
-
|
|
318
|
+
`ViewConfigOptions`: `{ jointOverlay?: JointOverlayViewConfigOptions }`
|
|
164
319
|
|
|
165
|
-
|
|
320
|
+
**`JointOverlayViewConfigOptions`**: `enabled?: boolean`, `axisColor?: string`, `axisCoreColor?: string`, `arcColor?: string`, `zeroColor?: string`, `arcVisualLimitDeg?: number`, `axisLengthScale?: number`, `axisLengthMin?: number`, `axisLineRadiusScale?: number`, `axisLineRadiusMin?: number`, `axisLineRadiusMax?: number`, `spokeLineRadiusScale?: number`, `spokeLineRadiusMin?: number`, `spokeLineRadiusMax?: number`, `arcLineRadiusScale?: number`, `arcLineRadiusMin?: number`, `arcLineRadiusMax?: number`, `axisDotRadiusScale?: number`, `axisDotRadiusMin?: number`, `axisArrowRadiusScale?: number`, `axisArrowRadiusMin?: number`, `axisArrowLengthScale?: number`, `axisArrowLengthMin?: number`, `axisArrowOffsetFactor?: number`, `arcRadiusScale?: number`, `arcRadiusMin?: number`, `arcDotRadiusScale?: number`, `arcDotRadiusMin?: number`, `arcArrowRadiusScale?: number`, `arcArrowRadiusMin?: number`, `arcArrowLengthScale?: number`, `arcArrowLengthMin?: number`, `arcArrowOffsetFactor?: number`, `arcStepDeg?: number`, `arcMinSteps?: number`, `arcTubeSegmentsMin?: number`, `arcTubeSegmentsFactor?: number`, `arcTubeRadialSegments?: number`
|
|
321
|
+
|
|
322
|
+
#### `showLabels()` — Highlight all user-labeled faces on a shape for visual debugging.
|
|
323
|
+
|
|
324
|
+
Shows each user-authored label name in the viewport for visual debugging. Returns the shape unchanged for chaining: `return showLabels(myShape)`.
|
|
166
325
|
|
|
167
326
|
```ts
|
|
168
|
-
|
|
327
|
+
showLabels(shape: Shape): Shape
|
|
169
328
|
```
|
|
170
329
|
|
|
171
|
-
|
|
330
|
+
#### `highlight()` — Highlight any geometry for visual debugging in the viewport.
|
|
172
331
|
|
|
173
|
-
|
|
332
|
+
Supported inputs:
|
|
333
|
+
|
|
334
|
+
- `string` — sketch entity ID (e.g. `'L0'`, `'P0'`, `'C0'`)
|
|
335
|
+
- `[x, y, z]` — 3D point
|
|
336
|
+
- `[[x1,y1,z1], [x2,y2,z2]]` — edge (line segment)
|
|
337
|
+
- `{ normal: [x,y,z], offset: number }` — plane by normal + distance from origin
|
|
338
|
+
- `{ normal: [x,y,z], point: [x,y,z] }` — plane by normal + point on plane
|
|
339
|
+
- [`Shape`](/docs/core#shape) — highlight entire 3D shape
|
|
340
|
+
- `FaceRef` (from `shape.face('top')`) — highlight as plane at face center
|
|
341
|
+
- `EdgeRef` (from `shape.edge('left')`) — highlight as edge segment
|
|
174
342
|
|
|
175
343
|
```ts
|
|
176
|
-
|
|
177
|
-
/** Optional offset along the plane normal (primarily for object-form overload). */
|
|
178
|
-
offset?: number;
|
|
179
|
-
/** Object names to keep uncut for this plane. */
|
|
180
|
-
exclude?: CutPlaneExcludeInput;
|
|
181
|
-
}
|
|
344
|
+
highlight(entityId: string, opts?: HighlightOptions): void
|
|
182
345
|
```
|
|
183
346
|
|
|
184
|
-
|
|
347
|
+
**`HighlightOptions`**
|
|
348
|
+
- `size?: number` — Size hint for points (radius in mm) or planes (disc radius in mm).
|
|
349
|
+
- Also: `color?: string, label?: string, pulse?: boolean`
|
|
185
350
|
|
|
186
|
-
#### `
|
|
351
|
+
#### `highlight()`
|
|
187
352
|
|
|
188
353
|
```ts
|
|
189
|
-
|
|
354
|
+
highlight(point: [ number, number, number ], opts?: HighlightOptions): void
|
|
190
355
|
```
|
|
191
356
|
|
|
192
|
-
#### `
|
|
357
|
+
#### `highlight()`
|
|
193
358
|
|
|
194
359
|
```ts
|
|
195
|
-
|
|
360
|
+
highlight(edge: [ [ number, number, number ], [ number, number, number ] ], opts?: HighlightOptions): void
|
|
196
361
|
```
|
|
197
362
|
|
|
198
|
-
|
|
363
|
+
#### `highlight()`
|
|
199
364
|
|
|
200
|
-
|
|
365
|
+
```ts
|
|
366
|
+
highlight(plane: { normal: [ number, number, number ]; offset: number; }, opts?: HighlightOptions): void
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### `highlight()`
|
|
201
370
|
|
|
202
371
|
```ts
|
|
203
|
-
|
|
204
|
-
background?: string | SceneBackgroundGradient;
|
|
205
|
-
camera?: SceneCameraConfig;
|
|
206
|
-
lights?: SceneLightConfig[];
|
|
207
|
-
environment?: SceneEnvironmentConfig;
|
|
208
|
-
fog?: SceneFogConfig;
|
|
209
|
-
postProcessing?: ScenePostProcessingConfig;
|
|
210
|
-
ground?: SceneGroundConfig;
|
|
211
|
-
/** Default capture parameters for `forgecad capture` — CLI flags override these. */
|
|
212
|
-
capture?: SceneCaptureConfig;
|
|
213
|
-
}
|
|
372
|
+
highlight(plane: { normal: [ number, number, number ]; point: [ number, number, number ]; }, opts?: HighlightOptions): void
|
|
214
373
|
```
|
|
215
374
|
|
|
216
|
-
|
|
375
|
+
#### `highlight()`
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
highlight(shape: Shape, opts?: HighlightOptions): void
|
|
379
|
+
```
|
|
217
380
|
|
|
218
|
-
|
|
381
|
+
#### `highlight()`
|
|
219
382
|
|
|
220
383
|
```ts
|
|
221
|
-
|
|
222
|
-
top: string;
|
|
223
|
-
bottom: string;
|
|
224
|
-
}
|
|
384
|
+
highlight(face: FaceRef, opts?: HighlightOptions): void
|
|
225
385
|
```
|
|
226
386
|
|
|
227
|
-
|
|
387
|
+
**`FaceRef`**
|
|
388
|
+
- `query?: FaceQueryRef` — Compiler-owned face query when available.
|
|
389
|
+
- `planar?: boolean` — True when the face can host a 2D sketch placement frame
|
|
390
|
+
- `descendant?: FaceDescendantMetadata` — Shared descendant-resolution metadata when this face is a semantic region/set.
|
|
391
|
+
- Also: `name: FaceName`
|
|
392
|
+
|
|
393
|
+
**`FaceDescendantMetadata`**: `kind: "single" | "face-set"`, `semantic: FaceDescendantSemantic`, `memberCount: number`, `memberNames: string[]`, `coplanar: boolean`
|
|
228
394
|
|
|
229
|
-
|
|
395
|
+
#### `highlight()`
|
|
230
396
|
|
|
231
397
|
```ts
|
|
232
|
-
|
|
233
|
-
fov?: number;
|
|
234
|
-
type?: "perspective" | "orthographic";
|
|
235
|
-
}
|
|
398
|
+
highlight(edge: EdgeRef, opts?: HighlightOptions): void
|
|
236
399
|
```
|
|
237
400
|
|
|
238
|
-
|
|
401
|
+
**`EdgeRef`**
|
|
402
|
+
- `query?: EdgeQueryRef` — Compiler-owned edge query when available.
|
|
403
|
+
- Also: `name: EdgeName`
|
|
239
404
|
|
|
240
|
-
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Classes
|
|
408
|
+
|
|
409
|
+
### `RouteBuilder`
|
|
410
|
+
|
|
411
|
+
#### `up()` — Vertical line going +Y. Length is optional (solver determines it from constraints).
|
|
241
412
|
|
|
242
413
|
```ts
|
|
243
|
-
|
|
244
|
-
type: SceneLightType;
|
|
245
|
-
color?: string;
|
|
246
|
-
intensity?: number;
|
|
247
|
-
/** Ground color for hemisphere lights */
|
|
248
|
-
groundColor?: string;
|
|
249
|
-
/** Sky color alias for hemisphere lights (same as color) */
|
|
250
|
-
skyColor?: string;
|
|
251
|
-
/** Spot light cone angle in radians */
|
|
252
|
-
angle?: number;
|
|
253
|
-
/** Spot light penumbra (0–1) */
|
|
254
|
-
penumbra?: number;
|
|
255
|
-
/** Point/spot light decay */
|
|
256
|
-
decay?: number;
|
|
257
|
-
/** Point/spot light distance (0 = infinite) */
|
|
258
|
-
distance?: number;
|
|
259
|
-
/** Whether this light casts shadows */
|
|
260
|
-
castShadow?: boolean;
|
|
261
|
-
}
|
|
414
|
+
up(length?: number): LineId
|
|
262
415
|
```
|
|
263
416
|
|
|
264
|
-
|
|
417
|
+
#### `down()` — Vertical line going -Y. Length is optional.
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
down(length?: number): LineId
|
|
421
|
+
```
|
|
265
422
|
|
|
266
|
-
|
|
423
|
+
#### `right()` — Horizontal line going +X. Length is optional.
|
|
267
424
|
|
|
268
425
|
```ts
|
|
269
|
-
|
|
270
|
-
/** Built-in preset name or 'none' to disable */
|
|
271
|
-
preset?: "studio" | "sunset" | "dawn" | "warehouse" | "forest" | "apartment" | "lobby" | "city" | "park" | "night" | "none";
|
|
272
|
-
/** Environment map intensity */
|
|
273
|
-
intensity?: number;
|
|
274
|
-
/** Use environment map as scene background */
|
|
275
|
-
background?: boolean;
|
|
276
|
-
}
|
|
426
|
+
right(length?: number): LineId
|
|
277
427
|
```
|
|
278
428
|
|
|
279
|
-
|
|
429
|
+
#### `left()` — Horizontal line going -X. Length is optional.
|
|
280
430
|
|
|
281
|
-
|
|
431
|
+
```ts
|
|
432
|
+
left(length?: number): LineId
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### `lineAt()` — Line at an arbitrary angle (degrees from +X). Length is optional.
|
|
282
436
|
|
|
283
437
|
```ts
|
|
284
|
-
|
|
285
|
-
color?: string;
|
|
286
|
-
/** Linear fog near distance */
|
|
287
|
-
near?: number;
|
|
288
|
-
/** Linear fog far distance */
|
|
289
|
-
far?: number;
|
|
290
|
-
/** Exponential fog density (if set, uses FogExp2 instead of linear Fog) */
|
|
291
|
-
density?: number;
|
|
292
|
-
}
|
|
438
|
+
lineAt(angleDeg: number, length?: number): LineId
|
|
293
439
|
```
|
|
294
440
|
|
|
295
|
-
|
|
441
|
+
#### [`line()`](/docs/sketch#line) — Line with solver-determined direction. Length is optional. Direction comes from tangency to previous arc or from constraints.
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
line(length?: number): LineId
|
|
445
|
+
```
|
|
296
446
|
|
|
297
|
-
|
|
447
|
+
#### `toward()` — Line toward a specific point. Length defaults to the distance to that point.
|
|
298
448
|
|
|
299
449
|
```ts
|
|
300
|
-
|
|
301
|
-
bloom?: SceneBloomConfig;
|
|
302
|
-
vignette?: SceneVignetteConfig;
|
|
303
|
-
grain?: SceneGrainConfig;
|
|
304
|
-
toneMappingExposure?: number;
|
|
305
|
-
}
|
|
450
|
+
toward(x: number, y: number): LineId
|
|
306
451
|
```
|
|
307
452
|
|
|
308
|
-
|
|
453
|
+
#### `arcLeft()` — Tangent arc turning left relative to travel direction.
|
|
309
454
|
|
|
310
|
-
|
|
455
|
+
or `{ minSweep: degrees }` to seed the geometry without constraining. `minSweep` guides the solver to the correct branch for arcs that sweep more than the default 90° seed.
|
|
311
456
|
|
|
312
457
|
```ts
|
|
313
|
-
|
|
314
|
-
intensity?: number;
|
|
315
|
-
threshold?: number;
|
|
316
|
-
radius?: number;
|
|
317
|
-
}
|
|
458
|
+
arcLeft(radius?: number, sweepDegOrOpts?: number | { minSweep: number; }): ArcId
|
|
318
459
|
```
|
|
319
460
|
|
|
320
|
-
|
|
461
|
+
#### `arcRight()` — Tangent arc turning right relative to travel direction.
|
|
321
462
|
|
|
322
|
-
|
|
463
|
+
or `{ minSweep: degrees }` to seed without constraining.
|
|
323
464
|
|
|
324
465
|
```ts
|
|
325
|
-
|
|
326
|
-
darkness?: number;
|
|
327
|
-
offset?: number;
|
|
328
|
-
}
|
|
466
|
+
arcRight(radius?: number, sweepDegOrOpts?: number | { minSweep: number; }): ArcId
|
|
329
467
|
```
|
|
330
468
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
<details><summary><code>SceneGrainConfig</code></summary>
|
|
469
|
+
#### `close()` — Close the route with a straight line back to the start point.
|
|
334
470
|
|
|
335
471
|
```ts
|
|
336
|
-
|
|
337
|
-
intensity?: number;
|
|
338
|
-
}
|
|
472
|
+
close(): void
|
|
339
473
|
```
|
|
340
474
|
|
|
341
|
-
|
|
475
|
+
#### `done()` — Close the route back to its start point and register as a profile loop.
|
|
342
476
|
|
|
343
|
-
|
|
477
|
+
No extra line segment is added. A coincident constraint connects the last point to the start, and tangency is added for G1 smoothness when arcs are at the junction. The session's incremental solver processes these constraints, keeping seed positions accurate for the final solve.
|
|
344
478
|
|
|
345
479
|
```ts
|
|
346
|
-
|
|
347
|
-
/** Show a ground plane */
|
|
348
|
-
visible?: boolean;
|
|
349
|
-
/** Ground color */
|
|
350
|
-
color?: string;
|
|
351
|
-
/** Offset below the model's bounding box minimum Z. Default 0 (flush with model bottom). */
|
|
352
|
-
offset?: number;
|
|
353
|
-
/** Receive shadows on the ground */
|
|
354
|
-
receiveShadow?: boolean;
|
|
355
|
-
}
|
|
480
|
+
done(): void
|
|
356
481
|
```
|
|
357
482
|
|
|
358
|
-
|
|
483
|
+
#### `start()` — PointId of the route's start point.
|
|
484
|
+
|
|
485
|
+
```ts
|
|
486
|
+
get start(): PointId
|
|
487
|
+
```
|
|
359
488
|
|
|
360
|
-
|
|
489
|
+
#### `end()` — PointId of the current cursor (route's end).
|
|
361
490
|
|
|
362
491
|
```ts
|
|
363
|
-
|
|
364
|
-
/** Frames for one full orbit rotation (default: 72) */
|
|
365
|
-
framesPerTurn?: number;
|
|
366
|
-
/** Frozen frames before motion starts (default: 6) */
|
|
367
|
-
holdFrames?: number;
|
|
368
|
-
/** Orbit pitch angle in degrees (default: auto from camera) */
|
|
369
|
-
pitchDeg?: number;
|
|
370
|
-
/** Output frame rate (default: 24) */
|
|
371
|
-
fps?: number;
|
|
372
|
-
/** Output frame size in pixels (default: 960) */
|
|
373
|
-
size?: number;
|
|
374
|
-
/** Canvas background color for capture (default: '#252526') */
|
|
375
|
-
background?: string;
|
|
376
|
-
}
|
|
492
|
+
get end(): PointId
|
|
377
493
|
```
|
|
378
494
|
|
|
379
|
-
|
|
495
|
+
#### `startOf()` — Get the start point of a segment.
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
startOf(segId: LineId | ArcId): PointId
|
|
499
|
+
```
|
|
380
500
|
|
|
381
|
-
#### `
|
|
501
|
+
#### `endOf()` — Get the end point of a segment.
|
|
382
502
|
|
|
383
503
|
```ts
|
|
384
|
-
|
|
504
|
+
endOf(segId: LineId | ArcId): PointId
|
|
385
505
|
```
|
|
386
506
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
</details>
|
|
398
|
-
|
|
399
|
-
<details><summary><code>JointOverlayViewConfigOptions</code></summary>
|
|
400
|
-
|
|
401
|
-
```ts
|
|
402
|
-
interface JointOverlayViewConfigOptions {
|
|
403
|
-
enabled?: boolean;
|
|
404
|
-
axisColor?: string;
|
|
405
|
-
axisCoreColor?: string;
|
|
406
|
-
arcColor?: string;
|
|
407
|
-
zeroColor?: string;
|
|
408
|
-
arcVisualLimitDeg?: number;
|
|
409
|
-
axisLengthScale?: number;
|
|
410
|
-
axisLengthMin?: number;
|
|
411
|
-
axisLineRadiusScale?: number;
|
|
412
|
-
axisLineRadiusMin?: number;
|
|
413
|
-
axisLineRadiusMax?: number;
|
|
414
|
-
spokeLineRadiusScale?: number;
|
|
415
|
-
spokeLineRadiusMin?: number;
|
|
416
|
-
spokeLineRadiusMax?: number;
|
|
417
|
-
arcLineRadiusScale?: number;
|
|
418
|
-
arcLineRadiusMin?: number;
|
|
419
|
-
arcLineRadiusMax?: number;
|
|
420
|
-
axisDotRadiusScale?: number;
|
|
421
|
-
axisDotRadiusMin?: number;
|
|
422
|
-
axisArrowRadiusScale?: number;
|
|
423
|
-
axisArrowRadiusMin?: number;
|
|
424
|
-
axisArrowLengthScale?: number;
|
|
425
|
-
axisArrowLengthMin?: number;
|
|
426
|
-
axisArrowOffsetFactor?: number;
|
|
427
|
-
arcRadiusScale?: number;
|
|
428
|
-
arcRadiusMin?: number;
|
|
429
|
-
arcDotRadiusScale?: number;
|
|
430
|
-
arcDotRadiusMin?: number;
|
|
431
|
-
arcArrowRadiusScale?: number;
|
|
432
|
-
arcArrowRadiusMin?: number;
|
|
433
|
-
arcArrowLengthScale?: number;
|
|
434
|
-
arcArrowLengthMin?: number;
|
|
435
|
-
arcArrowOffsetFactor?: number;
|
|
436
|
-
arcStepDeg?: number;
|
|
437
|
-
arcMinSteps?: number;
|
|
438
|
-
arcTubeSegmentsMin?: number;
|
|
439
|
-
arcTubeSegmentsFactor?: number;
|
|
440
|
-
arcTubeRadialSegments?: number;
|
|
441
|
-
}
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
</details>
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## Constants
|
|
510
|
+
|
|
511
|
+
### `route`
|
|
512
|
+
|
|
513
|
+
Route step factories. Access via `route.line()`, `route.fillet()`, etc.
|