dsh-cad 0.9.0 → 0.11.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.zh-CN.md CHANGED
@@ -1,222 +1,236 @@
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.md) | 简体中文
13
-
14
- [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) 的 CAD 插件:
15
- 在 Web UI 中提供**内嵌 3D/2D CAD 查看器**与**原生参数化建模工具族**(OCCT 内核),
16
- 让 agent 能够"边建边看"地完成 CAD 工作。
17
-
18
- ## 预览
19
-
20
- 启动即见的 CAD 编辑器:示例 L 型支架由内置的 `demo-bracket.brep` 经 OCCT
21
- 解析渲染——面 + 边显示模式、悬停即测(拾取面 4,800 mm²)、角落 ViewCube
22
- 导航块、支架 / 法兰 / 轴三种示例件一键切换:
23
-
24
- ![dsh-cad CAD 编辑器](docs/img/bracket-preview.png)
25
-
26
- ## 功能总览
27
-
28
- | 能力 | 说明 |
29
- | --- | --- |
30
- | ⚙️ 单内核架构 | **occt.ts 为主建模内核**(真 BSpline、抽壳/拔模原生、质心),opencascade.js 仅作为加载失败时的降级后端;v0.8 的「抽壳后不可编辑」接缝消失——抽壳/拔模后可继续圆角/倒角/布尔 |
31
- | 🔍 CAD 查看 | STL / OBJ / STEP / IGES / BREP / DCPRT(3D),DXF / SVG(2D),对话内嵌交互卡片(轨道旋转 / 缩放 / 线框 / 平移) |
32
- | 🧭 CAD 编辑器交互 | Onshape 风格 ViewCube(26 区域点击定向)、悬停/点选面与边实时测量(面积 mm² / 长度 mm)、面+边 / 面 / 线框三种渲染模式、支架 / 法兰 / 轴 BRep 示例件一键切换 |
33
- | 🏗️ 参数化建模 | 基本体、轮廓拉伸、**放样**、**扫掠**、**旋转体**、布尔、全边圆角/倒角、**抽壳**、**拔模**、**阵列(线性/圆周)**、变换;轮廓支持**曲线段**(圆弧/圆为精确 BRep,B 样条为采样近似)—— OCCT 精确 BRep,非网格近似 |
34
- | 🗂️ Codex 式文档页签 | 右侧显示区页签栏 + 「+」菜单:**零件**(Part Studio,默认)/ **装配体**(实例插入/移动/移除)/ **工程图**(真实隐藏线图纸),页签可关闭、常驻不丢状态 |
35
- | 📁 多文档 file 空间 | 工作区命名的建模文档(`.dsh-cad/docs/`),每个会话绑定自己的活动文档——新会话从空文档开始,不再继承历史遗留零件;面板上的文件夹按钮列出全部文档(预览 / 删除),对话中用 `cad_doc_new` / `cad_doc_open` 切换建模目标 |
36
- | 📐 工程图 | GB 第一角布局:主视图 / 俯视图 / 左视图 + 轴测图,**occt.ts** 内核(npm 依赖,OCCT 7.9)真实隐藏线消除(虚线);图框、标题栏、总尺寸标注、标准比例系列;导出 SVG / DXF |
37
- | 🔗 约束求解与运动 | 集成 **Ansatz** 几何约束求解器(**`ansatz-wasm` 一条命令即可**:`npm install ansatz-wasm`,零 Rust 工具链 / 零原生二进制 / 零依赖):实体/约束建模(装配实例 ↔ rigid3 位姿自动映射)、求解回写、DOF/残差/冗余/建议全量诊断(面向 LLM 的中文报告)、参数扫描运动学(`cad_constraint` / `cad_solve` / `cad_motion`) |
38
- | 📐 几何测量 | 精确体积(mm³)、包围盒、三角统计、DXF 图层 |
39
- | 📤 按需导出 | STEP(参数化)/ STL(网格),仅在用户要求时写文件 |
40
- | 🖥️ 常驻 CAD 显示区 | 会话页右侧常驻面板:Codex 式页签(零件 / 装配体 / 工程图),建模时实时跟踪最新模型 |
41
- | ⚡ 直通渲染管道 | worker 网格 → 内存二进制 → three.js typed-array,零 base64 / 零中间文件 / 零每步落盘 |
42
- | 💾 建模文档持久化 | 操作日志(JSON)+ 防抖磁盘镜像,进程重启后自动重放恢复 |
43
- | 🖼️ 图片 → 轮廓 | PNG 草图/截图 → Otsu 二值化 → 轮廓追踪 → 可直接拉伸的多边形(`cad_image_profile`) |
44
- | 🔌 FreeCAD 执行器 | 在外部 FreeCAD 控制台运行同一 op 族(STEP 输入/输出闭环);需本地安装 |
45
-
46
- ## 安装
47
-
48
- 插件已发布到 npm,一行命令即可:
49
-
50
- ```sh
51
- dsh plugin --profile web add dsh-cad
52
- ```
53
-
54
- 安装器会通过 `dsh.bundle` 清单自动应用包内自带的 `cordis.patch.yml`,无需手工改任何配置。
55
-
56
- ### 版本要求
57
-
58
- - **Node.js** ≥ 22
59
- - **dsh CLI**(`@deepseek-ai/dsh`):本项目开发基于 **0.1.0-rc.7**
60
- (最低支持版本,已在 `package.json` 的 `engines` 字段声明);
61
- 建议 **≥ 0.1.1-rc.2**(2026-08-31 实测通过)
62
-
63
- ### 从源码安装(开发模式)
64
-
65
- ```sh
66
- git clone https://github.com/LAU-MARS/dsh-cad.git
67
- cd dsh-cad
68
- npm install && npm run build && npm test # 依赖含 occt.ts(工程图真实消隐内核,~20MB wasm)
69
-
70
- npm install -g @deepseek-ai/dsh@^0.1.1-rc.2 pnpm # 需要 Node ≥ 22
71
- dsh web # 首次启动初始化 profile 后 Ctrl-C
72
-
73
- dsh plugin --profile web add /path/to/dsh-cad
74
-
75
- dsh web
76
- ```
77
-
78
- patch 内容以包根目录的 `cordis.patch.yml` 随包分发,安装器经同一条 `dsh.bundle` 清单自动应用。
79
-
80
- 设置 `DEEPSEEK_API_KEY` 后对话即可使用,例如:
81
-
82
- - “打开 bracket.stl 看看” → `cad_view`
83
- - “画一个 100×60×5 的板,中间打 ⌀20 孔,四角 R2 圆角,加 ⌀16 高 20 凸台,导出 plate.step”
84
- → `cad_create_prim` + `cad_boolean` + `cad_fillet` + `cad_export`,每步 3D 页签实时更新
85
- - “堆一个雪人” → 球体 + 圆锥鼻子 + 圆柱帽子(`at`/`axis` 精确定位)
86
- - “再放两个 b1,一个转到 90 度” → `cad_assembly_insert` + `cad_assembly_move`,装配体页签实时更新
87
- - “给 b1 出一张 A3 工程图,导出 dxf” → `cad_drawing`(三视图 + 轴测 + 虚线隐藏线 + 尺寸标注)→ `cad_export` `.dxf`
88
-
89
- ## 模型工具族
90
-
91
- | 工具 | 说明 |
92
- | --- | --- |
93
- | `cad_view` | 打开 CAD 文件,渲染交互式查看器卡片 |
94
- | `cad_info` | 只读几何元信息(格式/数量/包围盒/单位/图层) |
95
- | `cad_create_prim` | 基本体(mm,Z-up),`at` 定位、`axis` 定向(精确轴角旋转) |
96
- | `cad_extrude_profile` | XY 平面闭合多边形沿 +Z 拉伸成实体 |
97
- | `cad_loft` | 放样:多个闭合截面(各自平面内的 [x,y,z…] 环)蒙皮成体,截面形状/点数可不同,`ruled` 直纹 |
98
- | `cad_revolve` | 旋转体:闭合轮廓绕轴回转(profile 坐标 = (半径, 高度),支持曲线段——圆角轮缘精确),`angle` 角度可选 |
99
- | `cad_chamfer` | 倒角:全锐边等距离斜切(mm) |
100
- | `cad_pattern` | 阵列:线性(delta 间距)或圆周(主轴 + at 轴点 + 总角度),生成副本体,可再 fuse 合并 |
101
- | `cad_shell` | 抽壳:壁厚向内生长、外表面保留;`open` 为开口面的外法向列表(空 = 封闭内腔)。经 occt.ts 内核执行,结果为**托管体** |
102
- | `cad_draft` | 拔模:壁面绕中性面倾斜 `angle` 度(脱模斜度),`direction` 为拔模方向,默认自动选平行于该方向的壁面。经 occt.ts 内核执行,结果为**托管体** |
103
- | `cad_sweep` | 扫掠:闭合 2D 轮廓沿 3D 路径([x,y,z…])扫出实体;轮廓自动置于路径起点垂面,无需手工定向 |
104
- | `cad_boolean` | fuse / cut / common(经典打孔:plate cut cylinder) |
105
- | `cad_fillet` | 全锐边等半径圆角 |
106
- | `cad_transform` | 平移 / 欧拉旋转 / 镜像 |
107
- | `cad_volume` | 精确 BRep 体积(mm³) |
108
- | `cad_drawing` | 工程图:主/俯/左 + 轴测四视图,隐藏线(虚线)、图框、标题栏、总尺寸、标准比例,A4/A3 |
109
- | `cad_assembly_insert` | 将零件以实例插入装配体(`at` 定位、`rotate` 定向) |
110
- | `cad_assembly_move` | 设置实例绝对位置/姿态 |
111
- | `cad_assembly_remove` | 从装配体移除实例(零件保留) |
112
- | `cad_constraint` | 声明约束模型:实体(含装配实例绑定)+ 约束(distance/angle/mate/coaxial…),持久化于操作日志 |
113
- | `cad_solve` | Ansatz 求解并回写装配位姿;返回 DOF 剩余/残差/冗余/建议全量诊断 |
114
- | `cad_motion` | 运动学扫描:驱动一个约束值从 from 到 to 逐帧求解,应用末帧位姿并返回运动表 |
115
- | `cad_export` | 导出 STEP / STL / DCPRT(原生可重放零件文档)到工作区路径;`target: "assembly"` 导出装配体 STEP,`target: "drawing"` 导出工程图 SVG / DXF |
116
- | `cad_delete` | 删除 body |
117
- | `cad_docs` | 列出工作区建模文档(id / 名称 / 体数 / 更新时间,标记当前活动文档) |
118
- | `cad_doc_new` | 新建命名文档并设为会话建模目标(多零件项目从这里开始) |
119
- | `cad_doc_open` | 打开已有文档(按 id 或名称)作为会话建模目标——body 精确重放 |
120
- | `cad_doc_rename` | 重命名文档 |
121
- | `cad_doc_delete` | 永久删除文档(需 `confirm: true`) |
122
- | `cad_freecad` | 在外部 FreeCAD 执行器上运行 op 程序(可选 STEP 输入/导出) |
123
- | `cad_fusion` | 在外部 Fusion 360 执行器上运行 op 程序(GUI 桥;可选导出) |
124
- | `cad_image_profile` | PNG → 轮廓 → 可直接拉伸的多边形点集 |
125
-
126
- 每步建模后:**同一查看器卡片原地刷新**(稳定 viewId + 版本化 URL),
127
- "3D" 页签实时跟踪最新模型。
128
-
129
- ## 连接器(规划中)
130
-
131
- 建模主要由 **occt.ts** 内核承担(opencascade.js 为降级后端)(浏览器内的 OCCT 内核,零安装);
132
- 下表连接器指未来以**外部 CAD 引擎作为执行器**驱动同一工具族:
133
-
134
- | 连接器 | 套件 | 平台 | 状态 |
135
- | --- | --- | --- | --- |
136
- | **内置内核** | 基于 OCCT + WebGL 的 CAD 建模内核,浏览器内运行——零安装 | 全平台(WebGL 渲染) | ✅ 内置 |
137
- | FreeCAD | 开源参数化套件——可经其 Python API 作为本地执行器(控制台 + GUI 窗口双模式) | Windows / macOS / Linux | ✅ 可用(需本地安装) |
138
- | Fusion 360 | Autodesk CAD/CAM——常驻 Add-In + spool 桥(无 headless,Fusion 窗口即查看器) | Windows / macOS | 🧪 实验性(`cad_fusion`) |
139
- | SolidWorks | 达索系统的主流 3D CAD,COM/.NET 自动化 | 仅 Windows | 🚧 Windows demo 脚手架(`scripts/solidworks-bridge/`) |
140
- | Onshape | 云原生 SaaS CAD,完全在浏览器中 | 全平台(浏览器) | 🚧 规划中 |
141
- | 中望3D(ZW3D) | 中望软件的一体化 CAD/CAM | Windows / Linux | 🚧 规划中 |
142
- | 浩辰3D | 浩辰软件的 3D CAD | Windows | 🚧 规划中 |
143
-
144
- 所有外部引擎实现同一 **GeometryExecutor 契约**(`available()` / `run(op程序) → 网格`),
145
- WebGL 显示层因此永不改变——更换后端只影响生成几何的质量。
146
-
147
- ## 架构
148
-
149
- ```
150
- cad_view(path) 建模工具(cad_create_prim 等)
151
- → 导入 worker(occt-import-js) → 建模 worker(opencascade.js WASM)
152
- → CadScene JSON(base64-f32) → BRep 精确几何 + 网格化
153
- → GET /dsh-cad/scene/<id> → 内存二进制场景(f32/u32 打包)
154
- → GET /dsh-cad/bin/<docId>
155
- ↓ 会话 presentationMeta(viewId + 版本化 URL)↓
156
- 浏览器卡片 + 常驻 "3D" 页签(three.js / SVG,Z-up,XYZ 轴)
157
- ```
158
-
159
- - **两个 worker**:导入(occt-import-js,只读 STEP/IGES/BREP)与建模(opencascade.js 1.1.1,
160
- 完整 OCCT)分离,均惰性启动;embind 重载构造器的 `_N` 后缀约定封装在
161
- `src/modeling/occt-adapter.cjs`(全部经运行时实证)
162
- - **直通管道**:建模场景零 base64 / 零 JSON 大数组 / 零每步落盘(磁盘镜像 1.5s 防抖,
163
- 仅服务重启回放);`cad_export` 是唯一的显式文件导出
164
- - **建模文档**:`<workspace>/.dsh-cad/model.json` 操作日志,重启后重放恢复全部 body
165
- - **工程图消隐内核**:隐藏线由 **occt.ts**(npm 依赖,`npm i occt.ts`)执行
166
- 真实 OCCT 消隐,无替代引擎、缺失即报错。相对 opencascade.js 的新增 API:
167
- `hiddenLines()` 真实消隐线、STEP/BRep 字节级 `readStep`/`readBrep`/`writeStep`/
168
- `writeBrep`(无需 MEMFS)、自带特征边提取的网格化、`hasError()`/`lastError()`
169
- 错误契约。几何以 STEP 字节跨内核交换,投影线段重映射进图纸坐标系。内核 dist
170
- 解析顺序:`DSH_OCCTJS_DIST` 环境变量 → `node_modules/occt.ts/dist`(npm,
171
- 默认)→ `<repo>/../opencascade-ts/dist`(兄弟检出)→ `vendor/` →
172
- `node_modules/opencascade-ts`
173
- - **约束求解(Ansatz)**:求解器是 npm 依赖 **`ansatz-wasm`**(wasm-bindgen
174
- 构建,单包 ~538KB、零依赖)——安装 dsh-cad 即自动获得,也可单独
175
- `npm install ansatz-wasm` 升级;**无需 Rust 工具链、无需原生二进制、跨平台**。
176
- 解析顺序:npm 包(node_modules)→ `DSH_ANSATZ_WASM` 目录 → 兄弟 Ansatz 检出的
177
- pkg-node。求解器以 JSON 信封契约通信,工具层错误(`unsupported_constraint` 等)
178
- 原样透出给 LLM。装配实例位姿(平移 + XYZ 欧拉度)与求解器 rigid3(平移 + 指数映射
179
- 旋转,弧度)双向映射。求解器能力按阶段推进(当前支持点到原点距离),管道契约
180
- 已就绪、无需随求解器成长改动
181
- - **单内核架构(v0.9)**:建模主内核切换为 **occt.ts ≥0.5.0**——prims/曲线段轮廓
182
- (真 BSpline 插值)/放样/扫掠/旋转/布尔/圆角/倒角/抽壳/拔模/镜像(scale(-1)+
183
- 旋转 π 组合)/质心全在一个会话内,工程图 HLR 直接吃 shape(零 STEP 中转),
184
- 抽壳后继续编辑无缝(v0.8 的托管接缝删除)。opencascade.js 保留为**降级后端**
185
- (occt.ts 加载失败时自动启用)。装配体 STEP 导出因无 compound 绑定降级为
186
- fuse 单体(实例分离保留在装配场景/文档中)。面选择按 `describe()` 平面法向
187
- 匹配(±法向取外侧投影最大者)
188
- - **客户端**:esbuild 单文件 CJS 工厂(three.js 内联 ~560KB,react 由宿主模块表提供),
189
- Z-up CAD 惯例,带 XYZ 轴标签与地面网格的空场景常驻显示
190
-
191
- ## 测试
192
-
193
- ```sh
194
- npm test # 41 项:转换器 / 建模 worker(体积精确断言)/ DCPRT 往返 / FreeCAD 执行器 / 图片轮廓 / 二进制管道 / 文档持久化
195
- node test/m0-kernel-check.cjs # OCCT 内核 API 冒烟
196
- node test/route-check.mjs # JSON 场景路由层
197
- node test/visual/serve.mjs # 浏览器卡片/页签视觉验证页(http://127.0.0.1:3987)
198
- ```
199
-
200
- 覆盖的代表性断言:布尔打孔体积精确等于解析值(28429.20 mm³)、L 型轮廓拉伸
201
- 3000 mm³、球/锥/环带 `at`/`axis` 定位的体积与包围盒翻转、二进制打包 8 字节对齐、
202
- STL 导出往返(导出 → 一期解析器读回),以及 DCPRT 文档往返
203
- (序列化 → OCCT worker 重放 → 精确包围盒)。
204
-
205
- ## 已知限制
206
-
207
- - DWG(闭源)不支持;DXF bulge 弧以弦线近似;glTF/3MF 查看未实现(结构已预留)
208
- - `cad_fillet` 为全边等半径(embind 下按边选择不稳定);chamfer 未实现
209
- - 草图拉伸仅支持多边形轮廓(圆弧轮廓用布尔组合圆柱/圆环构造)
210
- - dsh 框架限制:已挂载的 single 槽(右侧 details 面板本体)不响应后注册组件,
211
- 故常驻显示区以 "3D" 视图页签提供(list 槽,官方组合方式)
212
- - 宿主读取 CAD 文件使用 node:fs(平台 fs 服务仅支持 UTF-8 文本,无法承载二进制)
213
-
214
- ## 贡献者
215
-
216
- 由提交历史自动生成,感谢每一位贡献者!
217
-
218
- [![Contributors](https://contrib.rocks/image?repo=LAU-MARS/dsh-cad)](https://github.com/LAU-MARS/dsh-cad/graphs/contributors)
219
-
220
- ## License
221
-
222
- 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.md) | 简体中文
13
+
14
+ [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) 的 CAD 插件:
15
+ 在 Web UI 中提供**内嵌 3D/2D CAD 查看器**与**原生参数化建模工具族**(OCCT 内核),
16
+ 让 agent 能够"边建边看"地完成 CAD 工作。
17
+
18
+ ## 预览
19
+
20
+ 一次完整的建模会话:在对话中直接搭参数化装配体——先建 120×80×8、四角 R5
21
+ 圆角的底板,再在四角放置 4 个螺栓实例——右侧常驻 CAD 面板全程实时跟踪
22
+ (带逐实例配色的零件树、ViewCube、"装配体"页签、5 实例 · 1,740 三角形)。
23
+ 完成后导出结构化 STEP 文档,agent 回读文件自检——2 个实体、3 个产品、
24
+ 2 个装配引用、1,125.00 mm³:
25
+
26
+ ![dsh-cad 装配建模会话](docs/img/assembly-preview.png)
27
+
28
+ ## 功能总览
29
+
30
+ | 能力 | 说明 |
31
+ | --- | --- |
32
+ | ⚙️ 单内核架构 | **occt.ts 为主建模内核**(真 BSpline、抽壳/拔模原生、质心),opencascade.js 仅作为加载失败时的降级后端;v0.8 的「抽壳后不可编辑」接缝消失——抽壳/拔模后可继续圆角/倒角/布尔 |
33
+ | 🔍 CAD 查看 | STL / OBJ / STEP / IGES / BREP / DCPRT(3D),DXF / SVG(2D),对话内嵌交互卡片(轨道旋转 / 缩放 / 线框 / 平移) |
34
+ | 🧭 CAD 编辑器交互 | Onshape 风格 ViewCube(26 区域点击定向)、悬停/点选面与边实时测量(面积 mm² / 长度 mm)、面+边 / 面 / 线框三种渲染模式、支架 / 法兰 / 轴 BRep 示例件一键切换 |
35
+ | 🏗️ 参数化建模 | 基本体、轮廓拉伸、**放样**、**扫掠**、**旋转体**、布尔、全边圆角/倒角、**抽壳**、**拔模**、**阵列(线性/圆周)**、变换;轮廓支持**曲线段**(圆弧/圆为精确 BRep,B 样条为采样近似)—— OCCT 精确 BRep,非网格近似 |
36
+ | 🗂️ Codex 式文档页签 | 右侧显示区页签栏 + 「+」菜单:**零件**(Part Studio,默认)/ **装配体**(实例插入/移动/移除)/ **工程图**(真实隐藏线图纸),页签可关闭、常驻不丢状态 |
37
+ | 📁 多文档 file 空间 | 工作区命名的建模文档(`.dsh-cad/docs/`),每个会话绑定自己的活动文档——新会话从空文档开始,不再继承历史遗留零件;面板上的文件夹按钮列出全部文档(预览 / 删除),对话中用 `cad_doc_new` / `cad_doc_open` 切换建模目标 |
38
+ | 📐 工程图 | GB 第一角布局:主视图 / 俯视图 / 左视图 + 轴测图,**occt.ts** 内核(npm 依赖,OCCT 7.9)真实隐藏线消除(虚线);图框、标题栏、总尺寸标注、标准比例系列;导出 SVG / DXF |
39
+ | 🔗 约束求解与运动 | 集成 **Ansatz** 几何约束求解器(**`ansatz-wasm` 一条命令即可**:`npm install ansatz-wasm`,零 Rust 工具链 / 零原生二进制 / 零依赖):实体/约束建模(装配实例 ↔ rigid3 位姿自动映射)、求解回写、DOF/残差/冗余/建议全量诊断(面向 LLM 的中文报告)、参数扫描运动学(`cad_constraint` / `cad_solve` / `cad_motion`) |
40
+ | 📐 几何测量 | 精确体积(mm³)、包围盒、三角统计、DXF 图层 |
41
+ | 📤 按需导出 | STEP(参数化)/ STL(网格),仅在用户要求时写文件 |
42
+ | 🖥️ 常驻 CAD 显示区 | 会话页右侧常驻面板:Codex 式页签(零件 / 装配体 / 工程图),建模时实时跟踪最新模型 |
43
+ | ⚡ 直通渲染管道 | worker 网格 → 内存二进制 → three.js typed-array,零 base64 / 零中间文件 / 零每步落盘 |
44
+ | 💾 建模文档持久化 | 操作日志(JSON)+ 防抖磁盘镜像,进程重启后自动重放恢复 |
45
+ | 🖼️ 图片 → 轮廓 | PNG 草图/截图 → Otsu 二值化 → 轮廓追踪 → 可直接拉伸的多边形(`cad_image_profile`) |
46
+ | 🔌 FreeCAD 执行器 | 在外部 FreeCAD 控制台运行同一 op 族(STEP 输入/输出闭环);需本地安装 |
47
+ | ☁️ Onshape 执行器 | 经**签名 REST API** 在 **Onshape** 云端运行同一 op 族——零本地安装:每个 op 编译为一个**标准 Onshape 特征**推入目标 Part Studio(无需 Feature Studio 配置)。回传分三级:默认按零件的廉价 STL、`readback: "step"` 精确 BRep 命名网格(服务端 STEP 翻译 + 本地 OCCT 解析)、`readback: "none"` 只建模型回文档链接(约 3 次调用,最省配额)。导出支持 `.stl` / `.step` / `.x_t`(Parasolid 原生内核 BRep)。配额感知错误区分密钥问题与免费档冷却;始终返回 Onshape 文档链接 |
48
+
49
+ ## 安装
50
+
51
+ 插件已发布到 npm,一行命令即可:
52
+
53
+ ```sh
54
+ dsh plugin --profile web add dsh-cad
55
+ ```
56
+
57
+ 安装器会通过 `dsh.bundle` 清单自动应用包内自带的 `cordis.patch.yml`,无需手工改任何配置。
58
+
59
+ ### 版本要求
60
+
61
+ - **Node.js** ≥ 22
62
+ - **dsh CLI**(`@deepseek-ai/dsh`):本项目开发基于 **0.1.0-rc.7**
63
+ (最低支持版本,已在 `package.json` 的 `engines` 字段声明);
64
+ 建议 **≥ 0.1.1-rc.2**(2026-08-31 实测通过)
65
+
66
+ ### 从源码安装(开发模式)
67
+
68
+ ```sh
69
+ git clone https://github.com/LAU-MARS/dsh-cad.git
70
+ cd dsh-cad
71
+ npm install && npm run build && npm test # 依赖含 occt.ts(工程图真实消隐内核,~20MB wasm)
72
+
73
+ npm install -g @deepseek-ai/dsh@^0.1.1-rc.2 pnpm # 需要 Node ≥ 22
74
+ dsh web # 首次启动初始化 profile 后 Ctrl-C
75
+
76
+ dsh plugin --profile web add /path/to/dsh-cad
77
+
78
+ dsh web
79
+ ```
80
+
81
+ patch 内容以包根目录的 `cordis.patch.yml` 随包分发,安装器经同一条 `dsh.bundle` 清单自动应用。
82
+
83
+ 设置 `DEEPSEEK_API_KEY` 后对话即可使用,例如:
84
+
85
+ - “打开 bracket.stl 看看” → `cad_view`
86
+ - “画一个 100×60×5 的板,中间打 ⌀20 孔,四角 R2 圆角,加 ⌀16 高 20 凸台,导出 plate.step”
87
+ → `cad_create_prim` + `cad_boolean` + `cad_fillet` + `cad_export`,每步 3D 页签实时更新
88
+ - “堆一个雪人” → 球体 + 圆锥鼻子 + 圆柱帽子(`at`/`axis` 精确定位)
89
+ - “再放两个 b1,一个转到 90 度” → `cad_assembly_insert` + `cad_assembly_move`,装配体页签实时更新
90
+ - “给 b1 出一张 A3 工程图,导出 dxf” → `cad_drawing`(三视图 + 轴测 + 虚线隐藏线 + 尺寸标注)→ `cad_export` `.dxf`
91
+
92
+ ## 模型工具族
93
+
94
+ | 工具 | 说明 |
95
+ | --- | --- |
96
+ | `cad_view` | 打开 CAD 文件,渲染交互式查看器卡片 |
97
+ | `cad_info` | 只读几何元信息(格式/数量/包围盒/单位/图层) |
98
+ | `cad_create_prim` | 基本体(mm,Z-up),`at` 定位、`axis` 定向(精确轴角旋转) |
99
+ | `cad_extrude_profile` | XY 平面闭合多边形沿 +Z 拉伸成实体 |
100
+ | `cad_loft` | 放样:多个闭合截面(各自平面内的 [x,y,z…] 环)蒙皮成体,截面形状/点数可不同,`ruled` 直纹 |
101
+ | `cad_revolve` | 旋转体:闭合轮廓绕轴回转(profile 坐标 = (半径, 高度),支持曲线段——圆角轮缘精确),`angle` 角度可选 |
102
+ | `cad_chamfer` | 倒角:全锐边等距离斜切(mm) |
103
+ | `cad_pattern` | 阵列:线性(delta 间距)或圆周(主轴 + at 轴点 + 总角度),生成副本体,可再 fuse 合并 |
104
+ | `cad_shell` | 抽壳:壁厚向内生长、外表面保留;`open` 为开口面的外法向列表(空 = 封闭内腔)。经 occt.ts 内核执行,结果为**托管体** |
105
+ | `cad_draft` | 拔模:壁面绕中性面倾斜 `angle` 度(脱模斜度),`direction` 为拔模方向,默认自动选平行于该方向的壁面。经 occt.ts 内核执行,结果为**托管体** |
106
+ | `cad_sweep` | 扫掠:闭合 2D 轮廓沿 3D 路径([x,y,z…])扫出实体;轮廓自动置于路径起点垂面,无需手工定向 |
107
+ | `cad_boolean` | fuse / cut / common(经典打孔:plate cut cylinder) |
108
+ | `cad_fillet` | 全锐边等半径圆角 |
109
+ | `cad_transform` | 平移 / 欧拉旋转 / 镜像 |
110
+ | `cad_volume` | 精确 BRep 体积(mm³) |
111
+ | `cad_drawing` | 工程图:主/俯/左 + 轴测四视图,隐藏线(虚线)、图框、标题栏、总尺寸、标准比例,A4/A3 |
112
+ | `cad_assembly_insert` | 将零件以实例插入装配体(`at` 定位、`rotate` 定向) |
113
+ | `cad_assembly_move` | 设置实例绝对位置/姿态 |
114
+ | `cad_assembly_remove` | 从装配体移除实例(零件保留) |
115
+ | `cad_constraint` | 声明约束模型:实体(含装配实例绑定)+ 约束(distance/angle/mate/coaxial…),持久化于操作日志 |
116
+ | `cad_solve` | Ansatz 求解并回写装配位姿;返回 DOF 剩余/残差/冗余/建议全量诊断 |
117
+ | `cad_motion` | 运动学扫描:驱动一个约束值从 from 到 to 逐帧求解,应用末帧位姿并返回运动表 |
118
+ | `cad_export` | 导出 STEP / STL / DCPRT(原生可重放零件文档)到工作区路径;`target: "assembly"` 导出装配体 STEP,`target: "drawing"` 导出工程图 SVG / DXF |
119
+ | `cad_delete` | 删除 body |
120
+ | `cad_docs` | 列出工作区建模文档(id / 名称 / 体数 / 更新时间,标记当前活动文档) |
121
+ | `cad_doc_new` | 新建命名文档并设为会话建模目标(多零件项目从这里开始) |
122
+ | `cad_doc_open` | 打开已有文档(按 id 或名称)作为会话建模目标——body 精确重放 |
123
+ | `cad_doc_rename` | 重命名文档 |
124
+ | `cad_doc_delete` | 永久删除文档(需 `confirm: true`) |
125
+ | `cad_freecad` | 在外部 FreeCAD 执行器上运行 op 程序(可选 STEP 输入/导出) |
126
+ | `cad_fusion` | 在外部 Fusion 360 执行器上运行 op 程序(GUI 桥;可选导出) |
127
+ | `cad_onshape` | 在 Onshape 云端运行 op 程序(签名 REST API):新建或驱动文档、返回文档链接;`readback: "step"` 回传精确 BRep 网格;导出 `.stl` / `.step` / `.x_t`(Parasolid) |
128
+ | `cad_image_profile` | PNG → 轮廓 → 可直接拉伸的多边形点集 |
129
+
130
+ 每步建模后:**同一查看器卡片原地刷新**(稳定 viewId + 版本化 URL),
131
+ "3D" 页签实时跟踪最新模型。
132
+
133
+ ## 连接器(规划中)
134
+
135
+ 建模主要由 **occt.ts** 内核承担(opencascade.js 为降级后端)(浏览器内的 OCCT 内核,零安装);
136
+ 下表连接器指未来以**外部 CAD 引擎作为执行器**驱动同一工具族:
137
+
138
+ | 连接器 | 套件 | 平台 | 状态 |
139
+ | --- | --- | --- | --- |
140
+ | **内置内核** | 基于 OCCT + WebGL 的 CAD 建模内核,浏览器内运行——零安装 | 全平台(WebGL 渲染) | ✅ 内置 |
141
+ | FreeCAD | 开源参数化套件——可经其 Python API 作为本地执行器(控制台 + GUI 窗口双模式) | Windows / macOS / Linux | ✅ 可用(需本地安装) |
142
+ | Fusion 360 | Autodesk CAD/CAM——常驻 Add-In + spool 桥(无 headless,Fusion 窗口即查看器) | Windows / macOS | 🧪 实验性(`cad_fusion`) |
143
+ | SolidWorks | 达索系统的主流 3D CAD,COM/.NET 自动化 | 仅 Windows | 🚧 Windows demo 脚手架(`scripts/solidworks-bridge/`) |
144
+ | Onshape | PTC 云原生 SaaS CAD,完全在浏览器——签名 REST API(cad.onshape.com 或私有 chamber 域名);每个 op 编译为标准 Onshape 特征推入 Part Studio,结果按零件回传 STL + 质量属性,云端即查看器 | 全平台(浏览器) | ✅ 可用(`cad_onshape`;设置 `DSH_ONSHAPE_ACCESS_KEY` / `DSH_ONSHAPE_SECRET_KEY`) |
145
+ | 中望3D(ZW3D) | 中望软件的一体化 CAD/CAM | Windows / Linux | 🚧 规划中 |
146
+ | 浩辰3D | 浩辰软件的 3D CAD | Windows | 🚧 规划中 |
147
+
148
+ 所有外部引擎实现同一 **GeometryExecutor 契约**(`available()` / `run(op程序) → 网格`),
149
+ WebGL 显示层因此永不改变——更换后端只影响生成几何的质量。
150
+
151
+ ## 架构
152
+
153
+ ```
154
+ cad_view(path) 建模工具(cad_create_prim 等)
155
+ → 导入 worker(occt-import-js) → 建模 worker(opencascade.js WASM)
156
+ → CadScene JSON(base64-f32) → BRep 精确几何 + 网格化
157
+ → GET /dsh-cad/scene/<id> → 内存二进制场景(f32/u32 打包)
158
+ → GET /dsh-cad/bin/<docId>
159
+ ↓ 会话 presentationMeta(viewId + 版本化 URL)↓
160
+ 浏览器卡片 + 常驻 "3D" 页签(three.js / SVG,Z-up,XYZ 轴)
161
+ ```
162
+
163
+ - **两个 worker**:导入(occt-import-js,只读 STEP/IGES/BREP)与建模(opencascade.js 1.1.1,
164
+ 完整 OCCT)分离,均惰性启动;embind 重载构造器的 `_N` 后缀约定封装在
165
+ `src/modeling/occt-adapter.cjs`(全部经运行时实证)
166
+ - **直通管道**:建模场景零 base64 / 零 JSON 大数组 / 零每步落盘(磁盘镜像 1.5s 防抖,
167
+ 仅服务重启回放);`cad_export` 是唯一的显式文件导出
168
+ - **建模文档**:`<workspace>/.dsh-cad/model.json` 操作日志,重启后重放恢复全部 body
169
+ - **工程图消隐内核**:隐藏线由 **occt.ts**(npm 依赖,`npm i occt.ts`)执行
170
+ 真实 OCCT 消隐,无替代引擎、缺失即报错。相对 opencascade.js 的新增 API:
171
+ `hiddenLines()` 真实消隐线、STEP/BRep 字节级 `readStep`/`readBrep`/`writeStep`/
172
+ `writeBrep`(无需 MEMFS)、自带特征边提取的网格化、`hasError()`/`lastError()`
173
+ 错误契约。几何以 STEP 字节跨内核交换,投影线段重映射进图纸坐标系。内核 dist
174
+ 解析顺序:`DSH_OCCTJS_DIST` 环境变量 → `node_modules/occt.ts/dist`(npm,
175
+ 默认)→ `<repo>/../opencascade-ts/dist`(兄弟检出)→ `vendor/` →
176
+ `node_modules/opencascade-ts`
177
+ - **约束求解(Ansatz)**:求解器是 npm 依赖 **`ansatz-wasm`**(wasm-bindgen
178
+ 构建,单包 ~538KB、零依赖)——安装 dsh-cad 即自动获得,也可单独
179
+ `npm install ansatz-wasm` 升级;**无需 Rust 工具链、无需原生二进制、跨平台**。
180
+ 解析顺序:npm 包(node_modules)→ `DSH_ANSATZ_WASM` 目录 → 兄弟 Ansatz 检出的
181
+ pkg-node。求解器以 JSON 信封契约通信,工具层错误(`unsupported_constraint` 等)
182
+ 原样透出给 LLM。装配实例位姿(平移 + XYZ 欧拉度)与求解器 rigid3(平移 + 指数映射
183
+ 旋转,弧度)双向映射。求解器能力按阶段推进(当前支持点到原点距离),管道契约
184
+ 已就绪、无需随求解器成长改动
185
+ - **单内核架构(v0.9)**:建模主内核切换为 **occt.ts ≥0.5.0**——prims/曲线段轮廓
186
+ (真 BSpline 插值)/放样/扫掠/旋转/布尔/圆角/倒角/抽壳/拔模/镜像(scale(-1)+
187
+ 旋转 π 组合)/质心全在一个会话内,工程图 HLR 直接吃 shape(零 STEP 中转),
188
+ 抽壳后继续编辑无缝(v0.8 的托管接缝删除)。opencascade.js 保留为**降级后端**
189
+ (occt.ts 加载失败时自动启用)。装配体 STEP 导出为**结构化文档**(occt.ts
190
+ ≥ 0.7.0 `writeStepDocument`):一个根产品 + 每实例一个命名、带位姿的子产品——
191
+ 实例分离在文件中保留(STL 仍为单一熔合网格;降级后端同样走 fuse)。fuse
192
+ 路径下实例分离仅保留在装配场景/文档中。面选择按 `describe()` 平面法向
193
+ 匹配(±法向取外侧投影最大者)
194
+ - **客户端**:esbuild 单文件 CJS 工厂(three.js 内联 ~560KB,react 由宿主模块表提供),
195
+ Z-up CAD 惯例,带 XYZ 轴标签与地面网格的空场景常驻显示
196
+
197
+ ## 测试
198
+
199
+ ```sh
200
+ npm test # 41 项:转换器 / 建模 worker(体积精确断言)/ DCPRT 往返 / FreeCAD 执行器 / 图片轮廓 / 二进制管道 / 文档持久化
201
+ node test/m0-kernel-check.cjs # OCCT 内核 API 冒烟
202
+ node test/route-check.mjs # JSON 场景路由层
203
+ node test/visual/serve.mjs # 浏览器卡片/页签视觉验证页(http://127.0.0.1:3987)
204
+ ```
205
+
206
+ 覆盖的代表性断言:布尔打孔体积精确等于解析值(28429.20 mm³)、L 型轮廓拉伸
207
+ 3000 mm³、球/锥/环带 `at`/`axis` 定位的体积与包围盒翻转、二进制打包 8 字节对齐、
208
+ STL 导出往返(导出 → 一期解析器读回),以及 DCPRT 文档往返
209
+ (序列化 → OCCT worker 重放 → 精确包围盒)。
210
+
211
+ ## 已知限制
212
+
213
+ - DWG(闭源)不支持;DXF bulge 弧以弦线近似;glTF/3MF 查看未实现(结构已预留)
214
+ - `cad_fillet` 为全边等半径(embind 下按边选择不稳定);chamfer 未实现
215
+ - 草图拉伸仅支持多边形轮廓(圆弧轮廓用布尔组合圆柱/圆环构造)
216
+ - dsh 框架限制:已挂载的 single 槽(右侧 details 面板本体)不响应后注册组件,
217
+ 故常驻显示区以 "3D" 视图页签提供(list 槽,官方组合方式)
218
+ - 宿主读取 CAD 文件使用 node:fs(平台 fs 服务仅支持 UTF-8 文本,无法承载二进制)
219
+
220
+ ## 社区
221
+
222
+ | QQ 群(🇨🇳 国内) | 飞书群(🇨🇳 国内) | X / Twitter(🌍 国际) | Discord(🌍 国际) |
223
+ | --- | --- | --- | --- |
224
+ | `485038246`(加群备注 dsh-cad) | 🚧 敬请期待 | 🚧 敬请期待 | 🚧 敬请期待 |
225
+
226
+ <!-- TODO: 发布前填入 X 账号 / Discord 邀请链接 -->
227
+
228
+ ## 贡献者
229
+
230
+ 由提交历史自动生成,感谢每一位贡献者!
231
+
232
+ [![Contributors](https://contrib.rocks/image?repo=LAU-MARS/dsh-cad)](https://github.com/LAU-MARS/dsh-cad/graphs/contributors)
233
+
234
+ ## License
235
+
236
+ MIT
@@ -65,11 +65,13 @@ export function isKnownOpKind(kind) {
65
65
  /** Registry of the executors compiled into this build (display order). */
66
66
  import { FREECAD_EXECUTOR } from './freecad-executor.js';
67
67
  import { FUSION360_EXECUTOR } from './fusion360-executor.js';
68
+ import { ONSHAPE_EXECUTOR } from './onshape-executor.js';
68
69
  import { BUILTIN_EXECUTOR } from './builtin-executor.js';
69
70
  export const EXECUTORS = [
70
71
  BUILTIN_EXECUTOR,
71
72
  FREECAD_EXECUTOR,
72
73
  FUSION360_EXECUTOR,
74
+ ONSHAPE_EXECUTOR,
73
75
  ];
74
76
  export function executorById(id) {
75
77
  return EXECUTORS.find((executor) => executor.id === id);