forgecad 0.10.1 → 0.10.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/README.md +7 -6
- package/dist/assets/{AdminPage-DcCnj0qo.js → AdminPage-CK7ObBz3.js} +1 -1
- package/dist/assets/{BenchmarkPage-BVEpJSVk.js → BenchmarkPage-Ds7Z2doN.js} +1 -1
- package/dist/assets/{BlogPage-DHaGP50_.js → BlogPage-DlPbpt6A.js} +1 -1
- package/dist/assets/{DocsPage-CDoxHkz8.js → DocsPage-vZb3b3Y0.js} +9 -14
- package/dist/assets/{EditorApp-BpjZgzk0.css → EditorApp-C5f24ZN9.css} +8 -0
- package/dist/assets/{EditorApp-BJ0Dloyh.js → EditorApp-HLoKfe15.js} +152 -21
- package/dist/assets/{EmbedViewer-CRKZbY0y.js → EmbedViewer--KnqBKrJ.js} +3 -3
- package/dist/assets/{LandingPageProofDriven-BxHkYRE7.js → LandingPageProofDriven-C_LssmnA.js} +1 -1
- package/dist/assets/{LegalPage-B-u6FrVv.js → LegalPage-DGsyo4n1.js} +1 -1
- package/dist/assets/{PricingPage-CzpZ6-Ce.js → PricingPage-BOE27B-R.js} +1 -1
- package/dist/assets/{SettingsPage-CIZSSAd0.js → SettingsPage-f47cnk39.js} +1 -1
- package/dist/assets/{app-DaTMg3nH.js → app-D6ccu2Xx.js} +7826 -7559
- package/dist/assets/{scalar-sampling-budget-prBw_s8t.js → backendInit-DbTkQN9J.js} +87141 -78777
- package/dist/assets/cli/{render-DPf4AYJK.js → render-BsngirjC.js} +147 -186
- package/dist/assets/{constructionHistoryWorker-AwMMWSxg.js → constructionHistoryWorker-PCwXrTDB.js} +8419 -1447
- package/dist/assets/{evalWorker-CjZZWRWW.js → evalWorker-CS63PfZu.js} +25501 -17997
- package/dist/assets/{forgecad_geometry-Dgceylq9.js → forgecad_geometry-CZ_IfuvA.js} +120 -9
- package/dist/assets/forgecad_geometry_bg-C3rQHfwg.wasm +0 -0
- package/dist/assets/{inspectWorker-CZsCFtQT.js → inspectWorker-Y4cOzNyA.js} +37208 -34464
- package/dist/assets/{jointPose-DzQOViQH.js → jointPose-AMvCywzS.js} +1 -1
- package/dist/assets/{manifold-DgXo0T5P.js → manifold-CBry38ly.js} +2 -2
- package/dist/assets/{manifold-K1SkarlQ.js → manifold-Crd_F2qx.js} +1 -1
- package/dist/assets/{manifold-BYlzU521.js → manifold-k2kRcc85.js} +1 -1
- package/dist/assets/{reportWorker-B9nWwSrB.js → reportWorker-CWvn0CEv.js} +46635 -44646
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/usage.md +2 -4
- package/dist/docs-raw/CLI.md +34 -20
- package/dist/docs-raw/README.md +1 -1
- package/dist/docs-raw/component-model.md +1 -1
- package/dist/docs-raw/generated/assembly.md +2 -2
- package/dist/docs-raw/generated/concepts.md +6 -4
- package/dist/docs-raw/generated/core.md +71 -2
- package/dist/docs-raw/generated/curves.md +8 -1
- package/dist/docs-raw/generated/lib.md +1 -1
- package/dist/docs-raw/generated/output.md +0 -64
- package/dist/docs-raw/generated/runtime-names.md +6 -6
- package/dist/docs-raw/generated/sdf.md +2 -2
- package/dist/docs-raw/generated/viewport.md +3 -12
- package/dist/docs-raw/guides/inspection-bundles.md +1 -1
- package/dist/docs-raw/guides/simready-quickstart.md +3 -1
- package/dist/docs-raw/simulation-workflow.md +58 -0
- package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
- package/dist/docs-raw/skills/forgecad-image-replicator.md +2 -2
- package/dist/docs-raw/skills/forgecad-mujoco-verify.md +78 -0
- package/dist/docs-raw/skills/forgecad-spec-by-walking-through-it.md +145 -0
- package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad.md +24 -24
- package/dist/docs-raw/skills/index.md +2 -3
- package/dist/index.html +1 -1
- package/dist/sitemap.xml +15 -15
- package/dist-cli/{check-compiler-II7NLPAB.js → check-compiler-HPF2T2FS.js} +1 -1
- package/dist-cli/{check-query-propagation-7462TR3R.js → check-query-propagation-HYSLTXAB.js} +1 -1
- package/dist-cli/{chunk-UWTJCGXF.js → chunk-WLUKAW3H.js} +51134 -43247
- package/dist-cli/forgecad.js +5467 -1451
- package/dist-cli/{forgecad_geometry-QOQIIP53.js → forgecad_geometry-2IMYCUWW.js} +119 -8
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +98 -86
- package/dist-skill/SKILL.md +1 -1
- package/dist-skill/docs/API/core/concepts.md +1 -1
- package/dist-skill/docs/CLI.md +34 -20
- package/dist-skill/docs/generated/assembly.md +2 -2
- package/dist-skill/docs/generated/core.md +71 -2
- package/dist-skill/docs/generated/curves.md +8 -1
- package/dist-skill/docs/generated/lib.md +1 -1
- package/dist-skill/docs/generated/output.md +0 -64
- package/dist-skill/docs/generated/runtime-names.md +6 -6
- package/dist-skill/docs/generated/sdf.md +2 -2
- package/dist-skill/docs/generated/viewport.md +3 -12
- package/dist-skill/docs/guides/inspection-bundles.md +1 -1
- package/dist-skill/library/README.md +2 -3
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +1 -1
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +2 -2
- package/dist-skill/library/forgecad-mujoco-verify/SKILL.md +66 -0
- package/dist-skill/library/forgecad-mujoco-verify/scripts/mujoco_verify.py +385 -0
- package/dist-skill/library/forgecad-spec-by-walking-through-it/SKILL.md +132 -0
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +1 -1
- package/dist-skill/website/skills/forgecad-blockout-model.md +1 -1
- package/dist-skill/website/skills/forgecad-image-replicator.md +2 -2
- package/dist-skill/website/skills/forgecad-mujoco-verify.md +78 -0
- package/dist-skill/website/skills/forgecad-spec-by-walking-through-it.md +145 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +1 -1
- package/dist-skill/website/skills/forgecad.md +24 -24
- package/dist-skill/website/skills/index.md +2 -3
- package/examples/analysis/clearance-fit.forge.js +31 -0
- package/examples/analysis/lever-arm-actuator.forge.js +43 -0
- package/examples/analysis/tipping-tripod.forge.js +35 -0
- 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/products/sportscar.forge.js +77 -0
- package/package.json +2 -4
- package/dist/assets/forgecad_geometry_bg-dD4RNQF1.wasm +0 -0
- package/dist/assets/manifold-CzYf_iub.js +0 -3023
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +0 -101
- package/dist/docs-raw/skills/forgecad-lld.md +0 -41
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +0 -63
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +0 -94
- package/dist-skill/library/forgecad-lld/SKILL.md +0 -34
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +0 -50
- package/dist-skill/website/skills/forgecad-high-level-spec.md +0 -101
- package/dist-skill/website/skills/forgecad-lld.md +0 -41
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +0 -63
- /package/dist-skill/library/{forgecad-prepare-prompt → forgecad-spec-by-walking-through-it}/references/default-profiles.md +0 -0
- /package/dist-skill/library/{forgecad-prepare-prompt → forgecad-spec-by-walking-through-it}/references/master-prompt.md +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<!-- Generated by scripts/build-forgecad-skill.mjs — do not edit. Edit agent-skill-library/forgecad-spec-by-walking-through-it/SKILL.md instead. -->
|
|
2
|
+
|
|
3
|
+
# forgecad-spec-by-walking-through-it
|
|
4
|
+
|
|
5
|
+
Design a ForgeCAD model, mechanism, or assembly by fixing WHAT before HOW in a git-reviewed design document, validated by mentally operating the thing step by step. Covers fuzzy-request intake and process choice, high-level design (HLD), and low-level design (LLD). Use on "spec this out", "plan the design", "write the HLD/LLD", a vague build request that needs concrete decisions, or any moment the right move is a reviewable spec before code.
|
|
6
|
+
|
|
7
|
+
| Field | Value |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| Installed by | `forgecad skill install` |
|
|
10
|
+
| Source | `agent-skill-library/forgecad-spec-by-walking-through-it/SKILL.md` |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Spec by Walking Through It
|
|
15
|
+
|
|
16
|
+
The design document — a git-committed, diff-reviewed markdown file — is the source of truth. Not the code, not the chat, not your head. You iterate it by commit-and-review, and the `git diff` is the review artifact.
|
|
17
|
+
|
|
18
|
+
**Validate the design by mentally operating the thing, step by step.** Walk it as someone assembles, uses, or moves it. The step with no answer — *"how does the servo get inside the housing?"* — is the real design gap. A spec that reads complete on the page can still hide a hole that only surfaces when you try to put it together in your head. State each gap falsifiably: not "tolerances might be tight" but "the 12mm arm cantilevers under gripping load, may flex >0.5mm."
|
|
19
|
+
|
|
20
|
+
**Every number has a reason; the narrative comes before the numbers.** Describe the object as if over the phone, then derive each value and show its math: `wallThickness = 2.4mm = 6 × 0.4mm nozzle`. The design is **implementation-blind** — shaped by the object, never by what the ForgeCAD API makes easy. **Manufacturing process is one of those reasons** — a design decision you weigh, never a default you inherit (never assume FDM/printing).
|
|
21
|
+
|
|
22
|
+
**A vague request is a set of decisions you make honestly, not information to extract.** No placeholders ("appropriate motor"); choose a defensible value, show why, continue. The Decisions table fills only after user review, so the loop stays in the document.
|
|
23
|
+
|
|
24
|
+
### Altitude — three phases, one document trail
|
|
25
|
+
|
|
26
|
+
| Phase | When | Output |
|
|
27
|
+
|-------|------|--------|
|
|
28
|
+
| Intake | request is fuzzy / process unspecified | engineering brief + master prompt |
|
|
29
|
+
| HLD | design is wrong in *approach*, alternatives exist | `<name>-hld.md` |
|
|
30
|
+
| LLD | decisions locked, or a simple single-body part | `<name>-lld.md` |
|
|
31
|
+
|
|
32
|
+
The HLD carries only decision-driving dimensions and genuinely-different alternatives; the LLD carries enough that someone builds from it alone. Speccing every tolerance in an HLD, or revisiting locked decisions in an LLD, is an altitude error — back up. Simple parts skip straight from HLD to code, or from a request to an LLD.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### Phase 1 — Intake (fuzzy request → concrete brief)
|
|
37
|
+
|
|
38
|
+
Use when the user wants something physically real but the ask is vague ("make me a robot gripper", "make it production ready", "pick sensible numbers"). This phase owns intake; once the brief is concrete, continue to HLD or hand off to the `forgecad` skill.
|
|
39
|
+
|
|
40
|
+
**Manufacturing is a design decision, not a default.** Derive the process stack from artifact family, load path, scale, safety expectations, material, production intent, and operating story — never assume printing/plastic. If the user names a process, honor it but warn when it is unsafe or dishonest for the duty. Family→process anchors live in `references/default-profiles.md`.
|
|
41
|
+
|
|
42
|
+
**Default posture: manufacture-realistic prototype** — real materials, purchased-part boundaries, assembly logic, validation; no claims of production tooling or certification. Other postures only when justified: `production-realistic`, `printable`, `visual-CAD`, or a specific process posture (`sheet-metal`, `CNC-machined`, `laser-cut`, `welded-tube`, `injection-molded`, `cast`, `hybrid purchased-hardware`). Pick the posture honest for the artifact, not the easiest CAD surface.
|
|
43
|
+
|
|
44
|
+
**Family-scoped numbers.** Every starter assumption is scoped to one artifact family; never reuse numbers across families.
|
|
45
|
+
|
|
46
|
+
Workflow:
|
|
47
|
+
1. **Normalize the ask** into plain mechanism language ("6 DOF gripper" → standalone gripper, wrist+gripper, or arm+gripper).
|
|
48
|
+
2. **Build a specific operating story** — invented (non-famous) org, named program, prototype revision, review moment, mission pressure (pilot gate, demo date, investor milestone), and the generic failure mode to avoid. Prefer bold high-agency stories over modest lab exercises. Never assert the user works for a named real company; use real products only as public comparison anchors; never clone proprietary designs.
|
|
49
|
+
3. **Classify the artifact family** (`references/default-profiles.md`); use the no-family-fits escape rather than forcing one. Rideables route to human-vehicles, never chassis.
|
|
50
|
+
4. **Choose the process posture** per the taxonomy above.
|
|
51
|
+
5. **Pick qualitative levers** — duty (`light`/`general`/`sturdy`), scale (`compact`/`medium`/`large`), cost (`cheapest`/`balanced`/`performance-first`) — and translate to family-scoped starter assumptions.
|
|
52
|
+
6. **Close only critical gaps** — at most 3 grouped questions, always choice menus, never raw engineering inputs unless the architecture truly depends on them. Good: "light desk demo, useful hobby tool, or sturdier bench mechanism?" Bad: "What payload mass?"
|
|
53
|
+
7. **Write the engineering brief**: artifact + family + normalized interpretation; operating story + production reason + test setting + failure mode to avoid; output posture; intended loads, size envelope, motion/DOF; process stack + material defaults; purchased-part (BOM) boundary; validation standard; variant policy (versions are selectable params, one rendered at a time); file organization (`main.forge.js` entry for multi-file); explicit uncertainty policy.
|
|
54
|
+
8. **Emit one master prompt** — fill `references/master-prompt.md`; return the finished prompt, not notes about it. It must demand exactly `BUILD-READY` or `BEST-EFFORT BUILD CANDIDATE` (human-bearing furniture and rideables usually end the latter).
|
|
55
|
+
|
|
56
|
+
Defaults if the user stays vague: `general-duty` / `medium` / `balanced`, invent the operating story, use family starter assumptions.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Phase 2 — High-Level Design (HLD)
|
|
61
|
+
|
|
62
|
+
Aligns user and agent on *what* to build before *how*. Brevity is a readability tool, not a metric — include whatever evidence, diagrams, and dimensions a good decision needs. Write the sections top to bottom; the order is the workflow.
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
# [Name] — High-Level Design
|
|
66
|
+
|
|
67
|
+
## Problem
|
|
68
|
+
What must this do? Hard requirements (grip 40-90mm objects, fit a 60mm
|
|
69
|
+
housing, use purchased bearings). State the problem without implying a
|
|
70
|
+
solution. Unspecified process choice is an open design dimension.
|
|
71
|
+
|
|
72
|
+
## Approach
|
|
73
|
+
How it works conceptually. ASCII diagram of key elements and their
|
|
74
|
+
spatial relationships — diagram labels stay in this markdown, never
|
|
75
|
+
carried into CAD geometry unless the real artifact needs markings.
|
|
76
|
+
|
|
77
|
+
## Key Interfaces
|
|
78
|
+
Every point where this touches another part or the outside world:
|
|
79
|
+
mating surfaces, shared dimensions, coordination points. These are the
|
|
80
|
+
contracts that constrain the design.
|
|
81
|
+
|
|
82
|
+
## Dictionary
|
|
83
|
+
| Term | What it is |
|
|
84
|
+
Define every domain term in plain words, with dimensions where relevant.
|
|
85
|
+
Write for a developer without a mechanical-engineering background.
|
|
86
|
+
|
|
87
|
+
## Alternatives
|
|
88
|
+
| Option | Description | Tradeoff |
|
|
89
|
+
2-3 genuinely different strategies, not minor variations. Mark one
|
|
90
|
+
recommended and say why. If there is honestly one approach, say so.
|
|
91
|
+
|
|
92
|
+
## Usage Guide
|
|
93
|
+
Work backwards from how someone uses, assembles, or operates the thing,
|
|
94
|
+
step by step. If a step doesn't make sense ("how does the servo get
|
|
95
|
+
inside?"), flag it inline with ⚠️ and promote it to Concerns.
|
|
96
|
+
|
|
97
|
+
## Concerns
|
|
98
|
+
1. Numbered, falsifiably specific — a reviewer must be able to say "real
|
|
99
|
+
problem" or "fine, because…".
|
|
100
|
+
|
|
101
|
+
## Decisions
|
|
102
|
+
| # | Decision | Rationale |
|
|
103
|
+
Filled ONLY after user review — never pre-decide. Each row resolves a
|
|
104
|
+
concern or alternative.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Rules: if you're speccing every part, formula, and tolerance, you're writing an LLD — back up. If you can't draw it, you don't understand it yet.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### Phase 3 — Low-Level Design (LLD)
|
|
112
|
+
|
|
113
|
+
Implements the HLD's locked Decisions table; it never revisits those decisions. Simple single-body parts skip the HLD and start here. Complex assemblies split into a numbered directory: overview, global constraints, per-component files, assembly, verification.
|
|
114
|
+
|
|
115
|
+
An LLD is **narrative-first** (reads like describing the object over the phone), **authoritative** (the single source code implements), **implementation-blind**, and shows **every number's rationale**.
|
|
116
|
+
|
|
117
|
+
Required structure:
|
|
118
|
+
1. **Narrative** — what it is, how it behaves and interacts, why it exists. Concrete comparisons ("about the size of a deck of cards"); no ungrounded vague terms.
|
|
119
|
+
2. **Technical** — typed parameter table (length / angle / count / boolean / choice / ratio / clearance — design-document vocabulary, not the runtime `Param.*` API), always with units (mm, degrees default) and a rationale for every default and range; derived dimensions shown as math; geometry and constraints, each constraint with a rationale.
|
|
120
|
+
3. **Verification** — mandatory checklist: dimensional, functional, printability/process checks.
|
|
121
|
+
|
|
122
|
+
Don'ts: never open with a parameter list (story before numbers), never leave a constraint implicit, never skip verification. Completeness gate before presenting: can someone build from this alone? Does it implement every HLD decision? Is every constraint explicit with a rationale?
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Review via git
|
|
127
|
+
|
|
128
|
+
HLDs and LLDs iterate through git, not conversation:
|
|
129
|
+
- **Commit every version.** No drafts floating in chat. After writing, commit and tell the user it's ready for review.
|
|
130
|
+
- **Feedback arrives as file edits (inline comments, strikethroughs) or chat — check both.** Read `git diff`: the diff is the review artifact.
|
|
131
|
+
- **Update, commit, repeat** until the Decisions table is filled and the user says "go."
|
|
132
|
+
|
|
133
|
+
### Pipeline
|
|
134
|
+
|
|
135
|
+
| Stage | This skill's phase | Output | Next |
|
|
136
|
+
|-------|--------------------|--------|------|
|
|
137
|
+
| Explore a fuzzy ask | Intake | engineering brief + master prompt | HLD |
|
|
138
|
+
| Decide *what* to build | HLD | `*-hld.md` (Decisions filled) | LLD |
|
|
139
|
+
| Detail *how* to build | LLD | `*-lld.md` | `forgecad-make-a-model` + `forgecad` → `.forge.js` |
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## Bundled Files
|
|
143
|
+
|
|
144
|
+
- `references/default-profiles.md`
|
|
145
|
+
- `references/master-prompt.md`
|
|
@@ -15,7 +15,7 @@ Turn a concrete ForgeCAD artifact, build brief, HLD, or existing model into buil
|
|
|
15
15
|
|
|
16
16
|
### Scope
|
|
17
17
|
|
|
18
|
-
Only for artifacts already concrete enough to visualize (a specific `.forge.js` model, build brief, or HLD); route vague briefs to `forgecad-
|
|
18
|
+
Only for artifacts already concrete enough to visualize (a specific `.forge.js` model, build brief, or HLD); route vague briefs to `forgecad-spec-by-walking-through-it` first. Read minimum context — entry `.forge.js`, one key helper if it delegates geometry, brief/HLD — and capture what must survive the image model: artifact type and scale, major subassemblies, actuation style, visible mechanisms, material and color cues.
|
|
19
19
|
|
|
20
20
|
### Core Rule
|
|
21
21
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Generated by scripts/build-forgecad-skill.mjs — do not edit. Edit docs/
|
|
1
|
+
<!-- Generated by scripts/build-forgecad-skill.mjs — do not edit. Edit docs/skill/ instead. -->
|
|
2
2
|
|
|
3
3
|
# forgecad
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ ForgeCAD model authoring, editing, debugging, and execution guidance for .forge.
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| Installed by | `forgecad skill install` |
|
|
10
|
-
| Source | Generated from `docs/
|
|
10
|
+
| Source | Generated from `docs/skill/` by `scripts/build-forgecad-skill.mjs` |
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -18,9 +18,9 @@ Author or modify ForgeCAD models, sketches, assemblies, and CLI workflows. Prefe
|
|
|
18
18
|
### Workflow
|
|
19
19
|
|
|
20
20
|
1. Identify the artifact: `.forge.js`, SVG asset, or CLI/export task.
|
|
21
|
-
2. **If the model has any moving parts, load the `assembly` group and `docs/
|
|
21
|
+
2. **If the model has any moving parts, load the `assembly` group and `docs/skill/guides/joint-design.md` upfront** — do not defer the kinematic structure to a refactor pass.
|
|
22
22
|
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.
|
|
23
|
-
4. If any two parts are intended to touch or mate in the final model, load `docs/
|
|
23
|
+
4. If any two parts are intended to touch or mate in the final model, load `docs/skill/guides/positioning.md` immediately and default to connectors + `matchTo()`.
|
|
24
24
|
5. Default to a concrete first pass — easy iteration beats speculative design review.
|
|
25
25
|
6. If an existing model is broken, replace the weak structure rather than preserving bad architecture.
|
|
26
26
|
7. Validate with `forgecad run <file>` (add `--debug-imports` for import chain issues; pass `--backend manifold|occt|truck` when the backend matters).
|
|
@@ -46,77 +46,77 @@ Load groups top-to-bottom, stopping when you have what the task needs.
|
|
|
46
46
|
|
|
47
47
|
Execution model, colors, coordinate system, primitives, booleans, patterns, imports, parameters, topology, edge queries.
|
|
48
48
|
|
|
49
|
-
- `docs/
|
|
50
|
-
- `docs/
|
|
51
|
-
- `docs/
|
|
49
|
+
- `docs/skill/API/core/concepts.md`
|
|
50
|
+
- `docs/skill/generated/runtime-names.md`
|
|
51
|
+
- `docs/skill/generated/core.md`
|
|
52
52
|
|
|
53
53
|
#### 2. Static Assembly and Positioning (for any multi-part model)
|
|
54
54
|
|
|
55
55
|
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.
|
|
56
56
|
|
|
57
|
-
- `docs/
|
|
58
|
-
- `docs/
|
|
57
|
+
- `docs/skill/guides/coordinate-system.md`
|
|
58
|
+
- `docs/skill/guides/positioning.md`
|
|
59
59
|
|
|
60
60
|
#### 3. Sketch APIs
|
|
61
61
|
|
|
62
62
|
2D construction, transforms, booleans, paths, on-face sketching, extrusion, anchors, text, regions.
|
|
63
63
|
|
|
64
|
-
- `docs/
|
|
64
|
+
- `docs/skill/generated/sketch.md`
|
|
65
65
|
|
|
66
66
|
#### 4. Curves and Surfacing (for lofts, sweeps, splines)
|
|
67
67
|
|
|
68
68
|
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.
|
|
69
69
|
|
|
70
|
-
- `docs/
|
|
71
|
-
- `docs/
|
|
70
|
+
- `docs/skill/guides/surface-members.md`
|
|
71
|
+
- `docs/skill/generated/curves.md`
|
|
72
72
|
|
|
73
73
|
#### 5. Assemblies and Mechanisms (for joints or kinematics)
|
|
74
74
|
|
|
75
|
-
Assembly graph, joint types, couplings, validation,
|
|
75
|
+
Assembly graph, joint types, couplings, validation, and simulation export.
|
|
76
76
|
|
|
77
|
-
- `docs/
|
|
77
|
+
- `docs/skill/generated/assembly.md`
|
|
78
78
|
|
|
79
79
|
#### 6. Sheet Metal (for bent parts, K-factor, flat patterns)
|
|
80
80
|
|
|
81
81
|
Bend operations, flat pattern unfolding, K-factor configuration.
|
|
82
82
|
|
|
83
|
-
- `docs/
|
|
83
|
+
- `docs/skill/generated/sheet-metal.md`
|
|
84
84
|
|
|
85
85
|
#### 7. Output and Export (for STL/3MF/STEP, BOM, dimensions)
|
|
86
86
|
|
|
87
87
|
Mesh export, exact geometry export, bill of materials, dimension annotations.
|
|
88
88
|
|
|
89
|
-
- `docs/
|
|
89
|
+
- `docs/skill/generated/output.md`
|
|
90
90
|
|
|
91
91
|
#### 8. Toolbox (fasteners and standard parts)
|
|
92
92
|
|
|
93
93
|
Parametric bolts, nuts, washers, standard hardware, gears, pipes, and structural profiles.
|
|
94
94
|
|
|
95
|
-
- `docs/
|
|
96
|
-
- `docs/
|
|
95
|
+
- `docs/skill/generated/lib.md`
|
|
96
|
+
- `docs/skill/generated/wood.md`
|
|
97
97
|
|
|
98
98
|
#### 9. Runtime Viewport APIs (for cut planes, exploded views, hiding, and animation playback)
|
|
99
99
|
|
|
100
100
|
Viewer-only APIs such as cutPlane, explodeView, render labels, comparison references, and runtime display behavior.
|
|
101
101
|
|
|
102
|
-
- `docs/
|
|
102
|
+
- `docs/skill/generated/viewport.md`
|
|
103
103
|
|
|
104
104
|
#### 10. Recipes and Debugging (for patterns and troubleshooting)
|
|
105
105
|
|
|
106
106
|
Modeling patterns, debugging tactics, copyable snippets.
|
|
107
107
|
|
|
108
|
-
- `docs/
|
|
109
|
-
- `docs/
|
|
108
|
+
- `docs/skill/guides/scene-presentation.md`
|
|
109
|
+
- `docs/skill/guides/joint-design.md`
|
|
110
110
|
|
|
111
111
|
#### 11. CLI (for validation/render/export tasks)
|
|
112
112
|
|
|
113
113
|
Test-run, export pipelines, debug flags.
|
|
114
114
|
|
|
115
|
-
- `docs/
|
|
116
|
-
- `docs/
|
|
115
|
+
- `docs/skill/CLI.md`
|
|
116
|
+
- `docs/skill/guides/inspection-bundles.md`
|
|
117
117
|
|
|
118
118
|
#### SDF Modeling (smooth booleans, TPMS, deformations, fromFunction)
|
|
119
119
|
|
|
120
120
|
Primitives, smooth booleans, TPMS lattices, twist/bend/displace, morph, custom functions, gotchas. The doc preamble's precision caution applies to every SDF workflow.
|
|
121
121
|
|
|
122
|
-
- `docs/
|
|
122
|
+
- `docs/skill/generated/sdf.md`
|
|
@@ -14,13 +14,12 @@ forgecad skill install
|
|
|
14
14
|
| [forgecad-3d-reconstruction](/docs/skills/forgecad-3d-reconstruction) | `forgecad skill install` | Reconstruct a parametric ForgeCAD model from an existing 3D CAD or mesh file such as STL, OBJ, 3MF, STEP, or STP; inspect the source asset directly, author real ForgeCAD geometry, and iteratively compare the candidate with `forgecad compare 3d`. |
|
|
15
15
|
| [forgecad-blockout-model](/docs/skills/forgecad-blockout-model) | `forgecad skill install` | Create rough high-level ForgeCAD concept models from simple primitives to explore layout, proportions, motion, and part relationships without production detail. Use when asked for a quick model sketch, blockout, spatial mockup, or intuitive low-detail 3D concept. |
|
|
16
16
|
| [forgecad-component-model](/docs/skills/forgecad-component-model) | `forgecad skill install` | Enforce the ForgeCAD Component Model when building multi-part assemblies. Parts build at origin, connectors position them, data flows down from parent. Use when building or reviewing any multi-file ForgeCAD project. |
|
|
17
|
-
| [forgecad-high-level-spec](/docs/skills/forgecad-high-level-spec) | `forgecad skill install` | Write a high-level design document (HLD) for a model, mechanism, or assembly before detailed specification or coding. Use when starting a new design, rethinking an existing one, or when the user asks to spec out, plan, or think through a model at a high level. Works backwards from requirements — defines the problem, explores alternatives, records decisions. Produces a right-sized design document for review and iteration. |
|
|
18
17
|
| [forgecad-image-replicator](/docs/skills/forgecad-image-replicator) | `forgecad skill install` | Build real ForgeCAD geometry from one or more reference images by treating images as evidence, inferring the object, then validating against both reference-matched and canonical views. |
|
|
19
|
-
| [forgecad-lld](/docs/skills/forgecad-lld) | `forgecad skill install` | Write a Low-Level Design (LLD) for a CAD model — exact dimensions, constraints, parameters, and verification criteria. Use after a High-Level Design (HLD) exists and decisions are locked, or for simple parts that don't need an HLD. The detailed design document that code implements. |
|
|
20
18
|
| [forgecad-make-a-model](/docs/skills/forgecad-make-a-model) | `forgecad skill install` | Create manufacture-realistic prototype ForgeCAD (.forge.js) models in the active CAD project. Handles file placement, invokes the forgecad skill for API guidance, and validates the result. |
|
|
21
19
|
| [forgecad-model-grader](/docs/skills/forgecad-model-grader) | `forgecad skill install` | Analyze, verify, and grade ForgeCAD or CAD-as-code models against a user requirement, design brief, prompt, reference, or acceptance criteria. Use when asked to evaluate, judge, QA, benchmark, score, rate, or compare a CAD model; render it from multiple angles, run targeted inspections when needed, visually verify the evidence, and produce a 0-10 score with concise justification. |
|
|
22
|
-
| [forgecad-
|
|
20
|
+
| [forgecad-mujoco-verify](/docs/skills/forgecad-mujoco-verify) | `forgecad skill install` | Verify ForgeCAD MJCF exports in MuJoCo with real dynamics, contacts, root behavior, controls, required joint travel, and rendered evidence before calling a model simulation-ready. Use when making a ForgeCAD assembly sim-ready, debugging MJCF contacts, checking why a body falls through the floor, validating actuator motion, or proving a mechanism moved through the intended range. |
|
|
23
21
|
| [forgecad-project](/docs/skills/forgecad-project) | `forgecad skill install` | ForgeCAD project CLI workflow — creating, managing, syncing projects and files on forgecad.io. Covers init, push, pull, file operations, member management, publishing, and sharing. |
|
|
24
22
|
| [forgecad-reconstruction-benchmark](/docs/skills/forgecad-reconstruction-benchmark) | `forgecad skill install` | Solve ForgeCAD CAD reconstruction benchmark or RL episodes in a prepared workspace by rebuilding a visible reference asset as readable parametric ForgeCAD in the fixed submission path, using visual and geometric self-checks while respecting sandbox limits. |
|
|
25
23
|
| [forgecad-render-inspect](/docs/skills/forgecad-render-inspect) | `forgecad skill install` | Run and interpret ForgeCAD inspection bundles for model verification. Use when asked to inspect a ForgeCAD model, analyze an inspection bundle, validate collisions, wall thickness, connectivity, floating bodies, sections, masks, depth, normals, or Zebra stripes. |
|
|
24
|
+
| [forgecad-spec-by-walking-through-it](/docs/skills/forgecad-spec-by-walking-through-it) | `forgecad skill install` | Design a ForgeCAD model, mechanism, or assembly by fixing WHAT before HOW in a git-reviewed design document, validated by mentally operating the thing step by step. Covers fuzzy-request intake and process choice, high-level design (HLD), and low-level design (LLD). Use on "spec this out", "plan the design", "write the HLD/LLD", a vague build request that needs concrete decisions, or any moment the right move is a reviewable spec before code. |
|
|
26
25
|
| [forgecad-visual-spec](/docs/skills/forgecad-visual-spec) | `forgecad skill install` | Turn a concrete ForgeCAD artifact, build brief, HLD, or existing model into builder-honest image prompts for AI image models. Use when the user wants visual-spec renders that show the final product while keeping mechanisms, seams, hardware, and build cues visible instead of drifting into concept art. |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shaft-in-bushing clearance fit — a tolerance stack-up closed-loop demo.
|
|
3
|
+
*
|
|
4
|
+
* The diametral clearance must land in [0.10, 0.50] mm. With the default
|
|
5
|
+
* (loose) manufacturing ranges the clearance varies too much to hold that spec,
|
|
6
|
+
* so the stack-up reports a low Cpk and names the dominant dimension:
|
|
7
|
+
*
|
|
8
|
+
* 1. forgecad sim tolerance examples/analysis/clearance-fit.forge.js --json
|
|
9
|
+
* → Cpk(Clearance) well below 1.33, yield ~84%, contributions split
|
|
10
|
+
* between BoreDia and ShaftDia.
|
|
11
|
+
* 2. Act on the feedback — tighten both bores:
|
|
12
|
+
* forgecad sim tolerance examples/analysis/clearance-fit.forge.js \
|
|
13
|
+
* --tol BoreDia=±0.05 --tol ShaftDia=±0.05 --json
|
|
14
|
+
* → Cpk comfortably above 1.33, exit 0.
|
|
15
|
+
*
|
|
16
|
+
* The response is an ordinary verify.inRange call and the inputs are ordinary
|
|
17
|
+
* params — no special tolerance API is needed.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const BoreDia = Param.number('BoreDia', 10.0, { min: 9.7, max: 10.3, unit: 'mm' });
|
|
21
|
+
const ShaftDia = Param.number('ShaftDia', 9.7, { min: 9.4, max: 10.0, unit: 'mm' });
|
|
22
|
+
|
|
23
|
+
// Diametral clearance is the measured response; its spec limits come from this call.
|
|
24
|
+
const clearance = BoreDia - ShaftDia;
|
|
25
|
+
verify.inRange('Clearance', clearance, 0.1, 0.5);
|
|
26
|
+
|
|
27
|
+
const length = 20;
|
|
28
|
+
const bushing = difference(cylinder(length, BoreDia / 2 + 3), cylinder(length, BoreDia / 2));
|
|
29
|
+
const shaft = cylinder(length + 5, ShaftDia / 2).translate(0, 0, -2.5);
|
|
30
|
+
|
|
31
|
+
return union(bushing, shaft);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lever-arm actuator — a mechanism torque-budget closed-loop demo.
|
|
3
|
+
*
|
|
4
|
+
* A 1 kg arm extends horizontally from a revolute shoulder driven by a motor
|
|
5
|
+
* rated at 4 N·m. The gravity-hold torque is m·g·r, so a longer arm needs more
|
|
6
|
+
* torque to simply hold position:
|
|
7
|
+
*
|
|
8
|
+
* 1. forgecad sim mechanism examples/analysis/lever-arm-actuator.forge.js --json
|
|
9
|
+
* → holdTorqueNm.shoulder ≈ 1.47 N·m (1 kg · g · 0.15 m), ~63% budget margin.
|
|
10
|
+
* 2. Stretch the arm past the motor's reach:
|
|
11
|
+
* forgecad sim mechanism examples/analysis/lever-arm-actuator.forge.js \
|
|
12
|
+
* --param ArmLength=900 --json
|
|
13
|
+
* → ≈ 4.41 N·m needed, MECHANISM.HOLD.OVER_BUDGET — the 4 N·m motor can't hold it.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const ArmLength = Param.number('ArmLength', 300, { min: 100, max: 1000, unit: 'mm' });
|
|
17
|
+
|
|
18
|
+
const base = box(40, 40, 30)
|
|
19
|
+
.translate(0, 0, 15)
|
|
20
|
+
.withConnectors({
|
|
21
|
+
pivot: connector({ origin: [0, 0, 30], axis: [0, 1, 0], up: [1, 0, 0], kind: 'revolute' }),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// A horizontal bar from the pivot (x=0) out to +X; its center of mass sits at ArmLength/2.
|
|
25
|
+
const arm = box(ArmLength, 20, 20)
|
|
26
|
+
.translate(ArmLength / 2, 0, 0)
|
|
27
|
+
.withConnectors({
|
|
28
|
+
pivot: connector({ origin: [0, 0, 0], axis: [0, 1, 0], up: [1, 0, 0], kind: 'revolute' }),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mechanism = assembly('Lever Arm Actuator')
|
|
32
|
+
.addPart('Base', base, { sim: Sim.body({ massKg: 2.0, collider: Sim.collider.boundingBox() }) })
|
|
33
|
+
.addPart('Arm', arm, { sim: Sim.body({ massKg: 1.0, collider: Sim.collider.boundingBox() }) })
|
|
34
|
+
.connect('Base.pivot', 'Arm.pivot', {
|
|
35
|
+
as: 'shoulder',
|
|
36
|
+
type: 'revolute',
|
|
37
|
+
min: -90,
|
|
38
|
+
max: 90,
|
|
39
|
+
drive: Sim.drive.velocity({ maxTorqueNm: 4, maxSpeedRpm: 30 }),
|
|
40
|
+
})
|
|
41
|
+
.withSimulation({ rootPart: 'Base', profile: Sim.profile.robotBodyRunnable() });
|
|
42
|
+
|
|
43
|
+
return mechanism;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipping tripod head — a closed-loop stability demo.
|
|
3
|
+
*
|
|
4
|
+
* A heavy camera head sits on a mast, offset in +X over a square base. With the
|
|
5
|
+
* default base the center of mass projects just outside the support footprint,
|
|
6
|
+
* so the rig tips over. This is the model→simulate→feedback→optimize loop:
|
|
7
|
+
*
|
|
8
|
+
* 1. forgecad check stability examples/analysis/tipping-tripod.forge.js --json
|
|
9
|
+
* → STABILITY.TIPS_OVER, tipOverMarginMm ≈ -3, and a comShiftToTargetMm
|
|
10
|
+
* hint pointing in −X (move mass inboard / widen the base).
|
|
11
|
+
* 2. Act on the feedback — widen the base:
|
|
12
|
+
* forgecad check stability examples/analysis/tipping-tripod.forge.js \
|
|
13
|
+
* --param BaseSpreadMm=90 --json
|
|
14
|
+
* → stable, positive margin.
|
|
15
|
+
*
|
|
16
|
+
* forgecad sim mass on the same model reports volume, mass, center of mass, and
|
|
17
|
+
* the inertia tensor (pass --density for a real material).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const BaseSpreadMm = Param.number('BaseSpreadMm', 50, { min: 20, max: 200, unit: 'mm' });
|
|
21
|
+
const HeadOffsetMm = Param.number('HeadOffsetMm', 70, { min: 0, max: 150, unit: 'mm' });
|
|
22
|
+
|
|
23
|
+
const baseThickness = 10;
|
|
24
|
+
const mastHeight = 140;
|
|
25
|
+
|
|
26
|
+
// Square base, footprint ±BaseSpreadMm in X and Y, resting on Z=0.
|
|
27
|
+
const base = box(BaseSpreadMm * 2, BaseSpreadMm * 2, baseThickness);
|
|
28
|
+
|
|
29
|
+
// Slim mast carrying the head, offset in +X.
|
|
30
|
+
const mast = cylinder(mastHeight, 8).translate(HeadOffsetMm, 0, baseThickness);
|
|
31
|
+
|
|
32
|
+
// Heavy camera head high up and offset — this dominates the center of mass.
|
|
33
|
+
const head = box(80, 60, 60).translate(HeadOffsetMm, 0, baseThickness + mastHeight);
|
|
34
|
+
|
|
35
|
+
return union(base, mast, head);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Gyroid-diamond blend — shader-compatible TPMS fields combined in one form.
|
|
2
|
-
// Return the
|
|
2
|
+
// Return the SDF directly for implicit preview data; use toShape(...) for export tuning.
|
|
3
3
|
|
|
4
4
|
const bounds = sdf.sphere(22);
|
|
5
5
|
const gyroid = sdf.gyroid({ cellSize: 10, thickness: 1.0 });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Organic noise sculpture — natural, coral-like form
|
|
2
|
-
//
|
|
2
|
+
// Explicit meshing keeps the noisy field on the ordinary mesh preview/export path.
|
|
3
3
|
|
|
4
4
|
const shell = sdf.sphere(20).shell(4);
|
|
5
5
|
const texture = sdf.noise({ scale: 0.15, amplitude: 3, octaves: 3 });
|
package/examples/api/{sdf-custom-raymarch.forge.js → sdf-custom-field-mesh-preview.forge.js}
RENAMED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
// Custom SDF
|
|
2
|
-
// and, when shader-safe, native raymarch preview.
|
|
1
|
+
// Custom SDF implicit preview — one user-authored expression drives the field.
|
|
3
2
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Returning SdfShape directly keeps the field implicit. Call .toShape(...) when
|
|
4
|
+
// you need explicit mesh quality for CAD operations or export.
|
|
6
5
|
|
|
7
6
|
const rippledSphere = sdf.fromFunction(
|
|
8
7
|
(x, y, z, radius, frequency, amplitude) =>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Return a plain SDF tree; scene mapping keeps SDF leaves implicit.
|
|
2
2
|
|
|
3
3
|
const insert = {
|
|
4
4
|
shell: sdf.sphere(18)
|
|
@@ -9,4 +9,4 @@ const insert = {
|
|
|
9
9
|
.color('#ffcf5a'),
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
return insert;
|
|
12
|
+
return insert;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// Plain
|
|
1
|
+
// Plain SDF return: no explicit Shape, no .toShape(), no Sculpt facade.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// Direct returns stay as implicit SDF preview data; call .toShape() when you
|
|
4
|
+
// need a mesh-backed Shape for CAD operations or export.
|
|
4
5
|
|
|
5
6
|
scene(Sculpt.look('soft-studio'));
|
|
6
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// SDF
|
|
1
|
+
// SDF implicit preview — SDF leaves stay lazy until .toShape(...).
|
|
2
2
|
//
|
|
3
|
-
// Use .toShape()
|
|
3
|
+
// Use .toShape(...) when you need explicit meshing controls, CAD operations, or export.
|
|
4
4
|
|
|
5
5
|
const smoothBlob = sdf.smoothUnion(
|
|
6
6
|
sdf.sphere(12),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Native SDF surface relief — user-composed Pattern2D IR lowers to
|
|
2
|
-
//
|
|
1
|
+
// Native SDF surface relief — user-composed Pattern2D IR lowers to CPU sampling.
|
|
2
|
+
// Direct SDF returns stay implicit; call .toShape(...) for mesh-backed export.
|
|
3
3
|
|
|
4
4
|
scene({
|
|
5
5
|
background: { top: '#f6fbff', bottom: '#dfe9f3' },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Voronoi lampshade — organic cell-wall dome, open at the bottom.
|
|
2
|
-
//
|
|
2
|
+
// Explicit meshing keeps this dense field on the ordinary mesh preview/export path.
|
|
3
3
|
|
|
4
4
|
const dome = sdf.sphere(30)
|
|
5
5
|
.subtract(sdf.sphere(27))
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Sports-car body — a showcase of class-A curve-network surfacing (Surface.Net).
|
|
2
|
+
// Two Gordon surfaces compose the car: a near-closed lower body with fender
|
|
3
|
+
// bulges, and an inset fastback greenhouse. Each is thickened to a glassy shell
|
|
4
|
+
// (analytic vertex normals that survive the boolean wheel-arch cuts), then the
|
|
5
|
+
// tyres are tucked into the arches.
|
|
6
|
+
|
|
7
|
+
// Normalized body cross-section outline (right side, bottom edge -> deck centre).
|
|
8
|
+
// y is a fraction of the half-width, z a fraction of floor..deck height.
|
|
9
|
+
const BODY_OUTLINE = [
|
|
10
|
+
[0.12, 0.00], [0.60, 0.01], [0.95, 0.10], [1.00, 0.32],
|
|
11
|
+
[0.99, 0.55], [0.90, 0.78], [0.62, 0.93], [0.00, 1.00],
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
// Wrap the outline into a full closed-ish section (right bottom -> deck -> left
|
|
15
|
+
// bottom), open only along a narrow underbody seam, so the thickened shell reads
|
|
16
|
+
// as a solid body.
|
|
17
|
+
function bodySection(halfW, floorZ, topZ) {
|
|
18
|
+
const cols = [];
|
|
19
|
+
for (let i = 0; i < BODY_OUTLINE.length; i++) {
|
|
20
|
+
const [yf, zf] = BODY_OUTLINE[i];
|
|
21
|
+
cols.push([yf * halfW, floorZ + zf * (topZ - floorZ)]);
|
|
22
|
+
}
|
|
23
|
+
for (let i = BODY_OUTLINE.length - 2; i >= 0; i--) {
|
|
24
|
+
const [yf, zf] = BODY_OUTLINE[i];
|
|
25
|
+
cols.push([-yf * halfW, floorZ + zf * (topZ - floorZ)]);
|
|
26
|
+
}
|
|
27
|
+
return cols; // [y, z] columns, right-bottom -> deck -> left-bottom
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// A simpler open arch (rocker/deck edge -> spine -> other edge) for the cabin dome.
|
|
31
|
+
function archSection(halfW, baseZ, topZ) {
|
|
32
|
+
const half = 7;
|
|
33
|
+
const cols = 2 * half - 1;
|
|
34
|
+
const out = [];
|
|
35
|
+
for (let c = 0; c < cols; c++) {
|
|
36
|
+
const s = c / (cols - 1);
|
|
37
|
+
const f = 1 - Math.abs(2 * s - 1);
|
|
38
|
+
const ease = f * f * (3 - 2 * f);
|
|
39
|
+
out.push([Math.sign(0.5 - s) * halfW * Math.pow(1 - f, 0.8), baseZ + (topZ - baseZ) * ease]);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Assemble a cage from per-station section columns.
|
|
45
|
+
function cageFrom(xs, sectionAt) {
|
|
46
|
+
return xs.map((x, i) => sectionAt(i).map(([y, z]) => [x, y, z]));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ── Lower body: long & wide, fender bulges over the wheels, low deck ──────────
|
|
50
|
+
const bodyX = [0, 400, 950, 1500, 2100, 2700, 3250, 3800, 4200];
|
|
51
|
+
const deckZ = [420, 600, 690, 705, 710, 715, 730, 700, 560];
|
|
52
|
+
const floorZ = [300, 180, 150, 150, 155, 160, 165, 240, 380];
|
|
53
|
+
const fenderW = [300, 620, 880, 760, 780, 760, 890, 760, 380];
|
|
54
|
+
const body0 = Surface.Net().cage(cageFrom(bodyX, (i) => bodySection(fenderW[i], floorZ[i], deckZ[i]))).degree(3, 3);
|
|
55
|
+
let body = body0.thicken(10).color('#c01622');
|
|
56
|
+
|
|
57
|
+
// ── Greenhouse / cabin: long, low fastback set back on the deck ───────────────
|
|
58
|
+
const ghX = [1480, 1950, 2420, 2900, 3450];
|
|
59
|
+
const ghBase = [700, 706, 710, 714, 724];
|
|
60
|
+
const ghRoof = [725, 915, 975, 930, 745]; // windshield -> roof -> long backlight
|
|
61
|
+
const ghW = [560, 610, 580, 500, 330];
|
|
62
|
+
const cabin = Surface.Net().cage(cageFrom(ghX, (i) => archSection(ghW[i], ghBase[i], ghRoof[i]))).degree(3, 3);
|
|
63
|
+
body = union(body, cabin.thicken(10));
|
|
64
|
+
body = body.color('#c01622').material({ metalness: 0.55, roughness: 0.28, clearcoat: 1 });
|
|
65
|
+
|
|
66
|
+
// ── Wheel arches + tyres (tucked under the fenders) ──────────────────────────
|
|
67
|
+
const wheelR = 360;
|
|
68
|
+
const archZ = 360; // wheel centre height -> bottom near the ground, top inside the fender
|
|
69
|
+
const axleX = [1000, 3250];
|
|
70
|
+
for (const x of axleX) body = body.subtract(cylinder(2 * 980, wheelR + 30).rotateX(90).translate(x, 980, archZ));
|
|
71
|
+
|
|
72
|
+
const tyre = (x, side) =>
|
|
73
|
+
cylinder(240, wheelR).rotateX(90).translate(x, side * 740, archZ).color('#141414').material({ roughness: 0.85 });
|
|
74
|
+
const wheels = [];
|
|
75
|
+
for (const x of axleX) for (const side of [1, -1]) wheels.push(tyre(x, side));
|
|
76
|
+
|
|
77
|
+
export default group(body, ...wheels);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forgecad",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "Code-first parametric CAD for JavaScript/TypeScript, in the browser and CLI.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://forgecad.io",
|
|
@@ -204,7 +204,6 @@
|
|
|
204
204
|
"@fastify/static": "^9.0.0",
|
|
205
205
|
"@fontsource/inter": "^5.2.8",
|
|
206
206
|
"@oclif/core": "^4.11.3",
|
|
207
|
-
"@react-three/postprocessing": "^3.0.4",
|
|
208
207
|
"argon2": "^0.44.0",
|
|
209
208
|
"chokidar": "^4.0.0",
|
|
210
209
|
"clipper-lib": "^6.4.2",
|
|
@@ -213,7 +212,7 @@
|
|
|
213
212
|
"gifenc": "^1.0.3",
|
|
214
213
|
"jsonwebtoken": "^9.0.3",
|
|
215
214
|
"lz-string": "^1.5.0",
|
|
216
|
-
"manifold-3d": "^3.
|
|
215
|
+
"manifold-3d": "^3.5.1",
|
|
217
216
|
"meshoptimizer": "^1.0.1",
|
|
218
217
|
"mp4-muxer": "^5.2.1",
|
|
219
218
|
"nanoid": "^5.1.7",
|
|
@@ -224,7 +223,6 @@
|
|
|
224
223
|
"pngjs": "^7.0.0",
|
|
225
224
|
"polygon-clipping": "^0.15.7",
|
|
226
225
|
"postgres": "^3.4.8",
|
|
227
|
-
"postprocessing": "^6.39.0",
|
|
228
226
|
"prom-client": "^15.1.3",
|
|
229
227
|
"puppeteer-core": "^24.37.2",
|
|
230
228
|
"react-router-dom": "^7.13.2",
|
|
Binary file
|