forgecad 0.10.0 → 0.10.2
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/dist/assets/{AdminPage-DwYHz72L.js → AdminPage-CHY6ZN-p.js} +1 -1
- package/dist/assets/{BenchmarkPage-a9_f-1US.js → BenchmarkPage-BcRT5iGN.js} +1 -1
- package/dist/assets/{BlogPage-DodHpvmf.js → BlogPage-BssBbnb-.js} +1 -1
- package/dist/assets/{DocsPage-B5LePEuj.js → DocsPage-DsvdiRNK.js} +33 -2
- package/dist/assets/{EditorApp-QXsAISLR.js → EditorApp-Bfd3jbtC.js} +185 -44
- package/dist/assets/{EmbedViewer-DdEHGUMU.js → EmbedViewer-D5t8WamV.js} +3 -3
- package/dist/assets/{LandingPageProofDriven-yhhOodbf.js → LandingPageProofDriven-DbN7o-Be.js} +1 -1
- package/dist/assets/{LegalPage-5RbKRGYK.js → LegalPage-DNGrrY0p.js} +1 -1
- package/dist/assets/{PricingPage-E3Rma7aV.js → PricingPage-Nczr3pRz.js} +1 -1
- package/dist/assets/{SettingsPage-BJZcM97j.js → SettingsPage-DZlyu4d4.js} +1 -1
- package/dist/assets/{app-DSYrDg0V.js → app-C9ct2hRD.js} +1752 -474
- package/dist/assets/{app-CE3sYcV7.css → app-CjsbDlb7.css} +143 -0
- package/dist/assets/{scalar-sampling-budget-o90NSNmF.js → backendInit-ymjonyQp.js} +85756 -78750
- package/dist/assets/cli/{render-ZMHR9HkV.js → render-B_0lQwKU.js} +71 -193
- package/dist/assets/{constructionHistoryWorker-AwMMWSxg.js → constructionHistoryWorker-CZ42Dksy.js} +8058 -1225
- package/dist/assets/{evalWorker-DbNs7Dkp.js → evalWorker-C2pm8LHP.js} +23037 -15821
- package/dist/assets/{forgecad_geometry-Dgceylq9.js → forgecad_geometry-BlMtqluF.js} +120 -1
- package/dist/assets/{forgecad_geometry_bg-dD4RNQF1.wasm → forgecad_geometry_bg-BllP_WiL.wasm} +0 -0
- package/dist/assets/{inspectWorker-CZsCFtQT.js → inspectWorker-D5T5VbfK.js} +31375 -32603
- package/dist/assets/{jointPose-DO6mnXn_.js → jointPose-4r8ed8_5.js} +1 -1
- package/dist/assets/{manifold-BU-tJwQh.js → manifold-5PP1eGLN.js} +1 -1
- package/dist/assets/{manifold-fy2MV7K1.js → manifold-C4r6B-XY.js} +2 -2
- package/dist/assets/{manifold-BGlQBBH9.js → manifold-DjBkyIc8.js} +1 -1
- package/dist/assets/{reportWorker-DO6hcQbh.js → reportWorker-CwenM7wB.js} +46620 -44936
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/CLI.md +43 -16
- package/dist/docs-raw/generated/assembly.md +71 -6
- package/dist/docs-raw/generated/concepts.md +17 -3
- package/dist/docs-raw/generated/core.md +10 -3
- package/dist/docs-raw/generated/output.md +14 -43
- package/dist/docs-raw/generated/runtime-names.md +4 -4
- package/dist/docs-raw/generated/sdf.md +2 -2
- package/dist/docs-raw/guides/simready-quickstart.md +173 -0
- package/dist/docs-raw/simulation-workflow.md +273 -0
- package/dist/index.html +2 -2
- package/dist/sitemap.xml +25 -13
- package/dist-cli/{check-compiler-JTVBITCR.js → check-compiler-SP7FAL7R.js} +1 -1
- package/dist-cli/{check-query-propagation-3FFLSMVN.js → check-query-propagation-BRLSHP22.js} +1 -1
- package/dist-cli/{chunk-OAN5T4XD.js → chunk-RQQ42YCP.js} +51209 -43456
- package/dist-cli/forgecad.js +5783 -1691
- package/dist-cli/{forgecad_geometry-QOQIIP53.js → forgecad_geometry-7TVSNVUB.js} +119 -0
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +107 -68
- package/dist-skill/docs/API/core/concepts.md +2 -2
- package/dist-skill/docs/CLI.md +43 -16
- package/dist-skill/docs/generated/assembly.md +67 -6
- package/dist-skill/docs/generated/core.md +10 -3
- package/dist-skill/docs/generated/output.md +14 -43
- package/dist-skill/docs/generated/runtime-names.md +4 -4
- package/dist-skill/docs/generated/sdf.md +2 -2
- package/examples/api/gyroid-voronoi-blend.forge.js +1 -1
- package/examples/api/organic-noise-sculpture.forge.js +1 -1
- package/examples/api/sdf-circular-array-knurling.forge.js +1 -1
- package/examples/api/{sdf-custom-raymarch.forge.js → sdf-custom-field-mesh-preview.forge.js} +3 -4
- package/examples/api/sdf-materialize-tree.forge.js +2 -2
- package/examples/api/sdf-plain-return.forge.js +3 -2
- package/examples/api/sdf-shapes.forge.js +2 -2
- package/examples/api/sdf-surface-basket-weave.forge.js +2 -2
- package/examples/generative/twisted-lattice-tower.forge.js +1 -1
- package/examples/generative/voronoi-lampshade.forge.js +1 -1
- package/examples/robotics/README.md +46 -0
- package/examples/robotics/scout-cam-rover-simready/README.md +119 -0
- package/examples/robotics/scout-cam-rover-simready/lib/dims.js +140 -0
- package/examples/robotics/scout-cam-rover-simready/main.forge.js +343 -0
- package/examples/robotics/scout-cam-rover-simready/parts/body.forge.js +304 -0
- package/examples/robotics/scout-cam-rover-simready/parts/chassis.forge.js +320 -0
- package/examples/robotics/scout-cam-rover-simready/parts/hardware.forge.js +21 -0
- package/examples/robotics/scout-cam-rover-simready/parts/turret.forge.js +70 -0
- package/examples/robotics/scout-cam-rover-simready/parts/wheel.forge.js +116 -0
- package/examples/robotics/simready-asset-crate.forge.js +79 -0
- package/examples/robotics/simready-diff-drive-rover.forge.js +141 -0
- package/examples/robotics/simready-parallel-gripper.forge.js +102 -0
- package/package.json +2 -2
- package/dist/assets/manifold-CzYf_iub.js +0 -3023
|
@@ -154,6 +154,25 @@ function geometry_create_revolved_regions(regions_json, degrees, segments) {
|
|
|
154
154
|
}
|
|
155
155
|
return ret[0] >>> 0;
|
|
156
156
|
}
|
|
157
|
+
function geometry_create_sdf_mesh(abi_version, opcodes, arg_a, arg_b, arg_c, constants, output, slot_count, options_json) {
|
|
158
|
+
const ptr0 = passArray8ToWasm0(opcodes, wasm.__wbindgen_malloc);
|
|
159
|
+
const len0 = WASM_VECTOR_LEN;
|
|
160
|
+
const ptr1 = passArray32ToWasm0(arg_a, wasm.__wbindgen_malloc);
|
|
161
|
+
const len1 = WASM_VECTOR_LEN;
|
|
162
|
+
const ptr2 = passArray32ToWasm0(arg_b, wasm.__wbindgen_malloc);
|
|
163
|
+
const len2 = WASM_VECTOR_LEN;
|
|
164
|
+
const ptr3 = passArray32ToWasm0(arg_c, wasm.__wbindgen_malloc);
|
|
165
|
+
const len3 = WASM_VECTOR_LEN;
|
|
166
|
+
const ptr4 = passArrayF64ToWasm0(constants, wasm.__wbindgen_malloc);
|
|
167
|
+
const len4 = WASM_VECTOR_LEN;
|
|
168
|
+
const ptr5 = passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
169
|
+
const len5 = WASM_VECTOR_LEN;
|
|
170
|
+
const ret = wasm.geometry_create_sdf_mesh(abi_version, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, output, slot_count, ptr5, len5);
|
|
171
|
+
if (ret[2]) {
|
|
172
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
173
|
+
}
|
|
174
|
+
return ret[0] >>> 0;
|
|
175
|
+
}
|
|
157
176
|
function geometry_create_side_profile_cut(spec_json) {
|
|
158
177
|
const ptr0 = passStringToWasm0(spec_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
159
178
|
const len0 = WASM_VECTOR_LEN;
|
|
@@ -249,6 +268,9 @@ function geometry_delete_nurbs_curve(handle) {
|
|
|
249
268
|
function geometry_delete_nurbs_surface(handle) {
|
|
250
269
|
wasm.geometry_delete_nurbs_surface(handle);
|
|
251
270
|
}
|
|
271
|
+
function geometry_delete_sdf_mesh(handle) {
|
|
272
|
+
wasm.geometry_delete_sdf_mesh(handle);
|
|
273
|
+
}
|
|
252
274
|
function geometry_export_step(handle) {
|
|
253
275
|
let deferred2_0;
|
|
254
276
|
let deferred2_1;
|
|
@@ -509,6 +531,47 @@ function geometry_sample_nurbs_surface(handle, u_samples, v_samples) {
|
|
|
509
531
|
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
510
532
|
}
|
|
511
533
|
}
|
|
534
|
+
function geometry_sdf_mesh_metadata(handle) {
|
|
535
|
+
let deferred2_0;
|
|
536
|
+
let deferred2_1;
|
|
537
|
+
try {
|
|
538
|
+
const ret = wasm.geometry_sdf_mesh_metadata(handle);
|
|
539
|
+
var ptr1 = ret[0];
|
|
540
|
+
var len1 = ret[1];
|
|
541
|
+
if (ret[3]) {
|
|
542
|
+
ptr1 = 0;
|
|
543
|
+
len1 = 0;
|
|
544
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
545
|
+
}
|
|
546
|
+
deferred2_0 = ptr1;
|
|
547
|
+
deferred2_1 = len1;
|
|
548
|
+
return getStringFromWasm0(ptr1, len1);
|
|
549
|
+
} finally {
|
|
550
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
function geometry_sdf_mesh_tri_verts(handle) {
|
|
554
|
+
const ret = wasm.geometry_sdf_mesh_tri_verts(handle);
|
|
555
|
+
if (ret[3]) {
|
|
556
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
557
|
+
}
|
|
558
|
+
var v1 = getArrayU32FromWasm0(ret[0], ret[1]).slice();
|
|
559
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
560
|
+
return v1;
|
|
561
|
+
}
|
|
562
|
+
function geometry_sdf_mesh_vert_properties(handle) {
|
|
563
|
+
const ret = wasm.geometry_sdf_mesh_vert_properties(handle);
|
|
564
|
+
if (ret[3]) {
|
|
565
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
566
|
+
}
|
|
567
|
+
var v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
|
|
568
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
569
|
+
return v1;
|
|
570
|
+
}
|
|
571
|
+
function geometry_sdf_mesher_abi_version() {
|
|
572
|
+
const ret = wasm.geometry_sdf_mesher_abi_version();
|
|
573
|
+
return ret >>> 0;
|
|
574
|
+
}
|
|
512
575
|
function geometry_select_edges(handle, query_json) {
|
|
513
576
|
let deferred3_0;
|
|
514
577
|
let deferred3_1;
|
|
@@ -621,9 +684,38 @@ function __wbg_get_imports() {
|
|
|
621
684
|
"./forgecad_geometry_bg.js": import0
|
|
622
685
|
};
|
|
623
686
|
}
|
|
687
|
+
function getArrayF32FromWasm0(ptr, len) {
|
|
688
|
+
ptr = ptr >>> 0;
|
|
689
|
+
return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
|
|
690
|
+
}
|
|
691
|
+
function getArrayU32FromWasm0(ptr, len) {
|
|
692
|
+
ptr = ptr >>> 0;
|
|
693
|
+
return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
|
|
694
|
+
}
|
|
695
|
+
var cachedFloat32ArrayMemory0 = null;
|
|
696
|
+
function getFloat32ArrayMemory0() {
|
|
697
|
+
if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {
|
|
698
|
+
cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);
|
|
699
|
+
}
|
|
700
|
+
return cachedFloat32ArrayMemory0;
|
|
701
|
+
}
|
|
702
|
+
var cachedFloat64ArrayMemory0 = null;
|
|
703
|
+
function getFloat64ArrayMemory0() {
|
|
704
|
+
if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {
|
|
705
|
+
cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);
|
|
706
|
+
}
|
|
707
|
+
return cachedFloat64ArrayMemory0;
|
|
708
|
+
}
|
|
624
709
|
function getStringFromWasm0(ptr, len) {
|
|
625
710
|
return decodeText(ptr >>> 0, len);
|
|
626
711
|
}
|
|
712
|
+
var cachedUint32ArrayMemory0 = null;
|
|
713
|
+
function getUint32ArrayMemory0() {
|
|
714
|
+
if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
|
|
715
|
+
cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
|
|
716
|
+
}
|
|
717
|
+
return cachedUint32ArrayMemory0;
|
|
718
|
+
}
|
|
627
719
|
var cachedUint8ArrayMemory0 = null;
|
|
628
720
|
function getUint8ArrayMemory0() {
|
|
629
721
|
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
@@ -631,6 +723,24 @@ function getUint8ArrayMemory0() {
|
|
|
631
723
|
}
|
|
632
724
|
return cachedUint8ArrayMemory0;
|
|
633
725
|
}
|
|
726
|
+
function passArray32ToWasm0(arg, malloc) {
|
|
727
|
+
const ptr = malloc(arg.length * 4, 4) >>> 0;
|
|
728
|
+
getUint32ArrayMemory0().set(arg, ptr / 4);
|
|
729
|
+
WASM_VECTOR_LEN = arg.length;
|
|
730
|
+
return ptr;
|
|
731
|
+
}
|
|
732
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
733
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
734
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
735
|
+
WASM_VECTOR_LEN = arg.length;
|
|
736
|
+
return ptr;
|
|
737
|
+
}
|
|
738
|
+
function passArrayF64ToWasm0(arg, malloc) {
|
|
739
|
+
const ptr = malloc(arg.length * 8, 8) >>> 0;
|
|
740
|
+
getFloat64ArrayMemory0().set(arg, ptr / 8);
|
|
741
|
+
WASM_VECTOR_LEN = arg.length;
|
|
742
|
+
return ptr;
|
|
743
|
+
}
|
|
634
744
|
function passStringToWasm0(arg, malloc, realloc) {
|
|
635
745
|
if (realloc === void 0) {
|
|
636
746
|
const buf = cachedTextEncoder.encode(arg);
|
|
@@ -698,6 +808,9 @@ function __wbg_finalize_init(instance, module) {
|
|
|
698
808
|
wasmInstance = instance;
|
|
699
809
|
wasm = instance.exports;
|
|
700
810
|
wasmModule = module;
|
|
811
|
+
cachedFloat32ArrayMemory0 = null;
|
|
812
|
+
cachedFloat64ArrayMemory0 = null;
|
|
813
|
+
cachedUint32ArrayMemory0 = null;
|
|
701
814
|
cachedUint8ArrayMemory0 = null;
|
|
702
815
|
wasm.__wbindgen_start();
|
|
703
816
|
return wasm;
|
|
@@ -791,6 +904,7 @@ export {
|
|
|
791
904
|
geometry_create_nurbs_surface_handle,
|
|
792
905
|
geometry_create_path_swept_regions,
|
|
793
906
|
geometry_create_revolved_regions,
|
|
907
|
+
geometry_create_sdf_mesh,
|
|
794
908
|
geometry_create_side_profile_cut,
|
|
795
909
|
geometry_create_sphere,
|
|
796
910
|
geometry_create_surface_grid,
|
|
@@ -804,6 +918,7 @@ export {
|
|
|
804
918
|
geometry_delete,
|
|
805
919
|
geometry_delete_nurbs_curve,
|
|
806
920
|
geometry_delete_nurbs_surface,
|
|
921
|
+
geometry_delete_sdf_mesh,
|
|
807
922
|
geometry_export_step,
|
|
808
923
|
geometry_export_step_multi,
|
|
809
924
|
geometry_fillet_edges,
|
|
@@ -818,6 +933,10 @@ export {
|
|
|
818
933
|
geometry_nurbs_surface_tessellation,
|
|
819
934
|
geometry_sample_nurbs_curve,
|
|
820
935
|
geometry_sample_nurbs_surface,
|
|
936
|
+
geometry_sdf_mesh_metadata,
|
|
937
|
+
geometry_sdf_mesh_tri_verts,
|
|
938
|
+
geometry_sdf_mesh_vert_properties,
|
|
939
|
+
geometry_sdf_mesher_abi_version,
|
|
821
940
|
geometry_select_edges,
|
|
822
941
|
geometry_topology,
|
|
823
942
|
geometry_transform,
|
|
Binary file
|
package/dist-skill/CONTEXT.md
CHANGED
|
@@ -39,16 +39,16 @@ Author or modify ForgeCAD models, sketches, assemblies, and CLI workflows. Prefe
|
|
|
39
39
|
### Validation and export commands (ask the user to run these)
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
forgecad run <file.forge.js> # geometry diagnostics, verify.* results — run after every edit
|
|
43
|
-
forgecad run <file.forge.js> --debug-imports
|
|
44
|
-
forgecad check print <file.forge.js> --json # collisions, mesh health, walls, overhangs, bed contact
|
|
45
|
-
forgecad render 3d <file.forge.js> # shaded PNG render
|
|
46
|
-
forgecad render wireframe <file.forge.js> # edges only — internal geometry, edge flow
|
|
47
|
-
forgecad render section <file.forge.js> --plane XZ # 2D cross-section (SVG/PNG)
|
|
48
|
-
forgecad capture gif <file.forge.js> # animated orbit or joint-playback GIF
|
|
49
|
-
forgecad export stl <file.forge.js> # mesh for 3D printing
|
|
50
|
-
forgecad export 3mf <file.forge.js> # mesh + metadata for 3D printing
|
|
51
|
-
forgecad export step <file.forge.js> # exact B-rep for CAD interchange
|
|
42
|
+
forgecad run <file.forge.js> [file ...] # geometry diagnostics, verify.* results — run after every edit
|
|
43
|
+
forgecad run <file.forge.js> --debug-imports # trace import-chain failures
|
|
44
|
+
forgecad check print <file.forge.js> [file ...] --json # collisions, mesh health, walls, overhangs, bed contact
|
|
45
|
+
forgecad render 3d <file.forge.js> [file ...] # shaded PNG render
|
|
46
|
+
forgecad render wireframe <file.forge.js> [file ...] # edges only — internal geometry, edge flow
|
|
47
|
+
forgecad render section <file.forge.js> [file ...] --plane XZ # 2D cross-section (SVG/PNG)
|
|
48
|
+
forgecad capture gif <file.forge.js> [file ...] # animated orbit or joint-playback GIF
|
|
49
|
+
forgecad export stl <file.forge.js> [file ...] # mesh for 3D printing
|
|
50
|
+
forgecad export 3mf <file.forge.js> [file ...] # mesh + metadata for 3D printing
|
|
51
|
+
forgecad export step <file.forge.js> [file ...] # exact B-rep for CAD interchange
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Add `--param Name=Value` to test a specific parameter value. Pick the export that matches the goal: STL/3MF for printing, STEP for exact CAD interchange.
|
|
@@ -89,7 +89,7 @@ A script must return one of three shapes:
|
|
|
89
89
|
];
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
3. **A metadata object** — a plain object whose renderable values are rendered and whose non-renderable values (numbers, hole tables, builder functions) are silently skipped at render but flow to importers via `require()`.
|
|
92
|
+
3. **A metadata object** — a plain object whose renderable values are rendered and whose non-renderable values (numbers, hole tables, builder functions) are silently skipped at render but flow to importers via `require()`. Each key becomes a named group, so don't pile independent parts into one array key (`{ parts: [a, b, c] }`) — the integrity gate reads that as a single fragmented part. Give each part its own key (`{ collar12, collar16, plug }`) or use named descriptors (form 2).
|
|
93
93
|
|
|
94
94
|
Return an unsolved `Assembly` directly — ForgeCAD solves it at default joint values for display. Use `assembly.solve(state)` for a specific pose. Never call `.toGroup()` just to make an assembly render; use it only when you need `ShapeGroup` composition or named-child lookup.
|
|
95
95
|
|
|
@@ -114,7 +114,7 @@ Resolve labels with `.face(name)` or `.face(query)` — see the Shape class docs
|
|
|
114
114
|
|
|
115
115
|
**No explanatory text inside CAD geometry.** Model the physical artifact; explain the design through names, comments, BOM entries, and docs. Use `text2d()` only when letters are part of the real object (engraving, branding, gauge ticks); use `Viewport.label()` only for temporary review/debug annotation — never to compensate for unclear geometry.
|
|
116
116
|
|
|
117
|
-
**SDF shapes preview natively** when returned directly; call `.toShape()` only when mesh-backed CAD/export behavior is needed. See [SDF docs](../../generated/sdf.md).
|
|
117
|
+
**SDF shapes preview natively** when returned directly — including plain object/array trees of SDF leaves; call `.toShape()` only when mesh-backed CAD/export behavior is needed. See [SDF docs](../../generated/sdf.md).
|
|
118
118
|
|
|
119
119
|
---
|
|
120
120
|
|
|
@@ -143,10 +143,10 @@ Point2D, Points, polygon, polygonVertices, port, Product, ProductPanelBuilder, P
|
|
|
143
143
|
ProductSkin, ProductSkinBuilder, ProductStationBuilder, ProductSurfaceBuilder, ProductSurfaceRef, projectToPlane, queueMicrotask, rect
|
|
144
144
|
Rectangle2D, robotExport, roundedRect, Route3D, scene, Sculpt, sdf, SdfShape
|
|
145
145
|
selectEdge, selectEdges, self, setActiveBackend, setImmediate, setInterval, setTimeout, Shape
|
|
146
|
-
ShapeGroup, sheetMetal, SheetMetalPart, sheetStock, Sketch, sketchToDxf, sketchToSvg
|
|
147
|
-
SolvedAssembly, spec, sphere, spline2d, stroke, Surface, SurfaceBody
|
|
148
|
-
sweep, text2d, textWidth, torus, toShape, Transform, union
|
|
149
|
-
variableSweep, verify, Viewport, window, Wood
|
|
146
|
+
ShapeGroup, sheetMetal, SheetMetalPart, sheetStock, Sim, Sketch, sketchToDxf, sketchToSvg
|
|
147
|
+
slot, SolvedAssembly, spec, sphere, spline2d, stroke, Surface, SurfaceBody
|
|
148
|
+
SurfaceMembers, sweep, text2d, textWidth, torus, toShape, Transform, union
|
|
149
|
+
union2d, variableSweep, verify, Viewport, window, Wood
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
`showLabels` is also a runtime global, but it is not part of the top-level collision check. Avoid reusing it unless you intentionally want a local value with that name.
|
|
@@ -263,6 +263,8 @@ The `edges` parameter is flexible:
|
|
|
263
263
|
|
|
264
264
|
Throws if no edges match the selection, or if `radius` is not a positive finite number.
|
|
265
265
|
|
|
266
|
+
Selectorless (all-edges) calls draw from a per-run broad edge-feature budget. Exceeding it throws — except in live preview, which skips the finish with a warning for responsiveness. Explicit edge selectors are never budgeted; `FORGECAD_BROAD_EDGE_FEATURE_BUDGET` / `FORGECAD_ALLOW_BROAD_EDGE_FEATURES=1` raise or lift the budget.
|
|
267
|
+
|
|
266
268
|
```ts
|
|
267
269
|
// Fillet all edges
|
|
268
270
|
fillet(myShape, 2)
|
|
@@ -285,6 +287,8 @@ fillet(base, 5, base.edge('vert-br'))
|
|
|
285
287
|
|
|
286
288
|
Produces a 45° bevel at the specified `size` (distance from edge). Edge selections compile into backend operations; unsupported selections fail as explicit kernel gaps instead of using TypeScript geometry fallbacks.
|
|
287
289
|
|
|
290
|
+
Selectorless (all-edges) calls draw from a per-run broad edge-feature budget. Exceeding it throws — except in live preview, which skips the finish with a warning for responsiveness. Explicit edge selectors are never budgeted; `FORGECAD_BROAD_EDGE_FEATURE_BUDGET` / `FORGECAD_ALLOW_BROAD_EDGE_FEATURES=1` raise or lift the budget.
|
|
291
|
+
|
|
288
292
|
The `edges` parameter accepts the same options as `fillet()`: inline `EdgeQuery`, pre-selected `EdgeSegment`/`EdgeSegment[]`, a tracked `EdgeRef` from `shape.edge('vert-br')` (exact compiler-owned path), or `undefined` (all sharp edges).
|
|
289
293
|
|
|
290
294
|
```ts
|
|
@@ -303,7 +307,7 @@ chamfer(base, 3, base.edge('vert-br'))
|
|
|
303
307
|
|
|
304
308
|
Adds a taper angle to the vertical faces of a solid so that it can be extracted from a mold. The neutral plane is the Z position where the draft angle is zero — faces above and below are tapered symmetrically. Typical values for injection molding are 1–5°.
|
|
305
309
|
|
|
306
|
-
Truck
|
|
310
|
+
SDF, Manifold, and Truck lower supported vertical-prism solids with Z-axis pull directions to a tapered loft. OCCT uses its native draft operation when available.
|
|
307
311
|
|
|
308
312
|
```ts
|
|
309
313
|
// Add 3° draft to a box for injection molding
|
|
@@ -1558,18 +1562,21 @@ Namespaced file-format import helpers — the single vocabulary for bringing ext
|
|
|
1558
1562
|
|
|
1559
1563
|
- `dxfSketch(fileName: string, options?: DxfImportOptions): Sketch` — Parse a DXF file and return closed 2D profile geometry as a Sketch. The result can be extruded directly.
|
|
1560
1564
|
- `svgSketch(fileName: string, options?: SvgImportOptions): Sketch` — Parse an SVG file and return it as a Sketch with options for region filtering, scaling, and simplification.
|
|
1561
|
-
- `mesh(fileName: string, options?:
|
|
1565
|
+
- `mesh(fileName: string, options?: MeshImportOptions): Shape | ShapeGroup` — Import an external mesh file (STL, OBJ, 3MF).
|
|
1562
1566
|
|
|
1563
1567
|
By default, 3MF build items are flattened into one Shape for compatibility. Use `separateObjects: true` to import 3MF build items/resource objects as a named ShapeGroup whose children are targetable by `forgecad ls`. Use `object` to import one item by the stable ref/name reported by `forgecad run`.
|
|
1564
1568
|
|
|
1565
1569
|
For 3MF sources, `forgecad run` prints a source-structure table with one line per build item: `[3mf:build:NNN:object:N] name type=... verts=... tris=... bbox=[min] → [max]`. Build items are numbered from `001`; files with no build items list resource objects as `3mf:object:N` instead. Per-item bboxes reveal multi-part structure — account for every substantial item before flattening. Pass any listed stable ref or name as `object` to import that item alone.
|
|
1566
1570
|
|
|
1571
|
+
Use `sourceFrame: { up: "+Y" }` when the file was authored in a non-Z-up coordinate system. ForgeCAD remains Z-up; the import is rotated so the named source axis becomes ForgeCAD +Z. Supported values: `"+X"`, `"-X"`, `"+Y"`, `"-Y"`, `"+Z"`, `"-Z"`.
|
|
1572
|
+
|
|
1567
1573
|
```js
|
|
1568
1574
|
const all = Import.mesh("./assembly.3mf", { separateObjects: true });
|
|
1569
1575
|
const pin = all.child("Pin #001");
|
|
1570
1576
|
const plate = Import.mesh("./assembly.3mf", { object: "3mf:build:001:object:7" });
|
|
1577
|
+
const yUpPart = Import.mesh("./part.obj", { sourceFrame: { up: "+Y" } });
|
|
1571
1578
|
```
|
|
1572
|
-
- `step(fileName: string): Shape` — Import a STEP file (.step, .stp) as an exact OCCT-backed Shape. Preserves NURBS curves, B-spline surfaces, and exact topology. Requires running with the OCCT backend.
|
|
1579
|
+
- `step(fileName: string, options?: StepImportOptions): Shape` — Import a STEP file (.step, .stp) as an exact OCCT-backed Shape. Preserves NURBS curves, B-spline surfaces, and exact topology. Requires running with the OCCT backend. Use `sourceFrame: { up: "+Y" }` to rotate Y-up source files into ForgeCAD's Z-up world.
|
|
1573
1580
|
|
|
1574
1581
|
---
|
|
1575
1582
|
|
|
@@ -3868,7 +3875,7 @@ const arm = bottle.path()
|
|
|
3868
3875
|
|
|
3869
3876
|
# Assembly API
|
|
3870
3877
|
|
|
3871
|
-
Assembly-owned links, constraints, connectors, solved poses, and
|
|
3878
|
+
Assembly-owned links, constraints, connectors, solved poses, and source-level simulation metadata.
|
|
3872
3879
|
|
|
3873
3880
|
## Contents
|
|
3874
3881
|
|
|
@@ -3881,6 +3888,59 @@ Assembly-owned links, constraints, connectors, solved poses, and robot export.
|
|
|
3881
3888
|
|
|
3882
3889
|
### Assembly & Joints
|
|
3883
3890
|
|
|
3891
|
+
#### `Sim.material(name: string, options?: SimMaterialOptions): SimMaterialDef` — Create a named physical material with density and contact coefficients for simulation export and checks.
|
|
3892
|
+
|
|
3893
|
+
`SimMaterialOptions`: `{ densityKgM3?: number, staticFriction?: number, dynamicFriction?: number, restitution?: number }`
|
|
3894
|
+
|
|
3895
|
+
`SimMaterialDef`: `{ kind: "material", name: string }`
|
|
3896
|
+
|
|
3897
|
+
#### `Sim.body(options: SimBodyOptions): SimBodyDef` — Describe one assembly part as a physical body with mass/density, material, collider intent, and optional contact surfaces.
|
|
3898
|
+
|
|
3899
|
+
**`SimBodyOptions`**: `massKg?: number`, `densityKgM3?: number`, `material?: SimMaterialDef`, `collider?: SimColliderDef`, `contacts?: Record<string, SimContactDef>`
|
|
3900
|
+
|
|
3901
|
+
`SimColliderDef`: `{ kind: "collider", mode: SimColliderMode, reason?: string }`
|
|
3902
|
+
|
|
3903
|
+
`SimContactDef`: `{ kind: "wheelSurface" | "gripperSurface", connectorName: string }`
|
|
3904
|
+
|
|
3905
|
+
`SimBodyDef`: `{ kind: "body" }`
|
|
3906
|
+
|
|
3907
|
+
#### `Sim.collider` — Collision-geometry intent constructors for physical parts.
|
|
3908
|
+
|
|
3909
|
+
- `Sim.collider.convexHull(): SimColliderDef` — Use a generated collision mesh for the part. This is the default fast rigid-body collider for irregular parts.
|
|
3910
|
+
- `Sim.collider.boundingBox(): SimColliderDef` — Use the part bounding box as the collision geometry. This is fastest and works well for chassis and simple blocks.
|
|
3911
|
+
- `Sim.collider.visualMesh(): SimColliderDef` — Use the visual mesh as collision geometry. This is exact but usually slower in physics engines.
|
|
3912
|
+
- `Sim.collider.none(reason: string): SimColliderDef` — Disable collision for a part with an explicit reason, such as a sensor-only or decorative object.
|
|
3913
|
+
|
|
3914
|
+
#### `Sim.drive` — Joint-drive intent constructors for passive or powered assembly joints.
|
|
3915
|
+
|
|
3916
|
+
- `Sim.drive.passive(options?: SimPassiveDriveOptions): SimDriveDef` — Mark a joint as passive while preserving damping and friction metadata for simulation export.
|
|
3917
|
+
- `Sim.drive.velocity(options: SimVelocityDriveOptions): SimDriveDef` — Mark a revolute joint as velocity-driven with torque and speed limits. Speed is authored in rpm and exported as deg/s or rad/s as needed.
|
|
3918
|
+
|
|
3919
|
+
`SimPassiveDriveOptions`: `{ damping?: number, friction?: number }`
|
|
3920
|
+
|
|
3921
|
+
`SimVelocityDriveOptions`: `{ maxTorqueNm: number, maxSpeedRpm: number }`
|
|
3922
|
+
|
|
3923
|
+
#### `Sim.contact` — Contact-surface metadata over existing part connectors.
|
|
3924
|
+
|
|
3925
|
+
- `Sim.contact.wheelSurface(connectorName: string): SimContactDef` — Mark a connector as the wheel tread contact surface for offline checks and downstream simulation metadata.
|
|
3926
|
+
- `Sim.contact.gripperSurface(connectorName: string): SimContactDef` — Mark a connector as a gripper pad/contact surface for offline checks and downstream grasp-readiness metadata.
|
|
3927
|
+
|
|
3928
|
+
#### `Sim.profile` — Named validation/export profile constructors.
|
|
3929
|
+
|
|
3930
|
+
- `Sim.profile.robotBodyRunnable(): SimProfileDef` — SimReady-style profile for a robot body that should be runnable in a physics simulator.
|
|
3931
|
+
- `Sim.profile.robotBodyIsaac(): SimProfileDef` — SimReady-style profile for robot bodies targeting Isaac Sim readiness.
|
|
3932
|
+
- `Sim.profile.roboticsAssetPhysx(): SimProfileDef` — SimReady-style profile for robotics assets with PhysX-ready rigid bodies and colliders.
|
|
3933
|
+
|
|
3934
|
+
`SimProfileDef`: `{ kind: "profile", name: SimProfileName }`
|
|
3935
|
+
|
|
3936
|
+
#### `Sim.controller` — Standard controller metadata constructors for simulator package generation.
|
|
3937
|
+
|
|
3938
|
+
- `Sim.controller.diffDrive(options: SimDiffDriveControllerOptions): SimDiffDriveControllerDef` — Describe a differential-drive controller from left/right wheel joints and wheel dimensions.
|
|
3939
|
+
|
|
3940
|
+
**`SimDiffDriveControllerOptions`**: `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`
|
|
3941
|
+
|
|
3942
|
+
`SimDiffDriveControllerDef`: `{ kind: "diffDrive" }`
|
|
3943
|
+
|
|
3884
3944
|
#### `assembly(name?: string): Assembly` — Create an assembly container with named parts, connectors, and kinematic links.
|
|
3885
3945
|
|
|
3886
3946
|
**Use this from iteration 1 for any model with moving parts.** Do not build one static pose and retrofit motion later.
|
|
@@ -4014,7 +4074,7 @@ const housing = group(
|
|
|
4014
4074
|
assembly.addPart("Base Assembly", housing);
|
|
4015
4075
|
```
|
|
4016
4076
|
|
|
4017
|
-
**`PartOptions`**: `transform?: TransformInput`, `metadata?: PartMetadata`, `mate?: AssemblyPartMateInput | AssemblyPartMateInput[]`, `bindToFrame?: string`
|
|
4077
|
+
**`PartOptions`**: `transform?: TransformInput`, `metadata?: PartMetadata`, `sim?: SimBodyDef`, `mate?: AssemblyPartMateInput | AssemblyPartMateInput[]`, `bindToFrame?: string`
|
|
4018
4078
|
|
|
4019
4079
|
**`PartMetadata`**
|
|
4020
4080
|
|
|
@@ -4075,7 +4135,9 @@ Frame semantics: `origin` is the pivot/contact point, `axis` the hinge or slide
|
|
|
4075
4135
|
|
|
4076
4136
|
**Face-to-face:** each connector's axis points outward from its part; mating makes the axes anti-parallel, like a plug meeting a socket (same convention as `matchTo()`).
|
|
4077
4137
|
|
|
4078
|
-
**
|
|
4138
|
+
**Revolute sign:** a positive joint value follows the right-hand rule about the **child** connector's placed axis. Because face-to-face mating makes the axes anti-parallel, that is the *left*-hand rule about the parent connector's outward axis — if `+30` swings the opposite way you expected, you predicted from the parent's axis. `forgecad debug assembly` prints each joint's resolved world axis.
|
|
4139
|
+
|
|
4140
|
+
**Mirrored revolute axes:** because of the right-hand rule, a mirrored hinge axis (`[1, 0, 0]` vs `[-1, 0, 0]`) rotates oppositely for the same `+theta`: negate the mirrored side's value and mirror limits as `[min, max] -> [-max, -min]`. Prismatic joints have no handedness flip. Use an explicit per-side sign mapping (or side-neutral link controls) for bilateral mechanisms.
|
|
4079
4141
|
|
|
4080
4142
|
Joint type defaults to the connector's `kind`. For `start`/`end` connectors, `align` / `parentAlign` / `childAlign` (`'start' | 'middle' | 'end'`) choose which point meets.
|
|
4081
4143
|
|
|
@@ -4102,7 +4164,7 @@ assembly("Door").addPart("Frame", frame).addPart("Door", door)
|
|
|
4102
4164
|
| `align?` | `PortAlign` | Shorthand: set both parentAlign and childAlign at once. |
|
|
4103
4165
|
| `follows?` | `JointFollowOptions` | Slave this joint to another joint: `value = ratio × source + offset` (e.g. a mirrored jaw with `ratio: -1`). |
|
|
4104
4166
|
|
|
4105
|
-
Also: `as?: string`, `type?: JointType`, `default?: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`.
|
|
4167
|
+
Also: `as?: string`, `type?: JointType`, `default?: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`, `drive?: SimDriveDef`.
|
|
4106
4168
|
|
|
4107
4169
|
**`JointFollowOptions`**
|
|
4108
4170
|
- `joint: string` — Name of the source joint that drives this one.
|
|
@@ -4162,6 +4224,12 @@ return mech.solve({ theta: 45 });
|
|
|
4162
4224
|
|
|
4163
4225
|
**Other**
|
|
4164
4226
|
|
|
4227
|
+
#### `withSimulation(options: SimAssemblySimulationOptions): Assembly` — Attach the root simulation contract for this assembly.
|
|
4228
|
+
|
|
4229
|
+
Use this after adding physical parts and joints. Robot-body profiles require `rootPart`; asset profiles can describe one-part or multi-part physical assets. URDF/SDF exporters and `forgecad check simready` read this contract directly, so model files no longer need a separate `robotExport(...)` side effect.
|
|
4230
|
+
|
|
4231
|
+
`SimAssemblySimulationOptions`: `{ profile: SimProfileDef, rootPart?: string, controllers?: SimControllerDef[] }`
|
|
4232
|
+
|
|
4165
4233
|
#### `edgeBetweenFrames(a: string, b: string, options?: AssemblyFrameEdgeOptions): Assembly` — Add a visual skeleton edge between two rig frame origins.
|
|
4166
4234
|
|
|
4167
4235
|
Frame edges follow the solved frame poses produced by `fixedJoint()`, `revoluteJoint()`, and `prismaticJoint()`. They do not add constraints, degrees of freedom, parts, or geometry; use them to make a frame-only rig readable in the Motion/rig inspection overlay.
|
|
@@ -4297,7 +4365,7 @@ The sub-assembly must have exactly one root part before it can be merged (collap
|
|
|
4297
4365
|
| `connectorRefs?` | `JointConnectorRefs` | Connector refs that define this joint contract. Usually set by `connect()` / `match()`. |
|
|
4298
4366
|
| `follows?` | `JointFollowOptions` | Slave this joint to another joint: `value = ratio × source + offset`. Use for mechanisms with one physical DOF expressed through several joints — a mirrored gripper jaw (`ratio: -1`), a gear pair, a drive crank turning with its servo. A followed joint stops being an independent control: the Motion view drives it from its source, `solve()` derives its value (a direct state override is ignored with a warning), and limits still clamp the derived value. |
|
|
4299
4367
|
|
|
4300
|
-
Also: `frame?: TransformInput`, `origin?: Vec3`, `axis?: Vec3`, `min?: number`, `max?: number`, `default?: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`.
|
|
4368
|
+
Also: `frame?: TransformInput`, `origin?: Vec3`, `axis?: Vec3`, `min?: number`, `max?: number`, `default?: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`, `drive?: SimDriveDef`.
|
|
4301
4369
|
|
|
4302
4370
|
`JointConnectorRefs`: `{ parent: string, child: string, parentAlign?: PortAlign, childAlign?: PortAlign }`
|
|
4303
4371
|
|
|
@@ -4369,7 +4437,7 @@ console.log("Collisions", solved.collisionReport());
|
|
|
4369
4437
|
|
|
4370
4438
|
#### `minClearance(partA: string, partB: string, searchLength?: number): number` — Compute the minimum gap (clearance) between two parts in this solved pose.
|
|
4371
4439
|
|
|
4372
|
-
Returns `0` if the parts are touching or overlapping.
|
|
4440
|
+
Returns `0` if the parts are touching or overlapping. Manifold-backed parts use the exact Manifold gap query. SDF-backed parts use a mesh-derived sampled gap. `searchLength` bounds the Manifold search radius in mm — increase it for widely separated Manifold parts.
|
|
4373
4441
|
|
|
4374
4442
|
---
|
|
4375
4443
|
|
|
@@ -4430,12 +4498,14 @@ bom(tubeLen, "rectangular steel tube", {
|
|
|
4430
4498
|
| `notes?` | `string` | Free-form notes |
|
|
4431
4499
|
| `grain?` | `string` | Wood grain direction, e.g. "long", "cross" |
|
|
4432
4500
|
|
|
4433
|
-
#### `robotExport(options: RobotExportOptions): CollectedRobotExport` —
|
|
4501
|
+
#### `robotExport(options: RobotExportOptions): CollectedRobotExport` — Compatibility shim for SDF/URDF robot package metadata.
|
|
4434
4502
|
|
|
4435
|
-
|
|
4503
|
+
Prefer returning `assembly(...).withSimulation(...)` with `Sim.body(...)`, `Sim.drive.*(...)`, and `Sim.controller.*(...)` metadata. The CLI commands `forgecad export sdf` and `forgecad export urdf` now read that assembly simulation contract directly.
|
|
4504
|
+
|
|
4505
|
+
`robotExport()` remains available for one compatibility window. It converts the legacy descriptor into the same internal simulation model used by source-authored `Sim` metadata and produces a robot package with:
|
|
4436
4506
|
|
|
4437
4507
|
- Mesh-based inertia tensors (full 6-component, not bounding-box approximations)
|
|
4438
|
-
- Separate collision meshes
|
|
4508
|
+
- Separate collision meshes
|
|
4439
4509
|
- Joint limits, effort/velocity/damping/friction metadata from assembly joints
|
|
4440
4510
|
|
|
4441
4511
|
**Collision mesh modes** (set per-link via `links["PartName"].collision`):
|
|
@@ -4454,6 +4524,8 @@ Call `robotExport()` alongside your assembly definition. `forgecad export sdf` /
|
|
|
4454
4524
|
- `massKg` is preferred; `densityKgM3` is used when mass is unknown.
|
|
4455
4525
|
- Compatibility coupling metadata, when present, maps only the primary term (largest ratio) to `<mimic>` — SDF/URDF support single-leader mimic only. Dropped terms emit a warning.
|
|
4456
4526
|
|
|
4527
|
+
**Legacy example**
|
|
4528
|
+
|
|
4457
4529
|
```ts
|
|
4458
4530
|
robotExport({
|
|
4459
4531
|
assembly: rover, // assembly() with parts + revolute wheel joints
|
|
@@ -4469,6 +4541,13 @@ robotExport({
|
|
|
4469
4541
|
});
|
|
4470
4542
|
```
|
|
4471
4543
|
|
|
4544
|
+
**Preferred CLI usage**
|
|
4545
|
+
|
|
4546
|
+
```bash
|
|
4547
|
+
forgecad export sdf model.forge.js # SDF package (Gazebo/Ignition)
|
|
4548
|
+
forgecad export urdf model.forge.js # URDF package (ROS/PyBullet/MuJoCo)
|
|
4549
|
+
```
|
|
4550
|
+
|
|
4472
4551
|
**`RobotExportOptions`**: `assembly: Assembly`, `modelName?: string`, `state?: JointState`, `static?: boolean`, `selfCollide?: boolean`, `allowAutoDisable?: boolean`, `links?: Record<string, RobotLinkExportOptions>`, `joints?: Record<string, RobotJointExportOptions>`, `plugins?: { diffDrive?: RobotDiffDrivePluginOptions; jointStatePublisher?: RobotJointStatePublisherOptions; }`, `world?: RobotWorldOptions`
|
|
4473
4552
|
|
|
4474
4553
|
`RobotLinkExportOptions`: `{ massKg?: number, densityKgM3?: number, collision?: "visual" | "convex" | "box" | "none" }`
|
|
@@ -4483,46 +4562,6 @@ robotExport({
|
|
|
4483
4562
|
|
|
4484
4563
|
`RobotWorldKeyboardTeleopOptions`: `{ enabled?: boolean, linearStep?: number, angularStep?: number }`
|
|
4485
4564
|
|
|
4486
|
-
**`CollectedRobotExport`**: `modelName: string`, `assembly: AssemblyDefinition`, `state: JointState`, `static: boolean`, `selfCollide: boolean`, `allowAutoDisable: boolean`, `links: Record<string, RobotLinkExportOptions>`, `joints: Record<string, RobotJointExportOptions>`, `plugins: { diffDrive?: RobotDiffDrivePluginOptions; jointStatePublisher?: RobotJointStatePublisherOptions; }`, `world: RobotWorldOptions | null`
|
|
4487
|
-
|
|
4488
|
-
**`AssemblyDefinition`**: `name: string`, `parts: AssemblyPartDef[]`, `joints: AssemblyJointDef[]`, `jointCouplings: AssemblyJointCouplingDef[]`, `kinematics: AssemblyKinematicGraphDef`, `frames: AssemblyFrameDef[]`, `frameJoints: AssemblyFrameJointDef[]`, `frameEdges: AssemblyFrameEdgeDef[]`
|
|
4489
|
-
|
|
4490
|
-
**`AssemblyPartDef`**: `name: string`, `part: AssemblyPart`, `base: Transform`, `metadata?: PartMetadata`, `mates: AssemblyPartMateInput[]`, `bindToFrame?: string`
|
|
4491
|
-
|
|
4492
|
-
`PartMetadata` — defined in [assembly](/docs/assembly).
|
|
4493
|
-
|
|
4494
|
-
`AssemblyPartMateInput` — defined in [assembly](/docs/assembly).
|
|
4495
|
-
|
|
4496
|
-
**`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`, `connectorRefs?: JointConnectorRefs`
|
|
4497
|
-
|
|
4498
|
-
`JointConnectorRefs` — defined in [assembly](/docs/assembly).
|
|
4499
|
-
|
|
4500
|
-
`AssemblyJointCouplingDef`: `{ joint: string, terms: JointCouplingTermRecord[], offset: number }`
|
|
4501
|
-
|
|
4502
|
-
`JointCouplingTermRecord`: `{ joint: string, ratio: number }`
|
|
4503
|
-
|
|
4504
|
-
**`AssemblyKinematicGraphDef`**: `links: AssemblyLinkDef[]`, `edges: AssemblyEdgeBetweenLinksDef[]`, `angles: AssemblyAngleBetweenLinksDef[]`, `derivedLinks: AssemblyDerivedLinkDef[]`
|
|
4505
|
-
|
|
4506
|
-
`AssemblyLinkDef`: `{ name: string, at: Vec3, fixed: boolean, metadata?: Record<string, unknown> }`
|
|
4507
|
-
|
|
4508
|
-
**`AssemblyEdgeBetweenLinksDef`**: `name: string`, `a: string`, `b: string`, `length: number | null`, `min?: number`, `max?: number`, `visualOnly: boolean`, `control?: AssemblyKinematicControlOptions`, `metadata?: Record<string, unknown>`
|
|
4509
|
-
|
|
4510
|
-
`AssemblyKinematicControlOptions` — defined in [assembly](/docs/assembly).
|
|
4511
|
-
|
|
4512
|
-
**`AssemblyAngleBetweenLinksDef`**: `name: string`, `a?: string`, `b: string`, `c: string`, `reference?: AssemblyAngleReferenceDef`, `target?: number`, `min?: number`, `max?: number`, `control?: AssemblyKinematicControlOptions`, `metadata?: Record<string, unknown>`
|
|
4513
|
-
|
|
4514
|
-
`AssemblyAngleReferenceDef`: `{ kind: "worldDirection", direction: Vec3 }`
|
|
4515
|
-
|
|
4516
|
-
**`AssemblyDerivedLinkDef`**
|
|
4517
|
-
- `distance: number` — Signed: positive moves from `fromLink` toward `towardLink`, negative moves away.
|
|
4518
|
-
- Also: `name: string`, `fromLink: string`, `towardLink: string`.
|
|
4519
|
-
|
|
4520
|
-
`AssemblyFrameDef`: `{ name: string, origin: Vec3, axis: Vec3, up: Vec3, fixed: boolean, metadata?: Record<string, unknown> }`
|
|
4521
|
-
|
|
4522
|
-
**`AssemblyFrameJointDef`**: `name: string`, `type: AssemblyFrameJointType`, `parent: string`, `child: string`, `rest: Transform`, `min?: number`, `max?: number`, `defaultValue: number`, `unit?: string`, `control: boolean`, `metadata?: Record<string, unknown>`
|
|
4523
|
-
|
|
4524
|
-
`AssemblyFrameEdgeDef`: `{ name: string, a: string, b: string, metadata?: Record<string, unknown> }`
|
|
4525
|
-
|
|
4526
4565
|
#### `dim()` — Add a dimension annotation between two points, or along an entity.
|
|
4527
4566
|
|
|
4528
4567
|
Overloads:
|
|
@@ -23,7 +23,7 @@ A script must return one of three shapes:
|
|
|
23
23
|
];
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
3. **A metadata object** — a plain object whose renderable values are rendered and whose non-renderable values (numbers, hole tables, builder functions) are silently skipped at render but flow to importers via `require()`.
|
|
26
|
+
3. **A metadata object** — a plain object whose renderable values are rendered and whose non-renderable values (numbers, hole tables, builder functions) are silently skipped at render but flow to importers via `require()`. Each key becomes a named group, so don't pile independent parts into one array key (`{ parts: [a, b, c] }`) — the integrity gate reads that as a single fragmented part. Give each part its own key (`{ collar12, collar16, plug }`) or use named descriptors (form 2).
|
|
27
27
|
|
|
28
28
|
Return an unsolved `Assembly` directly — ForgeCAD solves it at default joint values for display. Use `assembly.solve(state)` for a specific pose. Never call `.toGroup()` just to make an assembly render; use it only when you need `ShapeGroup` composition or named-child lookup.
|
|
29
29
|
|
|
@@ -48,4 +48,4 @@ Resolve labels with `.face(name)` or `.face(query)` — see the Shape class docs
|
|
|
48
48
|
|
|
49
49
|
**No explanatory text inside CAD geometry.** Model the physical artifact; explain the design through names, comments, BOM entries, and docs. Use `text2d()` only when letters are part of the real object (engraving, branding, gauge ticks); use `Viewport.label()` only for temporary review/debug annotation — never to compensate for unclear geometry.
|
|
50
50
|
|
|
51
|
-
**SDF shapes preview natively** when returned directly; call `.toShape()` only when mesh-backed CAD/export behavior is needed. See [SDF docs](../../generated/sdf.md).
|
|
51
|
+
**SDF shapes preview natively** when returned directly — including plain object/array trees of SDF leaves; call `.toShape()` only when mesh-backed CAD/export behavior is needed. See [SDF docs](../../generated/sdf.md).
|