最近这段时间我密集测了一轮 text-to-cad 相关的工具和开源项目。先说个最直观的感受:这个词虽然只比 text-to-3d 多了三个字母,但两者完全不是一个物种。text-to-3d 给你的是三角网格,做渲染摆件绰绰有余,但要拿去 CNC 加工、3D 打印出实物、或者丢进 CAE 里做仿真,网格基本等于废纸。text-to-cad 的目标是输出真正的 CAD 模型——带特征树、带草图约束、能改参数、能重新计算,导出的 STEP 文件能直接进 CAM 切刀路。
这篇文章就是我把这段实测过程整理出来的结果。内容包括:text-to-cad 到底在解决什么问题、当前几条主流技术路线各自的脾气、从一句自然语言到可编辑 CAD 文件的完整操作流程、决定生成质量的隐藏细节、落地时最常见的翻车场景和排查顺序,以及如果你们团队想自己训一套私有模型,最小可行方案应该怎么搭。适合正在评估这个方向能不能进研发流程的工程师,也适合做 AIGC 但对参数化建模不太熟的研究者。
1. 先搞明白一个前提:text-to-cad 的产物为什么不是"模型"而是"特征树"
1.1 从网格到 B-rep,差了一个"可编辑等级"
做 AI 生成的人,对 3D 的认知通常停留在 mesh——一堆三角形拼出来的表面。text-to-3d 的生成器本质上是去预测"这个形状长什么样",最后抽一个网格出来。但 CAD 行业的内部表示方式完全不是这样,主流是 B-rep(Boundary Representation,边界表示)。B-rep 用精确的拓扑关系来描述实体:面、边、顶点,以及它们之间怎么连接,而且这些曲面是解析曲面——平面、圆柱面、圆锥面、B 样条曲面。半径为 50 的圆柱面,算出来就是 50.000,不是 49.97。
这个差别决定了 text-to-cad 不能像 text-to-3d 那样"画一幅很像的图"就行。它必须生成拓扑正确、面与边完全闭合、能求出体积和质量属性的实体。CAD 内核(OpenCASCADE、Parasolid、ACIS 这类)在导入模型时非常严格,一旦检测到一条非流形边、一个自相交面、一片翻转法向的薄壳,随时会拒收这个文件。网格可以"看起来像"蒙混过关,B-rep 没有这个缓冲带。
1.2 设计意图:CAD 的灵魂不在形状,在参数关系
不少第一次接触参数化建模的人,会把"建模"理解成"造型"。但我在实际工程里待久了,越来越觉得参数化 CAD 更像写程序:草图是代码,尺寸是变量,特征操作是函数,特征树就是执行顺序。你改一个变量——比如法兰外径从 100 改成 120——理想情况下整个模型应该自动重新计算,所有关联的孔位、倒角、厚度跟着变。这个能力在 CAD 行话里叫设计意图(design intent),也是一个模型真正的价值所在。
所以 text-to-cad 要生成的,不只是"一个看起来像 X 的静止形状",而是"一整套可以被编辑的规则":孔位是阵列还是逐一草绘、倒角加在哪个特征后面、厚度由哪个尺寸驱动。如果生成的结果打开特征树一看,里面是一堆失去关联的绝对坐标草图,那跟拿 b-rep 网格又有什么区别?"生成一个看起来对的模型"只是及格线,"生成一个工程师能持续修改的模型"才是目标。这也是这个方向比 text-to-3d 难那么多的根源——它需要几何生成能力和程序(特征序列)生成能力同时在线。
1.3 为什么通用大模型不能直接"画"出 CAD
很多人会问:既然大模型什么都会,直接让它输出 CAD 文件不就行了?问题是 CAD 文件不是一张图,而是一串操作历史。你要从一块毛坯圆柱开始,拉伸、挖孔、倒角、布尔差集,每一步都有依赖关系。大模型本质上是个 token 预测器,它擅长的是语言序列、代码序列,但它没法直接"幻想"出一个拓扑闭合的实体。它必须借助 CAD 内核,把描述转成一步一步的建模指令,让内核去执行、去计算、去检验。所以 text-to-cad 的所有技术路线,本质都在解决同一件事:如何让模型生成"可执行且可编辑"的建模指令序列,而不是生成"好看的表皮"。
2. 当前主流的三条技术路线:代码生成、扩散模型、检索装配
2.1 路线一:让大模型写参数化代码
这条路是门槛最低、迭代最快的。思路特别朴素:CAD 的二次开发 API(CadQuery、build123d、OpenSCAD、Fusion 360 Python、Onshape FeatureScript)本质上是"用代码描述建模过程",而大模型最擅长的就是写代码。你让 LLM 直接输出一段 CadQuery 代码,扔进 Python 执行,跑通了就得到一个带特征树的模型。
我实测下来,这条路线对常见机械零件的命中率相当高。比如"一个带 6 孔法兰,外径 100,内径 50,厚度 20,均布 6 个直径 8 的孔",让现成的代码大模型直接写,一次跑通的概率不低。因为 CadQuery 社区有大量现成写法,模型在训练数据里见过类似代码。但一旦涉及复杂曲面放样、多实体布尔运算、扫掠路径之类的操作,代码就开始胡说,编造不存在的 API、参数名对不上函数签名,跑起来全是红色报错。
这条路的优点非常明确:输出天然可参数化,改尺寸就是改代码里的变量;建模过程完全透明,每一步干了什么都能审计。缺点也明显:模型的"幻觉"集中在 API 调用上,而且它经常为了凑你 prompt 里的某个词,硬加一堆无意义的操作,整个特征树冗余得没法看。
2.2 路线二:把建模操作序列当语言,用生成模型直接吐
这是现在学术界和工业界押注最多的方向。核心思路是把 CAD 建模过程表示成一个操作序列:画草图(圆、圆心在原点、半径 r)→ 拉伸(深度 d)→ 倒角(半径 f)→ 阵列孔(6 个)。这些操作可以离散化成 token,然后训练一个自回归模型或者扩散模型去生成 token 序列,最后在 CAD 内核里把这段操作"重新播放"一遍,得到实体。
公开工作里 DeepCAD、Text2CAD、以及 Zoo 推出的 Text2CAD、Google DeepMind 的 Grace,本质都是这个思路,只是工程化程度不一样。这种模型的好处是,它学的是真实建模习惯——什么操作先做、什么后做、草图怎么约束——而不是像路线一那样赌"代码库里恰好有这个写法"。坏处也直接:训练数据非常贵,需要把大量真实 CAD 模型反解成特征树和参数,光数据清洗就能干哭一个团队;而且生成能力被训练集里的操作类型锁死,遇到没见过的特殊特征,基本只能摆烂。
2.3 路线三:检索 + 模板参数化
这条路线往往被人忽略,但我觉得在工业落地里它是最"稳"的。思路是建一个零件库或者模板库,text-to-cad 先做语义检索,找到最匹配的模板,再用 LLM 或规则引擎把文本里的关键参数(尺寸、孔距、倒角值)映射到模板参数上。这相当于做"标准件派生":标准法兰、电机安装座、外壳类零件的变型设计。
它的上限不高,只能覆盖预先建好的零件族,但它几乎不会失败。参数从文本里抽错的比例,比从头生成低得多。制造业里大量需求本质上就一句话:"我要一个孔径 X、底座边长 Y、带 Z 个安装孔的电机座"。这种需求不叫"生成模型",但叫"参数化变型",能直接干活。很多时候,比一个"看起来像但没法改"的生成模型有用得多。
2.4 三条路线怎么选
我自己的取舍原则是:先用路线一跑通整个流程,把路线二作为研究上的重点,用路线三保底。
| 路线 | 可编辑性 | 泛化能力 | 数据需求 | 落地难度 | 最适配场景 |
|---|---|---|---|---|---|
| LLM 写参数化代码 | 高,代码即模型 | 较好,依赖底座模型 | 低,用现成 LLM | 低 | 概念设计、快速原型、非标方案初稿 |
| 扩散/自回归生成特征序列 | 中,特征树可改但受训练集限制 | 低,被操作类型锁死 | 很高,需要大量真实 CAD 特征序列 | 高 | 复杂零件的自动化生成研究 |
| 检索 + 模板参数化 | 高,模板内自由改 | 低,仅覆盖模板族 | 中,模板库建设成本 | 低 | 标准件、系列件变型设计 |
如果一个团队只有两三个工程师,又要快速出效果,我建议先做"路线一 + 路线三"的组合:常见件走模板派生,非常规件让 LLM 写代码,生成完再用统一脚本做几何检查和修模。路线二值得投入,但它是长线工程,别指望两个月内能替换掉你们现有的设计流程。
3. 实测流程:从一句自然语言到可编辑 CAD 文件
3.1 环境准备和工具选型
想上手实测,我建议从开源项目开始,不要一上来就买商业 API,否则你根本不知道生成的模型是怎么来的,后面排错也没法下手。以 Zoo Text2CAD 这个开源实现为例,它的通用流程大致是:
- 准备一台至少 24GB 显存的 GPU,生成质量跟显存关系很大,显存太小得降分辨率,而 CAD 这行降分辨率基本等于废。
- 用 conda 或者 uv 建 Python 虚拟环境,装 PyTorch、CAD kernel 相关的绑定库。
- 下载模型权重 checkpoint,现在公开权重一般是经过 CAD 操作序列预训练后再用文本-模型对微调的。
- 跑一句命令行,输入 prompt,指定输出路径,生成一个 STEP 文件:
python generate.py \ --prompt "a mounting bracket with two 6mm holes spaced 40mm apart, 10mm thick, with a 2mm fillet on all edges" \ --output bracket.step生成完成后,用 FreeCAD 打开 STEP 文件,或者直接打开项目导出的原生格式,你就能在左侧看到特征树了。这一步非常关键:如果打开后只有一个"哑实体"(没有特征历史),说明工具生成的是 B-rep 快照而不是参数化特征,可编辑性要打折扣。
3.2 写 prompt 的几条铁律(附示例)
prompt 写得好不好,直接决定生成结果是"能用的初稿"还是"要删掉重来"。这段时间我总结了六条铁律:
- 先说单位。所有尺寸后面都带 mm、inch 或 cm。不带单位是大模型的默认死穴,它只会随机猜一个。
- 给绝对尺寸和坐标。不要用"大一点""厚一点"这种相对词,要用"外径 100,厚度 20"这种绝对数值。模型做的是 token 预测,相对词它没法换算。
- 明确基准平面和拉伸方向。比如"草图在 XY 平面,沿 +Z 方向拉伸 10mm"。不说清楚,它可能默认 Y 轴向上,出来的模型整个翻面。
- 一次只描述一类核心特征。不要在一个 prompt 里同时要放样、扫掠、布尔、阵列,操作越多,出错概率指数上升。
- 删掉装饰性词汇。"漂亮的""光滑的""看起来很现代"这些词对大模型生成代码没有帮助,反而可能把它引向非 CAD 的语义空间,生成一堆不存在的 API。
- 用数字范围做约束。如果你对某个尺寸不敏感,可以写"between 20 and 30mm",这比"差不多就行"有效得多,模型会在数值分布里采样一个合理值。
举一个对比示例。好 prompt:
Create a rectangular mounting plate, 80 x 50 x 10 mm, in the XY plane, extruded along +Z. Add four 6 mm through-holes at the corners, centers 10 mm from each edge. Units: mm.
坏 prompt:
make a nice bracket with some holes, not too big, smooth edges
后者我跑出来的结果经常是:尺寸完全靠猜、孔位随机撒、还多出一堆莫名其妙的圆角特征。做 text-to-cad,prompt 的质量比在文生图里重要得多,因为几何是精确系统,差一毫米就是废件。
3.3 拿到输出后怎么验收
很多人跑通一次就开心地以为结束了,恰恰是这时候坑才开始。我有一个固定的验收清单,每次生成后必须过一遍:
| 检查项 | 方法 | 通过标准 |
|---|---|---|
| 形状 | 视觉 + 关键尺寸测量 | 与 prompt 描述的偏差在可接受范围 |
| 单位 | 看 FreeCAD 单位设置和 STEP 头文件 | mm / inch 确认无误 |
| 实体性 | 用几何检查功能检测 | 单一 solid,无开放壳、无非流形边 |
| 可重算 | 修改一个主尺寸,触发重新计算 | 特征树无红叉、无报错 |
| 可导出 | 导出 STEP 后再重新导入 | 无报警、几何保持完整 |
这里特别提醒"可重算"这一项。生成模型可能给你一个"看着很对"的实体,但一旦你改动父尺寸,整个特征树直接崩掉。我在实测里见过不少案例:模型生成时用的是写死的绝对坐标,没有约束关系,改一个孔距,其他孔全留在原地,这种模型在工程上等于一次性筷子。验收的时候一定要亲手改一个参数,看看模型的表现再下结论。
4. 决定生成质量的隐藏细节:坐标系、单位、约束与特征顺序
4.1 坐标系与草图平面:一个方向念错,整个模型翻面
CAD 江湖里一直有"Z 轴向上"和"Y 轴向上"两派。机械设计里常用 Z 上,某些 DCC 工具和部分仿真软件习惯 Y 上。生成的模型如果坐标系基准选错,轻则视图里看着歪,重则装配时所有约束全部失效。你验证方式很简单:生成后立刻检查基准平面和第一个草图的方向,看拉伸方向是不是和你要的一致。如果模型整体镜像了,大概率是草图平面的法向定义反了;如果模型转了 90 度,大概率是坐标轴向的约定问题。
要治这个病,prompt 里就得把"在哪个平面画草图、往哪个方向拉伸"写死,这是我在 3.2 里反复强调的原因。另外,生成后用对齐工具把基准坐标对齐到装配原点,花不了半分钟,但能避免后续一整套装配崩掉。
4.2 单位:模型眼里的毫米和英寸
这是我踩过最深的坑,没有之一。大模型训练数据里毫米和英寸混着来,你写"5mm"它可能理解成"5",但底层单位默认成了 inch,最后实际尺寸是 127mm。更阴险的是,有时候 STEP 文件里根本没写单位元数据,CAD 软件只能靠模型整体大小去猜——小模型被自动当 inch,大模型被当 mm,一旦猜错,导出 STEP 再导入,尺寸全变了。
所以验收清单里我专门放了一行"单位确认"。拿到文件第一件事,在 FreeCAD 的单位设置里看当前文档单位,量一个关键尺寸,和 prompt 里的数字对比。不要只看百分比,要实际量。另外,如果你准备做自动化流程,批处理生成完一定要用脚本检查 STEP 头文件里的单位字段,有问题直接标记,不要流到下游。
4.3 约束优先于坐标:能参数化才算 CAD
这里多说一句"约束"和"坐标"的区别。假设法兰上有 6 个孔,你可以用 6 个绝对坐标画 6 个圆,这就是"坐标驱动";你也可以画一个圆,标注直径,然后做阵列,用一个角度参数控制分布,这就是"约束驱动"。从外形上看,两者一模一样;但从设计意图上看,一个改参数就崩,一个改参数全会跟着变。
text-to-cad 生成的模型,我见过太多全是"坐标驱动"——因为它就是这么被训练的,写死坐标比推理约束关系简单得多。你自己做 prompt 的时候,可以明确要求"use pattern/array for holes"、"define hole centers relative to plate center",这能大幅提高生成结果的约束质量。万一生成出来没有约束,导入 FreeCAD 后手动加几个约束也不难,关键是要有这个意识:拿到模型先检查约束关系,而不是先看形状像不像。
4.4 特征顺序:为什么圆角不能乱加
参数化建模里特征顺序太重要了。标准流程一般是:拉伸主体 → 打孔 → 阵列 → 圆角/倒角。顺序错一步,结果可能天差地别。比如你先在棱边上加了 2mm 圆角,再打孔,孔口边缘的圆角会被布尔差集吃掉,边界就乱了;反过来,你先打孔再加圆角,圆角会沿着孔口边缘走,形态更干净。但很多 LLM 生成的代码完全不管这些,最后一个圆角命令经常因为找不到边而直接报错。
还有一个经典翻车:圆角半径大于壁厚。你要求"壁厚 3mm,圆角 4mm",几何内核里根本算不出来——材料都不够圆角吃,不是报错就是生成一个扭曲的自相交面。遇到这种情况,我一般是让 prompt 里圆角值跟壁厚挂钩,或者生成后看到报错就知道是特征顺序的问题,先删掉圆角,做完全部主体特征再加回去。
5. 落地时的翻车现场:常见失败模式与排查链路
5.1 非流形与自相交:几何内核的无声拒收
CAD 内核是最不讲情面的一层。网格模型流行一个三角形嵌进去,渲染出来没人发现;B-rep 只要有一个自相交面,很多下游操作直接罢工。我跑 text-to-cad 时遇到最多的一类报错就是:"profile is self-intersecting"(草图轮廓自相交)或者"cannot create solid: shell is not closed"。
根因很简单:生成模型在预测草图时,把两条本该分开的线段交错到一起了。比如拉伸截面是个 L 形,两条线段本该在拐角相接,模型却给画岔了。这种错误没有任何肉眼预兆,靠的就是内核检测。所以批处理跑生成任务时,一定要第一时间做几何健康检查,过滤掉所有 non-manifold、open shell、self-intersect 的结果。这一步不做,后面全是在垃圾上盖楼。
5.2 单位漂移:看起来对,量起来错
前面 4.2 讲了单位问题的原理,这里说一个我真实遇到的例子。我用 prompt 生成一个"直径 5mm 的定位销",出来的 STEP 文件在 FreeCAD 里显示尺寸是 5,但实际质量属性一算,体积对应的直径是 127mm——模型内部用的是 inch 单位,数值 5 英寸等于 127mm。单个零件看不出问题,一旦拿去装配或者加工,直接报废。
我的处理办法是:生成脚本里统一做一步"单位归一化"——用 OCP(OpenCASCADE 的 Python 绑定)打开模型,读文档单位,跟预设单位比较,不一致就缩放 25.4 倍并重写单位字段。这条逻辑写死在预处理流程里,不要靠人肉盯。
5.3 特征树重建失败:改一个尺寸,全线飘红
这是所有"看起来能用"的模型里最坑的一种。你把生成的文件拖进 FreeCAD,形状完美,孔位分布均匀,倒角似乎在。但你随手把板厚从 10 改成 15,点了重新计算,整个特征树瞬间红叉一片。原因是生成时用的是绝对坐标草图,父特征一变,依赖它的所有子特征全部失去参考。
遇到这种情况,别再傻傻地手修特征树。正确的做法是回到源头,给 prompt 加约束要求,或者换一种生成方式(比如改走检索模板路线),让模型生成时就用相对约束、用参考边、用标注尺寸。我花了很长时间才意识到,这类问题在你改第一个参数之前是永远发现不了的——所以验收清单里的"改一个主尺寸"步骤一定不能省。
5.4 我的排查顺序
生成结果出问题的时候,别慌,按这个链路从前往后排查,多数问题十分钟内能定位:
- 看日志。哪个操作报的错?拉伸还是布尔还是倒角?把报错卡点记住。
- 单独重放草图。把报错特征之前的草图单独拿出来,检查轮廓是否闭合、有无自相交。这一步能干掉一半问题。
- 检查布尔对象。布尔差集之后是不是残留了多余的实体、破面或者退化边?用布尔检查功能看是否可以重新合并成一个 solid。
- 按顺序消减特征。把所有倒角、圆角、装饰特征全删掉,只保留基础拉伸,看能不能重建。可以了,再一个个加回。通常很快就能发现是哪个特征触发的失败。
- 用修模工具清洗。有些非流形问题可以通过内核自带的 healing 功能修复,但不能指望,修复完还得再过一遍健康检查。
- 果断重新生成。如果模型结构已经烂到没法救了,直接改 prompt 重跑。生成模型重新跑一次的边际成本很低,比你在破模型上手工修两个小时值多了。
6. 想自己训一套私有 text-to-cad,最小方案长什么样
6.1 先锁死零件族:数据集的正确打开方式
很多人一上来就想训一个"什么都能生成"的通用模型,我劝你放弃这个念想。CAD 零件种类太庞大,特征组合是天文数字,通用模型的训练成本和数据需求根本不是普通团队扛得住的。正确的做法是先锁死一个零件族:只做钣金支架、只做电机安装法兰、只做外壳类零件。零件族定死了,特征模式有限,数据才攒得起来,效果才出得来。
数据来源我建议用"模板批量生产"而不是"到处爬"。你在 CadQuery 或者 build123d 里写一个参数化模板,随机化尺寸参数,批量跑出几千个模型,同时导出 STEP 文件和对应的建模代码。这种数据的质量比从网上七拼八凑高一个量级,因为它自带 ground truth 特征树,而且干净——没有破面、没有没人要的冗余特征。如果你需要文本-模型对,可以用模板化的文本生成器拼写出描述,比如"a bracket with ${width}mm width, ${hole_count} holes along the long edge"。
6.2 两条自训路线的性价比对比
| 方案 | 技术栈 | 代价 | 效果 | 适合团队 |
|---|---|---|---|---|
| A:开源代码模型 + LoRA 微调 | Qwen2.5-Coder / CodeLlama + LoRA | 低,几千条高质量代码-文本对就能看到效果 | 能生成 CadQuery 代码,间接得到 CAD 模型 | 1-2 个 ML 工程师,想快速落地 |
| B:自建操作序列生成模型 | 参考 DeepCAD / Text2CAD 思路,自己实现 tokenizer + transformer/diffusion | 高,要自己做 CAD 数据反解、序列化、训练、解码、内核重放 | 生成更接近真实建模习惯,但开发周期长 | 有 CAD 数据团队和算法研究能力的团队 |
我在 6.1 里说"锁死零件族",目的就是为了让方案 A 也能出效果。一个零件族内的 CadQuery 代码模式相对固定,LoRA 微调几百步就能学会这种风格。方案 B 是更本质的方向,但它每一步都是硬骨头:CAD 操作序列的反解工具链就够忙活大半年。如果团队预算和工期允许,我的建议是"A 保交付、B 做预研"。
6.3 评估指标:别只看相似度,要看能不能改
自训模型必须建一套自己的评估指标。别抄文生图那套,什么 FID、CLIP score,在 CAD 领域参考价值有限。我推荐三层评估:
- 几何相似度:在生成模型和真模型的表面上均匀采样点云,算 Chamfer Distance。这一层只能说明"像不像",通过门槛即可,不必过分追求。
- 结构正确性:模型必须是单一 solid、流形、无自相交;特征树能完整重新计算;导出 STEP 再导入无报警。这一层不通过,直接标记失败,不用进入下一层。
- 可编辑性:随机修改一个主参数,看特征树重算成功率、平均手动修复时间。这才是"能不能进研发流程"的核心指标。
另外非常推荐维护一个"金标准评测集":50 个典型零件,每个配 3 句话的描述,固定不变。每次模型迭代后都跑一遍,既防退化又方便对比。不要今天换一组测试样本明天换一组,那样你根本分不清是模型进步了还是题目变简单了。
6.4 踩完一圈后的几个实在建议
最后说几个我实操之后才明白的道理。
第一,prompt 模板库的收益比模型参数量大得多。我给同一个模型做了三套不同的 prompt 模板,生成成功率能从 40% 拉到 70% 以上。先把常用的几十种零件描述固化下来,再回头调模型,性价比完全不一样。
第二,把验收脚本自动化。生成完立刻跑几何健康检查,非流形、确定不了单位的直接打回重生成。我在团队里把这一步做成了流水线的一部分,效果立竿见影——下游工程师拿到的文件,平均返工次数降了一半。
第三,允许模型说"不知道"。我自己体验下来,最难受的不是模型生成得烂,是它明明烂还硬编一个尺寸充数。你可以让模型的输出先是一个置信度判断,如果它觉得 prompt 超出了它的能力范围,直接返回"无法生成"并建议改描述,比生成一个废件然后浪费一次排错周期要强。
第四,现在就开始攒数据。text-to-cad 这个方向,瓶颈不在模型结构,而在高质量的"文本-CAD 操作序列"数据。哪怕你暂时不训模型,把你团队历史项目的图纸、特征树、参数关系整理成结构化数据,半年后你想上这个方向的时候,数据就是你最大的护城河。我见过太多团队模型跑了三个月,最后发现卡死他们的不是算力,是数据集太脏。早一天开始整理,你落地就早一天。