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
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: viewport
|
|
3
|
-
skill-order: 1
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Viewport Runtime APIs
|
|
7
|
-
|
|
8
|
-
These APIs affect the viewer and scene presentation. They do not change the underlying model geometry contract, so they are not part of the required model-building reading set.
|
|
9
|
-
|
|
10
|
-
## `scene(options)`
|
|
11
|
-
|
|
12
|
-
Control the full visual environment — camera, lighting, background, fog, and post-processing. Essential for generative art, presentations, and dramatic renders.
|
|
13
|
-
|
|
14
|
-
When `scene()` is called, it **replaces** the default viewer settings for the specified properties. Properties not specified keep their defaults. Multiple calls merge (later overrides earlier).
|
|
15
|
-
|
|
16
|
-
**Parameters:**
|
|
17
|
-
- `background` (string or `{ top, bottom }`) — solid color (`'#0a0a0a'`) or vertical gradient
|
|
18
|
-
- `camera` (object):
|
|
19
|
-
- `position` (`[x, y, z]`) — camera world position (overrides auto-framing)
|
|
20
|
-
- `target` (`[x, y, z]`) — look-at point
|
|
21
|
-
- `fov` (number) — field of view in degrees (1–179)
|
|
22
|
-
- `up` (`[x, y, z]`) — up vector (default `[0, 0, 1]`)
|
|
23
|
-
- `type` (`'perspective' | 'orthographic'`)
|
|
24
|
-
- `lights` (array) — **replaces** all default lights. Each entry:
|
|
25
|
-
- `type` (`'ambient' | 'directional' | 'point' | 'spot' | 'hemisphere'`) — required
|
|
26
|
-
- `color` (string) — CSS color
|
|
27
|
-
- `intensity` (number)
|
|
28
|
-
- `position` (`[x, y, z]`) — for directional, point, spot
|
|
29
|
-
- `target` (`[x, y, z]`) — for directional, spot
|
|
30
|
-
- `groundColor` / `skyColor` (string) — for hemisphere
|
|
31
|
-
- `angle` (number) — spot cone angle in radians
|
|
32
|
-
- `penumbra` (number, 0–1) — spot penumbra
|
|
33
|
-
- `decay` (number) — point/spot light decay
|
|
34
|
-
- `distance` (number) — point/spot max range (0 = infinite)
|
|
35
|
-
- `castShadow` (boolean)
|
|
36
|
-
- `environment` (object):
|
|
37
|
-
- `preset` (`'studio' | 'sunset' | 'dawn' | 'warehouse' | 'forest' | 'apartment' | 'lobby' | 'city' | 'park' | 'night' | 'none'`)
|
|
38
|
-
- `intensity` (number) — environment map intensity
|
|
39
|
-
- `background` (boolean) — use environment map as scene background
|
|
40
|
-
- `fog` (object):
|
|
41
|
-
- `color` (string)
|
|
42
|
-
- `near` / `far` (number) — linear fog
|
|
43
|
-
- `density` (number) — if set, uses exponential fog instead of linear
|
|
44
|
-
- `postProcessing` (object):
|
|
45
|
-
- `bloom` — `{ intensity?, threshold?, radius? }`
|
|
46
|
-
- `vignette` — `{ darkness?, offset? }`
|
|
47
|
-
- `grain` — `{ intensity? }`
|
|
48
|
-
- `toneMappingExposure` (number)
|
|
49
|
-
- `ground` (object):
|
|
50
|
-
- `visible` (boolean)
|
|
51
|
-
- `color` (string)
|
|
52
|
-
- `height` (number) — Z offset
|
|
53
|
-
- `receiveShadow` (boolean)
|
|
54
|
-
- `capture` (object) — default capture parameters for `forgecad capture`; CLI flags override these:
|
|
55
|
-
- `framesPerTurn` (number, 12–720) — frames for one orbit rotation (default: 72)
|
|
56
|
-
- `holdFrames` (number, 0–300) — frozen frames before motion (default: 6)
|
|
57
|
-
- `pitchDeg` (number, -80–80) — orbit pitch angle (default: auto from camera)
|
|
58
|
-
- `fps` (number, 1–60) — output frame rate (default: 24)
|
|
59
|
-
- `size` (number) — output frame size in pixels (default: 960)
|
|
60
|
-
- `background` (string) — canvas background color (default: '#252526')
|
|
61
|
-
|
|
62
|
-
**Returns:** `void`
|
|
63
|
-
|
|
64
|
-
```javascript
|
|
65
|
-
scene({
|
|
66
|
-
background: { top: '#000814', bottom: '#001d3d' },
|
|
67
|
-
|
|
68
|
-
camera: {
|
|
69
|
-
position: [160, -120, 100],
|
|
70
|
-
target: [0, 0, 50],
|
|
71
|
-
fov: 52,
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
lights: [
|
|
75
|
-
{ type: 'ambient', color: '#001233', intensity: 0.08 },
|
|
76
|
-
{ type: 'point', position: [120, -80, 130], color: '#00f5d4', intensity: 4, distance: 400, decay: 1 },
|
|
77
|
-
{ type: 'point', position: [-100, 60, 20], color: '#f72585', intensity: 3, distance: 350 },
|
|
78
|
-
{ type: 'directional', position: [50, -30, 200], color: '#ffd60a', intensity: 1.2 },
|
|
79
|
-
{ type: 'hemisphere', skyColor: '#003566', groundColor: '#000814', intensity: 0.2 },
|
|
80
|
-
],
|
|
81
|
-
|
|
82
|
-
fog: { color: '#000814', near: 100, far: 450 },
|
|
83
|
-
|
|
84
|
-
postProcessing: {
|
|
85
|
-
bloom: { intensity: param('bloom', 1.5, 0, 4), threshold: 0.5, radius: 0.7 },
|
|
86
|
-
vignette: { darkness: 0.8, offset: 0.25 },
|
|
87
|
-
grain: { intensity: 0.08 },
|
|
88
|
-
toneMappingExposure: param('exposure', 1.5, 0.5, 4),
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Notes:
|
|
94
|
-
- All values work with `param()` for real-time slider control
|
|
95
|
-
- When `lights` is specified, **all** default lights are removed — you must provide your own ambient light or the scene will be very dark
|
|
96
|
-
- Post-processing (bloom, vignette, grain) works in the browser viewport only — CLI renders apply camera, lights, background, fog, and exposure but not shader-based effects
|
|
97
|
-
- Camera `position` overrides the auto-frame behavior — the viewport will not auto-fit the geometry to view
|
|
98
|
-
- See `examples/generative-art/` for full demos
|
|
99
|
-
|
|
100
|
-
## `shape.material(props)`
|
|
101
|
-
|
|
102
|
-
Set per-object material properties for controlling visual appearance. Returns a new Shape with the specified material properties. Material properties survive transforms (translate, rotate, scale, etc.) and boolean operations.
|
|
103
|
-
|
|
104
|
-
**Parameters (all optional):**
|
|
105
|
-
- `metalness` (number, 0–1) — metallic vs. dielectric appearance. Default: 0.05
|
|
106
|
-
- `roughness` (number, 0–1) — surface roughness (0 = mirror, 1 = matte). Default: 0.35
|
|
107
|
-
- `emissive` (string) — glow color (hex string, e.g. `'#ff6b35'`)
|
|
108
|
-
- `emissiveIntensity` (number) — glow multiplier. Default: 1
|
|
109
|
-
- `opacity` (number, 0–1) — transparency. Default: 1
|
|
110
|
-
- `wireframe` (boolean) — render as wireframe. Default: false
|
|
111
|
-
- `clearcoat` (number, 0–1) — clearcoat layer intensity. Default: 0.1
|
|
112
|
-
- `clearcoatRoughness` (number, 0–1) — clearcoat roughness. Default: 0.4
|
|
113
|
-
|
|
114
|
-
**Returns:** `Shape`
|
|
115
|
-
|
|
116
|
-
```javascript
|
|
117
|
-
// Polished metal
|
|
118
|
-
box(50, 50, 50).material({ metalness: 0.9, roughness: 0.1 });
|
|
119
|
-
|
|
120
|
-
// Glowing emissive
|
|
121
|
-
sphere(30).material({ emissive: '#ff6b35', emissiveIntensity: 2 });
|
|
122
|
-
|
|
123
|
-
// Translucent ice
|
|
124
|
-
cylinder(40, 20).material({ opacity: 0.4, clearcoat: 1.0, clearcoatRoughness: 0.02 });
|
|
125
|
-
|
|
126
|
-
// Chainable with other methods
|
|
127
|
-
box(100, 100, 10)
|
|
128
|
-
.color('#gold')
|
|
129
|
-
.material({ metalness: 0.95, roughness: 0.05 })
|
|
130
|
-
.translate(0, 0, 50);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Notes:
|
|
134
|
-
- Material properties are per-shape — each returned object can have different materials
|
|
135
|
-
- Works in both the browser viewport and CLI renderer
|
|
136
|
-
- `.color()` sets the base diffuse color; `.material()` controls how that color behaves under light
|
|
137
|
-
- Emissive color glows independently of lighting — great for generative art effects like bloom
|
|
138
|
-
- See `examples/generative-art/molten-forge.forge.js` and `frost-spires.forge.js` for full demos
|
|
139
|
-
|
|
140
|
-
## `cutPlane(name, normal, offsetOrOptions?, options?)`
|
|
141
|
-
|
|
142
|
-
Define a named section plane for inspection.
|
|
143
|
-
|
|
144
|
-
**Parameters:**
|
|
145
|
-
- `name` (string) - label shown in the viewport controls
|
|
146
|
-
- `normal` (`[number, number, number]`) - direction toward the clipped side
|
|
147
|
-
- `offsetOrOptions` (number or object, optional):
|
|
148
|
-
- number: plane offset from origin along `normal`
|
|
149
|
-
- object: `{ offset?: number, exclude?: string | string[] }`
|
|
150
|
-
- `options` (object, optional; used with numeric offset):
|
|
151
|
-
- `exclude` (`string | string[]`) - returned object `name` values to keep uncut
|
|
152
|
-
|
|
153
|
-
**Returns:** `void`
|
|
154
|
-
|
|
155
|
-
```javascript
|
|
156
|
-
const cutZ = param("Cut Height", 10, { min: -50, max: 50, unit: "mm" });
|
|
157
|
-
|
|
158
|
-
cutPlane("Inspection", [0, 0, 1], cutZ, {
|
|
159
|
-
exclude: ["Probe", "Fasteners"],
|
|
160
|
-
});
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Notes:
|
|
164
|
-
- planes are registered per script run
|
|
165
|
-
- viewport toggle state persists across parameter changes
|
|
166
|
-
- clipping is applied to returned named objects, so `exclude` only works when names are stable
|
|
167
|
-
- newly exposed section faces render with a hatched overlay; pre-existing coplanar boundary faces are left unhatched
|
|
168
|
-
|
|
169
|
-
## `explodeView(options?)`
|
|
170
|
-
|
|
171
|
-
Override how the viewport explode slider offsets returned objects.
|
|
172
|
-
|
|
173
|
-
Explode offsets are resolved from the returned object tree, not from a flat list.
|
|
174
|
-
In `radial` mode each node follows its parent branch direction, then adds a smaller
|
|
175
|
-
local fan from the immediate parent/subassembly center, so nested assemblies peel
|
|
176
|
-
apart level by level without losing their branch structure.
|
|
177
|
-
|
|
178
|
-
In fixed-axis or fixed-vector modes, the branch itself follows that axis/vector, but
|
|
179
|
-
nested descendants fan out perpendicular to the branch by default so deep trees do
|
|
180
|
-
not keep stacking farther along the same axis.
|
|
181
|
-
|
|
182
|
-
By default this is container-oriented: named groups/subassemblies advance along the
|
|
183
|
-
tree, while plain leaves inside a group stay much closer and mostly fan locally
|
|
184
|
-
around their parent cluster unless you override them explicitly.
|
|
185
|
-
|
|
186
|
-
**Parameters:**
|
|
187
|
-
- `enabled` (boolean) - disable explode offsets for this script when `false`
|
|
188
|
-
- `amountScale` (number) - multiply the UI explode amount
|
|
189
|
-
- `stages` (number[]) - per-depth multipliers (depth 1 = first level, defaults to `1, 1/2, 1/3, ...`)
|
|
190
|
-
- `mode` (`'radial' | 'x' | 'y' | 'z' | [x, y, z]`) - default explode direction
|
|
191
|
-
- `axisLock` (`'x' | 'y' | 'z'`) - optional global axis lock
|
|
192
|
-
- `byName` (`Record<string, { stage?, direction?, axisLock? }>`)- per-object overrides keyed by returned object `name`
|
|
193
|
-
- `byPath` (`Record<string, { stage?, direction?, axisLock? }>`)- per-tree-path overrides using slash-separated object tree paths such as `"Drive/Shaft"`
|
|
194
|
-
|
|
195
|
-
**Returns:** `void`
|
|
196
|
-
|
|
197
|
-
```javascript
|
|
198
|
-
explodeView({
|
|
199
|
-
amountScale: 1.2,
|
|
200
|
-
stages: [0.35, 0.8],
|
|
201
|
-
mode: 'radial',
|
|
202
|
-
byPath: {
|
|
203
|
-
"Drive/Shaft": { direction: [1, 0, 0], stage: 1.6 },
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## `jointsView(options?)`
|
|
209
|
-
|
|
210
|
-
Register viewport-only mechanism controls that animate returned objects without rerunning the script.
|
|
211
|
-
|
|
212
|
-
Use this when you want interactive articulation in the viewer but the geometry itself stays fixed.
|
|
213
|
-
|
|
214
|
-
Animation values are interpolated linearly between keyframes. Forge does **not**
|
|
215
|
-
auto-wrap revolute values across `-180/180` or `0/360` for you, because doing
|
|
216
|
-
that globally would break intentional multi-turn tracks.
|
|
217
|
-
|
|
218
|
-
**Key options:**
|
|
219
|
-
- `enabled`
|
|
220
|
-
- `joints`: `{ name, child, parent?, type?, axis?, pivot?, min?, max?, default?, unit? }[]` — `min`/`max` control the slider range in the UI; they do **not** clamp animation keyframe values
|
|
221
|
-
- `couplings`: `{ joint, terms, offset? }[]`
|
|
222
|
-
- `animations`: `{ name, duration?, loop?, continuous?, keyframes }[]`
|
|
223
|
-
- `defaultAnimation`
|
|
224
|
-
|
|
225
|
-
**Keyframe `at` is optional (tick-based mode):** If you omit `at` from all
|
|
226
|
-
keyframes, they are spaced across the timeline as sequential ticks. By default
|
|
227
|
-
all ticks are equal, but you can use `ticks` to weight individual segments:
|
|
228
|
-
|
|
229
|
-
```javascript
|
|
230
|
-
keyframes: [
|
|
231
|
-
{ ticks: 3, values: { "Shoulder": 20 } }, // slow move (3× weight)
|
|
232
|
-
{ ticks: 1, values: { "Shoulder": -10 } }, // fast snap (1× weight)
|
|
233
|
-
{ values: { "Shoulder": 20 } }, // last keyframe's ticks is ignored
|
|
234
|
-
]
|
|
235
|
-
// Positions: 0, 0.75, 1.0 (weights 3,1 → total 4 → at 0/4, 3/4, 4/4)
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
You can still use explicit `at` values when you need precise non-uniform
|
|
239
|
-
spacing, but mixing explicit and omitted `at` within the same animation is not
|
|
240
|
-
allowed. `ticks` is only valid in tick-based mode.
|
|
241
|
-
|
|
242
|
-
```javascript
|
|
243
|
-
jointsView({
|
|
244
|
-
joints: [
|
|
245
|
-
{
|
|
246
|
-
name: "Shoulder",
|
|
247
|
-
child: "Upper Arm",
|
|
248
|
-
parent: "Base",
|
|
249
|
-
type: "revolute",
|
|
250
|
-
axis: [0, -1, 0],
|
|
251
|
-
pivot: [0, 0, 46],
|
|
252
|
-
min: -30,
|
|
253
|
-
max: 110,
|
|
254
|
-
default: 15,
|
|
255
|
-
},
|
|
256
|
-
],
|
|
257
|
-
animations: [
|
|
258
|
-
{
|
|
259
|
-
name: "Walk Cycle",
|
|
260
|
-
duration: 1.6,
|
|
261
|
-
loop: true,
|
|
262
|
-
keyframes: [
|
|
263
|
-
{ values: { "Shoulder": 20 } },
|
|
264
|
-
{ values: { "Shoulder": -10 } },
|
|
265
|
-
{ values: { "Shoulder": 20 } },
|
|
266
|
-
],
|
|
267
|
-
},
|
|
268
|
-
],
|
|
269
|
-
});
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Using `jointsView` with assemblies
|
|
273
|
-
|
|
274
|
-
When combining `jointsView` animations with an `assembly().solve()` pipeline, the assembly must be solved at **rest pose** (all animated joints = 0). The viewport applies `jointsView` transforms on top of the scene objects' existing positions — if the assembly is already solved at non-zero joint angles, the animation will double-rotate everything.
|
|
275
|
-
|
|
276
|
-
```javascript
|
|
277
|
-
// BAD — assembly bakes in slider angles, then jointsView rotates again
|
|
278
|
-
const solved = mech.solve({ shoulder: 45, elbow: 30 });
|
|
279
|
-
jointsView({
|
|
280
|
-
joints: [{ name: "shoulder", child: "Upper Arm", ... }],
|
|
281
|
-
animations: [{ ... keyframes with shoulder values ... }],
|
|
282
|
-
});
|
|
283
|
-
return solved; // double-rotated mess
|
|
284
|
-
|
|
285
|
-
// GOOD — assembly at rest, jointsView controls all posing
|
|
286
|
-
const solved = mech.solve({ shoulder: 0, elbow: 0 });
|
|
287
|
-
jointsView({
|
|
288
|
-
joints: [
|
|
289
|
-
{ name: "shoulder", child: "Upper Arm", default: 45, ... },
|
|
290
|
-
{ name: "elbow", child: "Forearm", parent: "Upper Arm", default: 30, ... },
|
|
291
|
-
],
|
|
292
|
-
animations: [{ ... }],
|
|
293
|
-
});
|
|
294
|
-
return solved; // jointsView handles static pose via defaults AND animation
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**Pivot coordinates** are the world-space position of each joint origin at rest pose. For an assembly with `addRevolute("shoulder", "Base", "Link", { frame: Transform.identity().translate(0, 0, 20) })` where "Base" is at the world origin, the pivot is `[0, 0, 20]`.
|
|
298
|
-
|
|
299
|
-
For kinematic chains, child joint pivots are specified in the parent joint's rest-pose space — the viewport resolves them through the parent chain automatically.
|
|
300
|
-
|
|
301
|
-
**Fixed attachments** (e.g. an end effector bolted to the last link) need a zero-angle revolute joint in the `jointsView` chain so they follow the parent during animation:
|
|
302
|
-
|
|
303
|
-
```javascript
|
|
304
|
-
{ name: "EE_Follow", child: "End Effector", parent: "Last Link",
|
|
305
|
-
type: "revolute", axis: [0, 0, 1], pivot: [linkLength, 0, 0],
|
|
306
|
-
min: 0, max: 0, default: 0 }
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
**Slider-driven posing** still works: use `param()` for interactive angles, compute dependent joint values (FK/IK), and pass them as `default` values on the `jointsView` joints. When an animation plays it overrides the defaults; when stopped the slider defaults take over.
|
|
310
|
-
|
|
311
|
-
`continuous: true` is for looping tracks that should keep accumulating across
|
|
312
|
-
cycles instead of snapping back to the first keyframe each time. Use it for
|
|
313
|
-
monotonic multi-turn drives such as `0 -> 360 -> 720`.
|
|
314
|
-
|
|
315
|
-
### Animation continuity for revolute joints
|
|
316
|
-
|
|
317
|
-
If an animation channel comes from `atan2(...)`, `normalizeAngleDeg(...)`, or
|
|
318
|
-
any other wrapped angle source, keep the sampled keyframes continuous before
|
|
319
|
-
passing them to `jointsView()`.
|
|
320
|
-
|
|
321
|
-
Bad branch-cut sample stream:
|
|
322
|
-
|
|
323
|
-
```javascript
|
|
324
|
-
keyframes: [
|
|
325
|
-
{ at: 0.48, values: { "Power Rod": -171 } },
|
|
326
|
-
{ at: 0.50, values: { "Power Rod": -180 } },
|
|
327
|
-
{ at: 0.52, values: { "Power Rod": 171 } },
|
|
328
|
-
]
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
That `-180 -> 171` jump is interpreted literally and the viewer will spin the
|
|
332
|
-
part the long way around.
|
|
333
|
-
|
|
334
|
-
Good continuous sample stream:
|
|
335
|
-
|
|
336
|
-
```javascript
|
|
337
|
-
keyframes: [
|
|
338
|
-
{ at: 0.48, values: { "Power Rod": -171 } },
|
|
339
|
-
{ at: 0.50, values: { "Power Rod": -180 } },
|
|
340
|
-
{ at: 0.52, values: { "Power Rod": -189 } },
|
|
341
|
-
]
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Guidelines:
|
|
345
|
-
- Keep high-speed multi-turn joints authored as continuous angles (`0`, `360`,
|
|
346
|
-
`720`, etc.).
|
|
347
|
-
- Only unwrap channels that represent cyclic angles. Do not apply angle
|
|
348
|
-
unwrapping blindly to prismatic or other scalar values.
|
|
349
|
-
- If you build sampled helper utilities, let them unwrap a named set of joints
|
|
350
|
-
instead of guessing from every numeric channel.
|
|
351
|
-
|
|
352
|
-
## `viewConfig(options?)`
|
|
353
|
-
|
|
354
|
-
Configure viewport helper visuals for the current script.
|
|
355
|
-
|
|
356
|
-
Current support:
|
|
357
|
-
- `jointOverlay.enabled`
|
|
358
|
-
- joint overlay colors such as `axisColor`, `axisCoreColor`, `arcColor`, `zeroColor`
|
|
359
|
-
- joint overlay sizing and tessellation controls such as `axisLengthScale`, `arcVisualLimitDeg`, `arcStepDeg`
|
|
360
|
-
|
|
361
|
-
**Returns:** `void`
|
|
362
|
-
|
|
363
|
-
```javascript
|
|
364
|
-
viewConfig({
|
|
365
|
-
jointOverlay: {
|
|
366
|
-
axisColor: "#13dfff",
|
|
367
|
-
arcColor: "#ff7a1a",
|
|
368
|
-
axisLineRadiusScale: 0.03,
|
|
369
|
-
arcLineRadiusScale: 0.022,
|
|
370
|
-
},
|
|
371
|
-
});
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## `lib.explode(items, options?)`
|
|
375
|
-
|
|
376
|
-
Apply deterministic exploded-view offsets to an assembly tree while preserving names, colors, and nesting.
|
|
377
|
-
|
|
378
|
-
`radial` separation is branch-aware and parent-relative: each child follows the
|
|
379
|
-
direction of its parent branch, then fans out locally inside that branch. This keeps
|
|
380
|
-
subassemblies visually grouped while still letting their internals break apart.
|
|
381
|
-
|
|
382
|
-
For non-radial fixed-axis or fixed-vector modes, nested descendants keep the branch
|
|
383
|
-
offset but spread perpendicular to it by default.
|
|
384
|
-
|
|
385
|
-
Default behavior is tree-like rather than flat: containers separate recursively,
|
|
386
|
-
while unconfigured leaves inside a container use a smaller local fan so sibling parts
|
|
387
|
-
stay visually associated with their parent group.
|
|
388
|
-
|
|
389
|
-
Works with:
|
|
390
|
-
- arrays of shapes/sketches/named items
|
|
391
|
-
- nested `{ name, group: [...] }` structures
|
|
392
|
-
- `ShapeGroup` outputs
|
|
393
|
-
|
|
394
|
-
**Parameters:**
|
|
395
|
-
- `items` (`ExplodeItem[] | ShapeGroup`)
|
|
396
|
-
- `options`:
|
|
397
|
-
- `amount` (number)
|
|
398
|
-
- `stages` (number[])
|
|
399
|
-
- `mode` (`'radial' | 'x' | 'y' | 'z' | [x, y, z]`)
|
|
400
|
-
- `axisLock` (`'x' | 'y' | 'z'`)
|
|
401
|
-
- `byName`
|
|
402
|
-
- `byPath`
|
|
403
|
-
|
|
404
|
-
Named items may also include:
|
|
405
|
-
- `explode: { stage?, direction?, axisLock? }`
|
|
406
|
-
|
|
407
|
-
**Returns:** same structure type as input, with translated geometry
|
|
408
|
-
|
|
409
|
-
```javascript
|
|
410
|
-
const explodeAmt = param("Explode", 0, { min: 0, max: 40, unit: "mm" });
|
|
411
|
-
|
|
412
|
-
return lib.explode(assembly, {
|
|
413
|
-
amount: explodeAmt,
|
|
414
|
-
stages: [0.4, 0.8],
|
|
415
|
-
mode: 'radial',
|
|
416
|
-
byName: {
|
|
417
|
-
"Shaft": { direction: [1, 0, 0], stage: 1.4 },
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
```
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: sheet-metal
|
|
3
|
-
skill-order: 1
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Sheet Metal
|
|
7
|
-
|
|
8
|
-
`sheetMetal()` is ForgeCAD's first dedicated compiler-owned sheet-metal family.
|
|
9
|
-
|
|
10
|
-
It keeps one semantic model, then derives both:
|
|
11
|
-
|
|
12
|
-
- a folded solid
|
|
13
|
-
- a flat pattern
|
|
14
|
-
|
|
15
|
-
This is a strict v1 subset. Forge does not try to infer sheet metal from arbitrary solids.
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```javascript
|
|
20
|
-
const cover = sheetMetal({
|
|
21
|
-
panel: { width: 180, height: 110 },
|
|
22
|
-
thickness: 1.5,
|
|
23
|
-
bendRadius: 2,
|
|
24
|
-
bendAllowance: { kFactor: 0.42 },
|
|
25
|
-
cornerRelief: { size: 4 },
|
|
26
|
-
})
|
|
27
|
-
.flange('top', { length: 18 })
|
|
28
|
-
.flange('right', { length: 18 })
|
|
29
|
-
.flange('bottom', { length: 18 })
|
|
30
|
-
.flange('left', { length: 18 })
|
|
31
|
-
.cutout('panel', rect(72, 36, true), { selfAnchor: 'center' })
|
|
32
|
-
.cutout('flange-right', roundedRect(26, 10, 5, true), { selfAnchor: 'center' });
|
|
33
|
-
|
|
34
|
-
const folded = cover.folded();
|
|
35
|
-
const flat = cover.flatPattern();
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
The maintained proof artifact is [`examples/api/folded-service-panel-cover.forge.js`](../../../../examples/api/folded-service-panel-cover.forge.js).
|
|
39
|
-
|
|
40
|
-
## Practical First Pass
|
|
41
|
-
|
|
42
|
-
If the goal is "open docs and make a cover/bracket quickly," the most reliable current workflow is:
|
|
43
|
-
|
|
44
|
-
1. Build the base panel plus flanges first.
|
|
45
|
-
2. Validate `folded()` and `flatPattern()` before adding any cutouts.
|
|
46
|
-
3. Add panel cutouts before flange cutouts.
|
|
47
|
-
4. Add flange cutouts one region at a time instead of decorating every flange at once.
|
|
48
|
-
5. Re-run validation after each new region so cutout complexity stays easy to localize.
|
|
49
|
-
|
|
50
|
-
This keeps failures narrow and makes it obvious whether the issue is:
|
|
51
|
-
|
|
52
|
-
- the sheet-metal setup itself
|
|
53
|
-
- one specific region
|
|
54
|
-
- one specific cutout pattern
|
|
55
|
-
|
|
56
|
-
## Current Practical Cutout Lane
|
|
57
|
-
|
|
58
|
-
The defended API surface is wider than the current "fast to author" lane.
|
|
59
|
-
|
|
60
|
-
For quick, low-drama iteration, prefer:
|
|
61
|
-
|
|
62
|
-
- `circle2d(...)`
|
|
63
|
-
- `rect(...)`
|
|
64
|
-
- `roundedRect(...)`
|
|
65
|
-
|
|
66
|
-
These simple compile-covered sketches are the current safest first choice for panel and flange cutouts.
|
|
67
|
-
|
|
68
|
-
Decorative language still works best when expressed as several individually placed simple cutouts rather than one heavily composed art sketch. In practice, fewer larger apertures are more reliable than many tiny details when you are still exploring the part.
|
|
69
|
-
|
|
70
|
-
If runtime spikes or validation stops feeling immediate, simplify first by:
|
|
71
|
-
|
|
72
|
-
- reducing cutout count
|
|
73
|
-
- replacing composed motifs with simple repeated cutouts
|
|
74
|
-
- validating one region before mirroring the same detail to other flanges
|
|
75
|
-
|
|
76
|
-
## Placement Tips
|
|
77
|
-
|
|
78
|
-
- `selfAnchor: 'center'` is the easiest default for early iterations because it keeps panel and flange placement intent readable.
|
|
79
|
-
- Flange-local placement is easy to misread, especially on side flanges. Place one obvious asymmetric test cutout on one flange first, validate it, then mirror or repeat once the orientation is confirmed.
|
|
80
|
-
- Keep cutouts off bend regions for v1. The defended cutout lane is planar panel and flange regions only.
|
|
81
|
-
|
|
82
|
-
## API Surface
|
|
83
|
-
|
|
84
|
-
### `sheetMetal(options)`
|
|
85
|
-
|
|
86
|
-
Creates a `SheetMetalPart`.
|
|
87
|
-
|
|
88
|
-
Required options:
|
|
89
|
-
|
|
90
|
-
- `panel: { width, height }`
|
|
91
|
-
- `thickness`
|
|
92
|
-
- `bendRadius`
|
|
93
|
-
- `bendAllowance: { kFactor }`
|
|
94
|
-
|
|
95
|
-
Optional:
|
|
96
|
-
|
|
97
|
-
- `cornerRelief: { kind?: 'rect', size }`
|
|
98
|
-
|
|
99
|
-
### `part.flange(edge, options)`
|
|
100
|
-
|
|
101
|
-
Adds one edge flange.
|
|
102
|
-
|
|
103
|
-
- `edge`: `'top' | 'right' | 'bottom' | 'left'`
|
|
104
|
-
- `options.length`
|
|
105
|
-
- `options.angleDeg` defaults to `90`
|
|
106
|
-
|
|
107
|
-
Current v1 support is only `90°` flanges.
|
|
108
|
-
|
|
109
|
-
### `part.cutout(region, sketch, options?)`
|
|
110
|
-
|
|
111
|
-
Adds a planar cutout on a supported sheet-metal region.
|
|
112
|
-
|
|
113
|
-
- `region`: `'panel' | 'flange-top' | 'flange-right' | 'flange-bottom' | 'flange-left'`
|
|
114
|
-
- `sketch` must be an unplaced compile-covered 2D sketch
|
|
115
|
-
- `options.u` / `options.v` place the sketch in region-local coordinates
|
|
116
|
-
- `options.selfAnchor` works like other planar placement APIs
|
|
117
|
-
|
|
118
|
-
For exploratory authoring, prefer a loop like:
|
|
119
|
-
|
|
120
|
-
```javascript
|
|
121
|
-
let part = sheetMetal({
|
|
122
|
-
panel: { width: 180, height: 110 },
|
|
123
|
-
thickness: 1.5,
|
|
124
|
-
bendRadius: 2,
|
|
125
|
-
bendAllowance: { kFactor: 0.42 },
|
|
126
|
-
cornerRelief: { size: 4 },
|
|
127
|
-
})
|
|
128
|
-
.flange('top', { length: 18 })
|
|
129
|
-
.flange('right', { length: 18 });
|
|
130
|
-
|
|
131
|
-
part = part.cutout('panel', roundedRect(40, 10, 5, true), { selfAnchor: 'center' });
|
|
132
|
-
part = part.cutout('flange-right', circle2d(3), { u: 0, v: 0, selfAnchor: 'center' });
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
That authoring style keeps each downstream cutout step explicit and easy to debug.
|
|
136
|
-
|
|
137
|
-
### `part.regionNames()`
|
|
138
|
-
|
|
139
|
-
Returns the semantic region names currently available from the model.
|
|
140
|
-
|
|
141
|
-
### `part.folded()` / `part.flatPattern()`
|
|
142
|
-
|
|
143
|
-
Materialize the folded solid or flat pattern from the same semantic model.
|
|
144
|
-
|
|
145
|
-
Both outputs stay compiler-owned and exact-exportable inside the defended subset.
|
|
146
|
-
|
|
147
|
-
## Defended Region Names
|
|
148
|
-
|
|
149
|
-
Forge exposes the following semantic family where the corresponding flange exists:
|
|
150
|
-
|
|
151
|
-
- `panel`
|
|
152
|
-
- `flange-top`, `flange-right`, `flange-bottom`, `flange-left`
|
|
153
|
-
- `bend-top`, `bend-right`, `bend-bottom`, `bend-left`
|
|
154
|
-
|
|
155
|
-
Important behavior:
|
|
156
|
-
|
|
157
|
-
- planar panel/flange faces can resolve as descendant `region`s after downstream cutouts
|
|
158
|
-
- folded bend regions resolve explicitly as descendant `set`s because one bend can honestly span multiple surfaces
|
|
159
|
-
- flat-pattern bend regions stay explicit too, but as planar band descendants instead of guessed folded topology
|
|
160
|
-
|
|
161
|
-
## Supported V1 Subset
|
|
162
|
-
|
|
163
|
-
- one base panel
|
|
164
|
-
- up to four edge flanges
|
|
165
|
-
- constant thickness
|
|
166
|
-
- explicit bend radius
|
|
167
|
-
- explicit K-factor bend allowance input
|
|
168
|
-
- rectangular corner reliefs
|
|
169
|
-
- planar cutouts on the panel and existing flange regions
|
|
170
|
-
- folded preview and exact folded/flat lowering from the same semantic model
|
|
171
|
-
|
|
172
|
-
## Explicit Non-Goals
|
|
173
|
-
|
|
174
|
-
Not supported in v1:
|
|
175
|
-
|
|
176
|
-
- arbitrary solid-to-sheet-metal conversion
|
|
177
|
-
- hems
|
|
178
|
-
- jogs or offset bends
|
|
179
|
-
- lofted bends
|
|
180
|
-
- miter corner logic beyond the defended rectangular-relief subset
|
|
181
|
-
- nonuniform thickness
|
|
182
|
-
- bend-region cutouts
|
|
183
|
-
- non-`90°` flanges
|
|
184
|
-
|
|
185
|
-
If Forge cannot defend a requested operation inside that subset, it should fail with a targeted error instead of guessing.
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: sketch
|
|
3
|
-
skill-order: 9
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Sketch Anchor Positioning
|
|
7
|
-
|
|
8
|
-
Position sketches relative to each other using named anchor points.
|
|
9
|
-
|
|
10
|
-
## Methods
|
|
11
|
-
|
|
12
|
-
### `.attachTo(target, targetAnchor, selfAnchor?, offset?)`
|
|
13
|
-
Position a sketch relative to another using named anchor points.
|
|
14
|
-
|
|
15
|
-
**Parameters:**
|
|
16
|
-
- `target` (Sketch) — The sketch to attach to
|
|
17
|
-
- `targetAnchor` (Anchor) — Point on target: 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'top', 'bottom', 'left', 'right'
|
|
18
|
-
- `selfAnchor` (Anchor, optional) — Point on this sketch to align. Default: 'center'
|
|
19
|
-
- `offset` ([number, number], optional) — Additional offset after alignment
|
|
20
|
-
|
|
21
|
-
**Returns:** `Sketch`
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
const plate = rect(50, 4);
|
|
25
|
-
const arm = rect(4, 70).attachTo(plate, 'bottom-left', 'top-left');
|
|
26
|
-
return union2d(plate, arm);
|
|
27
|
-
|
|
28
|
-
// With offset: attach then shift 5mm right
|
|
29
|
-
const shifted = rect(4, 70).attachTo(plate, 'bottom-left', 'top-left', [5, 0]);
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Anchor Points
|
|
33
|
-
|
|
34
|
-
Available anchor positions:
|
|
35
|
-
- `'center'` — geometric center
|
|
36
|
-
- `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'` — corners
|
|
37
|
-
- `'top'`, `'bottom'`, `'left'`, `'right'` — edge midpoints
|