CAD 这行当有个特别拧巴的地方:设计师脑子里的三维结构,要变成机器能读的几何文件,中间隔着一整套手工建模流程。画个法兰盘,得先选基准面、画草图、约束尺寸、拉伸、倒角、打孔,一套下来十几分钟没了。要是碰上参数化系列件,改一个尺寸就得重新走一遍特征树。这几年大模型写代码、写文案都挺溜了,那能不能让它直接写 CAD 模型?text-to-cad这个方向就是冲着这件事去的——用一段自然语言描述,直接生成可用的 CAD 几何文件,输出 STEP、URDF、G-code 这类下游能直接消费的格式。它解决的不是"画图快一点"的问题,而是把"描述即模型"这条路打通,让不会 CAD 的人也能产出几何,让会 CAD 的人从重复建模里解放出来。下面我按自己趟过的路子,把这件事拆开讲透。
1. 先搞清楚 text-to-cad 到底在生成什么
很多人第一次听到 text-to-cad,脑子里浮现的是"AI 帮我点鼠标画图"。这个理解偏了。真正有价值的 text-to-cad,输出的不是屏幕上的像素或者某个私有格式的工程文件,而是结构化的几何描述,最终落到标准交换格式上。为什么强调这一点?因为 CAD 生态里格式就是命脉,你生成一个只有自家软件能打开的玩意儿,下游 CAM、仿真、3D 打印全接不上,等于白干。
1.1 三种目标格式对应三条完全不同的下游链路
从关键词里能看出,STEP、URDF、G-code 是三个高频词,它们其实代表了三条链路:
- STEP:中性几何交换格式,走的是"精确 B-rep(边界表示)"路线。它描述的是数学上精确的曲面和实体,公差可控,是机械加工、装配、CAE 仿真的通用语言。你生成 STEP,意味着下游可以拿去做数控编程、做有限元网格划分。
- URDF:统一机器人描述格式,本质是 XML,描述的是连杆 + 关节的树状结构。它不关心曲面精度,关心的是运动学关系——哪个部件绕哪个轴转、转多少度、质量多少、惯性张量多大。机器人仿真里导入 CoppeliaSim 这类工具,吃的就是 URDF。
- G-code:数控机床和 3D 打印机的指令流,是"刀具路径"级别的描述。它不描述实体,描述的是喷头或刀具怎么走。从文本直接到 G-code,中间其实跳过了实体建模,直接做路径规划,难度和风险都更高。
这三者不是一回事,做 text-to-cad 之前必须先想清楚:你要的是精确实体、运动学模型,还是加工路径?选错了格式,后面全白搭。
1.2 为什么"文本直接到几何"比"文本到代码"难得多
写代码有编译器兜底,语法错了立刻报错。几何不一样,一段描述生成出来的模型,可能语法上完全合法、能打开、能渲染,但尺寸是错的、壁厚是负的、孔打到了实体外面。几何的正确性是隐性的,它不会主动告诉你"这里不对"。所以 text-to-cad 的核心难点不在生成,而在约束求解和几何校验。
我自己的体会是,把这件事拆成两段更靠谱:第一段,大模型把自然语言翻译成参数化的结构化中间表示(比如一段描述尺寸、特征、约束的 JSON 或 DSL);第二段,用确定性的几何内核(OpenCASCADE、CadQuery、build123d 这类)去执行这个中间表示,生成真正的几何。大模型负责"理解意图",几何内核负责"保证正确",各干各擅长的事。让大模型直接吐 STEP 文本?那基本是在赌它背过多少几何数据,不可控。
1.3 一个最小可用的中间表示长什么样
假设用户输入"一个 80mm 见方、厚 10mm 的底板,四角各一个直径 6mm 的通孔,孔中心距边缘 10mm"。合理的中间表示大概是这样:
{ "type": "plate", "width": 80.0, "depth": 80.0, "thickness": 10.0, "features": [ { "type": "hole", "diameter": 6.0, "through": true, "positions": [ {"x": 10.0, "y": 10.0}, {"x": 70.0, "y": 10.0}, {"x": 10.0, "y": 70.0}, {"x": 70.0, "y": 70.0} ] } ] }这个 JSON 就是"意图"和"几何"之间的契约。大模型只要输出这个,几何内核负责把它变成实体。好处是:可校验、可复现、可参数化。用户改一个尺寸,改 JSON 就行,不用重新问模型。这也是为什么我强烈建议不要跳过中间表示这一步。
2. 从自然语言到参数化中间表示:提示词与约束设计
中间表示定好了,接下来就是怎么让大模型稳定地吐出它。这一步的坑比想象中多,因为自然语言描述几何天生是模糊的。"一个圆角"——多大?"几个孔"——几个、在哪、多大?用户不会说全,模型就得会补全,而补全的默认值必须合理。
2.1 把几何意图拆成"实体 + 特征 + 约束"三层
我实践下来,最稳的拆法是三层:
- 基体(base):模型的主体形状,长方体、圆柱、拉伸轮廓等。
- 特征(features):在基体上做的加减操作,孔、槽、凸台、倒角、圆角。
- 约束(constraints):尺寸、位置、对称、共线等关系。
提示词里要把这三层讲清楚,并且给出默认值策略。比如用户没说圆角半径,默认取壁厚的 1/4 或者一个固定小值(如 1mm),并在输出里标注"该值为推断值"。这一点特别重要——让模型显式声明哪些是用户给的、哪些是它猜的,下游才能判断风险。
2.2 提示词模板里必须钉死的几件事
我用的模板大致包含这些硬约束:
- 单位统一为毫米,所有数值必须带单位或明确声明为 mm。
- 坐标系约定:Z 轴向上,基体底面在 Z=0 平面。
- 特征顺序:先加后减,倒角圆角放最后。
- 输出必须是合法 JSON,不允许有注释、不允许有省略号。
- 遇到无法确定的参数,输出
"inferred": true并给出理由字段。
提示:不要指望一次提示就能稳定输出。我一般会做两轮——第一轮让模型输出中间表示,第二轮专门做"自检",让它检查尺寸是否自洽(比如孔径是否小于板宽、孔位是否在实体范围内),把问题在生成几何之前就拦下来。
2.3 处理"模糊描述"的实用技巧
用户说"给我做个支架",这几乎没法直接生成。我的做法是反问补全:模型先输出一个"待确认参数清单",列出它需要但用户没给的关键尺寸,让用户填。这比硬猜一个模型出来、用户发现全错要高效得多。实测下来,反问一轮能把返工率降一大半。
另一个技巧是给参照物。用户说"大概手掌大小",模型可以映射到一个经验尺寸区间(比如 80–100mm),并标注这是估算。把模糊词映射成数值区间,是 text-to-cad 里非常实用的一环。
3. 几何内核选型:为什么我最终落在代码化建模上
中间表示有了,得有个东西把它变成真几何。这一步的选型直接决定项目能不能落地。市面上的路子大概三类:直接调商业 CAD 的 API、用开源几何内核、用代码化建模库。我挨个试过,说说各自的坑。
3.1 商业 CAD API 路线:能力强但重
SolidWorks、中望 CAD 这类都有二次开发接口,能通过脚本驱动建模。优点是几何内核成熟、精度高、能直接出工程图。缺点是重——你得装一整套 CAD,还得处理授权、版本兼容。热词里"cad 激活页面脚本发生错误""安装 cad 一直出现 c++2005 错误"这些,全是这条路线的现实摩擦。做服务端批量生成,装一堆商业软件本身就不现实。
3.2 开源几何内核路线:OpenCASCADE 是底座
OpenCASCADE(OCCT)是很多开源 CAD 的几何内核,B-rep 能力完整,能读写 STEP。直接用它的 C++ API 门槛高,但它是很多上层库的地基。如果你要做严肃的、精度要求高的 text-to-cad,最终大概率会落到它上面。Python 侧有 pythonocc 封装,能用,但文档和示例偏少,踩坑成本不低。
3.3 代码化建模库:CadQuery 与 build123d
这是我最推荐的起步路线。CadQuery 用 Python 的链式调用描述几何,build123d 是它的后继思路,语法更接近 Python 原生。它们底层就是 OCCT,所以生成的 STEP 是精确 B-rep,不是网格。举个例子,生成前面那个带孔底板:
import cadquery as cq result = ( cq.Workplane("XY") .box(80, 80, 10) .faces(">Z") .workplane() .rect(60, 60, forConstruction=True) .vertices() .hole(6) ) cq.exporters.export(result, "plate.step")这段代码就是"中间表示 → 几何"的执行器。大模型生成的 JSON,映射成这样的调用,就能出 STEP。代码化建模的最大好处是可版本控制、可参数化、可批量,特别适合和 text-to-cad 结合。
3.4 三条路线的对比
| 路线 | 几何精度 | 部署成本 | 适合场景 | 主要坑 |
|---|---|---|---|---|
| 商业 CAD API | 高 | 高 | 出工程图、复杂装配 | 授权、版本、安装报错 |
| OpenCASCADE 直用 | 高 | 中 | 深度定制内核 | 学习曲线陡、文档少 |
| CadQuery/build123d | 高 | 低 | 参数化零件、批量生成 | 复杂曲面能力有限 |
我的建议是:先用 CadQuery 把链路跑通,验证价值,再考虑要不要下沉到 OCCT。一上来就啃 OCCT,很容易卡在环境配置上出不来。
4. 输出 STEP 与 URDF:两条链路的实操细节
生成几何只是第一步,导出成下游能用的格式才是交付。STEP 和 URDF 的导出逻辑差别很大,分开说。
4.1 STEP 导出:精度、单位、坐标系三件事
STEP 导出看着简单,其实有三个容易翻车的点:
- 单位:STEP 文件头里带单位声明,但不同内核默认值不一样。有的默认米,有的默认毫米。导出后一定要用工具(比如 FreeCAD 或 OCCT 的读取器)验证一下尺寸,别等下游加工出来才发现大了 1000 倍。
- 坐标系:约定好 Z 轴向上还是 Y 轴向上。机械领域常用 Z 向上,但有些仿真工具默认 Y 向上,导入后模型是躺着的。
- 精度:B-rep 的精度由内核公差控制,一般默认够用,但如果模型里有极小特征(比如 0.1mm 的槽),要检查公差是否把它抹掉了。
提示:批量导出时,给每个文件加上参数指纹(比如尺寸的哈希)作为文件名后缀,避免不同参数生成的同名文件互相覆盖。这个坑我在批量生成系列件时踩过,一晚上覆盖掉几十个模型。
4.2 URDF 导出:从几何到运动学,中间差了一整套物理属性
URDF 不是几何格式,是运动学 + 动力学描述。从 text-to-cad 生成 URDF,难点在于:几何只是外观,URDF 还需要连杆的质量、惯性张量、关节类型、关节轴、关节限位。这些信息自然语言里通常不会给。
我的处理方式是分两步:
- 先用几何生成每个连杆的 mesh(STL 或 DAE),作为 URDF 里的 visual 和 collision。
- 质量按体积乘密度估算(默认密度取 1000 kg/m³ 或按材料给),惯性张量按几何近似(长方体、圆柱有解析公式)算。
关节信息则从用户的描述里抽,比如"这个臂绕底座旋转"就对应一个 revolute 关节,轴是 Z。抽不出来的,输出待确认清单。
导入 CoppeliaSim 这类仿真器时,最常见的报错是 mesh 路径不对、惯性张量为零导致仿真发散。惯性张量千万别填零,哪怕给个很小的正值,也比零强,否则求解器直接崩。
4.3 G-code:为什么我不建议从文本直接生成
G-code 是刀具路径,从文本直接生成意味着模型要自己完成工艺规划——选刀具、定切削参数、排刀路、避让夹具。这已经超出几何生成范畴,进入 CAM 领域了。大模型对切削参数的理解非常不可靠,生成的 G-code 直接上机床是危险的。
我的做法是:text-to-cad 只负责生成 STEP,G-code 交给成熟的 CAM 软件(或 slicer)从 STEP 生成。这样责任边界清晰,几何归几何,工艺归工艺。如果非要做,也只在 3D 打印这种低风险场景下尝试,且必须人工检查路径。
5. 实测中暴露的问题与排查链路
链路跑通不代表能用。下面是我在实际项目里遇到的真问题,以及完整的排查过程,照着走能省不少时间。
5.1 模型能生成但打不开:从文件头开始查
第一次导出 STEP,下游软件报"文件损坏"。排查链路是这样的:
- 看文件大小:如果只有几百字节,基本是导出失败,内核没写入实体。
- 看文件头:STEP 文件开头应该是
ISO-10303-21;,如果开头是乱码或空,说明写文件时编码或路径出了问题。 - 用独立读取器验证:别用生成它的同一个库去读,换个工具(FreeCAD 命令行)读一遍,能区分是"文件真坏"还是"读取器不兼容"。
- 查几何是否为空:有时候布尔运算把实体减没了(比如孔比板还大),导出的就是个空壳。
最后定位到是布尔减操作把实体减空了——用户描述"板上打孔",但孔位算到了板外,减完啥也不剩。几何校验必须做,不能省。
5.2 尺寸对不上:单位与缩放的双重陷阱
有次生成的模型,下游反馈"大了 25.4 倍"。这是典型的英寸/毫米混淆。排查发现,中间表示里用户说的是"2 英寸",模型转成了 2(没乘 25.4),而导出时又按毫米写。单位转换必须在一个地方统一做,要么全在中间表示层转成毫米,要么全在导出层转,绝不能两处都动。
5.3 批量生成时内存爆掉:几何内核不是无状态的
批量跑几百个模型,跑到一半进程被 kill。原因是 OCCT 的对象不释放,内存持续增长。解决办法是每个模型处理完显式释放,或者干脆每个模型起一个子进程,跑完就退。用子进程虽然慢一点,但稳定,不会因为一个模型的内存泄漏拖垮整批。
5.4 常见问题速查表
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 文件打不开 | 导出失败/空实体 | 查文件头、文件大小、几何是否为空 |
| 尺寸差整数倍 | 单位混淆 | 检查中间表示与导出层的单位 |
| 导入仿真器报错 | mesh 路径/惯性为零 | 检查 URDF 路径、惯性张量 |
| 批量中途崩溃 | 内存泄漏 | 改子进程隔离、显式释放 |
| 圆角失败 | 半径大于壁厚 | 校验圆角半径与相邻特征尺寸 |
6. 把 text-to-cad 接进真实工作流的几点经验
技术链路通了,最后一步是让它真正有用。这一步的坑不在代码,在流程设计。
6.1 别追求"一句话出成品",追求"一句话出草稿"
我一开始的预期是用户说一句话就得到能直接加工的模型,实测下来这不现实。更靠谱的定位是快速出草稿:用户描述 → 生成初版几何 → 用户在 CAD 里微调。这样把 text-to-cad 当成"建模加速器"而不是"建模替代者",接受度高得多,也避开了精度和工艺的坑。
6.2 参数化是复用的关键
生成一次模型不算本事,能参数化复用才是价值。把中间表示存下来,用户改尺寸时只改 JSON,重新执行几何内核即可。这样一套"文本 → 参数 → 几何"的流水线,能覆盖整个系列件。热词里"python 批量对 cad 修改"说的就是这个需求,text-to-cad 天然适合干这个。
6.3 校验环节不能省,而且要自动化
几何校验要写成自动化的检查项,每次生成都跑一遍:实体是否非空、尺寸是否在合理区间、特征是否互相干涉、壁厚是否为正。这些检查用几何内核的 API 就能做,成本不高,但能拦住绝大多数低级错误。宁可生成失败报错,也不要生成一个看起来对、实际错的模型,后者危害大得多。
6.4 关于"cad 如何彻底卸载不影响二次安装"这类问题的联想
热词里这类问题特别多,本质是 CAD 生态的环境脆弱性。这也反过来印证了为什么我推荐代码化建模路线——它把几何生成从"装一堆软件"变成"跑一段脚本",环境依赖少,可容器化,可 CI。一个 text-to-cad 服务,理想状态下应该是一个 Docker 镜像,进去就是干净的 Python 环境加几何内核,不碰任何商业软件的安装和授权。这样部署、迁移、扩容都简单。
6.5 一个我常用的最小工作流
把上面这些串起来,我日常用的工作流是这样的:
- 用户输入自然语言描述。
- 大模型输出参数化中间表示(JSON),并标注推断值。
- 自动校验中间表示的自洽性,不自洽就反问补全。
- 几何内核执行中间表示,生成实体。
- 自动几何校验,通过则导出 STEP(或 URDF)。
- 存下中间表示,供后续参数化复用。
这套流程跑下来,一个简单零件的生成时间在秒级,复杂一点的也就十几秒。比起手工建模,效率提升是数量级的,而且可复现、可批量、可版本控制,这三点是手工建模给不了的。
最后分享一个我踩过的小坑:中间表示里的数值,一定要用浮点数而不是字符串存。我早期图省事把尺寸存成字符串,结果做参数化替换时字符串拼接出了"80" + "10"变成"8010"的乌龙,模型直接大了两个数量级。数值就是数值,别偷懒。