forgecad 0.9.16 → 0.10.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 (147) hide show
  1. package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DwYHz72L.js} +1 -1
  2. package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-a9_f-1US.js} +1 -1
  3. package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DodHpvmf.js} +1 -1
  4. package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-B5LePEuj.js} +8 -858
  5. package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
  6. package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-DdEHGUMU.js} +2 -2
  7. package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-yhhOodbf.js} +1 -1
  8. package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-5RbKRGYK.js} +1 -1
  9. package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-E3Rma7aV.js} +1 -1
  10. package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-BJZcM97j.js} +1 -1
  11. package/dist/assets/{app-T0pDcSX4.js → app-DSYrDg0V.js} +733 -205
  12. package/dist/assets/cli/{render-C5pcIISc.js → render-ZMHR9HkV.js} +19 -46
  13. package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
  14. package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-DbNs7Dkp.js} +3798 -1622
  15. package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
  16. package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DO6mnXn_.js} +1 -1
  17. package/dist/assets/{manifold-BWgsjmAM.js → manifold-BGlQBBH9.js} +1 -1
  18. package/dist/assets/{manifold-rZexZI0G.js → manifold-BU-tJwQh.js} +1 -1
  19. package/dist/assets/{manifold-D6IFSkhH.js → manifold-fy2MV7K1.js} +2 -2
  20. package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-DO6hcQbh.js} +7155 -2437
  21. package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-o90NSNmF.js} +3940 -1742
  22. package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
  23. package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
  24. package/dist/cli/render.html +1 -1
  25. package/dist/docs/index.html +3 -3
  26. package/dist/docs-raw/AI/usage.md +1 -1
  27. package/dist/docs-raw/CLI.md +63 -241
  28. package/dist/docs-raw/README.md +6 -0
  29. package/dist/docs-raw/component-model.md +17 -150
  30. package/dist/docs-raw/generated/assembly.md +139 -598
  31. package/dist/docs-raw/generated/concepts.md +245 -3501
  32. package/dist/docs-raw/generated/core.md +277 -1251
  33. package/dist/docs-raw/generated/curves.md +387 -1608
  34. package/dist/docs-raw/generated/legacy.md +162 -0
  35. package/dist/docs-raw/generated/lib.md +227 -85
  36. package/dist/docs-raw/generated/output.md +38 -73
  37. package/dist/docs-raw/generated/runtime-names.md +23 -23
  38. package/dist/docs-raw/generated/sdf.md +68 -284
  39. package/dist/docs-raw/generated/sheet-metal.md +68 -335
  40. package/dist/docs-raw/generated/sketch.md +240 -1161
  41. package/dist/docs-raw/generated/viewport.md +75 -316
  42. package/dist/docs-raw/generated/wood.md +21 -49
  43. package/dist/docs-raw/guides/coordinate-system.md +4 -42
  44. package/dist/docs-raw/guides/inspection-bundles.md +44 -442
  45. package/dist/docs-raw/guides/joint-design.md +18 -79
  46. package/dist/docs-raw/guides/positioning.md +21 -143
  47. package/dist/docs-raw/guides/scene-presentation.md +89 -0
  48. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
  49. package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
  50. package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
  51. package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
  52. package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
  53. package/dist/docs-raw/skills/forgecad-lld.md +19 -113
  54. package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
  55. package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
  56. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
  57. package/dist/docs-raw/skills/forgecad-project.md +13 -131
  58. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
  59. package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
  60. package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
  61. package/dist/docs-raw/skills/forgecad.md +19 -18
  62. package/dist/docs-raw/skills/index.md +2 -0
  63. package/dist/docs-raw/welcome.md +2 -2
  64. package/dist/index.html +1 -1
  65. package/dist/llms.txt +1 -2
  66. package/dist/sitemap.xml +13 -13
  67. package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-JTVBITCR.js} +1 -1
  68. package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-3FFLSMVN.js} +1 -1
  69. package/dist-cli/{chunk-SPZE3DUY.js → chunk-OAN5T4XD.js} +4412 -2212
  70. package/dist-cli/forgecad.js +507 -179
  71. package/dist-skill/CONTEXT.md +2172 -8377
  72. package/dist-skill/SKILL.md +15 -15
  73. package/dist-skill/docs/API/core/concepts.md +27 -157
  74. package/dist-skill/docs/CLI.md +63 -241
  75. package/dist-skill/docs/generated/assembly.md +138 -549
  76. package/dist-skill/docs/generated/core.md +277 -1251
  77. package/dist-skill/docs/generated/curves.md +387 -1609
  78. package/dist-skill/docs/generated/lib.md +227 -85
  79. package/dist-skill/docs/generated/output.md +38 -73
  80. package/dist-skill/docs/generated/runtime-names.md +16 -21
  81. package/dist-skill/docs/generated/sdf.md +68 -284
  82. package/dist-skill/docs/generated/sheet-metal.md +68 -335
  83. package/dist-skill/docs/generated/sketch.md +240 -1160
  84. package/dist-skill/docs/generated/viewport.md +75 -223
  85. package/dist-skill/docs/generated/wood.md +21 -49
  86. package/dist-skill/docs/guides/coordinate-system.md +4 -42
  87. package/dist-skill/docs/guides/inspection-bundles.md +44 -442
  88. package/dist-skill/docs/guides/joint-design.md +18 -79
  89. package/dist-skill/docs/guides/positioning.md +21 -143
  90. package/dist-skill/docs/guides/scene-presentation.md +89 -0
  91. package/dist-skill/docs/guides/surface-members.md +26 -0
  92. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
  93. package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
  94. package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
  95. package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
  96. package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
  97. package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
  98. package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
  99. package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
  100. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
  101. package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
  102. package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
  103. package/dist-skill/library/forgecad-project/SKILL.md +13 -133
  104. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
  105. package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
  106. package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
  107. package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
  108. package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
  109. package/dist-skill/website/skills/forgecad-component-model.md +53 -0
  110. package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
  111. package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
  112. package/dist-skill/website/skills/forgecad-lld.md +41 -0
  113. package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
  114. package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
  115. package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
  116. package/dist-skill/website/skills/forgecad-project.md +26 -0
  117. package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
  118. package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
  119. package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
  120. package/dist-skill/website/skills/forgecad.md +122 -0
  121. package/dist-skill/website/skills/index.md +26 -0
  122. package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
  123. package/examples/api/conformal-product-ribbon.forge.js +1 -1
  124. package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
  125. package/examples/api/extrude-options.forge.js +4 -2
  126. package/examples/api/field-loft-drive-tip.forge.js +40 -0
  127. package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
  128. package/examples/api/highlight-debug.forge.js +10 -10
  129. package/examples/api/mesh-import-slats.forge.js +1 -1
  130. package/examples/api/real-product-curves.forge.js +1 -1
  131. package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
  132. package/examples/api/sdf-shapes.forge.js +2 -5
  133. package/examples/api/sketch-rounding-strategies.forge.js +6 -6
  134. package/examples/api/surface-member-bottle-cage.forge.js +3 -3
  135. package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
  136. package/examples/api/surface-member-razor-inlay.forge.js +1 -1
  137. package/examples/api/variable-sweep-test.forge.js +3 -3
  138. package/examples/mechanical/airplane-propeller.forge.js +74 -39
  139. package/examples/nurbs-surface.forge.js +1 -1
  140. package/examples/products/iphone.forge.js +1 -1
  141. package/package.json +1 -1
  142. package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
  143. package/dist/docs-raw/guides/geometry-conventions.md +0 -52
  144. package/dist/docs-raw/guides/modeling-recipes.md +0 -78
  145. package/dist-skill/docs/guides/geometry-conventions.md +0 -52
  146. package/dist-skill/docs/guides/modeling-recipes.md +0 -78
  147. package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
@@ -11,25 +11,25 @@ Author or modify ForgeCAD models, sketches, assemblies, and CLI workflows. Prefe
11
11
  ## Workflow
12
12
 
13
13
  1. Identify the artifact: `.forge.js`, SVG asset, or CLI/export task.
14
- 2. **If the model has any moving parts, load the `assembly` group AND the `joint-design.md` recipe upfront** — do not defer the kinematic structure to a refactor pass.
15
- 3. Load only the docs the task needs (see Source Map below). Start from the top group, add others as needed.
16
- 4. If any two parts are intended to touch or mate in the final model, load the positioning guide immediately and default to connectors + `matchTo()`.
14
+ 2. **If the model has any moving parts, load the `assembly` group and `{{SKILL_DIR}}/docs/guides/joint-design.md` upfront** — do not defer the kinematic structure to a refactor pass.
15
+ 3. Load only the docs the task needs (see Source Map below). Start from the top group, add others as needed, and prefer these docs and recipes over ad-hoc repo examples.
16
+ 4. If any two parts are intended to touch or mate in the final model, load `{{SKILL_DIR}}/docs/guides/positioning.md` immediately and default to connectors + `matchTo()`.
17
17
  5. Default to a concrete first pass — easy iteration beats speculative design review.
18
18
  6. If an existing model is broken, replace the weak structure rather than preserving bad architecture.
19
- 7. Validate with `forgecad run <file>` (add `--debug-imports` for import chain issues, and pass `--backend manifold|occt|truck` when the backend matters).
19
+ 7. Validate with `forgecad run <file>` (add `--debug-imports` for import chain issues; pass `--backend manifold|occt|truck` when the backend matters).
20
20
  8. For moving assemblies, return the `Assembly` directly so runtime controls re-solve the link/edge kinematics model instead of stacking viewport-only transforms.
21
- 9. Model the physical artifact, not an educational diagram. Do not add explanatory labels, arrows, legends, or text plaques unless the user explicitly asks for a presentation or teaching view. Product markings are allowed only when they would exist on the real object.
22
- 10. Build the real closed CAD first. Do not bake cutaways, sectioned shells, permanently exploded layouts, or hidden-parts views into the default model just to show internals. Use viewer-only cut planes, `explodeView`, object hiding, transparency, or `inspect sections` after the artifact exists.
21
+ 9. Model the physical artifact, not an educational diagram. No explanatory labels, arrows, legends, or text plaques unless the user explicitly asks for a presentation or teaching view; product markings only where the real object would carry them.
22
+ 10. Build the real closed CAD first. Never bake cutaways, sectioned shells, permanently exploded layouts, or hidden-parts views into the default model just to show internals use viewer-only cut planes, `explodeView`, object hiding, transparency, or `inspect sections` after the artifact exists.
23
23
 
24
24
  ### Import and Composition
25
25
 
26
- - Always include the extension in relative imports: `require("./file.forge.js", { Param: value })` for model files and `require("./helpers.js")` for plain helper modules. Do not write extensionless imports such as `require("./file")`; ForgeCAD resolves project imports by exact path.
27
- - ForgeCAD APIs are injected globals in `.forge.js` files. Use `bom()`, `box()`, `scene()`, `Shape`, etc. directly; do not destructure those names from helpers with patterns like `const { bom } = require("./bom.js")`. If a helper file is needed, import it under a project-specific name such as `const bomHelpers = require("./bom.js")`.
26
+ - Always include the extension in relative imports: `require("./file.forge.js", { Param: value })` for model files, `require("./helpers.js")` for plain helper modules. Extensionless imports such as `require("./file")` do not resolve; ForgeCAD resolves project imports by exact path.
27
+ - ForgeCAD APIs are injected globals in `.forge.js` files. Use `bom()`, `box()`, `scene()`, `Shape`, etc. directly; never destructure those names from helpers (`const { bom } = require("./bom.js")`). Import helper files under a project-specific name such as `const bomHelpers = require("./bom.js")`.
28
28
  - For static multi-part models, connectors + `matchTo()` are the default way to assemble touching parts.
29
- - Top-level scripts can return `Assembly` or `SolvedAssembly` directly. Do not call `.toGroup()` just to render an assembly; use `.toGroup()` only when you need `ShapeGroup` composition, transforms, or named-child lookup.
30
- - `importSvgSketch()` for SVG files (file format loader, not a module import).
31
- - `.placeReference('bottom', [0,0,0])` to align any built-in anchor to a world coordinate; also works with custom `.withReferences()`.
32
- - Plain `.js` modules for shared helpers/constants (not model imports).
29
+ - Top-level scripts can return `Assembly` or `SolvedAssembly` directly. Do not call `.toGroup()` just to render an assembly; use it only when you need `ShapeGroup` composition, transforms, or named-child lookup.
30
+ - `Import.svgSketch()` loads SVG files (file format loader, not a module import).
31
+ - `.placeReference('bottom', [0,0,0])` aligns any built-in anchor to a world coordinate; also works with custom `.withReferences()`.
32
+ - Plain `.js` modules hold shared helpers/constants (not model imports).
33
33
 
34
34
  ## Source Map
35
35
 
@@ -48,7 +48,6 @@ Execution model, colors, coordinate system, primitives, booleans, patterns, impo
48
48
  Axis conventions, winding rules, and placement strategy. If parts should touch in the final model, read this group before writing placement code. Connectors + `matchTo()` are the default for mating interfaces; raw `translate()` and `rotate()` are for free offsets, not assembly contracts.
49
49
 
50
50
  - `{{SKILL_DIR}}/docs/guides/coordinate-system.md`
51
- - `{{SKILL_DIR}}/docs/guides/geometry-conventions.md`
52
51
  - `{{SKILL_DIR}}/docs/guides/positioning.md`
53
52
 
54
53
  ### 3. Sketch APIs
@@ -61,6 +60,7 @@ Axis conventions, winding rules, and placement strategy. If parts should touch i
61
60
 
62
61
  Smooth curves, Hermite splines, lofted and swept solids. For straps, inlays, guards, brace members, vents, or physical bands that live on a carrier surface, use `Carrier` + `SurfaceBody` surface-member primitives before reaching for `variableSweep`, SDF sculpting, or manual boolean overlap recipes.
63
62
 
63
+ - `{{SKILL_DIR}}/docs/guides/surface-members.md`
64
64
  - `{{SKILL_DIR}}/docs/generated/curves.md`
65
65
 
66
66
  ### 5. Assemblies and Mechanisms (for joints or kinematics)
@@ -98,7 +98,7 @@ Viewer-only APIs such as cutPlane, explodeView, render labels, comparison refere
98
98
 
99
99
  Modeling patterns, debugging tactics, copyable snippets.
100
100
 
101
- - `{{SKILL_DIR}}/docs/guides/modeling-recipes.md`
101
+ - `{{SKILL_DIR}}/docs/guides/scene-presentation.md`
102
102
  - `{{SKILL_DIR}}/docs/guides/joint-design.md`
103
103
 
104
104
  ### 11. CLI (for validation/render/export tasks)
@@ -110,6 +110,6 @@ Test-run, export pipelines, debug flags.
110
110
 
111
111
  ### SDF Modeling (smooth booleans, TPMS, deformations, fromFunction)
112
112
 
113
- Primitives, smooth booleans, TPMS lattices, twist/bend/displace, morph, custom functions, gotchas. SDF is inherently implicit and sampled, not B-rep/exact geometry; use caution for precision-critical parts and exact export workflows.
113
+ Primitives, smooth booleans, TPMS lattices, twist/bend/displace, morph, custom functions, gotchas. The doc preamble's precision caution applies to every SDF workflow.
114
114
 
115
115
  - `{{SKILL_DIR}}/docs/generated/sdf.md`
@@ -5,177 +5,47 @@ skill-order: 1
5
5
 
6
6
  # ForgeCAD Core Concepts
7
7
 
8
- ForgeCAD scripts are JavaScript that returns geometry. The forge API is globally availableno imports needed.
8
+ A `.forge.js` script is plain JavaScript that returns geometry. The entire forge API is injected as globals never `import`, `require`-destructure, or shadow ForgeCAD API names (`const lib = ...`, `let slot = ...`, `class Shape {}` all collide). The reserved list is in [Runtime Names](../../generated/runtime-names.md); check it before using natural local names.
9
9
 
10
- ```javascript
11
- const width = param("Width", 50, { min: 20, max: 100, unit: "mm" });
12
- return box(width, 30, 10);
13
- ```
10
+ ## Execution & Return Values
14
11
 
15
- ## Injected Runtime Names
12
+ All geometry operations are **immutable** — shapes, sketches, groups, assemblies, and boards return new values, never mutate in place.
16
13
 
17
- ForgeCAD API functions and classes are injected into every `.forge.js` script. Use them directly; do not import or destructure ForgeCAD API names from helper files.
14
+ A script must return one of three shapes:
18
15
 
19
- ```javascript
20
- // BAD `bom` and `bomToCsv` are already built-in runtime names.
21
- const { bom, bomToCsv } = require("./bom.js");
16
+ 1. **A single renderable** — `Shape`, `Sketch`, `ShapeGroup`, `Assembly`, `SolvedAssembly`, or `SdfShape`.
17
+ 2. **An array** of renderables or named descriptors `{ name, tags?, shape | sketch | group, color? }`:
22
18
 
23
- // GOOD — use the built-in directly.
24
- bom(4, "M4 bolt");
19
+ ```javascript
20
+ return [
21
+ { name: "Base Plate", tags: ["printed", "structural"], shape: base, color: "#888888" },
22
+ { name: "M4 Bolt", tags: "fastener", shape: bolt, color: "#4488cc" },
23
+ ];
24
+ ```
25
25
 
26
- // GOODkeep project helpers under their own local name.
27
- const bomHelpers = require("./bom.js");
28
- bomHelpers.addFasteners(...);
29
- ```
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()`.
30
27
 
31
- Top-level lexical declarations such as `const bom = ...`, `let slot = ...`, `const lib = ...`, `const joint = ...`, or `class Shape {}` collide with the injected runtime names. This is checked when the script runs, so agents should treat these names as reserved before executing the model.
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.
32
29
 
33
- Use project-specific local names instead:
30
+ For multi-file projects import path rules, the metadata pattern, and Forge-aware builder modules — see the [`require()` docs](../../generated/core.md).
34
31
 
35
- ```javascript
36
- // BAD — `lib` and `slot` are injected runtime names.
37
- const lib = require("./wheel-lib.js");
38
- const slot = rect(20, 5);
32
+ ## Identity
39
33
 
40
- // GOODlocal names describe the project role.
41
- const wheelLib = require("./wheel-lib.js");
42
- const axleSlotSketch = rect(20, 5);
43
- ```
34
+ `union()` merges shapes into one solid with one identity later operands lose separate colors and names. Use `group(...)` or named return objects when parts need separate colors, tags, or identities.
44
35
 
45
- If a helper module exports a name that matches a ForgeCAD runtime name, keep the module under one local object name or rename during destructuring:
36
+ ## Face Labels
46
37
 
47
- ```javascript
48
- // GOOD — no top-level `slot` declaration.
49
- const wheelHelpers = require("./wheel-helpers.js");
50
- const axleSlot = wheelHelpers.slot(...);
38
+ Shapes carry semantic face labels through their lifecycle:
51
39
 
52
- // GOOD imported helper is renamed.
53
- const { slot: makeAxleSlot } = require("./wheel-helpers.js");
54
- ```
40
+ 1. **Primitives** assign canonical names (`box()` → `top`, `bottom`, `side-left`, ...; `cylinder()` → `top`, `bottom`, `side`).
41
+ 2. **Extrusions** inherit sketch labels and add `top`/`bottom`.
42
+ 3. **Transforms** preserve all labels.
43
+ 4. **Booleans** preserve first-operand labels where geometry survives.
55
44
 
56
- The complete collision-reserved list is generated from the runtime source in [Runtime Names](../../generated/runtime-names.md). Check that list before using natural local names such as `lib`, `slot`, `joint`, `group`, `path`, `text2d`, `scene`, or `Shape`.
45
+ Resolve labels with `.face(name)` or `.face(query)` see the Shape class docs for the query API.
57
46
 
58
- ## Execution Model
47
+ ## Conventions
59
48
 
60
- - Scripts re-execute on every parameter change (400ms debounce)
61
- - Geometry operations are **immutable** — shapes, sketches, groups, imported assemblies, and wood boards return new values instead of modifying in place
62
- - Must return one of: `Shape`, `Sketch`, `ShapeGroup`, `Assembly`, `SolvedAssembly`, `SdfShape`, `Array` of renderables, `Array` of `{ name, tags?, shape?, sketch?, group?, color? }`, or a **metadata object** (see below)
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.
63
50
 
64
- Top-level assembly scripts can return an unsolved `Assembly` directly; ForgeCAD solves it at default joint values for display. Return `assembly.solve(state)` when you want a specific pose. Do not call `.toGroup()` just to make an assembly render — use `.toGroup()` only when you specifically need `ShapeGroup` composition, group-style transforms, or named-child lookup.
65
-
66
- ### Metadata Object Return
67
-
68
- A script can return a plain object whose values include renderable geometry alongside non-renderable metadata. All renderable entries (Shape, Sketch, ShapeGroup, Assembly, SolvedAssembly, SdfShape, or Array of named objects) are rendered; non-renderable entries are silently skipped. This is useful for multi-file projects where a part needs to publish interface data (bolt positions, dimensions) to other files:
69
-
70
- When importing project files, include the full extension in every relative path: `require('./motor-mount.forge.js')` for model files and `require('./helpers.js')` for plain helper modules. ForgeCAD resolves project imports by exact path and does not infer `.forge.js` or `.js` from `require('./motor-mount')`.
71
-
72
- ```javascript
73
- // motor-mount.forge.js — renders standalone, exports metadata via require()
74
- const holePositions = [[17, 15], [-29, 15], [17, -15], [-29, -15]];
75
- return {
76
- shape: mount.color('#556B2F'), // rendered
77
- bolts: { dia: 5.3, pos: holePositions }, // metadata — skipped in render, available via require()
78
- };
79
-
80
- // base-body.forge.js — imports mount, accesses .bolts
81
- const mount = require('./motor-mount.forge.js');
82
- for (const [x, y] of mount.bolts.pos) { ... } // use metadata
83
- // mount.shape is the Shape if you need it in an assembly
84
- ```
85
-
86
- Arrays inside the object are also rendered:
87
-
88
- ```javascript
89
- return {
90
- parts: [{ name: 'Left', shape: leftShape }, { name: 'Right', shape: rightShape }],
91
- armWidth: 6, // metadata
92
- };
93
- ```
94
-
95
- ### Forge-Aware Builder Modules
96
-
97
- A `.forge.js` file can also return builder functions. Those functions keep access to
98
- the ForgeCAD runtime names from their defining file, so this is the supported way
99
- to share sketch, profile, shape, or assembly builders that need APIs such as
100
- `path()`, `circle2d()`, `box()`, or `assembly()`.
101
-
102
- This pattern works well when a file should be both directly inspectable and
103
- importable: render the flat profiles or part preview when the file is opened on
104
- its own, and export builders under a named object for the assembly file.
105
-
106
- ```javascript
107
- // profiles.forge.js - inspectable on its own, reusable through require()
108
- function wheelProfile() {
109
- return circle2d(40).subtract(circle2d(18));
110
- }
111
-
112
- return {
113
- preview: [{ name: 'Wheel profile', sketch: wheelProfile() }],
114
- make: { wheelProfile },
115
- };
116
- ```
117
-
118
- ```javascript
119
- // main.forge.js - reuses the exact inspected profile
120
- const profiles = require('./profiles.forge.js');
121
- const wheel = profiles.make.wheelProfile().extrude(8);
122
- return wheel;
123
- ```
124
-
125
- Keep builder modules pure over top-level constants, top-level `param()` values,
126
- or explicit function arguments. Do not declare new `param()` values inside an
127
- exported builder if callers need `require('./profiles.forge.js', { Width: 80 })`
128
- overrides: import overrides are validated while the module loads, before any
129
- exported builder is called. For plain constants, tables, math helpers, and
130
- formatting code that does not construct ForgeCAD geometry, use `.js` helper
131
- modules instead.
132
-
133
- Named return objects and named `group(...)` children can include `tags`. Tags are viewport metadata: they do not affect geometry, exports, face labels, or BOM rows, but the command palette can hide, show only, or focus every object with a selected tag.
134
-
135
- ```javascript
136
- return [
137
- { name: 'Base Plate', tags: ['printed', 'structural'], shape: base },
138
- { name: 'M4 Bolt A', tags: 'fastener', shape: boltA },
139
- { name: 'M4 Bolt B', tags: 'fastener', shape: boltB },
140
- ];
141
- ```
142
-
143
- ## Coordinate System
144
-
145
- Z-up right-handed: X = left/right, Y = forward/back, Z = up/down.
146
-
147
- ## Colors
148
-
149
- `.color(hex)` works on `Shape` and `Sketch`. Colors survive transforms. Boolean operations return a single result shape, so only the first operand's color survives.
150
-
151
- **`union()` merges shapes into one solid mesh** — later operands do not keep separate colors or identities. Use `group(...)` or return named objects instead when you want separate parts:
152
-
153
- ```javascript
154
- return [
155
- { name: "Base", shape: box(100, 100, 5), color: "#888888" },
156
- { name: "Column", shape: cylinder(50, 10).translate(50, 50, 5), color: "#4488cc" },
157
- ];
158
- ```
159
-
160
- ## Face Operations
161
-
162
- Shapes carry semantic face labels through their lifecycle. The flow is:
163
-
164
- 1. **Primitives** assign canonical names — `box()` gives you `top`, `bottom`, `side-left`, etc.; `cylinder()` gives `top`, `bottom`, `side`.
165
- 2. **Extrusions** inherit labels from the sketch and add `top`/`bottom`.
166
- 3. **Transforms** (translate, rotate, scale, mirror) preserve all labels.
167
- 4. **Booleans** preserve labels from the first operand where geometry survives.
168
-
169
- You resolve labels to geometry with `.face(name)` or `.face(query)` — see the Shape class docs for the full query API. Operations like `.pocket()`, `.boss()`, `.hole()`, and `faceProfile()` all consume face references.
170
-
171
- ## Text vs Viewport Labels
172
-
173
- Default to no explanatory text inside CAD geometry. A ForgeCAD model should represent the physical artifact, not a labeled teaching diagram. Explain the design through file names, named return objects, comments, BOM entries, inspection bundles, and companion docs.
174
-
175
- Use `text2d()` only when the letters are part of the real object: raised branding, engraving, serial plates, keyboard legends, gauge ticks, connector labels, service arrows, scale markings, or exported manufacturing markings. `text2d()` builds filled sketch geometry from font outlines, so it can make exact/OCCT workflows slower.
176
-
177
- Use `Viewport.label(text, [x, y, z], options)` only for temporary review, debug, tutorial, or explicitly requested presentation views. Render labels are annotations only: they do not create meshes, do not export, do not enter the B-rep path, and do not add face labels. Do not use viewport labels to compensate for unclear geometry in the final model.
178
-
179
- ## SDF Modeling
180
-
181
- For organic shapes, smooth blending, TPMS lattices, and surface deformations. Return `SdfShape` values directly, or return a plain object/array tree of SDF leaves, for native raymarch preview. Use `.toShape()` or `toShape(...)` only when you need mesh-backed CAD/export behavior. See [sdf-primitives.md](sdf-primitives.md).
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).