Text-to-CAD 实测:自然语言如何生成可编辑的 CAD 模型
作为一个天天跟特征树和公差标注打交道的人,我第一次在技术社区看到 text-to-cad 时,第一反应是“这不是营销概念?”当时我刚做完一个非标自动化设备的电机安装支架,需求方在聊天软件里发了一段文字描述,我花了三个小时才把模型画出来并反复改孔位。如果那段文字可以直接变成模型,哪怕只是初稿,我的工作量也能少一大截。
后来我把几个公开项目真的跑了一遍,前后折腾了一周,确实改变了一些看法。text-to-cad 不是“输入一句话就输出完美工程图”,而是“把一段描述设计意图的自然语言,转成一份可以进入 CAD 软件继续编辑的几何模型或建模指令”。它和常见的 text-to-3D(生成三角网格)完全是两条技术路线,后者更像为渲染和动画服务的“数字雕塑”,而 text-to-cad 的落点是工程制造:要尺寸、要特征、要可编辑。
所以这篇文章适合谁呢?如果你画过机械零件、做过结构设计,或者刚入行被建模效率搞得头大,应该会有共鸣。我不会讲太多论文公式,重点讲清楚它背后的原理、现在能怎么用、以及最容易翻车的几个地方。
1. 先把话说清楚:text-to-cad 到底想解决什么
1.1 从“人画图”到“人说话”:建模意图的翻译问题
CAD 建模本质上是一个“翻译”过程:工程师脑中的一个结构想法,先变成文字或口头描述(“这里要一个 6 毫米的过孔,四个角倒圆角”),再翻译成软件里的特征操作(拉伸、打孔、倒角),最后形成一颗特征树。以前这个翻译主要靠人手动完成,text-to-cad 想替代的正是中间这一段。
但这个“翻译”没有想象中那么简单。同一句话在机械工程师、结构工程师、3D 打印爱好者嘴里含义完全不同。比如“两个孔”,可能是对称布置,也可能是按某个参考点阵列;可能是盲孔,也可能是通孔;孔径的公差范围是多少?这些信息自然语言里往往没有,而 CAD 模型又不能含糊。这是一个典型的欠定问题:文本信息不足,模型必须用合理先验去猜,猜错了就出现“看起来像,机械上不能用”的结果。
我后面会专门写提示词怎么写,因为现阶段 text-to-cad 能发挥多少价值,很大程度上取决于你多会“把话说全”。
1.2 和 text-to-3D 不是一回事,别被宣传带偏
我在试用时,发现很多人以为“能生成 3D 雕像的工具就也能生成零件”,这是最大的误区。
典型的 text-to-3D 工具(比如生成 OBJ/GLB 网格)输出的是三角形面片组成的表面。面片模型拿来渲染、3D 打印一些问题不大,但到了 CAD 里就麻烦了:网格没有参数化特征,没有草图,没有拉伸方向,你不能在原来的特征树上改一个孔的直径。工程师拿到网格之后,几乎无一例外要“重画一遍”,这和我们想省的时间完全相反。
text-to-cad 的目标输出是 B-Rep(边界表示)或者参数化建模指令序列,它的主体是拓扑结构和几何约束,而不是一堆三角形。也因为这个差异,text-to-cad 做起来比 text-to-3D 难得多。我自己跑下来最直观的感受是:生成“一个花盆”容易,生成“一个孔距误差不大于 0.1mm 的安装板”难,难在稳定地把特征关系表达出来。
1.3 先能用上的场景:标准件、概念件、定制件
在我看来,现阶段最能落地的场景有三类。
第一类是标准件和通用件,比如支架、法兰、盖板、L 型连接件。这类零件结构规范、特征单一,模型不容易“幻觉”,生成成功率最高。很多公司每年要重复画几百上千个相似零件,哪怕只是生成 70% 可用的初稿,都值得试。
第二类是概念设计阶段的快速方案。客户只说“我们想加一个这种形状的把手”,你与其从零建,不如先让 text-to-cad 生成五六个候选形态,选一个最接近的再精修。
第三类是 3D 打印和创客场景。打印件不需要严格公差,只要模型尺寸大致对、能打印出来,就有实用价值。这类场景对失败容忍度更高,所以现在很多社区案例都是开源硬件、外壳、夹具,真正高精度机械制造场景还不太敢全自动。
2. 现在的工具版图:别只盯着一个名字
2.1 学术圈的两个代表方向
如果你去翻论文,大概率会遇到两条主线。
一条是 Text2CAD 这类序列到序列方案:把自然语言编码后,通过 Transformer 解码器直接生成 CAD 建模命令序列,命令本身就是“从哪张草图、拉伸多高、做什么布尔运算”这类 token。它的优点是端到端,缺点是命令序列长、容易累积误差,模型一旦在中间某个 token 上跑偏,后面全废。
另一条是借助大语言模型(LLM)调用程序化建模 API 的思路,代表项目是 Zoo。它让模型生成一段 CadQuery / OpenSCAD 这类程序化代码,再执行代码得到模型。好处是代码可以被人工检查和局部修改,坏处是大语言模型的代码能力再强,也保不齐生成一个非法的几何操作,导致程序直接报错。
这两条路线我都在本地环境里跑过,给我的感觉是:前者更“深”,能处理复杂连续特征,但调试起来像黑盒;后者更“透明”,每一条建模语句都能看懂,适合和人配合,但表达能力受限于候选代码库的丰富程度。
2.2 商业与开源的真实差距
商业服务例如 Zoo 的在线 Text-to-CAD,调优过数据,开箱即用,支持导出 STEP 这类标准格式,上手体验流畅。但商业工具的缺点是“提示词黑盒”:你没法完全控制它背后的模型版本,也很难针对自家产品做私有化微调。
开源这边,Text2CAD 数据集和模型权重可以拿到,但需要自己部署,显存、CUDA 版本、tokenizer 兼容性都是拦路虎。我个人的建议是:如果想快速验证“这技术到底香不香”,先花两小时用在线演示;如果确认要集成到内部工具链,再考虑本地部署开源模型。
2.3 选型建议:按工作流,不按关键词热度
判断一个 text-to-cad 工具适不适合你,我建议按下述三个问题过滤:
- 输出是什么格式?STEP/BREP 可以进主流 CAD,SCAD/CadQuery 需要转格式。
- 我可不可以编辑中间结果?可读的代码比黑盒几何体对你更有长期价值。
- 尺寸和单位能否稳定表达?如果 100 次有 20 次把厚度搞错,放在工程里就是灾难。
我把常见方案的对比放在下面,方便直接参考:
| 方案 | 输出形态 | 可编辑性 | 适合场景 | 上手难度 |
|---|---|---|---|---|
| Text2CAD 开源路线 | BREP/命令序列 | 低,模型输出即结果 | 学术验证、批量相似件 | 较高 |
| Zoo 在线服务 | 程序化CAD代码 + 模型 | 中,代码可改 | 3D打印、概念件 | 低 |
| LLM + CadQuery 自建 | CadQuery 代码 | 高,代码即特征树 | 企业内工具链 | 高 |
| LLM + OpenSCAD 拼接 | OpenSCAD 脚本 | 高 | 参数化创客件 | 中 |
3. 原理部分:CAD模型为什么比“一张图”难生成
3.1 构造历史才是灵魂
用过 Fusion 360 或者 SOLIDWORKS 的人都知道,模型不只是屏幕上那个实体,它下面挂着一串“构造历史”:哪一步先画了矩形,哪一步拉伸了 20 毫米,哪一步又把边缘倒成了 R2。这串历史比最终实体本身还重要,因为改设计的本质是改历史。
text-to-cad 真正难的地方,就是它要同时生成“几何结果”和“构造逻辑”。哪怕两个模型长得一模一样,如果构造历史不同,后续改起来的工作量天差地别。比如同样是“带孔的板”,A 方案是“先拉伸板再打孔”,B 方案是“先在一个实体上切掉一个圆柱体”,孔的位置修改成本完全不同。所以我不建议把 text-to-cad 简单理解成“生成一个形状”,它是“构造一个建模过程”。
3.2 B-Rep 与网格的对决
B-Rep(边界表示)是 CAD 的底层语言:一个实体由面、边、顶点组成,每个面是解析曲面(平面、圆柱面)或样条曲面,面与面之间有精确的拓扑连接关系。这种表示天然支持测量、公差分析、制造工艺计算。
网格模型则没有这些逻辑:三角形面片之间只有“挨得近”,没有“共用一个边”的严格拓扑。因此从网格自动重建 CAD 特征是一个公认难题,业内现在还只能做逆向工程式的半自动拟合。这解释了为什么 text-to-cad 不能直接“套个壳”然后用 text-to-3D 的老办法——工程领域根本不认这种输出。
我拿同样一句“做一个带四个安装孔的支架”分别让 text-to-3D 工具和 text-to-cad 工具生成,前者给我一个表面坑坑洼洼的雕塑,后者给出一个能进装配体的 STEP 零件。差距不在“好看”,而在“能不能量尺寸、能不能约束配合”。
3.3 从文本到命令序列,本质是代码生成
前面提到的“序列到序列”做法,在我实际跑的时候感觉更像文本翻译:模型把自然语言“翻译”成一条条 CAD 命令。这个思路有个工程化优势——模型不需要直接算几何,它只需要学会预测“下一个该执行什么命令”,几何计算全部交给 CAD 内核。
但这也就带来了代码生成类模型的老问题:误差会累积。命令序列第 23 步如果多了一个冗余切槽,后面第 24 步之后的特征可能全部错位。所以开源模型经常出现在简单零件上表现尚可、复杂零件上一塌糊涂的现象,不要觉得是模型笨,其实是序列预测的天然缺陷。
3.4 当前最稳的策略:由草图到实体
我实测下来,目前最稳的生成策略不是一次性给出完整特征树,而是先让模型描述“草图截面”,再描述“拉伸/旋转等基础操作”,最后附加孔、倒角等局部特征。这和人建模的习惯一致。
为什么会稳?因为草图+拉伸是 CAD 里最基础、最不易出错的构造方式,模型训练数据里这类样本也最多。反过来,如果你一上来就要求“用放样、扫描、布尔并集做出一整块异形曲面”,模型翻车概率直线上升。我的经验是:尽量把复杂目标拆成“基体 + 若干局部特征”的层次,再逐段喂给模型或者逐段生成后人工拼接,成功率会显著高。
4. 实操:用一个开源项目把第一版跑通
4.1 环境准备与模型加载
以我本地跑的一个开源 text-to-cad 流程为例(Text2CAD 风格的端到端模型),环境如下:Python 3.10、PyTorch 2.x、Transformers 4.35 以上,显卡是 RTX 3060 12G。因为我显存有限,把模型用半精度加载,推理时单条英文提示词耗时大概 12 秒。
安装时最大的坑是 transformers 版本。这个项目在旧版本会报“xxx attribute not found”,一路强制升级到新版反而又和 tokenizer 不兼容。最后我的做法是老老实实建一个独立 conda 环境,按项目 requirements.txt 锁版本,不要图省事直接用全局环境。
核心加载逻辑大致长这样(示例代码,具体项目以你用的仓库为准):
import torch from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("./text2cad-weights") model = AutoModelForCausalLM.from_pretrained( "./text2cad-weights", torch_dtype=torch.float16, device_map="auto" ) prompt = ( "A flat rectangular plate, 100mm long, 60mm wide, 5mm thick, " "with four 6mm through holes at corners, each hole 8mm from the edges." ) inputs = tokenizer(prompt, return_tensors="pt").to("cuda") output_ids = model.generate(**inputs, max_new_tokens=1024)看到这里你会发现,它本质上就是一次“文本到命令序列”的自回归生成,和聊天机器人没有本质区别。区别在于词表里的 token 都是建模动作。
4.2 三类典型提示词的实际输出对比
为了更直观,我给模型喂了三类提示词,结果差异很大:
- 简单标准件:“A rectangular base plate…4 through holes…3mm fillet”——输出基本可用,尺寸误差肉眼不可见,STEP 文件能正常导入。
- 带相对位置的中等零件:“A support bracket with a 90 degree bend, two ribs on the left side…”——输出存在一个孔的位置偏移,我检查命令序列发现模型把“left side”理解到了 Y 轴正方向,这是因为训练数据里很少有“左右”这种相对语义。
- 高复杂件:“A bicycle frame with custom dropouts, internal cable routing, compatibility with disc brakes”——完全不可用,模型在第二个特征后开始重复循环,生成了一堆自相交曲面,我只能放弃。
这个测试告诉我:现阶段不要在提示词里写“看起来像什么”,要写“由什么组成、尺寸多少、特征在哪”。复杂整体直接生成会失败,但分部分生成再装配是可行的。
4.3 输出格式与导入 CAD 的后处理
开源模型给的原始输出往往是一串建模 token 或者命令代码,不是直接可以用的 STEP。我的处理流程是三步:
- 把输出解析成建模指令;
- 用 CadQuery 或 OpenCASCADE 内核执行指令,生成 STEP;
- 把 STEP 导入 FreeCAD 或者 Fusion 360 检查尺寸。
这三步里最容易坏的是第二步:模型生成的命令偶尔会引用不存在的参考面,或者拉伸方向反了。我写了个小脚本批量做几何合法性检查,遇到异常就自动跳过,并把对应提示词标记为“失败”,这样至少不会让整个批次崩掉。
import cadquery as cq def build_part(cmds): result = None for cmd in cmds: if cmd["op"] == "box": result = cq.Workplane("XY").box( cmd["length"], cmd["width"], cmd["height"] ) elif cmd["op"] == "hole": result = result.faces(">Z").workplane().hole(cmd["diameter"]) # 其他操作按需扩展 return result4.4 我踩过的版本坑与修复方法
头号坑:编译器/内核版本不匹配导致 STEP 导出后模型破面。我一开始用旧版 OCP 内核,导出的文件在 FreeCAD 里显示一堆红色报错。换到项目指定的 OpenCASCADE 版本后,问题消失。所以如果你是照着某个开源项目的 README 部署,不要自作聪明升级它的几何内核。
二号坑:CUDA 内存不足。模型生成 max_new_tokens 太大时,显存会突然爆掉。我加了 length_penalty 和 early_stopping 参数控制生成长度,同时把 batch size 设为 1。
三号坑:生成结果的随机性。同一句提示词,换一次 seed 就可能孔位变了。后来我在推理时固定随机种子,保证同一 prompt 至少可复现。这听起来很蠢,但工程复现很重要。
5. 提示词里藏着大多数成败
5.1 先写“规格说明”,再写“希望”
我看了很多失败案例,发现大家普遍把 text-to-cad 当成“跟 AI 聊天”,上来就写“帮我做一个好看点的支架”。这类主观词对 CAD 生成毫无信息量,模型要的是客观几何描述。
好的提示词应该像一份口头采购单:先报零件名,再报整体尺寸,再报特征,最后报关系。比如下面这段,就比“做一个支架”靠谱得多:
A corner bracket with two flat faces perpendicular to each other. Face A is 50mm by 30mm, face B is 50mm by 40mm, thickness 4mm. The bracket has a 20mm diameter hole centered on face A, and a slot 10mm wide, 25mm long on face B, positioned 5mm from the top edge.模型接受这种“规格说明式”文本的成功率,明显高于形容词堆砌。
5.2 特征顺序就是建模顺序
大多数人写提示词时想到哪个特征写哪个,这是个隐蔽的坑。模型对序列很敏感:它倾向于把先提到的几何当成基体,把后提到的特征叠加在上面。
我建议按这个顺序写:主轮廓 → 拉伸/旋转操作 → 切除/打孔 → 倒角/圆角 → 表面处理。这个顺序和人建模的顺序一致,模型最容易理解。反过来的例子是:先把“四个角倒 R3”放在开头,模型可能会把倒角当成主特征,生成一个莫名其妙的弯曲板。
5.3 别让模型替你猜约束
“两个孔”“一条槽”“对齐”这种话,在自然语言里很自然,但对模型来说约束不足。你应该主动给出几何约束:通孔还是盲孔?孔心到边的距离是多少?槽的中心在哪个面上?与哪个边平行?
如果某些约束不好描述,可以采用“常识默认 + 修正”的思路:先让模型按最常见布局生成(比如对称均布、四角倒角),导入软件后我再手动调整。不要试图用一句超长提示词同时包含所有公差,因为模型现在对尺寸公差的敏感度很低,写多了它反而容易忽略前面的基体尺寸。
5.4 一个可复用的提示词模板
我反复试下来,沉淀出一个相对好用的模板,写出来供大家参考:
[零件类型]:A [name] [整体轮廓]:with overall dimensions L x W x H, in millimeters [基体特征]:extrude the base profile from XY plane to +Z [局部特征]:add/remove [feature type] [特征位置]:centered at / offset from / aligned with ... [特征尺寸]:diameter X, depth Y, radius Z [边界处理]:fillet/chamfer all exposed edges with value ... [单位与约定]:units in mm; through holes unless stated otherwise当然模板不能覆盖所有情况,但它能有效把最重要的信息放在最前面,避免模型在“次要语义”上浪费生成长度。
6. 把它接进真实工作流,以及接下来会发生什么
6.1 现阶段最现实的定位:需求到方案之间的中间层
以我目前的使用感受,把 text-to-cad 当“全自动出图机”是不现实的,但把它当“需求翻译器”很顺手。客户在电话里描述一个大概想法,我先生成一个 80% 正确的三维草稿,然后在 CAD 里修正约束、补公差、做工程图。整个过程比从零建模至少节省一半时间,尤其适合那些每周都会重复的通用件。
这个定位听起来不够“科幻”,但恰恰是能稳定落地的位置。真正全自动生成并直接进车间的场景,短期内还很难;而“把模糊需求快速变成可讨论的三维实体”这件事,现在就已经有实用价值。
6.2 参数化历史树的可编辑性决定未来上限
我接触到的很多工程团队,对“模型能不能改”这件事的在意程度远超“模型像不像”。如果一个 text-to-cad 工具不能让用户回到某个特征去改参数,那它就只能用于展示,进入不了真正的制造环节。
因此我判断,未来一年内真正有价值的方向是“生成参数化历史树”而不是“生成一个死模型”。我已经看到一些项目尝试让 LLM 直接输出 CadQuery 代码,因为代码本身就是特征历史,改一行参数等于改特征。这件事的想象空间很大:以后用户说“把孔直径从 6 改成 8”,AI 直接定位到历史树的对应节点,而不是整个模型重新生成。
6.3 短期能用上的两个入口
一是标准件复用。把常用零件库的文本描述和参数关联起来,text-to-cad 生成的不再是全新模型,而是从库里调参数、改尺寸。这技术含量不高但极其稳定,适合第一批落地。
二是设计评审。评审之前让生成式模型基于需求文档快速生成一版示意模型,作为讨论对象,降低沟通成本。评审通过后再进入精细化建模,而不是一开始就在 CAD 里拉着尺寸草图。
6.4 设计师和工程师现在该做什么准备
我想说的不是“学 prompt 就能保住饭碗”,而是建议你把一部分重复建模工作交给这类工具,把省下来的时间用在定义规范和校核结果上。长期看,真正值钱的不是“画得快”,而是“知道该画什么、怎么保证它能加工”。
建议现在就开始做三件事:整理你自己业务里出现频率最高的 20 个零件描述模板;记录人类建模时的常见特征顺序,形成内部的“提示词规范”;每次生成结果都保留 prompt、输出、失败原因,积累自己的数据库。这东西用得越久,后续微调模型时的数据就越值钱。
我自己目前还在持续跑这个方向,最直接的收获是“对建模的抽象能力变强了”——以前我拿到一个模糊需求,第一反应是打开 CAD 开始拉草图;现在会先想:它的特征结构到底是什么?基体是什么?有哪些局部特征?这个思维转变,可能比工具本身更重要。
最后再分享一个小技巧:每次生成完,不要急着看渲染效果,第一步永远是“量尺寸”。打开 STEP 文件后先核对长宽厚和孔位,只要尺寸对,这版结果就能进工作流;尺寸不对,渲染得再漂亮也是废模。把这条习惯刻进流程里,比研究任何新功能都管用。