dsh-cad 0.2.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,190 +1,235 @@
1
- # dsh-cad — CAD Plugin for DeepSeek Harness
2
-
3
- ![dsh-cad banner](docs/img/banner.svg)
4
-
5
- [![homepage](https://img.shields.io/badge/homepage-dsh--cad-4D6BFE)](https://lau-mars.github.io/dsh-cad/)
6
- [![dsh plugin](https://img.shields.io/badge/dsh-plugin-4D6BFE)](https://github.com/deepseek-ai/deepseek-harness)
7
- [![Node](https://img.shields.io/badge/node-%3E%3D%2022-4D6BFE)](https://nodejs.org/)
8
- [![OCCT](https://img.shields.io/badge/kernel-OCCT-4D6BFE)](https://github.com/donalffons/opencascade.js)
9
- [![License: MIT](https://img.shields.io/badge/license-MIT-4D6BFE)](./LICENSE)
10
-
11
- English | [简体中文](./README.zh-CN.md)
12
-
13
- A CAD plugin for [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness):
14
- an **embedded 3D/2D CAD viewer** plus a **native parametric modeling tool family**
15
- (OCCT kernel) in the Web UI, letting the agent build and inspect CAD geometry
16
- step by step "model while you watch".
17
-
18
- ## Preview
19
-
20
- The CAD editor at startup: the demo L-bracket parsed from the packaged
21
- `demo-bracket.brep` by OCCT face + edge rendering, hover measurement of the
22
- picked face (4,800 mm²), a ViewCube navigation cube in the corner, and
23
- switchable demo parts (bracket / flange / shaft):
24
-
25
- ![dsh-cad CAD editor](docs/img/bracket-preview.png)
26
-
27
- ## Feature Overview
28
-
29
- | Capability | Description |
30
- | --- | --- |
31
- | 🔍 CAD viewing | STL / OBJ / STEP / IGES / BREP / DCPRT (3D), DXF / SVG (2D); interactive in-chat card (orbit / zoom / wireframe / pan) |
32
- | 🧭 CAD editor interactions | Onshape-style ViewCube (26-zone click-to-orient), hover/click face & edge picking with live measurement (area mm² / length mm), Faces+Edges / Faces / Wireframe render modes, switchable BRep demo parts (bracket / flange / shaft) |
33
- | 🏗️ Parametric modeling | Primitives (box/cylinder/sphere/cone/torus), profile extrusion, booleans (fuse/cut/common), all-edge fillet, transforms (translate/rotate/mirror) exact OCCT BRep, not a mesh approximation |
34
- | 🗂️ Codex-style document tabs | The resident display panel gets a tab strip with a "+" menu: **Part** (Part Studio, the default) / **Assembly** (instance insert/move/remove) / **Drawing** (true hidden-line sheets); tabs are closable and keep their state |
35
- | 📐 Engineering drawings | GB first-angle layout: front / top / left views + isometric, mesh-projected hidden-line removal (dashed), sheet frame, title block, overall dimensions, standard scale series; exports SVG / DXF |
36
- | 📐 Geometry measurement | Exact volume (mm³), bounding box, triangle counts, DXF layers |
37
- | 📤 On-demand export | STEP (parametric) / STL (mesh); files are written only when the user asks |
38
- | 🖥️ Resident CAD panel | A permanent panel right of the conversation: Codex-style tabs (Part / Assembly / Drawing), tracking the latest model in real time while modeling |
39
- | Zero-copy render pipeline | worker mesh in-memory binary three.js typed arrays; zero base64 / zero intermediate files / zero per-step disk writes |
40
- | 💾 Modeling document persistence | Operation log (JSON) + debounced disk mirror; automatically replayed to restore state after a process restart |
41
- | 🖼️ Image profile | PNG sketch/screenshot Otsu binarization contour tracing extrusion-ready polygon (`cad_image_profile`) |
42
- | 🔌 FreeCAD executor | Run the same op family on an external FreeCAD console (STEP in/out); requires a local FreeCAD install |
43
-
44
- ## Installation (dev mode)
45
-
46
- ```sh
47
- git clone https://github.com/LAU-MARS/dsh-cad.git
48
- cd dsh-cad
49
- npm install && npm run build && npm test
50
-
51
- npm install -g @deepseek-ai/dsh@^0.1.1-rc.2 pnpm # requires Node ≥ 22
52
- dsh web # let the first launch init the profile, then Ctrl-C
53
-
54
- dsh plugin --profile web add /path/to/dsh-cad
55
-
56
- # append to ~/.dsh/profiles/web/cordis.patch.yml:
57
- # - insert:
58
- # - id: dsh-cad
59
- # name: 'dsh-cad'
60
-
61
- dsh web
62
- ```
63
-
64
- ### Version requirements
65
-
66
- - **Node.js** ≥ 22
67
- - **dsh CLI** (`@deepseek-ai/dsh`): this plugin is developed against **0.1.0-rc.7**
68
- (minimum supported version, declared in the `engines` field of `package.json`);
69
- recommended **≥ 0.1.1-rc.2** (verified 2026-08-31)
70
-
71
- Set `DEEPSEEK_API_KEY` and you are ready for example:
72
-
73
- - “open bracket.stl” → `cad_view`
74
- - “model a 100×60×5 plate, punch a ⌀20 hole in the middle, R2 fillets on the four
75
- corners, add a ⌀16 boss 20 tall, export plate.step”
76
- `cad_create_prim` + `cad_boolean` + `cad_fillet` + `cad_export`, with the 3D tab
77
- updating live at every step
78
- - “build a snowman” → spheres + a cone nose + a cylinder hat (precise `at`/`axis` placement)
79
- - “add two more b1, one rotated 90 degrees” `cad_assembly_insert` + `cad_assembly_move`, the Assembly tab updates live
80
- - “make an A3 drawing of b1 and export dxf” → `cad_drawing` (three views + iso + dashed hidden lines + dimensions) → `cad_export` `.dxf`
81
-
82
- ## Modeling Tool Family
83
-
84
- | Tool | Description |
85
- | --- | --- |
86
- | `cad_view` | Open a CAD file and render an interactive viewer card |
87
- | `cad_info` | Read-only geometry metadata (format / counts / bounding box / units / layers) |
88
- | `cad_create_prim` | Primitives (mm, Z-up); `at` for placement, `axis` for orientation (exact axis-angle rotation) |
89
- | `cad_extrude_profile` | Extrude a closed XY-plane polygon along +Z into a solid |
90
- | `cad_boolean` | fuse / cut / common (classic hole punching: plate cut cylinder) |
91
- | `cad_fillet` | Constant-radius fillet on all sharp edges |
92
- | `cad_transform` | Translate / Euler rotate / mirror |
93
- | `cad_volume` | Exact BRep volume (mm³) |
94
- | `cad_drawing` | Engineering drawing: front/top/left + isometric views, dashed hidden lines, frame, title block, overall dimensions, standard scale, A4/A3 |
95
- | `cad_assembly_insert` | Insert a body into the assembly as a placed instance (`at` position, `rotate` orientation) |
96
- | `cad_assembly_move` | Set an instance's absolute placement |
97
- | `cad_assembly_remove` | Remove an instance from the assembly (the body stays) |
98
- | `cad_export` | Export STEP / STL / DCPRT (the native replayable part document) to a workspace path; `target: "assembly"` writes the assembly STEP, `target: "drawing"` writes the sheet as SVG / DXF |
99
- | `cad_delete` | Delete a body |
100
- | `cad_freecad` | Run an op program on an external FreeCAD executor (optional STEP input / export) |
101
- | `cad_fusion` | Run an op program on an external Fusion 360 executor (GUI bridge; optional export) |
102
- | `cad_image_profile` | PNG contours extrusion-ready polygon points |
103
-
104
- After every modeling step: **the same viewer card refreshes in place** (stable viewId +
105
- versioned URL), and the "3D" tab tracks the latest model in real time.
106
-
107
- ## Connectors (roadmap)
108
-
109
- Modeling today runs on the **built-in WebGL-class kernel** (OCCT in the browser
110
- zero install). The connectors below refer to **external CAD engines** acting as
111
- executors for the same tool family, planned for future support:
112
-
113
- | Connector | Suite | Platform | Status |
114
- | --- | --- | --- | --- |
115
- | **Built-in kernel** | CAD modeling kernel based on OCCT + WebGL, runs in the browser zero install | All platforms (WebGL rendering) | Built-in |
116
- | FreeCAD | open-source parametric suite natural local executor via its Python API (console + GUI window modes) | Windows / macOS / Linux | Available (needs local install) |
117
- | Fusion 360 | Autodesk CAD/CAM — resident add-in + spool bridge (no headless; the Fusion window doubles as a viewer) | Windows / macOS | 🧪 Experimental (`cad_fusion`) |
118
- | SolidWorks | Dassault Systèmes industry-standard 3D CAD, COM/.NET automation | Windows only | 🚧 Windows demo scaffold (`scripts/solidworks-bridge/`) |
119
- | Onshape | cloud-native SaaS CAD, fully in the browser | All platforms (browser) | 🚧 Planned |
120
- | ZW3D(中望3D) | ZWSOFT all-in-one CAD/CAM | Windows / Linux | 🚧 Planned |
121
- | GstarCAD 3D(浩辰3D) | Gstarsoft 3D CAD | Windows | 🚧 Planned |
122
-
123
- All external engines implement the same **GeometryExecutor contract** (`available()` /
124
- `run(opProgram) meshes`), so the WebGL display layer never changes swapping a
125
- backend changes only the quality of the produced geometry.
126
-
127
- ## Architecture
128
-
129
- ```
130
- cad_view(path) modeling tools (cad_create_prim, …)
131
- → import worker (occt-import-js) → modeling worker (opencascade.js WASM)
132
- CadScene JSON (base64-f32) → exact BRep geometry + meshing
133
- GET /dsh-cad/scene/<id> → in-memory binary scene (f32/u32 packed)
134
- GET /dsh-cad/bin/<docId>
135
- ↓ session presentationMeta (viewId + versioned URL) ↓
136
- browser card + persistent "3D" tab (three.js / SVG, Z-up, XYZ axes)
137
- ```
138
-
139
- - **Two workers**: import (occt-import-js, read-only STEP/IGES/BREP) and modeling
140
- (opencascade.js 1.1.1, full OCCT) are separate, both lazily started; the `_N`
141
- suffix convention of embind overloaded constructors is wrapped in
142
- `src/modeling/occt-adapter.cjs` (all verified at runtime)
143
- - **Zero-copy pipeline**: modeling scenes use zero base64 / zero large JSON arrays /
144
- zero per-step disk writes (disk mirror debounced 1.5s, replayed only on service
145
- restart); `cad_export` is the only explicit file export
146
- - **Modeling document**: `<workspace>/.dsh-cad/model.json` operation log; all bodies
147
- are restored by replay after a restart
148
- - **Client**: esbuild single-file CJS factory (three.js inlined ~560KB, react provided
149
- by the host module table), Z-up CAD convention, empty scene with XYZ axis labels
150
- and a ground grid always displayed
151
-
152
- ## Tests
153
-
154
- ```sh
155
- npm test # 41 tests: converters / modeling worker (exact volume assertions) / DCPRT round-trip / FreeCAD executor / image profiles / binary pipeline
156
- node test/m0-kernel-check.cjs # OCCT kernel API smoke test
157
- node test/route-check.mjs # JSON scene routing layer
158
- node test/visual/serve.mjs # browser card/tab visual verification page (http://127.0.0.1:3987)
159
- ```
160
-
161
- Representative assertions covered: the boolean-punched volume exactly equals the
162
- analytic value (28429.20 mm³), L-shaped profile extrusion 3000 mm³, volumes and
163
- bounding-box flips of sphere/cone/torus placed with `at`/`axis`, 8-byte alignment
164
- of the binary packing, an STL export round-trip (export → read back by the
165
- phase-1 parser), and a DCPRT document round-trip (serialize replay on the
166
- OCCT worker exact bounds).
167
-
168
- ## Known Limitations
169
-
170
- - DWG (closed-source) is unsupported; DXF bulge arcs are approximated by chords;
171
- glTF/3MF viewing is not implemented (the structure is reserved)
172
- - `cad_fillet` is all-edge constant-radius (per-edge selection is unstable under
173
- embind); chamfer is not implemented
174
- - Sketch extrusion supports polygon profiles only (arc profiles are constructed by
175
- boolean combinations of cylinders/tori)
176
- - dsh framework limitation: an already-mounted single slot (the right-side details
177
- panel itself) does not respond to components registered later, so the persistent
178
- view is provided as the "3D" view tab (a list slot, the official composition)
179
- - The host reads CAD files via node:fs (the platform fs service supports UTF-8 text
180
- only and cannot carry binary data)
181
-
182
- ## Contributors
183
-
184
- Auto-generated from the commit history thanks to everyone who has contributed!
185
-
186
- [![Contributors](https://contrib.rocks/image?repo=LAU-MARS/dsh-cad)](https://github.com/LAU-MARS/dsh-cad/graphs/contributors)
187
-
188
- ## License
189
-
190
- MIT
1
+ # dsh-cad — CAD Plugin for DeepSeek Harness
2
+
3
+ ![dsh-cad banner](docs/img/banner.svg)
4
+
5
+ [![homepage](https://img.shields.io/badge/homepage-dsh--cad-4D6BFE)](https://lau-mars.github.io/dsh-cad/)
6
+ [![npm](https://img.shields.io/npm/v/dsh-cad)](https://www.npmjs.com/package/dsh-cad)
7
+ [![dsh plugin](https://img.shields.io/badge/dsh-plugin-4D6BFE)](https://github.com/deepseek-ai/deepseek-harness)
8
+ [![Node](https://img.shields.io/badge/node-%3E%3D%2022-4D6BFE)](https://nodejs.org/)
9
+ [![OCCT](https://img.shields.io/badge/kernel-OCCT-4D6BFE)](https://github.com/donalffons/opencascade.js)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-4D6BFE)](./LICENSE)
11
+
12
+ English | [简体中文](./README.zh-CN.md)
13
+
14
+ A CAD plugin for [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness):
15
+ an **embedded 3D/2D CAD viewer** plus a **native parametric modeling tool family**
16
+ (OCCT kernel) in the Web UI, letting the agent build and inspect CAD geometry
17
+ step by step — "model while you watch".
18
+
19
+ ## Preview
20
+
21
+ The CAD editor at startup: the demo L-bracket parsed from the packaged
22
+ `demo-bracket.brep` by OCCT face + edge rendering, hover measurement of the
23
+ picked face (4,800 mm²), a ViewCube navigation cube in the corner, and
24
+ switchable demo parts (bracket / flange / shaft):
25
+
26
+ ![dsh-cad CAD editor](docs/img/bracket-preview.png)
27
+
28
+ ## Feature Overview
29
+
30
+ | Capability | Description |
31
+ | --- | --- |
32
+ | 🔍 CAD viewing | STL / OBJ / STEP / IGES / BREP / DCPRT (3D), DXF / SVG (2D); interactive in-chat card (orbit / zoom / wireframe / pan) |
33
+ | 🧭 CAD editor interactions | Onshape-style ViewCube (26-zone click-to-orient), hover/click face & edge picking with live measurement (area mm² / length mm), Faces+Edges / Faces / Wireframe render modes, switchable BRep demo parts (bracket / flange / shaft) |
34
+ | 🏗️ Parametric modeling | Primitives, profile extrusion, **loft**, **sweep**, **revolve**, booleans, all-edge fillet/chamfer, **patterns** (linear/circular), transforms; profiles take **curve segments** (arcs/circles exact BRep; B-splines sampled approximation) exact OCCT BRep, not a mesh approximation |
35
+ | 🗂️ Codex-style document tabs | The resident display panel gets a tab strip with a "+" menu: **Part** (Part Studio, the default) / **Assembly** (instance insert/move/remove) / **Drawing** (true hidden-line sheets); tabs are closable and keep their state |
36
+ | 📁 Multi-document file space | Named documents per workspace (`.dsh-cad/docs/`), each session bound to its own active document — new sessions start empty instead of inheriting leftovers; a folder button in the panel lists every document (preview / delete), and `cad_doc_new` / `cad_doc_open` manage the modeling target from chat |
37
+ | 📐 Engineering drawings | GB first-angle layout: front / top / left views + isometric, true OCCT hidden-line removal via the **occt.ts** kernel (an npm dependency, dashed); sheet frame, title block, overall dimensions, standard scale series; exports SVG / DXF |
38
+ | 🔗 Constraint solving & motion | **Ansatz** geometric constraint solver (**one command: `npm install ansatz-wasm`** a wasm dependency, no Rust toolchain, no native binary): entity/constraint modeling (assembly instances ↔ rigid3 poses mapped automatically), solve-with-writeback, full DOF/residual/redundancy/suggestion diagnostics (LLM-oriented), and parametric kinematic sweeps (`cad_constraint` / `cad_solve` / `cad_motion`) |
39
+ | 📐 Geometry measurement | Exact volume (mm³), bounding box, triangle counts, DXF layers |
40
+ | 📤 On-demand export | STEP (parametric) / STL (mesh); files are written only when the user asks |
41
+ | 🖥️ Resident CAD panel | A permanent panel right of the conversation: Codex-style tabs (Part / Assembly / Drawing), tracking the latest model in real time while modeling |
42
+ | Zero-copy render pipeline | worker mesh in-memory binary three.js typed arrays; zero base64 / zero intermediate files / zero per-step disk writes |
43
+ | 💾 Modeling document persistence | Operation log (JSON) + debounced disk mirror; automatically replayed to restore state after a process restart |
44
+ | 🖼️ Image → profile | PNG sketch/screenshot → Otsu binarization → contour tracing → extrusion-ready polygon (`cad_image_profile`) |
45
+ | 🔌 FreeCAD executor | Run the same op family on an external FreeCAD console (STEP in/out); requires a local FreeCAD install |
46
+
47
+ ## Installation
48
+
49
+ The plugin is published to npm one line:
50
+
51
+ ```sh
52
+ dsh plugin --profile web add dsh-cad
53
+ ```
54
+
55
+ The installer applies the bundled `cordis.patch.yml` (declared in the `dsh.bundle` manifest) automatically, so there is nothing to configure by hand.
56
+
57
+ ### Version requirements
58
+
59
+ - **Node.js** ≥ 22
60
+ - **dsh CLI** (`@deepseek-ai/dsh`): this plugin is developed against **0.1.0-rc.7**
61
+ (minimum supported version, declared in the `engines` field of `package.json`);
62
+ recommended **≥ 0.1.1-rc.2** (verified 2026-08-31)
63
+
64
+ ### Install from source (dev mode)
65
+
66
+ ```sh
67
+ git clone https://github.com/LAU-MARS/dsh-cad.git
68
+ cd dsh-cad
69
+ npm install && npm run build && npm test # deps include occt.ts (true-HLR drawing kernel, ~20MB wasm)
70
+
71
+ npm install -g @deepseek-ai/dsh@^0.1.1-rc.2 pnpm # requires Node 22
72
+ dsh web # let the first launch init the profile, then Ctrl-C
73
+
74
+ dsh plugin --profile web add /path/to/dsh-cad
75
+
76
+ dsh web
77
+ ```
78
+
79
+ The patch insert ships as `cordis.patch.yml` in the package root and is applied by the installer via the same `dsh.bundle` manifest.
80
+
81
+ Set `DEEPSEEK_API_KEY` and you are ready — for example:
82
+
83
+ - “open bracket.stl” → `cad_view`
84
+ - “model a 100×60×5 plate, punch a ⌀20 hole in the middle, R2 fillets on the four
85
+ corners, add a ⌀16 boss 20 tall, export plate.step”
86
+ `cad_create_prim` + `cad_boolean` + `cad_fillet` + `cad_export`, with the 3D tab
87
+ updating live at every step
88
+ - “build a snowman” spheres + a cone nose + a cylinder hat (precise `at`/`axis` placement)
89
+ - “add two more b1, one rotated 90 degrees” → `cad_assembly_insert` + `cad_assembly_move`, the Assembly tab updates live
90
+ - “make an A3 drawing of b1 and export dxf” → `cad_drawing` (three views + iso + dashed hidden lines + dimensions) → `cad_export` `.dxf`
91
+
92
+ ## Modeling Tool Family
93
+
94
+ | Tool | Description |
95
+ | --- | --- |
96
+ | `cad_view` | Open a CAD file and render an interactive viewer card |
97
+ | `cad_info` | Read-only geometry metadata (format / counts / bounding box / units / layers) |
98
+ | `cad_create_prim` | Primitives (mm, Z-up); `at` for placement, `axis` for orientation (exact axis-angle rotation) |
99
+ | `cad_extrude_profile` | Extrude a closed XY-plane polygon along +Z into a solid |
100
+ | `cad_loft` | Loft: skin a solid through successive closed sections (each a [x,y,z,…] loop in its own plane); sections may differ in shape and point count; `ruled` for straight sides |
101
+ | `cad_revolve` | Solid of revolution: revolve a closed profile around an axis (profile coords = (radius, height); curve segments supported — rounded rims exact); optional `angle` |
102
+ | `cad_chamfer` | Chamfer: bevel every sharp edge with one equal distance (mm) |
103
+ | `cad_pattern` | Pattern: linear (`delta` spacing) or circular (principal axis + `at` point + sweep angle); creates copy bodies, fuse afterwards for one body |
104
+ | `cad_sweep` | Sweep: pipe a closed 2D profile along a 3D [x,y,z,…] path; the profile is auto-placed on the start plane, so no manual orientation |
105
+ | `cad_boolean` | fuse / cut / common (classic hole punching: plate cut cylinder) |
106
+ | `cad_fillet` | Constant-radius fillet on all sharp edges |
107
+ | `cad_transform` | Translate / Euler rotate / mirror |
108
+ | `cad_volume` | Exact BRep volume (mm³) |
109
+ | `cad_drawing` | Engineering drawing: front/top/left + isometric views, dashed hidden lines, frame, title block, overall dimensions, standard scale, A4/A3 |
110
+ | `cad_assembly_insert` | Insert a body into the assembly as a placed instance (`at` position, `rotate` orientation) |
111
+ | `cad_assembly_move` | Set an instance's absolute placement |
112
+ | `cad_assembly_remove` | Remove an instance from the assembly (the body stays) |
113
+ | `cad_constraint` | Declare the constraint model: entities (assembly-instance bindings) + constraints (distance/angle/mate/coaxial…), persisted in the op log |
114
+ | `cad_solve` | Solve with Ansatz and write poses back; returns DOF/residual/redundancy/suggestion diagnostics |
115
+ | `cad_motion` | Kinematic sweep: drive one constraint value from `from` to `to`, solve frame by frame, apply the last pose, return the motion table |
116
+ | `cad_export` | Export STEP / STL / DCPRT (the native replayable part document) to a workspace path; `target: "assembly"` writes the assembly STEP, `target: "drawing"` writes the sheet as SVG / DXF |
117
+ | `cad_delete` | Delete a body |
118
+ | `cad_docs` | List the workspace's modeling documents (id / name / bodies / updated, active marked) |
119
+ | `cad_doc_new` | Create a named document and make it the session's modeling target (start multi-part projects here) |
120
+ | `cad_doc_open` | Open an existing document (by id or name) as the session's modeling target — bodies replay exactly |
121
+ | `cad_doc_rename` | Rename a document |
122
+ | `cad_doc_delete` | Permanently delete a document (requires `confirm: true`) |
123
+ | `cad_freecad` | Run an op program on an external FreeCAD executor (optional STEP input / export) |
124
+ | `cad_fusion` | Run an op program on an external Fusion 360 executor (GUI bridge; optional export) |
125
+ | `cad_image_profile` | PNG contours extrusion-ready polygon points |
126
+
127
+ After every modeling step: **the same viewer card refreshes in place** (stable viewId +
128
+ versioned URL), and the "3D" tab tracks the latest model in real time.
129
+
130
+ ## Connectors (roadmap)
131
+
132
+ Modeling today runs on the **built-in WebGL-class kernel** (OCCT in the browser —
133
+ zero install). The connectors below refer to **external CAD engines** acting as
134
+ executors for the same tool family, planned for future support:
135
+
136
+ | Connector | Suite | Platform | Status |
137
+ | --- | --- | --- | --- |
138
+ | **Built-in kernel** | CAD modeling kernel based on OCCT + WebGL, runs in the browser — zero install | All platforms (WebGL rendering) | ✅ Built-in |
139
+ | FreeCAD | open-source parametric suite natural local executor via its Python API (console + GUI window modes) | Windows / macOS / Linux | ✅ Available (needs local install) |
140
+ | Fusion 360 | Autodesk CAD/CAM resident add-in + spool bridge (no headless; the Fusion window doubles as a viewer) | Windows / macOS | 🧪 Experimental (`cad_fusion`) |
141
+ | SolidWorks | Dassault Systèmes industry-standard 3D CAD, COM/.NET automation | Windows only | 🚧 Windows demo scaffold (`scripts/solidworks-bridge/`) |
142
+ | Onshape | cloud-native SaaS CAD, fully in the browser | All platforms (browser) | 🚧 Planned |
143
+ | ZW3D(中望3D) | ZWSOFT all-in-one CAD/CAM | Windows / Linux | 🚧 Planned |
144
+ | GstarCAD 3D(浩辰3D) | Gstarsoft 3D CAD | Windows | 🚧 Planned |
145
+
146
+ All external engines implement the same **GeometryExecutor contract** (`available()` /
147
+ `run(opProgram) meshes`), so the WebGL display layer never changes — swapping a
148
+ backend changes only the quality of the produced geometry.
149
+
150
+ ## Architecture
151
+
152
+ ```
153
+ cad_view(path) modeling tools (cad_create_prim, …)
154
+ → import worker (occt-import-js) → modeling worker (opencascade.js WASM)
155
+ CadScene JSON (base64-f32) exact BRep geometry + meshing
156
+ GET /dsh-cad/scene/<id> → in-memory binary scene (f32/u32 packed)
157
+ GET /dsh-cad/bin/<docId>
158
+ session presentationMeta (viewId + versioned URL)
159
+ browser card + persistent "3D" tab (three.js / SVG, Z-up, XYZ axes)
160
+ ```
161
+
162
+ - **Two workers**: import (occt-import-js, read-only STEP/IGES/BREP) and modeling
163
+ (opencascade.js 1.1.1, full OCCT) are separate, both lazily started; the `_N`
164
+ suffix convention of embind overloaded constructors is wrapped in
165
+ `src/modeling/occt-adapter.cjs` (all verified at runtime)
166
+ - **Zero-copy pipeline**: modeling scenes use zero base64 / zero large JSON arrays /
167
+ zero per-step disk writes (disk mirror debounced 1.5s, replayed only on service
168
+ restart); `cad_export` is the only explicit file export
169
+ - **Modeling document**: `<workspace>/.dsh-cad/model.json` operation log; all bodies
170
+ are restored by replay after a restart
171
+ - **Drawing HLR kernel**: hidden lines run on **occt.ts** (npm dependency,
172
+ `npm i occt.ts`) true OCCT removal, no fallback engine, a missing kernel is
173
+ a hard error. New APIs over opencascade.js: `hiddenLines()` true hidden-line
174
+ removal, byte-level STEP/BRep `readStep`/`readBrep`/`writeStep`/`writeBrep`
175
+ without MEMFS, tessellation with built-in feature-edge extraction, and a
176
+ `hasError()`/`lastError()` error contract. Geometry crosses kernels as STEP
177
+ bytes and the projected segments are remapped into the sheet frame. Kernel
178
+ dist resolution: `DSH_OCCTJS_DIST` env var `node_modules/occt.ts/dist`
179
+ (npm, default) `<repo>/../opencascade-ts/dist` (sibling checkout) `vendor/`
180
+ `node_modules/opencascade-ts`
181
+ - **Constraint solving (Ansatz)**: the solver is the npm dependency
182
+ **`ansatz-wasm`** (a wasm-bindgen build, single package ~538KB, zero deps) —
183
+ installing dsh-cad pulls it automatically, and `npm install ansatz-wasm` alone
184
+ upgrades it. **No Rust toolchain, no native binary, platform independent.**
185
+ Resolution: the npm package (node_modules) → a `DSH_ANSATZ_WASM` directory → a
186
+ sibling Ansatz checkout's pkg-node. The solver speaks one JSON envelope
187
+ contract, with tool-layer errors (e.g. `unsupported_constraint`) surfaced
188
+ verbatim for the LLM. Assembly placements (translate + XYZ Euler
189
+ degrees) map bidirectionally to the solver's rigid3 poses (translate +
190
+ exponential-map rotation, radians). Solver capability is staged
191
+ (point-distance-to-origin today) — the plumbing contract is finished and needs
192
+ no changes as it grows
193
+ - **Client**: esbuild single-file CJS factory (three.js inlined ~560KB, react provided
194
+ by the host module table), Z-up CAD convention, empty scene with XYZ axis labels
195
+ and a ground grid always displayed
196
+
197
+ ## Tests
198
+
199
+ ```sh
200
+ npm test # 41 tests: converters / modeling worker (exact volume assertions) / DCPRT round-trip / FreeCAD executor / image profiles / binary pipeline
201
+ node test/m0-kernel-check.cjs # OCCT kernel API smoke test
202
+ node test/route-check.mjs # JSON scene routing layer
203
+ node test/visual/serve.mjs # browser card/tab visual verification page (http://127.0.0.1:3987)
204
+ ```
205
+
206
+ Representative assertions covered: the boolean-punched volume exactly equals the
207
+ analytic value (28429.20 mm³), L-shaped profile extrusion 3000 mm³, volumes and
208
+ bounding-box flips of sphere/cone/torus placed with `at`/`axis`, 8-byte alignment
209
+ of the binary packing, an STL export round-trip (export → read back by the
210
+ phase-1 parser), and a DCPRT document round-trip (serialize → replay on the
211
+ OCCT worker → exact bounds).
212
+
213
+ ## Known Limitations
214
+
215
+ - DWG (closed-source) is unsupported; DXF bulge arcs are approximated by chords;
216
+ glTF/3MF viewing is not implemented (the structure is reserved)
217
+ - `cad_fillet` is all-edge constant-radius (per-edge selection is unstable under
218
+ embind); chamfer is not implemented
219
+ - Sketch extrusion supports polygon profiles only (arc profiles are constructed by
220
+ boolean combinations of cylinders/tori)
221
+ - dsh framework limitation: an already-mounted single slot (the right-side details
222
+ panel itself) does not respond to components registered later, so the persistent
223
+ view is provided as the "3D" view tab (a list slot, the official composition)
224
+ - The host reads CAD files via node:fs (the platform fs service supports UTF-8 text
225
+ only and cannot carry binary data)
226
+
227
+ ## Contributors
228
+
229
+ Auto-generated from the commit history — thanks to everyone who has contributed!
230
+
231
+ [![Contributors](https://contrib.rocks/image?repo=LAU-MARS/dsh-cad)](https://github.com/LAU-MARS/dsh-cad/graphs/contributors)
232
+
233
+ ## License
234
+
235
+ MIT