forgecad 0.6.3 → 0.7.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 +2 -11
- package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-DAu1C1ST.js} +250 -151
- package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
- package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-Gc_BCdqC.js} +269 -143
- package/dist/assets/EditorApp-D9bJvtf7.js +11338 -0
- package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-DG1-oUSV.css} +459 -87
- package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-CEO8XbV8.js} +2 -4
- package/dist/assets/LandingPage-CdCuEOdC.js +451 -0
- package/dist/assets/PricingPage-BSrxu6d7.js +232 -0
- package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-FUCSIRq6.js} +129 -5
- package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-KoR0SNKq.js} +6770 -2914
- package/dist/assets/{index-2hfs_ub0.css → index-CyVd1D4D.css} +227 -53
- package/dist/assets/{Viewport-CoB46f5R.js → index-wTEK39at.js} +31385 -6439
- package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
- package/dist/assets/{manifold-CqNMHHKO.js → manifold-B1sGWdYk.js} +4 -3
- package/dist/assets/{manifold-Cce9wRFz.js → manifold-D7o0N50J.js} +1 -1
- package/dist/assets/{manifold-D6BeHIOo.js → manifold-G5sBaXzi.js} +1 -1
- package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-DYcRHhv9.js} +6798 -3341
- package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
- package/dist/docs-raw/generated/assembly.md +691 -112
- package/dist/docs-raw/generated/concepts.md +1225 -1400
- package/dist/docs-raw/generated/core.md +464 -1412
- package/dist/docs-raw/generated/curves.md +593 -117
- package/dist/docs-raw/generated/lib.md +38 -748
- package/dist/docs-raw/generated/output.md +139 -245
- package/dist/docs-raw/generated/sheet-metal.md +473 -21
- package/dist/docs-raw/generated/sketch.md +553 -349
- package/dist/docs-raw/generated/viewport.md +345 -303
- package/dist/docs-raw/generated/wood.md +104 -0
- package/dist/index.html +2 -2
- package/dist/sitemap.xml +6 -6
- package/dist-cli/chunk-PZ5AY32C.js +10 -0
- package/dist-cli/chunk-PZ5AY32C.js.map +1 -0
- package/dist-cli/forgecad.js +9435 -5407
- package/dist-cli/forgecad.js.map +1 -0
- package/dist-cli/solver-FV7TJZGI.js +365 -0
- package/dist-cli/solver-FV7TJZGI.js.map +1 -0
- package/dist-skill/CONTEXT.md +3186 -7145
- package/dist-skill/SKILL-dev.md +21 -63
- package/dist-skill/SKILL.md +12 -56
- package/dist-skill/docs/API/core/concepts.md +16 -98
- package/dist-skill/docs/CLI/export.md +91 -0
- package/dist-skill/docs/CLI/projects.md +107 -0
- package/dist-skill/docs/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs/CLI/validation.md +66 -0
- package/dist-skill/docs/generated/assembly.md +691 -112
- package/dist-skill/docs/generated/core.md +464 -1412
- package/dist-skill/docs/generated/curves.md +593 -117
- package/dist-skill/docs/generated/lib.md +38 -748
- package/dist-skill/docs/generated/output.md +139 -245
- package/dist-skill/docs/generated/sheet-metal.md +473 -21
- package/dist-skill/docs/generated/sketch.md +553 -349
- package/dist-skill/docs/generated/viewport.md +345 -303
- 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/modeling-recipes.md +22 -195
- package/dist-skill/docs/guides/positioning.md +88 -147
- package/dist-skill/docs-dev/API/core/concepts.md +51 -0
- package/dist-skill/docs-dev/API/core/sdf-advanced.md +92 -0
- package/dist-skill/docs-dev/API/core/sdf-primitives.md +58 -0
- package/dist-skill/docs-dev/API/core/sdf-workflow.md +42 -0
- package/dist-skill/docs-dev/CLI/export.md +91 -0
- package/dist-skill/docs-dev/CLI/projects.md +107 -0
- package/dist-skill/docs-dev/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs-dev/CLI/validation.md +66 -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 +1 -3
- package/dist-skill/docs-dev/generated/assembly.md +771 -0
- package/dist-skill/docs-dev/generated/core.md +775 -0
- package/dist-skill/docs-dev/generated/curves.md +688 -0
- package/dist-skill/docs-dev/generated/lib.md +50 -0
- package/dist-skill/docs-dev/generated/output.md +234 -0
- package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
- package/dist-skill/docs-dev/generated/sketch.md +801 -0
- package/dist-skill/docs-dev/generated/viewport.md +486 -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/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 +5 -5
- package/examples/api/boolean-operations.forge.js +3 -3
- package/examples/api/bounding-box-visualizer.forge.js +2 -2
- package/examples/api/clone-duplicate.forge.js +1 -1
- package/examples/api/colors-union-vs-array.forge.js +6 -6
- package/examples/api/connector-assembly.forge.js +4 -4
- package/examples/api/connector-basics.forge.js +2 -2
- package/examples/api/extrude-options.forge.js +4 -10
- package/examples/api/feature-created-faces.forge.js +6 -10
- package/examples/api/fillet-showcase.forge.js +1 -1
- package/examples/api/folded-service-panel-cover.forge.js +2 -2
- package/examples/api/group-test.forge.js +1 -1
- 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 +1 -1
- package/examples/api/pointAlong-orientation.forge.js +1 -1
- package/examples/api/profile-2020-b-slot6.forge.js +0 -1
- 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/transition-curves.forge.js +1 -1
- 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/experiments/drone-arm.forge.js +53 -0
- package/examples/furniture/adjustable-table.forge.js +2 -2
- package/examples/furniture/bathroom.forge.js +11 -11
- package/examples/furniture/chair.forge.js +1 -1
- package/examples/generative/crystal-growth.forge.js +2 -2
- package/examples/generative/frost-spires.forge.js +3 -3
- package/examples/generative/golden-spiral-tower.forge.js +3 -3
- package/examples/mechanical/3d-printer.forge.js +28 -28
- package/examples/mechanical/5-finger-robot-hand.forge.js +15 -15
- package/examples/mechanical/airplane-propeller.forge.js +2 -2
- package/examples/mechanical/fillet-enclosure.forge.js +1 -1
- package/examples/mechanical/headphone-hanger-v2.forge.js +2 -2
- package/examples/mechanical/robot_hand.forge.js +15 -15
- package/examples/mechanical/robot_hand_2.forge.js +9 -9
- package/examples/products/bottle.forge.js +1 -1
- package/examples/products/chess-set.forge.js +19 -19
- package/examples/products/classical-piano.forge.js +11 -11
- package/examples/products/clock.forge.js +12 -12
- package/examples/products/iphone.forge.js +8 -8
- package/examples/products/laptop.forge.js +15 -15
- package/examples/products/liquid-soap-dispenser.forge.js +18 -18
- package/examples/products/origami-fish.forge.js +8 -6
- package/examples/products/spiderman-cake.forge.js +4 -4
- package/examples/toolbox/bolted-joint.forge.js +2 -2
- package/package.json +7 -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/docs-raw/CLI.md +0 -865
- 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/CLI.md +0 -865
- 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()`](/docs/core#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. |
|