forgecad 0.9.2 → 0.9.3
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/LICENSE +7 -5
- package/README.md +1 -1
- package/README.public.md +24 -2
- package/dist/assets/{AdminPage-Bs4PiK00.js → AdminPage-4jihcEk_.js} +1 -1
- package/dist/assets/{BlogPage-DVmgN0ma.js → BlogPage-BvzruKtw.js} +1 -1
- package/dist/assets/{DocsPage-BP6wlsBN.js → DocsPage-DHbd-WS-.js} +13 -13
- package/dist/assets/{EditorApp-Arw2NnGJ.js → EditorApp-C5P2rBfh.js} +433 -84
- package/dist/assets/{EditorApp-VY9lXx0N.css → EditorApp-DS0AIUrZ.css} +25 -0
- package/dist/assets/{EmbedViewer-qgQiOahL.js → EmbedViewer-B70wQwlE.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-DvhtmWOz.js → LandingPageProofDriven-DIsYTnep.js} +1 -1
- package/dist/assets/{PricingPage-Ck3CP2ti.css → PricingPage-BMedqFef.css} +48 -0
- package/dist/assets/{PricingPage-657oLvWh.js → PricingPage-YPOr12pP.js} +34 -6
- package/dist/assets/{SettingsPage-wNy3_2yn.js → SettingsPage-rntoyJ3b.js} +10 -13
- package/dist/assets/{app-BdBoMQeO.js → app-CWucmnLZ.js} +801 -1208
- package/dist/assets/cli/{render-Ci3jjyT1.js → render-DZHmUySW.js} +214 -23
- package/dist/assets/copy-CQKQppF-.js +8 -0
- package/dist/assets/{evalWorker-CMCAbK8r.js → evalWorker-C3dKxi9Y.js} +1117 -95
- package/dist/assets/{manifold-BMn-8Vf8.js → manifold-CQ3FhfWB.js} +1 -1
- package/dist/assets/{manifold-jlYQ6E5R.js → manifold-CU0G1yYL.js} +1 -1
- package/dist/assets/{manifold-DbyILno4.js → manifold-CYWZMfjB.js} +2 -2
- package/dist/assets/{renderSceneState-DAnqvxSt.js → renderSceneState-BBUrnsUN.js} +1 -1
- package/dist/assets/{reportWorker-BcRVMHK-.js → reportWorker-BhZ7DjxQ.js} +1091 -95
- package/dist/assets/{sectionPlaneMath-DXJ_TdIW.js → sectionPlaneMath-BxfokaJE.js} +1091 -95
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/usage.md +182 -89
- package/dist/docs-raw/API/core/concepts.md +26 -0
- package/dist/docs-raw/CLI.md +58 -37
- package/dist/docs-raw/INDEX.md +81 -64
- package/dist/docs-raw/cli-monetization.md +9 -8
- package/dist/docs-raw/generated/concepts.md +111 -4
- package/dist/docs-raw/generated/core.md +2 -0
- package/dist/docs-raw/generated/curves.md +480 -1
- package/dist/docs-raw/generated/output.md +1 -0
- package/dist/docs-raw/generated/sketch.md +2 -0
- package/dist/docs-raw/generated/viewport.md +81 -3
- package/dist/docs-raw/product/user-outreach-email-templates.md +159 -0
- package/dist/docs-raw/skills/forgecad-image-replicator.md +1 -1
- package/dist/docs-raw/skills/forgecad-make-a-model.md +33 -4
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +1 -1
- package/dist/docs-raw/skills/forgecad-project.md +1 -1
- package/dist/docs-raw/skills/forgecad-render-inspect.md +1 -1
- package/dist/docs-raw/skills/forgecad.md +2 -1
- package/dist/docs-raw/welcome.md +85 -137
- package/dist/index.html +1 -1
- package/dist/llms.txt +4 -3
- package/dist/sitemap.xml +6 -6
- package/dist-cli/forgecad.js +1413 -219
- package/dist-cli/forgecad.js.map +1 -1
- package/dist-skill/CONTEXT.md +594 -5
- package/dist-skill/SKILL-dev.md +2 -1
- package/dist-skill/SKILL.md +2 -1
- package/dist-skill/docs/API/core/concepts.md +26 -0
- package/dist-skill/docs/CLI.md +58 -37
- package/dist-skill/docs/generated/core.md +2 -0
- package/dist-skill/docs/generated/curves.md +480 -1
- package/dist-skill/docs/generated/output.md +1 -0
- package/dist-skill/docs/generated/sketch.md +2 -0
- package/dist-skill/docs/generated/viewport.md +81 -3
- package/dist-skill/docs-dev/API/core/concepts.md +26 -0
- package/dist-skill/docs-dev/CLI.md +58 -37
- package/dist-skill/docs-dev/generated/core.md +2 -0
- package/dist-skill/docs-dev/generated/curves.md +480 -1
- package/dist-skill/docs-dev/generated/output.md +1 -0
- package/dist-skill/docs-dev/generated/sketch.md +2 -0
- package/dist-skill/docs-dev/generated/viewport.md +81 -3
- package/dist-skill/library/README.md +0 -1
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +1 -1
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +33 -4
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
- package/dist-skill/library/forgecad-project/SKILL.md +1 -1
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +1 -1
- package/examples/api/conformal-product-ribbon.forge.js +77 -0
- package/examples/api/render-labels.forge.js +33 -0
- package/examples/api/text2d-basics.forge.js +6 -3
- package/package.json +1 -1
- package/dist-skill/library/forgecad-deep-dive/SKILL.md +0 -120
- package/dist-skill/library/forgecad-deep-dive/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-deep-dive/references/output-shape.md +0 -64
|
@@ -9,7 +9,7 @@ Cut planes, exploded views, joint animations, and scene configuration.
|
|
|
9
9
|
|
|
10
10
|
## Contents
|
|
11
11
|
|
|
12
|
-
- [Viewport & Runtime](#viewport-runtime) — `scene`, `viewConfig`, `explodeView`, `jointsView`, `cutPlane`, `mock`, `showLabels`, `highlight`
|
|
12
|
+
- [Viewport & Runtime](#viewport-runtime) — `Viewport.label`, `scene`, `viewConfig`, `explodeView`, `jointsView`, `cutPlane`, `mock`, `showLabels`, `highlight`
|
|
13
13
|
- [RouteBuilder](#routebuilder)
|
|
14
14
|
- [route](#route)
|
|
15
15
|
|
|
@@ -17,14 +17,50 @@ Cut planes, exploded views, joint animations, and scene configuration.
|
|
|
17
17
|
|
|
18
18
|
### Viewport & Runtime
|
|
19
19
|
|
|
20
|
+
#### `Viewport.label()` — Add a render-only viewport label at a world-space point.
|
|
21
|
+
|
|
22
|
+
`Viewport.label()` is for explanatory text that helps a viewer understand the model. It does not create sketches, meshes, B-rep topology, exported text, or face labels, so it stays off the OCCT path. Use [`text2d()`](/docs/sketch#text2d) only when the letters should become manufactured geometry, such as raised lettering, engraved serial numbers, or exported nameplates.
|
|
23
|
+
|
|
24
|
+
Labels are collected during script execution and rendered by the viewport as lightweight overlay annotations. They are ignored by exports and do not appear in `objects`.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
Viewport.label('Bearing bore', [0, 0, 18], {
|
|
28
|
+
color: '#f8fafc',
|
|
29
|
+
background: '#0f172acc',
|
|
30
|
+
offset: [0, 0, 8],
|
|
31
|
+
anchor: 'bottom',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return box(40, 30, 12);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
Viewport.label(text: string, at: [ number, number, number ], options?: RenderLabelOptions): void
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**`RenderLabelOptions`**
|
|
42
|
+
|
|
43
|
+
| Option | Type | Description |
|
|
44
|
+
|--------|------|-------------|
|
|
45
|
+
| `color?` | `string` | Text color as any CSS color string. |
|
|
46
|
+
| `background?` | `string` | Background color as any CSS color string. Use `'transparent'` for no pill background. |
|
|
47
|
+
| `size?` | `number` | Font size in CSS pixels. Defaults to 12. |
|
|
48
|
+
| `offset?` | `[ number, number, number ]` | Additional world-space offset from `at`. |
|
|
49
|
+
| `anchor?` | `RenderLabelAnchor` | Which point of the label box is anchored to `at`. Defaults to `'center'`. |
|
|
50
|
+
| `alwaysOnTop?` | `boolean` | When false, the label is hidden when occluded by scene geometry. Defaults to true. |
|
|
51
|
+
|
|
20
52
|
#### `scene()` — Configure the scene environment for the current script execution.
|
|
21
53
|
|
|
22
|
-
Controls camera position, lighting rig, background color or gradient, atmospheric fog, environment maps, post-processing effects, and capture parameters for the `forgecad capture` command. Multiple calls merge — later values override earlier ones on a per-key basis, so you can split configuration across multiple `scene()` calls.
|
|
54
|
+
Controls camera position, named render views, optional model journeys, lighting rig, background color or gradient, atmospheric fog, environment maps, post-processing effects, and capture parameters for the `forgecad capture` command. Multiple calls merge — later values override earlier ones on a per-key basis, so you can split configuration across multiple `scene()` calls.
|
|
23
55
|
|
|
24
56
|
When `lights` is specified, **all** default lights are removed. You must include your own ambient light or the scene will be fully dark.
|
|
25
57
|
|
|
26
58
|
Setting `camera.position` overrides auto-framing — the viewport will no longer auto-fit the geometry on script reload.
|
|
27
59
|
|
|
60
|
+
Named render views let scripts check in repeatable cameras next to the model code. The canonical shape is `{ camera: { position, target } }`, and a direct camera shorthand `{ position, target }` is also accepted. Use the canonical shape when you may add view metadata later. Use it from the CLI with `forgecad render 3d model.forge.js --view hero`.
|
|
61
|
+
|
|
62
|
+
Model journeys let scripts check in a compact guided path through named objects. Each journey has ordered `steps`; each step can name a `focus` target by object name/tree path, provide a caption, and optionally provide an explicit camera. In the viewer, journeys are opt-in: they appear as a small Explore control and do not move the camera until the user starts them. Use `forgecad run model.forge.js --journeys` or `--journeys-json` to inspect resolved targets.
|
|
63
|
+
|
|
28
64
|
Post-processing effects (`bloom`, `vignette`, `grain`) work in the browser viewport only. The CLI applies camera, lights, background, fog, and `toneMappingExposure` but skips shader effects.
|
|
29
65
|
|
|
30
66
|
All numeric values accept `param()` expressions.
|
|
@@ -33,6 +69,22 @@ All numeric values accept `param()` expressions.
|
|
|
33
69
|
scene({
|
|
34
70
|
background: { top: '#000814', bottom: '#001d3d' },
|
|
35
71
|
camera: { position: [160, -120, 100], target: [0, 0, 50], fov: 52 },
|
|
72
|
+
views: {
|
|
73
|
+
hero: {
|
|
74
|
+
camera: { position: [180, -140, 90], target: [0, 0, 25], up: [0, 0, 1], fov: 38 },
|
|
75
|
+
},
|
|
76
|
+
side: { position: [240, 0, 70], target: [0, 0, 25], fov: 34 },
|
|
77
|
+
},
|
|
78
|
+
journeys: {
|
|
79
|
+
grandTour: {
|
|
80
|
+
title: 'Grand Tour',
|
|
81
|
+
startsAt: 'overview',
|
|
82
|
+
steps: [
|
|
83
|
+
{ id: 'overview', focus: 'Solar System', caption: 'Start with the whole model.' },
|
|
84
|
+
{ id: 'earth', focus: 'Earth', caption: 'Fit and inspect Earth.' },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
36
88
|
lights: [
|
|
37
89
|
{ type: 'ambient', color: '#001233', intensity: 0.08 },
|
|
38
90
|
{ type: 'point', position: [120, -80, 130], color: '#00f5d4', intensity: 4, distance: 400, decay: 1 },
|
|
@@ -59,12 +111,38 @@ scene(options: SceneOptions): void
|
|
|
59
111
|
| Option | Type | Description |
|
|
60
112
|
|--------|------|-------------|
|
|
61
113
|
| `capture?` | `SceneCaptureConfig` | Default capture parameters for `forgecad capture` — CLI flags override these. |
|
|
62
|
-
| `background?`, `camera?`, `lights?`, `environment?`, `fog?`, `postProcessing?`, `ground?` | | — |
|
|
114
|
+
| `background?`, `camera?`, `views?`, `journeys?`, `lights?`, `environment?`, `fog?`, `postProcessing?`, `ground?` | | — |
|
|
63
115
|
|
|
64
116
|
`SceneBackgroundGradient`: `{ top: string, bottom: string }`
|
|
65
117
|
|
|
66
118
|
**`SceneCameraConfig`**: `position?: [ number, number, number ]`, `target?: [ number, number, number ]`, `up?: [ number, number, number ]`, `fov?: number`, `type?: "perspective" | "orthographic"`
|
|
67
119
|
|
|
120
|
+
**`SceneJourneyConfig`**
|
|
121
|
+
|
|
122
|
+
| Option | Type | Description |
|
|
123
|
+
|--------|------|-------------|
|
|
124
|
+
| `title?` | `string` | Viewer-facing journey title. Defaults to the journey id. |
|
|
125
|
+
| `startsAt?` | `string` | Optional starting step id. Defaults to the first step. |
|
|
126
|
+
| `behavior?` | `"opt-in" \| "auto"` | Whether the viewer should offer or auto-open the journey. First slice supports opt-in. |
|
|
127
|
+
| `steps` | `SceneJourneyStepConfig[]` | Ordered journey spine. Branches can be added later without changing this core contract. |
|
|
128
|
+
| `valid?` | `boolean` | True unless any journey or step diagnostic has level "error". |
|
|
129
|
+
| `diagnostics?` | `SceneJourneyDiagnostic[]` | Whole-journey diagnostics, including unresolved startsAt and step target diagnostics. |
|
|
130
|
+
|
|
131
|
+
**`SceneJourneyStepConfig`**
|
|
132
|
+
|
|
133
|
+
| Option | Type | Description |
|
|
134
|
+
|--------|------|-------------|
|
|
135
|
+
| `id` | `string` | Stable step id used by viewer links and Next/Back state. |
|
|
136
|
+
| `title?` | `string` | Viewer-facing title. Defaults to the step id. |
|
|
137
|
+
| `focus?` | `string` | Object name or slash-separated tree path to focus. |
|
|
138
|
+
| `caption?` | `string` | Short optional viewer caption. |
|
|
139
|
+
| `camera?` | `SceneViewCameraConfig` | Optional explicit camera for this step. When omitted, the viewer fits `focus`. |
|
|
140
|
+
| `resolvedFocusId?` | `string \| null` | Resolved object id after script execution, when `focus` matched exactly one object. |
|
|
141
|
+
| `resolvedFocusPath?` | `string \| null` | Resolved object tree path or name after script execution. |
|
|
142
|
+
| `diagnostics?` | `SceneJourneyDiagnostic[]` | Resolution diagnostics for this step. |
|
|
143
|
+
|
|
144
|
+
`SceneJourneyDiagnostic`: `{ level: SceneJourneyDiagnosticLevel, message: string, stepId?: string, suggestions?: string[] }`
|
|
145
|
+
|
|
68
146
|
**`SceneLightConfig`**
|
|
69
147
|
|
|
70
148
|
| Option | Type | Description |
|
|
@@ -11,7 +11,6 @@ The installed skill names are namespaced to avoid collisions with a user's exist
|
|
|
11
11
|
- `forgecad-api-dogfood`
|
|
12
12
|
- `forgecad-blockout-model`
|
|
13
13
|
- `forgecad-component-model`
|
|
14
|
-
- `forgecad-deep-dive`
|
|
15
14
|
- `forgecad-high-level-spec`
|
|
16
15
|
- `forgecad-image-replicator`
|
|
17
16
|
- `forgecad-lld`
|
|
@@ -54,7 +54,7 @@ Reference matching is a validation step after the object exists.
|
|
|
54
54
|
- validation views and inspection channels
|
|
55
55
|
|
|
56
56
|
4. Choose the modeling structure.
|
|
57
|
-
Use a multi-file `main.forge.js` project when the object has distinct parts, repeated feature families, internals, purchased hardware, variants, or meaningful manufacturing assumptions.
|
|
57
|
+
Use a multi-file `main.forge.js` project when the object has distinct parts, repeated feature families, internals, purchased hardware, variants, or meaningful manufacturing assumptions. Put renderable/importable parts and sub-assemblies in neighboring `.forge.js` files; keep only pure dimensions, materials, math helpers, and lookup tables in plain `.js` files.
|
|
58
58
|
|
|
59
59
|
5. Build a coarse 3D blockout.
|
|
60
60
|
Model the object, not the image. Start with the large volumes, axes, symmetry, side depth, rear form, underside, and hidden continuations. Render canonical views before doing reference-camera comparison.
|
|
@@ -15,7 +15,8 @@ All new `.forge.js` files go under the date-based directory structure:
|
|
|
15
15
|
```
|
|
16
16
|
YYYY/MM/DD/file.forge.js — single-file model
|
|
17
17
|
YYYY/MM/DD/folder/main.forge.js — multi-file project entry point
|
|
18
|
-
YYYY/MM/DD/folder/*.js
|
|
18
|
+
YYYY/MM/DD/folder/parts/*.forge.js — standalone/importable model parts
|
|
19
|
+
YYYY/MM/DD/folder/lib/*.js — pure helpers/constants only, no geometry return
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
Use today's date for the directory. Use the user's current ForgeCAD project when one is available; otherwise use a clearly named local model folder.
|
|
@@ -25,8 +26,9 @@ Use today's date for the directory. Use the user's current ForgeCAD project when
|
|
|
25
26
|
- Use kebab-case for file and folder names: `parametric-lego.forge.js`
|
|
26
27
|
- Use descriptive names that communicate what the model is
|
|
27
28
|
- For any multi-file project, name the runnable ForgeCAD entry point `main.forge.js`
|
|
28
|
-
-
|
|
29
|
-
-
|
|
29
|
+
- Put renderable/importable parts and sub-assemblies in separate `.forge.js` files when splitting is justified; each should be standalone-runnable and importable with `require('./parts/name.forge.js', params)`.
|
|
30
|
+
- Use plain `.js` files only for pure constants, math helpers, tables, or formatting code that does not construct and return ForgeCAD geometry.
|
|
31
|
+
- Do not create multiple `.forge.js` files merely for organization; split only for reusable parts, large self-contained components, or independent sub-assemblies.
|
|
30
32
|
|
|
31
33
|
## Workflow
|
|
32
34
|
|
|
@@ -34,12 +36,13 @@ Use today's date for the directory. Use the user's current ForgeCAD project when
|
|
|
34
36
|
2. Create the directory — `mkdir -p YYYY/MM/DD/[folder]` as needed.
|
|
35
37
|
3. Write the model — create the `.forge.js` file(s) following ForgeCAD conventions:
|
|
36
38
|
- Declare `param()` / `boolParam()` for all tunable dimensions
|
|
37
|
-
- If the model is split across files, use `main.forge.js` as the
|
|
39
|
+
- If the model is split across files, use `main.forge.js` as the primary entry point, import renderable parts from neighboring `.forge.js` files, and keep only pure helpers/constants in plain `.js` modules
|
|
38
40
|
- When there are multiple versions of the same object, expose the version as a choice parameter and render one selected version at a time
|
|
39
41
|
- Use clear variable names
|
|
40
42
|
- Build any implied internal structure as real geometry, even when it will be hidden in the final view
|
|
41
43
|
- Make final mating geometry physically plausible: parts may touch, clear each other, or be boolean-joined, but should not unintentionally pass through each other
|
|
42
44
|
- Return the final geometry (single shape, array, or named objects array)
|
|
45
|
+
- Avoid expensive global edge treatment on repeated decorative geometry: do not call `fillet(shape, r)` or `chamfer(shape, r)` on every edge of large unioned/repeated parts unless the render/run loop proves it is fast enough. Prefer simpler primitive profiles, lower segment counts, or targeted edge selectors.
|
|
43
46
|
4. Validate — run `forgecad run <file>` to check for errors. For multi-file projects, always validate `main.forge.js`.
|
|
44
47
|
5. Verify geometry — render the result and run `forgecad render inspect` with the relevant channels for the task (see Render-Verify Loop below). For multi-file projects, render and inspect `main.forge.js`.
|
|
45
48
|
|
|
@@ -289,6 +292,32 @@ scene({
|
|
|
289
292
|
});
|
|
290
293
|
```
|
|
291
294
|
|
|
295
|
+
### Named render views
|
|
296
|
+
|
|
297
|
+
For models that need repeatable review, docs, or hero renders, declare named views inside
|
|
298
|
+
`scene({ views })`. The canonical form wraps each camera in `{ camera: ... }`; direct camera
|
|
299
|
+
shorthand is accepted by the runtime, but the wrapped form is the clearest prompt/example shape.
|
|
300
|
+
|
|
301
|
+
```js
|
|
302
|
+
scene({
|
|
303
|
+
camera: { position: [430, -540, 340], target: [0, 30, 125], fov: 38 },
|
|
304
|
+
views: {
|
|
305
|
+
hero: {
|
|
306
|
+
camera: { position: [430, -540, 340], target: [0, 30, 125], up: [0, 0, 1], fov: 38 },
|
|
307
|
+
},
|
|
308
|
+
side: {
|
|
309
|
+
camera: { position: [700, 0, 180], target: [0, 30, 100], up: [0, 0, 1], fov: 32 },
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Render one later with:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
forgecad render 3d model.forge.js --view hero
|
|
319
|
+
```
|
|
320
|
+
|
|
292
321
|
### Lighting principles
|
|
293
322
|
|
|
294
323
|
- When `lights` is set, all defaults are replaced, so always include an ambient light or the scene goes black.
|
|
@@ -157,7 +157,7 @@ By the end of this skill, there should be:
|
|
|
157
157
|
- purchased-part boundary
|
|
158
158
|
- validation standard
|
|
159
159
|
- variant-selection policy when multiple versions of the same object are requested
|
|
160
|
-
- file-organization policy: if the implementation needs multiple files, the runnable ForgeCAD entry point must be `main.forge.js
|
|
160
|
+
- file-organization policy: if the implementation needs multiple files, the runnable ForgeCAD entry point must be `main.forge.js`; renderable parts/sub-assemblies belong in neighboring `.forge.js` files, while plain `.js` files are only for pure helpers/constants
|
|
161
161
|
- explicit uncertainty policy
|
|
162
162
|
|
|
163
163
|
8. Emit one master prompt.
|
|
@@ -8,7 +8,7 @@ forgecad-public: true
|
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
11
|
-
**forgecad.io** is the primary platform for ForgeCAD projects. The CLI is the main way AI agents interact with it — creating projects, managing files, publishing models, and collaborating. `forgecad studio <project-path> [project-path ...]`
|
|
11
|
+
**forgecad.io** is the primary platform for ForgeCAD projects. The CLI is the main way AI agents interact with it — creating projects, managing files, publishing models, and collaborating. `forgecad studio <project-path> [project-path ...]` opens the installed local editor for users; `forgecad dev <project-path> [project-path ...]` is mainly for ForgeCAD source development.
|
|
12
12
|
|
|
13
13
|
## Authentication
|
|
14
14
|
|
|
@@ -38,7 +38,7 @@ Routing:
|
|
|
38
38
|
Use `/tmp/<model-name>-inspect` by default so generated PNGs do not dirty the repo. Use a project output directory only when the user wants a persistent artifact.
|
|
39
39
|
|
|
40
40
|
3. Pick the channel set.
|
|
41
|
-
Use the table below. Prefer small targeted channel sets;
|
|
41
|
+
Use the table below. Prefer small targeted channel sets; broad stress checks should still list explicit channels.
|
|
42
42
|
|
|
43
43
|
4. Run the command.
|
|
44
44
|
In the ForgeCAD repo, prefer the built CLI when you want the current checkout:
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformal product ribbon: a razor-style handle with a metal insert and
|
|
3
|
+
* overmold strips that follow the product skin instead of floating as flat bars.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
Product.scenePreset('product');
|
|
7
|
+
|
|
8
|
+
viewConfig({
|
|
9
|
+
camera: { position: [78, -180, 88], target: [0, 0, 58], fov: 31 },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const charcoal = Product.materials.mattePlastic('#2b3033');
|
|
13
|
+
const satin = Product.materials.brushedSteel({ color: '#c6c9c9' });
|
|
14
|
+
const rubber = Product.materials.softRubber({ color: '#14191b' });
|
|
15
|
+
|
|
16
|
+
const handle = Product.skin('asymmetric-razor-handle-skin')
|
|
17
|
+
.axis('Z')
|
|
18
|
+
.stations([
|
|
19
|
+
Product.station('flared-butt').at([0, 0, 0]).superEllipse(18, 13, { exponent: 2.7, segments: 88 }),
|
|
20
|
+
Product.station('rear-hook').at([-1.5, 0.5, 18]).superEllipse(20, 14.5, { exponent: 3.1, segments: 96 }),
|
|
21
|
+
Product.station('palm-swell').at([1.2, -0.4, 55]).superEllipse(24, 17.5, { exponent: 3.35, segments: 104 }),
|
|
22
|
+
Product.station('pinch-waist').at([0.6, 0.2, 86]).superEllipse(16.5, 12.5, { exponent: 2.9, segments: 88 }),
|
|
23
|
+
Product.station('neck').at([0, 0, 118]).superEllipse(12.5, 9.5, { exponent: 2.5, segments: 80 }),
|
|
24
|
+
])
|
|
25
|
+
.refs({
|
|
26
|
+
'spine-start': { side: 'bottom', u: 0.5, v: 0.08 },
|
|
27
|
+
'spine-end': { side: 'bottom', u: 0.5, v: 0.94 },
|
|
28
|
+
})
|
|
29
|
+
.material(charcoal)
|
|
30
|
+
.edgeLength(1.7)
|
|
31
|
+
.build();
|
|
32
|
+
|
|
33
|
+
const metalSpine = Product.ribbon('brushed-metal-weight-spine')
|
|
34
|
+
.on(handle, [handle.ref('spine-start'), handle.ref('spine-end')])
|
|
35
|
+
.width(6.4)
|
|
36
|
+
.thickness(0.72)
|
|
37
|
+
.offset(0.22)
|
|
38
|
+
.samples(28)
|
|
39
|
+
.widthSamples(7)
|
|
40
|
+
.material(satin)
|
|
41
|
+
.build();
|
|
42
|
+
|
|
43
|
+
const leftGrip = handle
|
|
44
|
+
.surface('left')
|
|
45
|
+
.ribbon('left-conformal-tpe-grip', [
|
|
46
|
+
{ u: 0.3, v: 0.18 },
|
|
47
|
+
{ u: 0.34, v: 0.48 },
|
|
48
|
+
{ u: 0.32, v: 0.78 },
|
|
49
|
+
])
|
|
50
|
+
.width(5.8)
|
|
51
|
+
.thickness(0.9)
|
|
52
|
+
.offset(0.75)
|
|
53
|
+
.samples(24)
|
|
54
|
+
.widthSamples(5)
|
|
55
|
+
.material(rubber)
|
|
56
|
+
.build();
|
|
57
|
+
|
|
58
|
+
const rightGripFeature = Product.surface(handle, 'right')
|
|
59
|
+
.ribbon('right-conformal-tpe-grip', [
|
|
60
|
+
{ u: 0.7, v: 0.18 },
|
|
61
|
+
{ u: 0.66, v: 0.48 },
|
|
62
|
+
{ u: 0.68, v: 0.78 },
|
|
63
|
+
])
|
|
64
|
+
.width(5.8)
|
|
65
|
+
.thickness(0.9)
|
|
66
|
+
.offset(0.75)
|
|
67
|
+
.samples(24)
|
|
68
|
+
.widthSamples(5)
|
|
69
|
+
.material(rubber)
|
|
70
|
+
.buildWithDiagnostics();
|
|
71
|
+
|
|
72
|
+
return group(
|
|
73
|
+
{ name: 'handle-skin', shape: handle.toShape() },
|
|
74
|
+
{ name: 'metal-spine', shape: metalSpine },
|
|
75
|
+
{ name: 'left-grip', shape: leftGrip },
|
|
76
|
+
{ name: 'right-grip', shape: rightGripFeature.shape },
|
|
77
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewport.label — viewport-only annotations.
|
|
3
|
+
*
|
|
4
|
+
* Use Viewport.label() for explanatory text that should help the viewer understand
|
|
5
|
+
* the model but should not become manufactured geometry. Use text2d() only for
|
|
6
|
+
* raised, engraved, cut, or exported text.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const base = box(70, 40, 6).color('#64748b');
|
|
10
|
+
const tower = cylinder(34, 8).translate(0, 0, 6).color('#38bdf8');
|
|
11
|
+
const arm = box(50, 8, 8).translate(0, 0, 44).color('#f59e0b');
|
|
12
|
+
|
|
13
|
+
Viewport.label('base plate', [-28, -16, 9], {
|
|
14
|
+
color: '#f8fafc',
|
|
15
|
+
background: '#0f172acc',
|
|
16
|
+
anchor: 'bottom-left',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
Viewport.label('non-exported viewport label', [0, 0, 47], {
|
|
20
|
+
color: '#fde68a',
|
|
21
|
+
background: '#1f2937dd',
|
|
22
|
+
size: 14,
|
|
23
|
+
anchor: 'bottom',
|
|
24
|
+
offset: [0, 0, 6],
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
Viewport.label('geometry stays simple', [27, 0, 44], {
|
|
28
|
+
color: '#d1fae5',
|
|
29
|
+
background: '#064e3bcc',
|
|
30
|
+
anchor: 'left',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return { base, tower, arm };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* text2d — first-class text geometry examples.
|
|
3
3
|
*
|
|
4
|
-
* Demonstrates
|
|
5
|
-
* text with other
|
|
4
|
+
* Demonstrates text that becomes real geometry: raised labels, engraved text,
|
|
5
|
+
* centred badges, and combining text with other solids.
|
|
6
|
+
*
|
|
7
|
+
* For explanatory viewport-only labels, use Viewport.label() instead. text2d()
|
|
8
|
+
* creates sketch geometry and can slow exact/OCCT workflows.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
// 1. Simple extruded nameplate ─────────────────────────────────────────────
|
|
9
12
|
const nameplate = text2d('FORGE CAD', { size: 8 }).extrude(1.5);
|
|
10
13
|
|
|
11
|
-
// 2. Centred
|
|
14
|
+
// 2. Centred badge text as physical geometry ────────────────────────────────
|
|
12
15
|
const badge = text2d('V 2.0', {
|
|
13
16
|
size: 5,
|
|
14
17
|
align: 'center',
|
package/package.json
CHANGED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: forgecad-deep-dive
|
|
3
|
-
description: Create a linked folder of concept one-pagers that deconstruct a ForgeCAD idea, architecture area, scientific concept, competitor capability, or future feature into a recursive concept tree. Use when the user wants a deep dive, concept book, walkthrough folder, architecture explainer, state-of-the-art analysis, or future-facing capability teardown saved under docs/temporary/projects/ or in Obsidian.
|
|
4
|
-
forgecad-public: true
|
|
5
|
-
forgecad-docs: false
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# ForgeCAD Deep Dive
|
|
9
|
-
|
|
10
|
-
Create a durable deep-dive folder that helps a reader internalize one idea by walking from the thesis down to its irreducible concepts.
|
|
11
|
-
|
|
12
|
-
This skill is for understanding, not for shipping code directly. The deliverable is a linked set of notes that makes one concept feel obvious after reading, especially when the topic spans architecture, geometry, science, manufacturing, or competitor workflows.
|
|
13
|
-
|
|
14
|
-
## Distinct Intent
|
|
15
|
-
|
|
16
|
-
- Use this skill when the user wants a multi-page concept tree, not a single page.
|
|
17
|
-
- If the user only wants one short narrative memo, use `concept-one-pager` instead.
|
|
18
|
-
- If the user wants implementation design without the teaching artifact, use `forgecad-high-level-spec` or `design-doc`.
|
|
19
|
-
- If the user wants brainstorming or pushback before writing, use `nonaction` or `discuss`.
|
|
20
|
-
|
|
21
|
-
## Output Contract
|
|
22
|
-
|
|
23
|
-
1. Choose the artifact location.
|
|
24
|
-
Default to `docs/temporary/projects/YYYY/MM/DD/<slug>/`.
|
|
25
|
-
Only write into Obsidian when the user explicitly asks for it or provides a vault path.
|
|
26
|
-
2. Create `INDEX.md`.
|
|
27
|
-
Start with a short thesis paragraph, then show the concept tree and suggested reading order.
|
|
28
|
-
3. Create a linked set of concept notes.
|
|
29
|
-
The usual range is 5-12 notes.
|
|
30
|
-
Each note should cover one pure concept and link to its parent and children.
|
|
31
|
-
4. Keep each note narrative-first.
|
|
32
|
-
The main body should read like a concept one-pager.
|
|
33
|
-
Put examples, sources, code references, and neighboring-note links in an appendix.
|
|
34
|
-
5. Add `appendix/sources.md`.
|
|
35
|
-
Use primary sources whenever possible.
|
|
36
|
-
If a claim is inferred from public evidence rather than explicitly stated, label it as an inference.
|
|
37
|
-
6. When the topic touches ForgeCAD, add `appendix/forgecad-code-map.md` or an equivalent file that maps the concept back to concrete repo files, current limitations, and leverage points.
|
|
38
|
-
|
|
39
|
-
Before drafting, read [references/output-shape.md](references/output-shape.md).
|
|
40
|
-
|
|
41
|
-
## Workflow
|
|
42
|
-
|
|
43
|
-
1. Frame the root question.
|
|
44
|
-
State what the user is actually trying to understand and why it matters.
|
|
45
|
-
2. Find the central thesis.
|
|
46
|
-
The entire folder should orbit one claim, not a bag of notes.
|
|
47
|
-
3. Decompose the thesis into a concept tree.
|
|
48
|
-
Start with 3-6 first-order concepts.
|
|
49
|
-
Recurse only where a child concept is still too impure or overloaded.
|
|
50
|
-
4. Gather evidence from both sides of the problem.
|
|
51
|
-
For ForgeCAD topics, read the relevant local code and docs.
|
|
52
|
-
For competitor or industry topics, verify temporally unstable claims on the internet and prefer official docs, product pages, release notes, standards, or research papers.
|
|
53
|
-
5. Draft the notes from top to bottom.
|
|
54
|
-
Write the root thesis first, then the foundational notes, then the downstream implications.
|
|
55
|
-
6. Link the notes.
|
|
56
|
-
The reader should always know what concept a note depends on and where to go next.
|
|
57
|
-
7. Close with implications.
|
|
58
|
-
If the topic is external or competitive, end with what ForgeCAD should learn, copy, reject, or build.
|
|
59
|
-
|
|
60
|
-
## Writing Rules
|
|
61
|
-
|
|
62
|
-
- One concept per note.
|
|
63
|
-
- The main body should be mostly paragraphs, not bullets.
|
|
64
|
-
- Explain the plain-language version before introducing specialized vocabulary.
|
|
65
|
-
- Keep the note short enough that a motivated reader can finish it in one sitting.
|
|
66
|
-
- Avoid changelog language. The goal is understanding, not event reporting.
|
|
67
|
-
- If you include comparisons, separate direct evidence from your inference.
|
|
68
|
-
- Be explicit about uncertainty when public material is incomplete.
|
|
69
|
-
|
|
70
|
-
## Quality Bar
|
|
71
|
-
|
|
72
|
-
A good deep dive leaves the reader with:
|
|
73
|
-
|
|
74
|
-
- a clear root thesis,
|
|
75
|
-
- a believable decomposition into smaller ideas,
|
|
76
|
-
- a sense of what is proven versus inferred,
|
|
77
|
-
- a practical bridge back to ForgeCAD,
|
|
78
|
-
- and a folder they can revisit later without needing the original conversation.
|
|
79
|
-
|
|
80
|
-
If the folder reads like notes from a research sprint instead of a teachable walkthrough, rewrite it.
|
|
81
|
-
|
|
82
|
-
## Common Patterns
|
|
83
|
-
|
|
84
|
-
- Competitor teardown:
|
|
85
|
-
Explain the public model, the likely internal architecture, the user-visible constraints, and the implications for ForgeCAD.
|
|
86
|
-
- Future feature deep dive:
|
|
87
|
-
Explain what the feature is, what abstractions it needs, what the hard parts really are, and what a staged roadmap should look like.
|
|
88
|
-
- Science concept deep dive:
|
|
89
|
-
Isolate the math or geometry concepts until each note has one job.
|
|
90
|
-
- Repo architecture deep dive:
|
|
91
|
-
Tie every major concept back to the current codebase and make the missing abstractions obvious.
|
|
92
|
-
|
|
93
|
-
## Deliverable Shape
|
|
94
|
-
|
|
95
|
-
Use a shape like this unless the topic strongly suggests a different tree:
|
|
96
|
-
|
|
97
|
-
```text
|
|
98
|
-
<slug>/
|
|
99
|
-
├── INDEX.md
|
|
100
|
-
├── 00-thesis.md
|
|
101
|
-
├── 10-<cluster>/
|
|
102
|
-
│ ├── 11-<concept>.md
|
|
103
|
-
│ └── 12-<concept>.md
|
|
104
|
-
├── 20-<cluster>/
|
|
105
|
-
│ └── ...
|
|
106
|
-
└── appendix/
|
|
107
|
-
├── sources.md
|
|
108
|
-
└── forgecad-code-map.md
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Use numbered prefixes so the notes are readable both as a graph and as a linear path.
|
|
112
|
-
|
|
113
|
-
## Final Check
|
|
114
|
-
|
|
115
|
-
Ask these questions before you stop:
|
|
116
|
-
|
|
117
|
-
- Would a new teammate understand the idea from the folder alone?
|
|
118
|
-
- Did I split overloaded notes into purer concepts?
|
|
119
|
-
- Are the most important public claims verified and dated where needed?
|
|
120
|
-
- Does the folder make a concrete difference to ForgeCAD, not just summarize a competitor?
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Output Shape
|
|
2
|
-
|
|
3
|
-
Use this reference before drafting the deep-dive folder.
|
|
4
|
-
|
|
5
|
-
## Folder skeleton
|
|
6
|
-
|
|
7
|
-
```text
|
|
8
|
-
docs/temporary/projects/YYYY/MM/DD/<slug>/
|
|
9
|
-
├── INDEX.md
|
|
10
|
-
├── 00-thesis.md
|
|
11
|
-
├── 10-<cluster>/
|
|
12
|
-
│ ├── 11-<concept>.md
|
|
13
|
-
│ └── 12-<concept>.md
|
|
14
|
-
├── 20-<cluster>/
|
|
15
|
-
│ └── ...
|
|
16
|
-
└── appendix/
|
|
17
|
-
├── sources.md
|
|
18
|
-
└── forgecad-code-map.md
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## INDEX.md
|
|
22
|
-
|
|
23
|
-
`INDEX.md` is the navigation surface, not just a title page.
|
|
24
|
-
|
|
25
|
-
Include:
|
|
26
|
-
|
|
27
|
-
- one short thesis paragraph,
|
|
28
|
-
- the concept tree,
|
|
29
|
-
- one or two recommended reading paths,
|
|
30
|
-
- links to the appendix files,
|
|
31
|
-
- a short note on source posture if the topic mixes verified facts and inference.
|
|
32
|
-
|
|
33
|
-
## Concept note template
|
|
34
|
-
|
|
35
|
-
Use this template for each concept page:
|
|
36
|
-
|
|
37
|
-
```markdown
|
|
38
|
-
# <Concept Title>
|
|
39
|
-
|
|
40
|
-
<A few clean paragraphs that explain one concept from first principles.>
|
|
41
|
-
|
|
42
|
-
## Appendix
|
|
43
|
-
|
|
44
|
-
- Parent: <link or none>
|
|
45
|
-
- Children: <links>
|
|
46
|
-
- ForgeCAD anchors: <repo files, docs, or APIs>
|
|
47
|
-
- Primary sources: <URLs or local artifacts>
|
|
48
|
-
- Inference notes: <what was inferred rather than directly stated>
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Writing standard
|
|
52
|
-
|
|
53
|
-
- Keep the main body narrative-first.
|
|
54
|
-
- Do not let the appendix become larger than the explanation.
|
|
55
|
-
- Prefer a few high-signal sources over a noisy dump.
|
|
56
|
-
- Use concrete product or code examples only when they clarify the concept.
|
|
57
|
-
- End external analyses with a concrete implication for ForgeCAD.
|
|
58
|
-
|
|
59
|
-
## What to avoid
|
|
60
|
-
|
|
61
|
-
- Changelog summaries.
|
|
62
|
-
- A giant report pasted into one file.
|
|
63
|
-
- Notes that each cover three or four ideas at once.
|
|
64
|
-
- Hiding uncertainty. If a conclusion is inferred, say so.
|