1. 从一个奇怪的需求说起:为什么我需要text-to-cad
先交代一下背景。我本职是做机械结构设计的,传统工作流是SolidWorks建模、出工程图、打样、改模,一个零件从需求到产出,快则几个小时,慢则一两天。前阵子接了个活儿,对方丢过来一个概念图,说"这里要有个支架,要能托住电机,还要留出走线孔",然后就不管了。按老办法,我得从零拉草图、定约束、算尺寸,虽然都能做,但整个过程里大量时间花在了重复操作上。
于是我第一次认真试了text-to-cad——也就是用自然语言直接生成CAD模型。说实话,最初我是抱着怀疑态度的,毕竟我们这行讲究的是精确到小数点后两位的尺寸公差,让AI凭空画图听起来就像让实习生自由发挥。但实际用下来,我发现这东西的价值不在"一次性出最终图纸",而在"把从想法到草图雏形的过程压缩到几十秒"。
所谓text-to-cad,核心就是输入一段描述物体形状、结构、尺寸的文字,由AI生成可供编辑的CAD文件。它输出的不是渲染图片,而是真实可用的参数化模型或BREP实体,能导入SolidWorks、Fusion 360、FreeCAD这些主流软件继续编辑。这项技术最适合的人群很明确:机械工程师想快速做概念方案对比、工业设计师想把头脑风暴变成3D草稿、创客和开发者需要快速验证结构可行性,以及任何对"从一句话到三维模型"这件事有需求的人。
这篇文章我会把我从接触、踩坑到形成稳定工作流的完整经验写下来,包括底层原理、工具选型、提示词写法、修复流程,以及哪些项目适合用它、哪些项目碰都别碰。内容偏工程向,但我会尽量把原理用大白话讲清楚,刚入门的朋友也能跟着复现。
2. 底层原理拆解:语言模型是怎么"画出"三维世界的
2.1 核心思路:让AI写代码,而不是画像素
一开始我也以为text-to-cad是靠某种"三维扩散模型"直接生成点云或者网格体。深入研究后发现,当前主流方案完全走了另一条路:让AI生成一段程序化建模脚本,然后执行脚本生成几何体。
这个思路的巧妙之处在于,它避开了"直接预测三维坐标"这个极其困难的问题。想象一下,你要描述一个茶杯,如果你试图逐个点预测杯子的几千个三维坐标,误差会累积到完全没法用。但如果你让AI生成一段代码,写明"圆柱体半径30、高度80、抽壳厚度2、底部倒圆角",每个参数都精确可控,那生成的模型在几何精度上天然就是可用的。
目前最典型的实现方式是生成OpenSCAD脚本或CadQuery脚本,这两种都是参数化建模语言。OpenSCAD语法简单,适合表达基本的布尔运算和几何变换;CadQuery基于Python,能利用编程能力表达更复杂的逻辑,比如循环、条件判断、基于外部尺寸的自动适配。
以CadQuery为例,AI生成的代码大致长这样:
import cadquery as cq result = (cq.Workplane("XY") .box(100, 60, 10) .faces(">Z") .workplane() .rect(80, 40) .cutBlind(-5) .faces(">Z") .workplane() .circle(15) .cutBlind(-10) .edges("|Z") .fillet(2))这段代码的意思是:在XY平面创建一个100×60×10的长方体,然后在顶面上挖一个80×40、深度5的矩形槽,再挖一个直径30、深度10的圆孔,最后对垂直方向的棱边做2mm倒角。AI要做的不是"想象"这个零件长什么样,而是理解用户文字描述中每一个结构特征,并翻译成对应的建模操作和参数。
2.2 解决"文字到参数"的三个关键模块
整个text-to-cad系统其实由三个相互独立的部分组成:自然语言理解、程序代码生成、几何内核执行。
自然语言理解负责从用户描述中抽取关键信息。"直径30的圆孔"会被解析成两个实体:特征类型是"圆孔",参数是"直径30"。这个过程主要依赖大语言模型对语义的理解能力,训练数据越贴近工程文本,理解就越准确。
程序代码生成负责把抽取出来的特征组织成可执行的建模脚本。这一层是当前技术迭代最快的地方。早期的实现只能处理固定的模板填空,比如你只能从预设的"孔、槽、凸台"里选择操作;现在基于大模型的实现已经可以理解"在顶面靠近右侧的位置开三个等距排列的通孔"这种带有空间关系的描述,并自动计算布点位置。
几何内核执行是最成熟的部分。OpenSCAD、CadQuery最终都会调用CGAL或OpenCASCADE这类底层几何内核来完成布尔运算、倒角、抽壳等操作。这部分完全确定性强,同样的脚本执行一万次结果都一模一样,这也是text-to-cad相比直接生成网格更可靠的根本原因。
2.3 为什么现阶段代码生成路线会胜出
我见过不少讨论,说既然有Stable Diffusion这类图像生成模型,为什么不能训练一个"Stable CAD"直接生成三维模型?技术上确实有团队在做,比如通过扩散模型生成体素、点云或隐式神经场,但实际工程场景里还有几个绕不开的问题。
首先是精度。扩散模型天然带有随机性,生成的点云或者网格表面会有噪声,而机械零件需要的是毫米甚至微米级的精确配合面。你可以让模型生成一张图片再放大,但你不能让一个结构件"看起来差不多"就装到设备上去。
其次是可编辑性。AI直接生成的三维网格往往是无法参数化编辑的"死模型",你想改一个孔的位置只能重来。而程序化生成的脚本,你随时可以改一行参数重新执行。
最后是数据问题。训练一个直接输出三维模型的网络需要海量带标注的高质量CAD数据,目前这类数据极度匮乏。反而是代码生成的路线可以充分利用互联网上已有的开源脚本(GitHub上有大量OpenSCAD、CadQuery项目)作为训练语料。我查到的几个公开模型基本都用了这个思路:先用代码数据微调大模型,再配合自动执行脚本生成模型数据进行迭代。这也是为什么我说"AI写代码"这条路在当前是更务实的选择。
3. 主流text-to-cad工具横评与选型建议
3.1 先说结论:没有全能工具,只有匹配场景的工具
市面上能用的text-to-cad工具,我先用一张表把核心差异列出来,再逐个说我的实测感受。
| 工具 | 生成方式 | 输出格式 | 参数化程度 | 上手难度 | 适合场景 |
|---|---|---|---|---|---|
| ZooKeeper Text-to-CAD | 大模型生成CadQuery脚本 | STEP | 高,完全参数化 | 低,网页版 | 概念验证、标准件生成 |
| CAD-GPT(学术项目) | 大模型生成OpenSCAD/CadQuery脚本 | STEP/SCAD | 中到高 | 中 | 研究探索、自定义训练 |
| Fusion 360 AI助手 | 集成在软件内生成特征树 | 原生Fusion格式 | 高 | 中 | 已有Fusion 360使用习惯的工程师 |
| 通用LLM+代码库 | ChatGPT等直接生成CadQuery代码 | 自己控制 | 最高 | 高 | 有编程基础的深度用户 |
3.2 几款工具的实际体验
ZooKeeper的Text-to-CAD网页版是我最先尝试的。界面极简,一个输入框,输入描述,点生成,几秒后就能下载STEP文件。我测试了几个典型的工程描述,比如"带中心孔的圆形法兰盘,外径100、内径40、厚度10,均布4个直径8的通孔"。它生成的模型完全正确,而且我能明显感觉到它对"均布""通孔"这类工程术语理解得很准确。这背后应该是专门微调过的模型,因为通用大模型对"均布4个孔"的处理往往不太稳定。
再来说说通用LLM方案。理论上你可以让ChatGPT直接写CadQuery代码,然后自己在本地执行。这样做的优势是完全免费、不受限,而且你可以通过对话反复修改。缺点也很明显:通用模型没有经过CAD数据微调,经常写出语法正确但逻辑混乱的代码。比如我之前让它生成一个带矩形槽的底座,它写出来的代码运行到一半就报错,原因是Workplane的选取方式有问题,在CadQuery里"faces(">Z")"和"workplane()"之间的关系如果处理不当,生成的平面方向会反。
Fusion 360集成的AI功能走的是另一个方向,它不生成独立脚本,而是在建模环境里直接生成特征操作记录。它的优势是生成结果完全融入现有工作流,但前提是你用的是Fusion 360,而且你理解它的特征树逻辑才能继续编辑。
我的建议是:如果只是想快速验证一个想法,用ZooKeeper这类专用工具;如果打算长期依赖这个工作流且有编程基础,可以尝试通用LLM+CadQuery的组合,虽然前期陡峭,但后期自由度最大。
4. 完整实操:从一段描述到可用的STEP模型
4.1 环境准备:最省事的组合方案
我目前稳定使用的组合是:本地安装CadQuery + Python环境,配合通用大模型生成代码,再通过VS Code或者命令行执行。这套组合的好处是模型生成的代码可以直接跑,报错了也能当场改。
安装CadQuery非常简单,最推荐的方式是用conda创建独立环境:
conda create -n cadquery -c conda-forge cadquery=master conda activate cadquery python -c "import cadquery; print(cadquery.__version__)"如果你不想折腾本地环境,也可以直接在线用CadQuery的Jupyter示例环境。但考虑到后面要反复调试、批量生成,本地环境迟早要装,早点装早省心。
生成STEP文件的写法也很固定:
result = (cq.Workplane("XY") .box(100, 60, 10)) cq.exporters.export(result, "output.step")4.2 提示词怎么写:描述三维物体的一套方法论
这是在实操中我花最多时间琢磨的部分。同一个模型,用不同的描述方式,生成质量可以天差地别。我总结了一套"三层描述法":
第一层:定义整体基体形状和尺寸。比如"创建一个长100、宽60、高10的长方体底座"——明确基本形状和三个方向尺寸。
第二层:定义特征操作及位置关系。比如"顶面中心挖直径30、深度5的圆形凹槽""左侧边缘中心开直径8的通孔"——这里要点明面方向、特征类型、尺寸、空间位置。尽量避免使用"上面""下面"这种模糊词汇,用"顶面(>Z方向)""前面(>Y方向)"更准确。
第三层:定义阵列、镜像等重复性操作。比如"在距离边缘10的位置、沿长度方向均布5个直径6的安装孔"——这里"均布"是关键,AI需要计算起始和结束位置然后均匀间隔。
我还发现一个细节:尽量把描述拆成短句,而不是用一长串嵌套的复句。模型对"在A面上做B,然后在B的中心做C,再绕B阵列4个"这种并列短句的理解准确率显著高于"在A面的B中心做四个绕B阵列的C"。你可以把这条当成通用经验来用,实际测试下来失误率能降一半。
4.3 生成结果的检查与修复闭环
一次生成的模型直接可用的概率大约是六到七成,剩下的情况需要人为干预。我建议养成一个固定流程:先视觉检查,再几何检查,最后导入目标CAD软件检查。
视觉检查最简单,在CadQuery里直接可以快速预览:
from cq_viewer import show show(result)如果形状不对,先看代码逻辑,通常是布尔运算的方向反了或者Workplane选错面。几何检查就要导入专业软件了,我这里推荐用FreeCAD做中间检查,因为它是免费的,能查看实体属性、检查是否有非流形边。
最后一步是导出STEP导入SolidWorks或Fusion 360。这一步往往能发现最隐蔽的问题——单位不同。CadQuery默认是毫米,STEP文件里会带上单位信息,但如果你拿到的模型是其他工具生成的,最好在导入界面确认单位设置,不然一个100mm的零件可能在某个软件里显示成100英寸。
5. 实际项目中的坑与绕坑心得
5.1 几何精度:AI不会帮你保证公差
我在测试中最常遇到的坑是:模型生成得"看起来完全正确",但关键配合面的尺寸就是差那么一点。有一次我让AI生成一个轴承座,描述里写了"内孔直径30,公差H7",结果模型生成的孔直径是30.00,但公差带信息根本没有体现在几何里。这其实是程序化生成路线的天然短板:脚本执行只负责生成标称几何,公差标注属于工程注释范畴,目前的AI建模脚本根本不会处理。
解决办法是在提示词里就规避公差需求,标称尺寸负责几何,公差信息放到生成的STEP文件导入后手动标注,或者干脆把描述里的公差词换成具体的最大/最小尺寸。比如把"内孔H7,直径30"换成"内孔直径30.2"(上差),让几何本身就落在配合的极限范围内。
5.2 单位、坐标系与装配关系的隐性陷阱
坐标系方向是另一个大坑。text-to-cad生成的模型默认在XY平面创建草图,Z轴向上。但不同CAD软件对"前视图""顶视图"的默认方向定义不一致,导入后模型很可能躺着或者倒着。这不是生成模型的问题,而是导入环节需要做个简单的旋转对齐。
装配关系就更有意思了。目前所有主流text-to-cad工具都只生成单个零件,不支持生成带配合约束的装配体。如果你描述"一块底板上面用四个螺栓固定一个电机支架",AI大概率会把底板、支架、螺栓"焊死"成一个实体,而不是生成三个零件加配合关系。想靠AI直接输出装配体,现阶段不用指望,建议的做法是分别生成每个零件,再用传统方式装配。
我自己踩过最痛的一个坑是在CadQuery里使用阵列。生成"沿圆周均布8个孔"时,AI写的代码有时候会漏掉最后一个孔,原因是在计算极坐标角度时,用"range(8)"乘以45度得到的最后一个位置恰好是360度,与第一个孔重合,而某些布尔运算会把重合特征当成空操作跳过。这种问题靠视觉检查很难发现,因为8个孔看起来像7个孔在视觉上是容易被忽略的。后来我养成了一个习惯:每次生成阵列特征,都额外验证一下特征数量。
5.3 校验脚本:给自己的模型上个保险
我最终为日常使用写了一套简单的自动化检查脚本,专门用来验证生成结果符合预期。核心逻辑很简单:提取实体的体积、边界框尺寸、孔数等关键指标,与预期值对比。
import cadquery as cq def validate_bbox(shape, expect_lwh): bbox = shape.BoundingBox() actual = (round(bbox.xlen, 2), round(bbox.ylen, 2), round(bbox.zlen, 2)) ok = all(abs(a - e) < 0.01 for a, e in zip(actual, expect_lwh)) print(f"bbox: {actual}, expected: {expect_lwh}, pass: {ok}") # 验证孔数量 def count_holes(shape, radius): faces = shape.Faces() hole_faces = [f for f in faces if abs(f.Area - (3.14159 * radius * radius)) < 1] print(f"hole count: {len(hole_faces)}")这种方式特别适合批量化场景。比如你让AI生成20种不同尺寸的安装板,靠眼睛一个个检查不现实,写个脚本自动提取长宽高、孔径、孔数,跟配置表比对,5分钟全部搞定。
6. 什么样的项目才适合用text-to-cad
6.1 我画了条"该用与不该用"的分界线
用了这么多之后,我对text-to-cad的能力边界有了比较清醒的判断。它真正适合的场景有几个共性:
- 结构以标准特征为主:板类件、轴类件、壳体、法兰、支架,主要靠拉伸、旋转、打孔、倒角这些基本操作构成。
- 尺寸参数明确:不依赖复杂的曲面造型,所有关键尺寸可以直接用文字描述出来。
- 需要大量变体:同一个结构换十组尺寸生成十个模型,传统方式要建十个文件或改十次参数,text-to-cad只需要换描述里的数字。
- 概念方案比选:在正式设计前快速出几个粗糙结构做空间布置验证。
不适合的场景也很清晰:自由曲面外形(鼠标外壳、汽车覆盖件)、雕塑类造型、需要复杂分型面的注塑件,以及任何依赖光滑曲率连续性的设计。这些需求还是老老实实用细分曲面建模或者逆向扫描来得靠谱。
6.2 人机协作的新工作流:我现在的标准流程
我现在做结构件设计的流程已经变成了"AI出初稿、我出终稿"。第一步,用text-to-cad生成3到5个概念变体,每个只需要改几个关键尺寸词。第二步,导入SolidWorks,挑一个结构最合理的,手动重构特征树——这一步最关键,AI生成的脚本虽然能出模型,但特征历史不一定干净,可能一个孔位被反复计算了三次。手动重构一遍,后续改图才顺手。第三步,用传统方式补齐公差、表面粗糙度、焊接符号这些AI完全不懂的工程信息。
这个流程下来,单个零件从需求到初稿省的时间,大概是从2到3小时压缩到30分钟。省下来的时间被用在真正需要工程师判断的地方:干涉检查、材料选择、制造工艺评估。
6.3 说点实在的:局限与我对它的预期
现在市面上的text-to-cad还没有任何一家敢说"能取代工程师画图"。从我实测的情况看,它目前更像一个"超级草图生成器",价值在于把空白画布变成有内容的起始点。
最后分享一个我一直在用的小技巧:给AI描述模型时,永远把最具有结构标志性的特征放在描述的最前面。比如"带T型槽的铸铁平板",你要先说"T型槽",而不是先说"一个长500宽300高50的平板"。原因是模型在生成脚本时,对描述顺序是有一定敏感度的,靠前的描述词往往获得更高的注意力权重。把核心特征前置,整体生成成功率明显更高。
这个领域迭代速度非常快,我三个月前测试的工具,到现在再看已经更新了好几版。我个人最大的体会是:不要等工具完美了再学,先把手头的重复建模工作试着交给它做一两个,你很快就能找到属于自己的最佳使用方式。