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,336 +5,230 @@ skill-order: 100
|
|
|
5
5
|
|
|
6
6
|
# Output & Annotations
|
|
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
|
Dimensions, BOM entries, verification checks, and sketch export.
|
|
11
9
|
|
|
12
|
-
##
|
|
10
|
+
## Contents
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
- [Annotations & Output](#annotations-output) — `bom`, `robotExport`, `dim`, `dimLine`
|
|
13
|
+
- [Sketch Export](#sketch-export) — `sketchToDxf`, `sketchToSvg`
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
## Functions
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
### Annotations & Output
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
bom(quantity: number, description: string, opts?: BomOpts): void
|
|
22
|
-
```
|
|
19
|
+
#### `bom()` — Register a Bill of Materials entry for report export.
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
BOM entries are accumulated during script execution and exported alongside the model in report views. Rows are grouped by normalized `description + unit`. Pass an explicit `key` to force multiple descriptions to collapse into a single line item.
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
- `quantity` must be a finite number `>= 0`. A quantity of `0` is silently ignored (useful for conditional scripting with `param()`-driven counts).
|
|
24
|
+
- `unit` defaults to `"pieces"` when omitted or empty.
|
|
25
|
+
- The assembly `solved.bom()` / `solved.bomCsv()` API is separate and covers per-part assembly metadata; this function is for free-form purchased-item annotation.
|
|
27
26
|
|
|
28
27
|
```ts
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
unit?: string;
|
|
32
|
-
/** Optional explicit grouping key used during report aggregation. */
|
|
33
|
-
key?: string;
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
</details>
|
|
28
|
+
const tubeLen = param("Tube Length", 1200, { min: 300, max: 4000, unit: "mm" });
|
|
29
|
+
const boltCount = param("Bolt Count", 16, { min: 0, max: 200, integer: true });
|
|
38
30
|
|
|
39
|
-
|
|
31
|
+
bom(tubeLen, "iron tube 30 x 20", { unit: "mm" });
|
|
32
|
+
bom(boltCount, "M4 bolt, 16 mm length");
|
|
33
|
+
bom(4, "rubber foot", { key: "foot-rubber" }); // explicit aggregation key
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
// Structured metadata for richer reports:
|
|
36
|
+
bom(tubeLen, "rectangular steel tube", {
|
|
37
|
+
unit: "mm",
|
|
38
|
+
material: "steel",
|
|
39
|
+
section: [30, 20],
|
|
40
|
+
wall: 3,
|
|
41
|
+
});
|
|
43
42
|
```
|
|
44
43
|
|
|
45
|
-
Declare that the current script should export an assembly as a robot package for the SDF CLI. Configures inertial properties, joint limits, and optional plugins (e.g. diff-drive for Gazebo).
|
|
46
|
-
|
|
47
|
-
<details><summary><code>RobotExportOptions</code></summary>
|
|
48
|
-
|
|
49
44
|
```ts
|
|
50
|
-
|
|
51
|
-
assembly: Assembly;
|
|
52
|
-
modelName?: string;
|
|
53
|
-
state?: JointState;
|
|
54
|
-
static?: boolean;
|
|
55
|
-
selfCollide?: boolean;
|
|
56
|
-
allowAutoDisable?: boolean;
|
|
57
|
-
links?: Record<string, RobotLinkExportOptions>;
|
|
58
|
-
joints?: Record<string, RobotJointExportOptions>;
|
|
59
|
-
diffDrive?: RobotDiffDrivePluginOptions;
|
|
60
|
-
jointStatePublisher?: RobotJointStatePublisherOptions;
|
|
61
|
-
world?: RobotWorldOptions;
|
|
62
|
-
}
|
|
45
|
+
bom(quantity: number, description: string, opts?: BomOpts): void
|
|
63
46
|
```
|
|
64
47
|
|
|
65
|
-
|
|
48
|
+
**`BomOpts`**
|
|
66
49
|
|
|
67
|
-
|
|
50
|
+
| Option | Type | Description |
|
|
51
|
+
|--------|------|-------------|
|
|
52
|
+
| `unit?` | `string` | Quantity unit label, e.g. "mm", "pieces", "kg". Default: "pieces" |
|
|
53
|
+
| `key?` | `string` | Optional explicit grouping key used during report aggregation. |
|
|
54
|
+
| `material?` | `string` | Material name, e.g. "steel", "birch plywood", "nylon" |
|
|
55
|
+
| `dimensions?` | `number[]` | Overall dimensions `[width, height]` or `[width, height, thickness]` in the entry's unit |
|
|
56
|
+
| `section?` | `number[]` | Cross-section dimensions `[w, h]` for tubes and profiles |
|
|
57
|
+
| `wall?` | `number` | Wall thickness for hollow sections (mm) |
|
|
58
|
+
| `diameter?` | `number` | Diameter for round stock, bolts, dowels (mm) |
|
|
59
|
+
| `length?` | `number` | Length for fasteners (mm) |
|
|
60
|
+
| `process?` | `string` | Manufacturing process, e.g. "laser cut", "CNC", "welded" |
|
|
61
|
+
| `notes?` | `string` | Free-form notes |
|
|
62
|
+
| `grain?` | `string` | Wood grain direction, e.g. "long", "cross" |
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
interface RobotLinkExportOptions {
|
|
71
|
-
massKg?: number;
|
|
72
|
-
densityKgM3?: number;
|
|
73
|
-
collision?: "visual" | "convex" | "box" | "none";
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
</details>
|
|
78
|
-
|
|
79
|
-
<details><summary><code>RobotJointExportOptions</code></summary>
|
|
64
|
+
#### `robotExport()` — Declare that this script should export the assembly as a SDF/URDF robot package.
|
|
80
65
|
|
|
81
|
-
|
|
82
|
-
interface RobotJointExportOptions {
|
|
83
|
-
effort?: number;
|
|
84
|
-
velocity?: number;
|
|
85
|
-
damping?: number;
|
|
86
|
-
friction?: number;
|
|
87
|
-
}
|
|
88
|
-
```
|
|
66
|
+
Call `robotExport()` alongside your assembly definition. The CLI commands `forgecad export sdf` and `forgecad export urdf` pick up the declaration and produce a robot package with:
|
|
89
67
|
|
|
90
|
-
|
|
68
|
+
- Mesh-based inertia tensors (full 6-component, not bounding-box approximations)
|
|
69
|
+
- Separate collision meshes (convex hull by default — ~50–80% smaller)
|
|
70
|
+
- Joint mimic elements derived from `addJointCoupling` / `addGearCoupling`
|
|
91
71
|
|
|
92
|
-
|
|
72
|
+
**Collision mesh modes** (set per-link via `links["PartName"].collision`):
|
|
93
73
|
|
|
94
|
-
|
|
95
|
-
interface RobotDiffDrivePluginOptions {
|
|
96
|
-
leftJoints: string[];
|
|
97
|
-
rightJoints: string[];
|
|
98
|
-
wheelSeparationMm: number;
|
|
99
|
-
wheelRadiusMm: number;
|
|
100
|
-
topic?: string;
|
|
101
|
-
odomTopic?: string;
|
|
102
|
-
tfTopic?: string;
|
|
103
|
-
frameId?: string;
|
|
104
|
-
odomFrameId?: string;
|
|
105
|
-
maxLinearVelocity?: number;
|
|
106
|
-
maxAngularVelocity?: number;
|
|
107
|
-
linearAcceleration?: number;
|
|
108
|
-
angularAcceleration?: number;
|
|
109
|
-
}
|
|
110
|
-
```
|
|
74
|
+
| Mode | Description | Default | |------|-------------|---------| | `'convex'` | Convex hull (separate `_collision.stl`) | Yes | | `'box'` | AABB primitive — fastest physics | | | `'visual'` | Same mesh as visual — exact but slow | | | `'none'` | No collision geometry | |
|
|
111
75
|
|
|
112
|
-
|
|
76
|
+
**Unit conventions:**
|
|
113
77
|
|
|
114
|
-
|
|
78
|
+
- Revolute `velocity` is in degrees/second in Forge; exporters convert to rad/s.
|
|
79
|
+
- Prismatic distances are in mm in Forge; exported in meters.
|
|
80
|
+
- `massKg` is preferred; `densityKgM3` is used when mass is unknown.
|
|
81
|
+
- Couplings with multiple terms: only the primary term (largest ratio) maps to `<mimic>` — SDF/URDF support single-leader mimic only. Dropped terms emit a warning.
|
|
115
82
|
|
|
116
83
|
```ts
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
</details>
|
|
84
|
+
const rover = assembly("Scout")
|
|
85
|
+
.addPart("Chassis", box(300, 220, 50, true))
|
|
86
|
+
.addPart("Left Wheel", cylinder(30, 60, undefined, 48, true))
|
|
87
|
+
.addRevolute("leftWheel", "Chassis", "Left Wheel", {
|
|
88
|
+
axis: [0, 1, 0],
|
|
89
|
+
frame: Transform.identity().translate(90, 140, 60),
|
|
90
|
+
effort: 20, velocity: 1080,
|
|
91
|
+
});
|
|
126
92
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
93
|
+
robotExport({
|
|
94
|
+
assembly: rover,
|
|
95
|
+
modelName: "Scout",
|
|
96
|
+
links: {
|
|
97
|
+
Chassis: { massKg: 10 },
|
|
98
|
+
"Left Wheel": { massKg: 0.8 },
|
|
99
|
+
},
|
|
100
|
+
plugins: {
|
|
101
|
+
diffDrive: {
|
|
102
|
+
leftJoints: ["leftWheel"], rightJoints: ["rightWheel"],
|
|
103
|
+
wheelSeparationMm: 280, wheelRadiusMm: 60,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
world: { generateDemoWorld: true },
|
|
107
|
+
});
|
|
136
108
|
```
|
|
137
109
|
|
|
138
|
-
|
|
110
|
+
**CLI usage**
|
|
139
111
|
|
|
140
|
-
|
|
112
|
+
```bash
|
|
113
|
+
forgecad export sdf model.forge.js # SDF package (Gazebo/Ignition)
|
|
114
|
+
forgecad export urdf model.forge.js # URDF package (ROS/PyBullet/MuJoCo)
|
|
115
|
+
```
|
|
141
116
|
|
|
142
117
|
```ts
|
|
143
|
-
|
|
144
|
-
enabled?: boolean;
|
|
145
|
-
linearStep?: number;
|
|
146
|
-
angularStep?: number;
|
|
147
|
-
}
|
|
118
|
+
robotExport(options: RobotExportOptions): CollectedRobotExport
|
|
148
119
|
```
|
|
149
120
|
|
|
150
|
-
|
|
121
|
+
**`RobotExportOptions`**: `assembly: Assembly`, `modelName?: string`, `state?: JointState`, `static?: boolean`, `selfCollide?: boolean`, `allowAutoDisable?: boolean`, `links?: Record<string, RobotLinkExportOptions>`, `joints?: Record<string, RobotJointExportOptions>`, `diffDrive?: RobotDiffDrivePluginOptions`, `jointStatePublisher?: RobotJointStatePublisherOptions`, `world?: RobotWorldOptions`
|
|
151
122
|
|
|
152
|
-
|
|
123
|
+
`RobotLinkExportOptions`: `{ massKg?: number, densityKgM3?: number, collision?: "visual" | "convex" | "box" | "none" }`
|
|
153
124
|
|
|
154
|
-
|
|
155
|
-
interface CollectedRobotExport {
|
|
156
|
-
modelName: string;
|
|
157
|
-
assembly: AssemblyDefinition;
|
|
158
|
-
state: JointState;
|
|
159
|
-
static: boolean;
|
|
160
|
-
selfCollide: boolean;
|
|
161
|
-
allowAutoDisable: boolean;
|
|
162
|
-
links: Record<string, RobotLinkExportOptions>;
|
|
163
|
-
joints: Record<string, RobotJointExportOptions>;
|
|
164
|
-
diffDrive?: RobotDiffDrivePluginOptions;
|
|
165
|
-
jointStatePublisher?: RobotJointStatePublisherOptions;
|
|
166
|
-
world: RobotWorldOptions | null;
|
|
167
|
-
}
|
|
168
|
-
```
|
|
125
|
+
`RobotJointExportOptions`: `{ effort?: number, velocity?: number, damping?: number, friction?: number }`
|
|
169
126
|
|
|
170
|
-
|
|
127
|
+
**`RobotDiffDrivePluginOptions`**: `leftJoints: string[]`, `rightJoints: string[]`, `wheelSeparationMm: number`, `wheelRadiusMm: number`, `topic?: string`, `odomTopic?: string`, `tfTopic?: string`, `frameId?: string`, `odomFrameId?: string`, `maxLinearVelocity?: number`, `maxAngularVelocity?: number`, `linearAcceleration?: number`, `angularAcceleration?: number`
|
|
171
128
|
|
|
172
|
-
|
|
129
|
+
`RobotJointStatePublisherOptions`: `{ enabled?: boolean, joints?: string[], topic?: string, updateRate?: number }`
|
|
173
130
|
|
|
174
|
-
|
|
175
|
-
interface AssemblyDefinition {
|
|
176
|
-
name: string;
|
|
177
|
-
parts: AssemblyPartDef[];
|
|
178
|
-
joints: AssemblyJointDef[];
|
|
179
|
-
jointCouplings: AssemblyJointCouplingDef[];
|
|
180
|
-
}
|
|
181
|
-
```
|
|
131
|
+
`RobotWorldOptions`: `{ name?: string, generateDemoWorld?: boolean, spawnPose?: RobotPose6, keyboardTeleop?: RobotWorldKeyboardTeleopOptions }`
|
|
182
132
|
|
|
183
|
-
|
|
133
|
+
`RobotWorldKeyboardTeleopOptions`: `{ enabled?: boolean, linearStep?: number, angularStep?: number }`
|
|
184
134
|
|
|
185
|
-
<
|
|
135
|
+
**`CollectedRobotExport`**: `modelName: string`, `assembly: AssemblyDefinition`, `state: JointState`, `static: boolean`, `selfCollide: boolean`, `allowAutoDisable: boolean`, `links: Record<string, RobotLinkExportOptions>`, `joints: Record<string, RobotJointExportOptions>`, `diffDrive?: RobotDiffDrivePluginOptions`, `jointStatePublisher?: RobotJointStatePublisherOptions`, `world: RobotWorldOptions | null`
|
|
186
136
|
|
|
187
|
-
|
|
188
|
-
interface AssemblyPartDef {
|
|
189
|
-
name: string;
|
|
190
|
-
part: AssemblyPart;
|
|
191
|
-
base: Transform;
|
|
192
|
-
metadata?: PartMetadata;
|
|
193
|
-
}
|
|
194
|
-
```
|
|
137
|
+
`AssemblyDefinition`: `{ name: string, parts: AssemblyPartDef[], joints: AssemblyJointDef[], jointCouplings: AssemblyJointCouplingDef[] }`
|
|
195
138
|
|
|
196
|
-
|
|
139
|
+
`AssemblyPartDef`: `{ name: string, part: AssemblyPart, base: Transform, metadata?: PartMetadata }`
|
|
197
140
|
|
|
198
|
-
|
|
141
|
+
**`PartMetadata`**: `material?: string`, `process?: string`, `tolerance?: string`, `qty?: number`, `notes?: string`, `densityKgM3?: number`, `massKg?: number`
|
|
199
142
|
|
|
200
|
-
|
|
201
|
-
interface PartMetadata {
|
|
202
|
-
material?: string;
|
|
203
|
-
process?: string;
|
|
204
|
-
tolerance?: string;
|
|
205
|
-
qty?: number;
|
|
206
|
-
notes?: string;
|
|
207
|
-
densityKgM3?: number;
|
|
208
|
-
massKg?: number;
|
|
209
|
-
}
|
|
210
|
-
```
|
|
143
|
+
**`AssemblyJointDef`**: `name: string`, `type: JointType`, `parent: string`, `child: string`, `frame: Transform`, `axis: Vec3`, `min?: number`, `max?: number`, `defaultValue: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`
|
|
211
144
|
|
|
212
|
-
|
|
145
|
+
`AssemblyJointCouplingDef`: `{ joint: string, terms: JointCouplingTermRecord[], offset: number }`
|
|
213
146
|
|
|
214
|
-
|
|
147
|
+
`JointCouplingTermRecord`: `{ joint: string, ratio: number }`
|
|
215
148
|
|
|
216
|
-
|
|
217
|
-
interface AssemblyJointDef {
|
|
218
|
-
name: string;
|
|
219
|
-
type: JointType;
|
|
220
|
-
parent: string;
|
|
221
|
-
child: string;
|
|
222
|
-
frame: Transform;
|
|
223
|
-
axis: Vec3;
|
|
224
|
-
min?: number;
|
|
225
|
-
max?: number;
|
|
226
|
-
defaultValue: number;
|
|
227
|
-
unit?: string;
|
|
228
|
-
effort?: number;
|
|
229
|
-
velocity?: number;
|
|
230
|
-
damping?: number;
|
|
231
|
-
friction?: number;
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
</details>
|
|
149
|
+
#### `dim()` — Add a dimension annotation between two points.
|
|
236
150
|
|
|
237
|
-
|
|
151
|
+
Dimension annotations are purely visual callouts rendered in the viewport and report export. They do not affect geometry or constrain the model.
|
|
238
152
|
|
|
239
|
-
|
|
240
|
-
interface AssemblyJointCouplingDef {
|
|
241
|
-
joint: string;
|
|
242
|
-
terms: JointCouplingTermRecord[];
|
|
243
|
-
offset: number;
|
|
244
|
-
}
|
|
245
|
-
```
|
|
153
|
+
Point arguments accept 2D tuples `[x, y]`, 3D tuples `[x, y, z]`, or [`Point2D`](/docs/sketch#point2d) objects (Z is treated as 0 for 2D inputs).
|
|
246
154
|
|
|
247
|
-
|
|
155
|
+
**Ownership Rules (Report Pages)**
|
|
248
156
|
|
|
249
|
-
|
|
157
|
+
- `currentComponent: true` — deterministic ownership by the calling import instance. Use when authoring reusable imported parts.
|
|
158
|
+
- `component: "Part Name"` — route dimension to another named returned object.
|
|
159
|
+
- Multiple owners: dimension is shared and appears on the assembly overview page.
|
|
160
|
+
- No ownership set: report export infers ownership via endpoint-in-bbox.
|
|
250
161
|
|
|
251
162
|
```ts
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
163
|
+
dim([-w / 2, 0, 0], [w / 2, 0, 0], { label: "Width" });
|
|
164
|
+
dim([0, 0, -h / 2], [0, 0, h / 2], { label: "Height", offset: 14 });
|
|
165
|
+
dim([0, 0, 0], [100, 0, 0], { component: "Base", color: "#00AAFF" });
|
|
256
166
|
```
|
|
257
167
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
#### `dim()`
|
|
168
|
+
`component` (string or string[] — report ownership), `currentComponent` (boolean)
|
|
261
169
|
|
|
262
170
|
```ts
|
|
263
|
-
dim(from: PointArg
|
|
171
|
+
dim(from: PointArg, to: PointArg, opts?: DimOpts): void
|
|
264
172
|
```
|
|
265
173
|
|
|
266
|
-
|
|
174
|
+
`DimOpts`: `{ offset?: number, label?: string, color?: string, component?: string | string[], currentComponent?: boolean }`
|
|
175
|
+
|
|
176
|
+
#### `dimLine()` — Add a dimension annotation along a [`Line2D`](/docs/sketch#line2d).
|
|
267
177
|
|
|
268
|
-
|
|
178
|
+
Convenience wrapper around { points from a constrained-sketch [`Line2D`](/docs/sketch#line2d) entity. All `opts` are forwarded unchanged.
|
|
269
179
|
|
|
270
180
|
```ts
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
color?: string;
|
|
275
|
-
component?: string | string[];
|
|
276
|
-
currentComponent?: boolean;
|
|
277
|
-
}
|
|
181
|
+
const a = point(0, 0);
|
|
182
|
+
const b = point(100, 0);
|
|
183
|
+
dimLine(line(a, b), { label: "Span", offset: -8 });
|
|
278
184
|
```
|
|
279
185
|
|
|
280
|
-
</details>
|
|
281
|
-
|
|
282
|
-
#### `dimLine()`
|
|
283
|
-
|
|
284
186
|
```ts
|
|
285
187
|
dimLine(l: Line2D, opts?: DimOpts): void
|
|
286
188
|
```
|
|
287
189
|
|
|
288
|
-
Add a dimension annotation along a Line2D.
|
|
289
|
-
|
|
290
190
|
### Sketch Export
|
|
291
191
|
|
|
292
|
-
Export 2D
|
|
192
|
+
#### `sketchToDxf()` — Export a 2D sketch as a DXF string (R12/AC1009 — maximally compatible).
|
|
293
193
|
|
|
294
|
-
|
|
194
|
+
For regular sketches, each polygon loop becomes a closed `LWPOLYLINE`. For constrained sketches, exports raw `LINE`, `CIRCLE`, and `ARC` entities from the constraint edge geometry, which preserves internal/shared edges that `toPolygons()` would merge away.
|
|
195
|
+
|
|
196
|
+
The R12 format is chosen for maximum compatibility with CAM tools, laser-cutter software, and older CAD readers.
|
|
295
197
|
|
|
296
198
|
```ts
|
|
297
|
-
|
|
199
|
+
const s = rect(100, 60);
|
|
200
|
+
const dxf = sketchToDxf(s, { layer: 'cut' });
|
|
298
201
|
```
|
|
299
202
|
|
|
300
|
-
Export a 2D sketch as a DXF string (R12/AC1009 — maximally compatible). For regular sketches, each polygon loop becomes a closed LWPOLYLINE. For constraint sketches, exports LINE, CIRCLE, and ARC entities from the constraint edge geometry.
|
|
301
|
-
|
|
302
|
-
<details><summary><code>SketchDxfOptions</code></summary>
|
|
303
|
-
|
|
304
203
|
```ts
|
|
305
|
-
|
|
306
|
-
/** DXF layer name. Default: "0" */
|
|
307
|
-
layer?: string;
|
|
308
|
-
/** DXF color index (1–255, AutoCAD ACI). Default: 7 (white/black) */
|
|
309
|
-
colorIndex?: number;
|
|
310
|
-
}
|
|
204
|
+
sketchToDxf(sketch: Sketch, options?: SketchDxfOptions): string
|
|
311
205
|
```
|
|
312
206
|
|
|
313
|
-
|
|
207
|
+
**`SketchDxfOptions`**
|
|
208
|
+
- `layer?: string` — DXF layer name. Default: "0"
|
|
209
|
+
- `colorIndex?: number` — DXF color index (1–255, AutoCAD ACI). Default: 7 (white/black)
|
|
314
210
|
|
|
315
|
-
#### `sketchToSvg()`
|
|
211
|
+
#### `sketchToSvg()` — Export a 2D sketch as an SVG string.
|
|
316
212
|
|
|
317
|
-
|
|
318
|
-
sketchToSvg(sketch: Sketch, options?: SketchSvgOptions): string
|
|
319
|
-
```
|
|
213
|
+
For regular sketches, exports filled polygon regions. For constrained sketches, exports raw edge geometry (LINE, ARC, CIRCLE) which preserves internal/shared edges that `toPolygons()` would merge away.
|
|
320
214
|
|
|
321
|
-
|
|
215
|
+
The SVG uses the sketch's native coordinate system (Y-up) with a CSS transform that flips Y so the output renders correctly in SVG's Y-down space. Coordinates are in sketch units (typically mm).
|
|
322
216
|
|
|
323
|
-
|
|
217
|
+
```ts
|
|
218
|
+
const s = rect(100, 60);
|
|
219
|
+
const svg = sketchToSvg(s, { stroke: '#333', strokeWidth: 0.8 });
|
|
220
|
+
```
|
|
324
221
|
|
|
325
222
|
```ts
|
|
326
|
-
|
|
327
|
-
/** Stroke color. Default: "black" */
|
|
328
|
-
stroke?: string;
|
|
329
|
-
/** Stroke width in sketch units. Default: 0.5 */
|
|
330
|
-
strokeWidth?: number;
|
|
331
|
-
/** Fill color. Default: "none" */
|
|
332
|
-
fill?: string;
|
|
333
|
-
/** Padding around the sketch bounding box in sketch units. Default: 2 */
|
|
334
|
-
padding?: number;
|
|
335
|
-
/** If set, scale so 1 sketch-unit = this many px. Otherwise auto-fit. */
|
|
336
|
-
pixelsPerUnit?: number;
|
|
337
|
-
}
|
|
223
|
+
sketchToSvg(sketch: Sketch, options?: SketchSvgOptions): string
|
|
338
224
|
```
|
|
339
225
|
|
|
340
|
-
|
|
226
|
+
**`SketchSvgOptions`**
|
|
227
|
+
|
|
228
|
+
| Option | Type | Description |
|
|
229
|
+
|--------|------|-------------|
|
|
230
|
+
| `stroke?` | `string` | Stroke color. Default: "black" |
|
|
231
|
+
| `strokeWidth?` | `number` | Stroke width in sketch units. Default: 0.5 |
|
|
232
|
+
| `fill?` | `string` | Fill color. Default: "none" |
|
|
233
|
+
| `padding?` | `number` | Padding around the sketch bounding box in sketch units. Default: 2 |
|
|
234
|
+
| `pixelsPerUnit?` | `number` | If set, scale so 1 sketch-unit = this many px. Otherwise auto-fit. |
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill-group: sdf
|
|
3
|
+
skill-order: 100
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDF Modeling (Experimental)
|
|
7
|
+
|
|
8
|
+
Signed Distance Field modeling for organic forms, smooth booleans, TPMS lattices, and deformations. Access via `sdf.*`. Experimental — slower render times and lower mesh quality than B-rep.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [SdfShape](#sdfshape)
|
|
13
|
+
- [sdf](#sdf)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Classes
|
|
18
|
+
|
|
19
|
+
### `SdfShape`
|
|
20
|
+
|
|
21
|
+
An immutable SDF expression. Supports SDF-specific operations (smooth booleans, domain warps, etc.) and converts to a ForgeCAD Shape via `.toShape()`.
|
|
22
|
+
|
|
23
|
+
#### `toShape()` — Mesh this SDF into a ForgeCAD Shape via Manifold.levelSet(). Once converted, the result is a regular Shape — booleans, transforms, export all work.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
toShape(options?: SdfToShapeOptions): Shape
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### [`union()`](/docs/core#union) — SDF union (sharp).
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
union(...others: SdfShape[]): SdfShape
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### `subtract()` — SDF difference (sharp) — subtracts others from this.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
subtract(...others: SdfShape[]): SdfShape
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### `intersect()` — SDF intersection (sharp).
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
intersect(...others: SdfShape[]): SdfShape
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### `smoothUnion()` — Smooth union — blends shapes together with a smooth radius.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
smoothUnion(other: SdfShape, radius: number): SdfShape
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### `smoothSubtract()` — Smooth difference — smoothly carves other from this.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
smoothSubtract(other: SdfShape, radius: number): SdfShape
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### `smoothIntersect()` — Smooth intersection — smoothly intersects.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
smoothIntersect(other: SdfShape, radius: number): SdfShape
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### `morph()` — Morph between this shape and another. t=0 → this, t=1 → other.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
morph(other: SdfShape, t: number): SdfShape
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `translate()`
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
translate(x: number, y: number, z: number): SdfShape
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### `rotate()` — Rotate around an arbitrary axis through the origin.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
rotate(axis: [ number, number, number ], angleDeg: number): SdfShape
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### `rotateX()` — Rotate around the X axis by the given angle in degrees.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
rotateX(angleDeg: number): SdfShape
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `rotateY()` — Rotate around the Y axis by the given angle in degrees.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
rotateY(angleDeg: number): SdfShape
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### `rotateZ()` — Rotate around the Z axis by the given angle in degrees.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
rotateZ(angleDeg: number): SdfShape
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### `scale()`
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
scale(factor: number): SdfShape
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### `twist()` — Twist around the Z axis.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
twist(degreesPerUnit: number): SdfShape
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### `bend()` — Bend around the Z axis with given radius.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
bend(radius: number): SdfShape
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `repeat()` — Repeat in space. Spacing of 0 on an axis means no repetition. Count of 0 = infinite.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
repeat(spacing: Vec3, count?: Vec3): SdfShape
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `shell()` — Hollow out, keeping only a shell of given thickness.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
shell(thickness: number): SdfShape
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### `displace()` — Displace the surface by a function of position, or by a pattern SdfShape.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
// Function displacement
|
|
135
|
+
shape.displace((x, y, z) => Math.sin(x) * 0.5)
|
|
136
|
+
|
|
137
|
+
// Pattern displacement (e.g. basketWeave)
|
|
138
|
+
shape.displace(sdf.basketWeave({ threads: 16, spacing: 3 }))
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
displace(fn: ((x: number, y: number, z: number) => number) | SdfShape, constants?: Record<string, number>): SdfShape
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### `surfaceDisplace()` — Displace the surface using a 2D pattern in surface-local UV coordinates.
|
|
146
|
+
|
|
147
|
+
Automatically detects the shape's UV parametrization (sphere, cylinder, torus) from the SDF tree. Falls back to triplanar mapping for arbitrary shapes.
|
|
148
|
+
|
|
149
|
+
UV coordinates are in **surface millimeters** — patterns defined with `spacing: 3` always produce 3mm spacing, regardless of shape size.
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
// Surface-following basket weave — auto-detects sphere UV
|
|
153
|
+
sdf.sphere(27).shell(3)
|
|
154
|
+
.surfaceDisplace(sdf.basketWeave({ spacing: 3, depth: 0.8 }))
|
|
155
|
+
.toShape()
|
|
156
|
+
|
|
157
|
+
// Custom 2D pattern via function
|
|
158
|
+
shape.surfaceDisplace((u, v) => -Math.sin(u * 2) * 0.3)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
surfaceDisplace(pattern: SurfacePattern | ((u: number, v: number) => number), options?: SurfaceDisplaceOptions): SdfShape
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### `onion()` — Create concentric onion layers.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
onion(layers: number, thickness: number): SdfShape
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Constants
|
|
174
|
+
|
|
175
|
+
### `sdf`
|
|
176
|
+
|
|
177
|
+
SDF modeling — signed distance field primitives, smooth booleans, TPMS lattices, domain warps, and surface patterns. **Experimental.** Slower render times and lower mesh quality than B-rep. Use for organic forms, smooth blending, or TPMS lattices where these trade-offs are acceptable. For mechanical parts, prefer B-rep. All shapes live as a lazy expression tree until `.toShape()` is called, which meshes them via `Manifold.levelSet()` and returns a regular Shape. ```js const shape = sdf.smoothUnion(sdf.sphere(10), sdf.box(15, 15, 15), { radius: 3 }) .toShape({ edgeLength: 0.5 }) .color('#4488cc'); ```
|
|
178
|
+
|
|
179
|
+
- `sphere(radius: number): SdfShape` — Create an SDF sphere centered at the origin.
|
|
180
|
+
- `box(x: number, y: number, z: number): SdfShape` — Create an SDF box centered at the origin with given full dimensions (not half-extents).
|
|
181
|
+
- `cylinder(height: number, radius: number): SdfShape` — Create an SDF cylinder centered at the origin, axis along Z.
|
|
182
|
+
- `torus(majorRadius: number, minorRadius: number): SdfShape` — Create an SDF torus centered at the origin, lying in the XY plane.
|
|
183
|
+
- `capsule(height: number, radius: number): SdfShape` — Create an SDF capsule centered at the origin, axis along Z.
|
|
184
|
+
- `cone(height: number, radius: number): SdfShape` — Create an SDF cone with base at z=0 and tip at z=height.
|
|
185
|
+
- `smoothUnion(a: SdfShape, b: SdfShape, options: { radius: number; }): SdfShape` — Smooth union — blends shapes together with a smooth transition radius.
|
|
186
|
+
- `smoothDifference(a: SdfShape, b: SdfShape, options: { radius: number; }): SdfShape` — Smooth difference — smoothly subtracts b from a.
|
|
187
|
+
- `smoothIntersection(a: SdfShape, b: SdfShape, options: { radius: number; }): SdfShape` — Smooth intersection — smoothly intersects a and b.
|
|
188
|
+
- `morph(a: SdfShape, b: SdfShape, t: number): SdfShape` — Morph between two SDF shapes. t=0 → a, t=1 → b.
|
|
189
|
+
- `blend(a: SdfShape, b: SdfShape, fn: (x: number, y: number, z: number) => number, options?: BlendOptions): SdfShape` — Spatially blend between two SDF patterns. The blend function receives (x, y, z) and returns 0..1: 0 = fully pattern `a`, 1 = fully pattern `b`.
|
|
190
|
+
- `gyroid(options: TpmsOptions): SdfShape` — Gyroid TPMS lattice — the most common lattice for additive manufacturing.
|
|
191
|
+
- `schwarzP(options: TpmsOptions): SdfShape` — Schwarz-P TPMS lattice — isotropic pore structure.
|
|
192
|
+
- `diamond(options: TpmsOptions): SdfShape` — Diamond TPMS lattice — stiffest TPMS structure.
|
|
193
|
+
- `lidinoid(options: TpmsOptions): SdfShape` — Lidinoid TPMS lattice — visually distinct from gyroid, popular in research and art.
|
|
194
|
+
- `noise(options?: NoiseOptions): SdfShape` — 3D Simplex noise field — produces organic, natural-looking displacements.
|
|
195
|
+
- `voronoi(options?: VoronoiOptions): SdfShape` — 3D Voronoi pattern — organic cellular structures like bone, coral, or soap bubbles.
|
|
196
|
+
- `honeycomb(options?: HoneycombOptions): SdfShape` — Honeycomb (hexagonal) lattice pattern. Intersect with your shape to apply.
|
|
197
|
+
- `waves(options?: WavesOptions): SdfShape` — Sinusoidal wave ridges — parallel ridges along an axis.
|
|
198
|
+
- `knurl(options?: KnurlOptions): SdfShape` — Knurl pattern — crossed helical grooves for grips and handles.
|
|
199
|
+
- `perforated(options?: PerforatedOptions): SdfShape` — Perforated plate pattern — regular array of cylindrical holes.
|
|
200
|
+
- `scales(options?: ScalesOptions): SdfShape` — Fish/dragon scale pattern — overlapping circular scales in hex-packed rows.
|
|
201
|
+
- `brick(options?: BrickOptions): SdfShape` — Brick/stone wall pattern — running bond with mortar grooves.
|
|
202
|
+
- `weave(options?: WeaveOptions): SdfShape` — Grid lattice pattern — two families of infinite slabs crossing at 90°.
|
|
203
|
+
- `basketWeave(options?: BasketWeaveOptions): SurfacePattern` — Basket weave surface pattern — threads with over-under crossings in UV space. Returns a SurfacePattern for use with `.surfaceDisplace()`.
|
|
204
|
+
- `twist(shape: SdfShape, degreesPerUnit: number): SdfShape` — Twist an SDF shape around the Z axis.
|
|
205
|
+
- `bend(shape: SdfShape, radius: number): SdfShape` — Bend an SDF shape around the Z axis.
|
|
206
|
+
- `repeat(shape: SdfShape, spacing: Vec3, count?: Vec3): SdfShape` — Repeat an SDF shape in space.
|
|
207
|
+
- `SurfacePattern: typeof SurfacePattern` — A 2D surface pattern — a heightmap function for use with `.surfaceDisplace()`.
|
|
208
|
+
- `fromFunction(fn: (x: number, y: number, z: number) => number, bounds: { min: Vec3; max: Vec3; }, constants?: Record<string, number>): SdfShape` — Create an SDF shape from an arbitrary distance function. You must provide bounds since the function is opaque.
|