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.
Files changed (193) hide show
  1. package/README.md +2 -11
  2. package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-DAu1C1ST.js} +250 -151
  3. package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
  4. package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-Gc_BCdqC.js} +269 -143
  5. package/dist/assets/EditorApp-D9bJvtf7.js +11338 -0
  6. package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-DG1-oUSV.css} +459 -87
  7. package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-CEO8XbV8.js} +2 -4
  8. package/dist/assets/LandingPage-CdCuEOdC.js +451 -0
  9. package/dist/assets/PricingPage-BSrxu6d7.js +232 -0
  10. package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-FUCSIRq6.js} +129 -5
  11. package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-KoR0SNKq.js} +6770 -2914
  12. package/dist/assets/{index-2hfs_ub0.css → index-CyVd1D4D.css} +227 -53
  13. package/dist/assets/{Viewport-CoB46f5R.js → index-wTEK39at.js} +31385 -6439
  14. package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
  15. package/dist/assets/{manifold-CqNMHHKO.js → manifold-B1sGWdYk.js} +4 -3
  16. package/dist/assets/{manifold-Cce9wRFz.js → manifold-D7o0N50J.js} +1 -1
  17. package/dist/assets/{manifold-D6BeHIOo.js → manifold-G5sBaXzi.js} +1 -1
  18. package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-DYcRHhv9.js} +6798 -3341
  19. package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
  20. package/dist/docs-raw/generated/assembly.md +691 -112
  21. package/dist/docs-raw/generated/concepts.md +1225 -1400
  22. package/dist/docs-raw/generated/core.md +464 -1412
  23. package/dist/docs-raw/generated/curves.md +593 -117
  24. package/dist/docs-raw/generated/lib.md +38 -748
  25. package/dist/docs-raw/generated/output.md +139 -245
  26. package/dist/docs-raw/generated/sheet-metal.md +473 -21
  27. package/dist/docs-raw/generated/sketch.md +553 -349
  28. package/dist/docs-raw/generated/viewport.md +345 -303
  29. package/dist/docs-raw/generated/wood.md +104 -0
  30. package/dist/index.html +2 -2
  31. package/dist/sitemap.xml +6 -6
  32. package/dist-cli/chunk-PZ5AY32C.js +10 -0
  33. package/dist-cli/chunk-PZ5AY32C.js.map +1 -0
  34. package/dist-cli/forgecad.js +9435 -5407
  35. package/dist-cli/forgecad.js.map +1 -0
  36. package/dist-cli/solver-FV7TJZGI.js +365 -0
  37. package/dist-cli/solver-FV7TJZGI.js.map +1 -0
  38. package/dist-skill/CONTEXT.md +3186 -7145
  39. package/dist-skill/SKILL-dev.md +21 -63
  40. package/dist-skill/SKILL.md +12 -56
  41. package/dist-skill/docs/API/core/concepts.md +16 -98
  42. package/dist-skill/docs/CLI/export.md +91 -0
  43. package/dist-skill/docs/CLI/projects.md +107 -0
  44. package/dist-skill/docs/CLI/studio_publishing.md +52 -0
  45. package/dist-skill/docs/CLI/validation.md +66 -0
  46. package/dist-skill/docs/generated/assembly.md +691 -112
  47. package/dist-skill/docs/generated/core.md +464 -1412
  48. package/dist-skill/docs/generated/curves.md +593 -117
  49. package/dist-skill/docs/generated/lib.md +38 -748
  50. package/dist-skill/docs/generated/output.md +139 -245
  51. package/dist-skill/docs/generated/sheet-metal.md +473 -21
  52. package/dist-skill/docs/generated/sketch.md +553 -349
  53. package/dist-skill/docs/generated/viewport.md +345 -303
  54. package/dist-skill/docs/generated/wood.md +104 -0
  55. package/dist-skill/docs/guides/coordinate-system.md +11 -17
  56. package/dist-skill/docs/guides/geometry-conventions.md +13 -70
  57. package/dist-skill/docs/guides/modeling-recipes.md +22 -195
  58. package/dist-skill/docs/guides/positioning.md +88 -147
  59. package/dist-skill/docs-dev/API/core/concepts.md +51 -0
  60. package/dist-skill/docs-dev/API/core/sdf-advanced.md +92 -0
  61. package/dist-skill/docs-dev/API/core/sdf-primitives.md +58 -0
  62. package/dist-skill/docs-dev/API/core/sdf-workflow.md +42 -0
  63. package/dist-skill/docs-dev/CLI/export.md +91 -0
  64. package/dist-skill/docs-dev/CLI/projects.md +107 -0
  65. package/dist-skill/docs-dev/CLI/studio_publishing.md +52 -0
  66. package/dist-skill/docs-dev/CLI/validation.md +66 -0
  67. package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
  68. package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
  69. package/dist-skill/{docs → docs-dev}/coding.md +1 -3
  70. package/dist-skill/docs-dev/generated/assembly.md +771 -0
  71. package/dist-skill/docs-dev/generated/core.md +775 -0
  72. package/dist-skill/docs-dev/generated/curves.md +688 -0
  73. package/dist-skill/docs-dev/generated/lib.md +50 -0
  74. package/dist-skill/docs-dev/generated/output.md +234 -0
  75. package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
  76. package/dist-skill/docs-dev/generated/sketch.md +801 -0
  77. package/dist-skill/docs-dev/generated/viewport.md +486 -0
  78. package/dist-skill/docs-dev/generated/wood.md +104 -0
  79. package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
  80. package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
  81. package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
  82. package/dist-skill/docs-dev/guides/positioning.md +151 -0
  83. package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
  84. package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
  85. package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
  86. package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
  87. package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
  88. package/examples/api/attachTo-basics.forge.js +5 -5
  89. package/examples/api/boolean-operations.forge.js +3 -3
  90. package/examples/api/bounding-box-visualizer.forge.js +2 -2
  91. package/examples/api/clone-duplicate.forge.js +1 -1
  92. package/examples/api/colors-union-vs-array.forge.js +6 -6
  93. package/examples/api/connector-assembly.forge.js +4 -4
  94. package/examples/api/connector-basics.forge.js +2 -2
  95. package/examples/api/extrude-options.forge.js +4 -10
  96. package/examples/api/feature-created-faces.forge.js +6 -10
  97. package/examples/api/fillet-showcase.forge.js +1 -1
  98. package/examples/api/folded-service-panel-cover.forge.js +2 -2
  99. package/examples/api/group-test.forge.js +1 -1
  100. package/examples/api/group-vs-union.forge.js +1 -1
  101. package/examples/api/highlight-debug.forge.js +4 -0
  102. package/examples/api/js-module-pillars.js +1 -1
  103. package/examples/api/js-module-scene.js +2 -2
  104. package/examples/api/mesh-import-slats.forge.js +1 -1
  105. package/examples/api/pointAlong-orientation.forge.js +1 -1
  106. package/examples/api/profile-2020-b-slot6.forge.js +0 -1
  107. package/examples/api/route-perimeter-flange.forge.js +1 -1
  108. package/examples/api/sdf-rover-demo.forge.js +10 -10
  109. package/examples/api/sketch-on-face-demo.forge.js +2 -2
  110. package/examples/api/sketch-regions.forge.js +4 -4
  111. package/examples/api/transition-curves.forge.js +1 -1
  112. package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
  113. package/examples/api/variable-sweep-test.forge.js +2 -2
  114. package/examples/api/wood-joinery.forge.js +60 -0
  115. package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
  116. package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
  117. package/examples/experiments/drone-arm.forge.js +53 -0
  118. package/examples/furniture/adjustable-table.forge.js +2 -2
  119. package/examples/furniture/bathroom.forge.js +11 -11
  120. package/examples/furniture/chair.forge.js +1 -1
  121. package/examples/generative/crystal-growth.forge.js +2 -2
  122. package/examples/generative/frost-spires.forge.js +3 -3
  123. package/examples/generative/golden-spiral-tower.forge.js +3 -3
  124. package/examples/mechanical/3d-printer.forge.js +28 -28
  125. package/examples/mechanical/5-finger-robot-hand.forge.js +15 -15
  126. package/examples/mechanical/airplane-propeller.forge.js +2 -2
  127. package/examples/mechanical/fillet-enclosure.forge.js +1 -1
  128. package/examples/mechanical/headphone-hanger-v2.forge.js +2 -2
  129. package/examples/mechanical/robot_hand.forge.js +15 -15
  130. package/examples/mechanical/robot_hand_2.forge.js +9 -9
  131. package/examples/products/bottle.forge.js +1 -1
  132. package/examples/products/chess-set.forge.js +19 -19
  133. package/examples/products/classical-piano.forge.js +11 -11
  134. package/examples/products/clock.forge.js +12 -12
  135. package/examples/products/iphone.forge.js +8 -8
  136. package/examples/products/laptop.forge.js +15 -15
  137. package/examples/products/liquid-soap-dispenser.forge.js +18 -18
  138. package/examples/products/origami-fish.forge.js +8 -6
  139. package/examples/products/spiderman-cake.forge.js +4 -4
  140. package/examples/toolbox/bolted-joint.forge.js +2 -2
  141. package/package.json +7 -4
  142. package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
  143. package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
  144. package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
  145. package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
  146. package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
  147. package/dist/assets/index-1CYp3zUp.js +0 -1455
  148. package/dist/docs-raw/CLI.md +0 -865
  149. package/dist-skill/docs/API/API.md +0 -1666
  150. package/dist-skill/docs/API/README.md +0 -37
  151. package/dist-skill/docs/API/assembly/assembly.md +0 -617
  152. package/dist-skill/docs/API/core/edge-queries.md +0 -130
  153. package/dist-skill/docs/API/core/parameters.md +0 -122
  154. package/dist-skill/docs/API/core/reserved-terms.md +0 -137
  155. package/dist-skill/docs/API/core/sdf.md +0 -326
  156. package/dist-skill/docs/API/core/skill-cli.md +0 -194
  157. package/dist-skill/docs/API/core/skill-guide.md +0 -205
  158. package/dist-skill/docs/API/core/specs.md +0 -186
  159. package/dist-skill/docs/API/core/topology.md +0 -372
  160. package/dist-skill/docs/API/entities.md +0 -268
  161. package/dist-skill/docs/API/output/bom.md +0 -58
  162. package/dist-skill/docs/API/output/brep-export.md +0 -87
  163. package/dist-skill/docs/API/output/dimensions.md +0 -67
  164. package/dist-skill/docs/API/output/export.md +0 -110
  165. package/dist-skill/docs/API/output/gcode.md +0 -195
  166. package/dist-skill/docs/API/runtime/viewport.md +0 -420
  167. package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
  168. package/dist-skill/docs/API/sketch/anchor.md +0 -37
  169. package/dist-skill/docs/API/sketch/booleans.md +0 -91
  170. package/dist-skill/docs/API/sketch/core.md +0 -73
  171. package/dist-skill/docs/API/sketch/extrude.md +0 -62
  172. package/dist-skill/docs/API/sketch/on-face.md +0 -104
  173. package/dist-skill/docs/API/sketch/operations.md +0 -78
  174. package/dist-skill/docs/API/sketch/path.md +0 -75
  175. package/dist-skill/docs/API/sketch/primitives.md +0 -146
  176. package/dist-skill/docs/API/sketch/regions.md +0 -80
  177. package/dist-skill/docs/API/sketch/text.md +0 -108
  178. package/dist-skill/docs/API/sketch/transforms.md +0 -65
  179. package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
  180. package/dist-skill/docs/CLI.md +0 -865
  181. package/dist-skill/docs/INDEX.md +0 -94
  182. package/dist-skill/docs/RELEASING.md +0 -55
  183. package/dist-skill/docs/cli-monetization.md +0 -111
  184. package/dist-skill/docs/deployment.md +0 -281
  185. package/dist-skill/docs/generated/concepts.md +0 -2112
  186. package/dist-skill/docs/internals/shape-from-slices.md +0 -152
  187. package/dist-skill/docs/platform/admin.md +0 -45
  188. package/dist-skill/docs/platform/architecture.md +0 -79
  189. package/dist-skill/docs/platform/auth.md +0 -110
  190. package/dist-skill/docs/platform/email.md +0 -67
  191. package/dist-skill/docs/platform/projects.md +0 -111
  192. package/dist-skill/docs/platform/sharing.md +0 -90
  193. 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
- ## Functions
10
+ ## Contents
13
11
 
14
- ### Annotations & Output
12
+ - [Annotations & Output](#annotations-output) — `bom`, `robotExport`, `dim`, `dimLine`
13
+ - [Sketch Export](#sketch-export) — `sketchToDxf`, `sketchToSvg`
15
14
 
16
- Add dimensions, BOM entries, verification checks, and robot export.
15
+ ## Functions
17
16
 
18
- #### `bom()`
17
+ ### Annotations & Output
19
18
 
20
- ```ts
21
- bom(quantity: number, description: string, opts?: BomOpts): void
22
- ```
19
+ #### `bom()` — Register a Bill of Materials entry for report export.
23
20
 
24
- Add a bill-of-materials entry.
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
- <details><summary><code>BomOpts</code></summary>
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
- interface BomOpts {
30
- /** Quantity unit label, e.g. "mm", "pieces", "kg". Default: "pieces" */
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
- #### `robotExport()`
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
- ```ts
42
- robotExport(options: RobotExportOptions): CollectedRobotExport
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
- interface RobotExportOptions {
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
- </details>
48
+ **`BomOpts`**
66
49
 
67
- <details><summary><code>RobotLinkExportOptions</code></summary>
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
- ```ts
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
- ```ts
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
- </details>
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
- <details><summary><code>RobotDiffDrivePluginOptions</code></summary>
72
+ **Collision mesh modes** (set per-link via `links["PartName"].collision`):
93
73
 
94
- ```ts
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
- </details>
76
+ **Unit conventions:**
113
77
 
114
- <details><summary><code>RobotJointStatePublisherOptions</code></summary>
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
- interface RobotJointStatePublisherOptions {
118
- enabled?: boolean;
119
- joints?: string[];
120
- topic?: string;
121
- updateRate?: number;
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
- <details><summary><code>RobotWorldOptions</code></summary>
128
-
129
- ```ts
130
- interface RobotWorldOptions {
131
- name?: string;
132
- generateDemoWorld?: boolean;
133
- spawnPose?: RobotPose6;
134
- keyboardTeleop?: RobotWorldKeyboardTeleopOptions;
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
- </details>
110
+ **CLI usage**
139
111
 
140
- <details><summary><code>RobotWorldKeyboardTeleopOptions</code></summary>
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
- interface RobotWorldKeyboardTeleopOptions {
144
- enabled?: boolean;
145
- linearStep?: number;
146
- angularStep?: number;
147
- }
118
+ robotExport(options: RobotExportOptions): CollectedRobotExport
148
119
  ```
149
120
 
150
- </details>
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
- <details><summary><code>CollectedRobotExport</code></summary>
123
+ `RobotLinkExportOptions`: `{ massKg?: number, densityKgM3?: number, collision?: "visual" | "convex" | "box" | "none" }`
153
124
 
154
- ```ts
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
- </details>
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
- <details><summary><code>AssemblyDefinition</code></summary>
129
+ `RobotJointStatePublisherOptions`: `{ enabled?: boolean, joints?: string[], topic?: string, updateRate?: number }`
173
130
 
174
- ```ts
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
- </details>
133
+ `RobotWorldKeyboardTeleopOptions`: `{ enabled?: boolean, linearStep?: number, angularStep?: number }`
184
134
 
185
- <details><summary><code>AssemblyPartDef</code></summary>
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
- ```ts
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
- </details>
139
+ `AssemblyPartDef`: `{ name: string, part: AssemblyPart, base: Transform, metadata?: PartMetadata }`
197
140
 
198
- <details><summary><code>PartMetadata</code></summary>
141
+ **`PartMetadata`**: `material?: string`, `process?: string`, `tolerance?: string`, `qty?: number`, `notes?: string`, `densityKgM3?: number`, `massKg?: number`
199
142
 
200
- ```ts
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
- </details>
145
+ `AssemblyJointCouplingDef`: `{ joint: string, terms: JointCouplingTermRecord[], offset: number }`
213
146
 
214
- <details><summary><code>AssemblyJointDef</code></summary>
147
+ `JointCouplingTermRecord`: `{ joint: string, ratio: number }`
215
148
 
216
- ```ts
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
- <details><summary><code>AssemblyJointCouplingDef</code></summary>
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
- ```ts
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
- </details>
155
+ **Ownership Rules (Report Pages)**
248
156
 
249
- <details><summary><code>JointCouplingTermRecord</code></summary>
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
- interface JointCouplingTermRecord {
253
- joint: string;
254
- ratio: number;
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
- </details>
259
-
260
- #### `dim()`
168
+ `component` (string or string[] — report ownership), `currentComponent` (boolean)
261
169
 
262
170
  ```ts
263
- dim(from: PointArg$1, to: PointArg$1, opts?: DimOpts): void
171
+ dim(from: PointArg, to: PointArg, opts?: DimOpts): void
264
172
  ```
265
173
 
266
- Add a dimension annotation between two points.
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
- <details><summary><code>DimOpts</code></summary>
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
- interface DimOpts {
272
- offset?: number;
273
- label?: string;
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 sketches to SVG or DXF format strings.
192
+ #### `sketchToDxf()` — Export a 2D sketch as a DXF string (R12/AC1009 — maximally compatible).
293
193
 
294
- #### `sketchToDxf()`
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
- sketchToDxf(sketch: Sketch, options?: SketchDxfOptions): string
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
- interface SketchDxfOptions {
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
- </details>
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
- ```ts
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
- Export a 2D sketch as an SVG string. For regular sketches, exports filled polygon regions. For constraint sketches, exports line/arc/circle edge geometry. The SVG uses the sketch's native coordinate system (Y-up) with a transform that flips Y so the output renders correctly in SVG's Y-down space. Coordinates are in sketch units (typically mm).
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
- <details><summary><code>SketchSvgOptions</code></summary>
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
- interface SketchSvgOptions {
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
- </details>
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. |