☰
text-to-cad:自然语言如何生成可编辑的CAD模型
2026/10/27 4:06:21 网站建设 项目流程

text-to-cad这个词,最近在3D建模圈子里被反复刷到。它要解决的其实是一件很直白的事:你用一句自然语言描述一个零件,比如“法兰盘,外径80,内径40,厚度12,四个安装孔均匀分布”,AI直接给你生成一个能打开、能编辑、能进装配、能出工程图的CAD模型。注意,我说的是CAD模型,不是那种只能看不能用的三角网格模型。这个方向把大语言模型的语义理解能力和参数化建模的严谨性串在了一条链路上,对机械设计、结构设计、3D打印、产品初期打样这些场景来说,价值非常直接。这篇文章里,我会把text-to-cad的原理、工具链、可实操的落地路径,以及踩坑记录完整拆一遍。不管你是做CAD二次开发的工程师,还是第一次听说这个概念的产品设计,都建议读完,至少能弄明白这一波热潮到底在热什么。

1. 这个概念到底解决什么问题

1.1 text-to-cad是什么,不是什么

先做一个严格一点的区分。text-to-cad很容易被误解成“文本生成三维模型”,但这两者本质上是两码事。文本生成三维模型,比如输入“一只戴帽子的猫”,输出一个OBJ或GLB文件,这是典型的内容生成场景,生成的模型由密密麻麻的三角面片构成,适合渲染、动画、游戏,但几乎没法用于工程设计。

text-to-cad则完全不同。它要生成的是CAD原生模型,也就是带边界表示(B-rep)、带特征树、带参数约束的实体模型。在CAD里,一个圆孔不是一堆三角形的近似,而是一个有明确定义的特征:圆心坐标、半径、深度、方向,以及它和哪些表面相交。改一个参数,整个模型要能同步更新,这才叫CAD。

我给很多朋友解释过这个差异,最直接的一个例子就是改壁厚。用mesh模型,你拿到一个机壳,想从2毫米壁厚改成2.5毫米,等于要重新建模,因为mesh里根本不存在“壁厚”这个语义。但CAD模型不一样,设计树里写的是“拉伸1深度2mm”,改一下数字,模型自动更新。所以text-to-cad如果做不到“可编辑、参数化、特征可追溯”,它就没有真正解决CAD场景的问题。

1.2 为什么行业的关注点从“建模”转向“命令序列”

如果你稍微关注过这个方向,会发现在2023年前后,学术界和工业界最热的是“文生3D”,也就是用扩散模型生成形状。那时候大家想的还是怎么从噪声和文本条件中采样出一个三维体素、一个神经隐式场,或者直接生成网格。结果做出来的东西十有八九是艺术化的、不可编辑的几何形状,离工程落地差着十万八千里。

转机出现在“命令序列”这个思路上。CAD建模软件里,一个零件的诞生,本质上是一串有序的建模操作:画草图、约束、拉伸、切除、打孔、倒角、阵列,每一步都有明确的参数。那么问题就变成了——能不能让大模型直接生成这一串操作命令,而不是生成几何本身?

这样做的优势非常明显。第一,输出天然是CAD工具链可以识别的,因为它本身就是CAD操作的抽象。第二,生成的结果自带可编辑性,因为命令可以被重新执行、修改参数、部分回滚。第三,对模型来说,生成“命令序列”的难度远低于直接预测精确的几何拓扑,本质上它是在生成一种结构化的编程语言。所以后来出现的DeepCAD、Text2CAD等工作,基本都朝着这个方向走:把CAD建模表达成类似代码的序列,再让大模型来做生成。

1.3 哪些人最应该关注这个方向

我梳理过这个方向真正适用的用户群体,大概是这几类:机械工程师,尤其需要在方案阶段快速出多种结构对比的;3D打印爱好者,脑子里有个想法但建模手法生疏,文本描述比拉草图快得多;CAD二次开发程序员,想给自己的插件系统加上自然语言入口;还有做企业内部标准化工作的,如果有一批系列化零件要反复建模,text-to-cad可以用自然语言把标准件调出来。

反过来,如果你做的是影视级资产、手办原型这种偏艺术造型的东西,那text-to-cad目前不是最优解,文本生成mesh的方向可能更符合你的需求。这个定位搞清楚,后面看任何项目都不会再被绕晕。

2. 核心原理拆解:文本是怎么一步一步变成CAD模型的

2.1 整体链路:语义分析、命令生成、内核执行

一条完整的text-to-cad链路,可以拆成三个环节。首先是文本解析,模型得先理解用户描述里的语义:哪些是尺寸、哪些是方位、哪些是特征类型、哪些是隐含的设计意图。然后是命令映射,模型把理解到的语义转成一组有序的CAD建模指令,这一步是核心难点,因为同一个意思可以有很多种建模路径,比如“加个凸台”,可以拉伸、可以旋转、可以用布尔并集,路径不同,结果的可编辑性也不同。最后是内核执行,把生成的指令送到CAD内核里真正构建实体。

你仔细想想,这个架构和程序员写代码有异曲同工之处。文本是需求,命令序列是代码,CAD内核是编译器。大模型在这里并没有直接操作几何,它只是在“编写程序”,真正的几何构建是内核完成的。这样做有个额外的好处,就是如果生成结果不对,你可以像调试代码一样去检查到底是哪一步建模指令出了问题,而不是面对一个黑盒生成的mesh无从下手。

我自己的一个体会是,这个“程序化”的视角非常重要。早期不少做文生3D的人痛苦于“生成结果不可控”,很大原因是他们在让模型直接预测结果,而不是让模型预测过程。CAD场景天然需要过程可控,所以命令序列方案几乎是必然的选择。

2.2 训练阶段:CAD数据序列化与文本配对

要让大模型学会生成CAD命令序列,首先得有足够多的训练数据,而且这些数据必须是“文本描述”和“CAD命令序列”的配对。但现实情况是,主流CAD数据集,比如ABC数据集、Fusion 360 Gallery,它们以几何模型或建模历史为主,绝大多数没有自然语言标注。

所以Text2CAD这类工作的一个重要贡献是,把CAD模型重新表示成命令序列,再为这些序列配上文本描述。具体做法大概是:先把已有的CAD模型逆向解析成草图和特征操作序列,然后根据模型形状特征、尺寸特征,用规则或模板生成对应的文本描述,比如“一个带中心孔的圆柱体底座”“四个对称分布在角落的安装孔”这类的句子。这样就能构建出一个大规模配对的语料。

训练方式上,实际上是把CAD命令序列当作一种序列数据,让大模型去做监督学习,目标就是给定文本前缀,预测接下来的命令Token序列。这和训练代码生成模型的范式高度重合,所以很多工作直接用了代码大模型作为底座。顺带说一个细节:CAD命令序列和普通代码有一个重要差异,普通代码可以单独看一行,CAD命令必须考虑“当前已经生成了哪些形状”,因为后续的拉伸、切除都要依赖前面的特征,所以模型生成时必须保持对历史状态的理解。这也是这类任务比普通代码生成更复杂的地方。

2.3 为什么选择“命令序列”而不是直接生成几何

这个问题我问过自己很多次,后来想通了。直接生成几何可以有两条路:生成网格模型,或者生成STEP/B-rep数据。第一条路生成的网格对工程不可用,前文说过了,没有参数化信息,没法改。第二条路听起来正统,但B-rep的数据结构极其复杂,里面有拓扑层级、几何容差、面边关系,要让模型直接输出这种结构,几乎等于让它学会了一整套CAD内核的数据调度,现阶段根本不现实。

命令序列作为中间表示,刚好卡在中间。它比自然语言结构化得多,又没有B-rep那么底层;它保留了建模逻辑,又不需要模型去预测每个微小的几何顶点;它还能直接映射到OpenCASCADE这类开源内核的API上。所以从工程可落地的角度看,命令序列是目前最合理的折中。

还有一个潜在优势是,“命令序列”未来可以更新换代。比如某个CAD软件新出了一个特征类型,只要把特征命令加入函数集,模型就能学着用。而如果是直接生成几何,任何改动都要重新训练。这个方向的可扩展性,决定了它有更长的生命周期。

3. 自己动手搭建一条可用的text-to-cad链路

3.1 方案选型:LLM加FreeCAD的组合

前面讲的都是行业级研究成果,你可能觉得离自己很远。其实,现在完全可以在自己电脑上搭出一条最小可用的text-to-cad链路,不需要训练模型,不用买专业软件,思路是:用一个支持工具调用的大语言模型,配合FreeCAD的Python脚本接口,让LLM输出结构化的建模指令,再由本地脚本执行并生成实体。

为什么选FreeCAD而不是SolidWorks或AutoCAD?最核心的原因是FreeCAD完全开源,它有良好的Python API,底层是OpenCASCADE内核,能支持B-rep建模、布尔运算、STEP导出。很多下游流程都能接上。而大模型部分,本地推理可以用Ollama拉一个支持function calling的模型,比如Qwen2.5-Coder 7B或14B这类代码能力比较强的,云端API也可以,但本地的好处是方便调试和批量实验。

这个方案的定位我要先说清楚:它不是一个工业级的text-to-cad系统,而是一个能跑通、能体会核心原理、能完成简单零件建模的验证环境。你可以在它上面做原型、做教学、做个人工具,但要直接用于量产设计还不够,这点必须现实一点。

3.2 定义CAD函数集与JSON接口

要让LLM“会建模”,第一步不是写提示词,而是定义它能调用的函数。你可以把FreeCAD里的常见建模操作封装成一组函数,然后用JSON格式描述它们的参数,交给LLM按格式调用。函数数量不宜过多,一开始给六到八个就够,太多会让模型频繁选错函数。

我建议的初始函数集大概是这样:create_box,立方体拉伸体;create_cylinder,圆柱体;create_hole,在指定平面上生成孔特征;boolean_union,布尔并集;boolean_cut,布尔差集;chamfer,倒角;fillet,圆角。每个函数都要规定清楚参数单位、坐标基准和方位。比如create_box的参数就是length、width、height、pos,单位固定为毫米,坐标按右手定则,Z轴向上。

这一步相当于是给模型“划定了能力边界”,它只能在函数集内操作,不能自由发挥。表面上看限制了生成能力,实际上反而提升了成功率,因为模型要猜测的空间变小了。这也是从传统对话式交互转向结构化工具调用的关键一步。

3.3 提示词工程:让模型输出可执行的建模指令

定义好JSON接口后,提示词工程就变得至关重要。我的做法是给模型设定一个系统提示词,内容大致包括:角色是CAD建模助手;只能输出JSON命令序列,不能输出解释性文字;单位是毫米;必须使用右手坐标系统;Z轴默认向上;十个关键尺寸要在规划阶段明确;输出格式必须包含一个“plan”字段和“commands”字段。

为什么要强制分两步输出?因为如果让模型直接写命令,它经常漏特征,尤其遇到“中心有孔,底部有四个安装孔”这种多个特征叠加的描述时,漏掉一两个特征几乎是必然。但如果让模型先输出一个建模计划,列出准备做哪几步、每步的尺寸,再输出命令,漏特征的概率会大幅下降。这相当于让模型先做一个推理,再基于推理结果行动,效果非常明显。

实际操作中,用户输入的文本还得做一些预处理。比如“一个矩形底座”这种描述,尺寸可能根本没给全,模型需要自己补合理值。我会在提示词里加一条:“对于未指定的尺寸,根据整体比例给出合理默认值,如板厚取5-10mm”,这能防止模型生成一个厚度0.1毫米的离奇零件。

3.4 解析执行:从JSON到实体模型

LLM返回JSON之后,就到了解析执行阶段。你需要在FreeCAD的Python环境里加载命令序列,逐条调用对应的API。下面是一个精简的示例框架,运行在freecadcmd控制台里。

import json import Part import App def execute_commands(payload): shapes = [] for cmd in payload["commands"]: op = cmd["op"] p = cmd["params"] if op == "create_box": shape = Part.makeBox( p["length"], p["width"], p["height"], App.Vector(p.get("pos", [0, 0, 0])) ) shapes.append(shape) elif op == "create_cylinder": shape = Part.makeCylinder( p["radius"], p["height"], App.Vector(p.get("pos", [0, 0, 0])) ) shapes.append(shape) elif op == "boolean_union": a = shapes[p["a"]] b = shapes[p["b"]] shapes.append(a.fuse(b)) return shapes

这里我省略了create_hole和chamfer的实现,但它们原理相同,都是调用Part模块对应的API。布尔运算时要特别注意,fuse是并集,cut是差集,参数是对象索引。设计这个索引机制是因为LLM生成的命令序列里,后续命令需要引用之前生成的形状。

这个框架跑起来之后,你会明显感觉到“CAD命令序列”方案的魅力:模型生成的命令可以被记录、复现、修改。如果你觉得某个尺寸不对,不需要重新生成整个模型,只需要改JSON里的一个数字,重新执行一遍就行。这种可调试性,是mesh生成方案完全给不了的。

3.5 输出校验:形状对不对、能不能打开

生成完实体,不能直接拿去用,必须做校验。最基本的校验项是:模型是否为一个有效的B-rep实体;体积是否为正值;几何尺寸是否在合理范围内;布尔运算后是否产生了异常拓扑。FreeCAD的Part模块自带check方法,可以快速判断:

def validate_shape(shape): if shape.isNull(): return False, "shape is null" if not shape.isValid(): return False, "shape invalid" if shape.Volume <= 0: return False, "volume <= 0" return True, shape.Volume

我还会额外加一个尺寸检查,从文本描述里抽取关键尺寸列表,再和模型实际包围盒尺寸做比对,偏差超过一定比例就认为生成异常。这个方法简单粗暴但非常有效,能把很多离谱的错误提前拦下来。你也可以在每一步命令执行后记录当前的体积和包围盒信息,这样一旦最后结果不对,能快速定位是哪一步搞坏了模型。

4. 实操中一定会碰到的几个坑

4.1 模型生成的尺寸总是不合常理

我在第一次跑通链路时遇到的最典型问题,是模型生成“外径80、内径40”的时候,孔直径直接按40生成。从纯语言角度看,这并没有错,但从工程常识看,“内径”是直径不是半径,而且孔的实际尺寸不会等于整体外径。这种量级和逻辑的错误非常普遍,因为语言模型并没有接受过机械制图的训练。

解决办法是两步走。第一步,在提示词里要求模型输出一个“尺寸规划表”,列出它理解的所有关键尺寸以及数值依据;第二步,在解析阶段设置尺寸合理性校验,比如孔直径不能超过实体宽度的一半,如果超过就直接缓存告警。实测下来,加入这两步之后,离谱误差发生率下降很多。另外把temperature调到0.2以下,能明显减少随机波动。

4.2 布尔运算失败和零厚度问题

布尔运算是text-to-cad链路里最容易出错的地方。最常见的失败场景是两个特征恰好共面,比如你要在一个长方体顶面上放一个圆柱凸台,如果圆柱底面和长方体顶面完全贴合,布尔并集很大概率会失败,OpenCASCADE在这种边界相切情况下会抛出异常或生成异常形状。

解决方案是让特征之间留一点“余量”。要么让圆柱体起始位置向下多沉0.01毫米,要么让拉伸高度比理论值多0.01毫米。这个思路在3D建模里叫“overlap策略”,虽然从工程图角度看,多出来的0.01毫米在导出STEP后并不影响实际使用,但它能让布尔运算稳定执行。我用的固定做法是:所有“贴合放置”的特征,都在接触方向上多重叠0.01mm,并把这条规则写进提示词。

4.3 零件出现非流形实体

非流形实体是CAD建模中的经典噩梦,简单说就是模型存在悬空的边、面,或者多个部分只在一点上连接,导致整个实体在物理上不可制造。这种现象在布尔运算组合特别多的时候更容易出现。

遇到这种情况,排查路径一般是先用Part.check检查具体错误类型,然后尝试换一种布尔运算顺序。比如先做一个并集,再统一做差集,比分步交替布尔更稳定。还有一个经验是,尽量不要把生成的结果直接拿去转网格做3D打印,先导出STEP用任意一个支持CAD的软件打开检查一遍。

4.4 方位描述与坐标基准混乱

用户说“右侧面开一个孔”,但模型没有“右”的概念。实际的坐标系统里,右是哪一路取决于观察角度。如果你不明确指定坐标系,模型就可能毫无根据地猜一个方位。这个问题在工业级系统里尤其致命,因为一个孔开在左侧还是右侧,零件可能就是废品和合格品的差别。

我在提示词里固定了一套约定的观察约定:Z轴向上,Y轴朝屏幕里,X轴朝右。所有方位描述都基于这个基准换算。同时在建模命令里,要求模型在每个涉及方向的参数后都附带坐标系说明文本。这样即使生成的命令有问题,人也能快速看出是方位理解错了,而不是毫无头绪地翻几何。

4.5 问题排查速查表

把这段时间踩的坑汇总成一张表,方便按图索骥。

现象可能原因处理办法
孔直径超大、壁厚为负尺寸量级未校准强制先出尺寸规划表,再生成命令
布尔并集失败抛异常特征共面或边界相切特征重叠0.01mm后再做布尔
导出的STEP在别的软件打不开非流形实体、自相交Part.check自查,换布尔顺序重生成
孔开在了错误的面上坐标系约定不明确固定Z轴向上、右方向约定,写入提示词
特征遗漏,比如漏了沉孔模型没有先规划强制输出plan字段,规划后再出commands
生成结果每次都不一样采样温度过高temperature调到0.2以下

这张表我建议直接贴在调试环境旁边,很多时候模型反复出错不是玄学,就是你绕过了其中一个步骤。

5. 这个方向能用到哪些实际场景

5.1 机械零件与3D打印的快速热身

对很多做机械设计的人来说,第一步建模往往最痛苦,尤其面对一个完全没有思路的新零件,你不知道该从哪个特征入手。text-to-cad此时可以当一个“思路引擎”:你输入零件的功能描述,它先给你生成一版可编辑的CAD模型和建模过程。你可以直接在这个基础上改参数、调整特征顺序,而不是对着空白设计树发呆。

配合3D打印就更直观了。生成STL直接打印原型,用来验证尺寸比例、装配配合关系,手感很快就有了。我见过不少硬件创业团队在用这种方式做产品前期的概念打样,效率比我刚入行那时候高出一大截。

5.2 快速出装配方案、做干涉检查

单个零件生成只是第一步,更有想象力的是多个零件一起生成然后做装配验证。你可以描述“一个电机安装座,带四个安装孔,上方预留联轴器空间”,生成后用FreeCAD的装配工作台把它和标准电机模型组装起来,快速看是否存在干涉。

这条路目前还很糙,因为生成的模型缺少配合公差、定位基准,直接拿来出工程图肯定不够。但作为方案阶段的“空间占位检查”,它已经能提供很大的参考价值。你可以把生成模型看作高精度的三维草稿,后续细化工作人工补上即可。

5.3 企业内部标准件库的自然语言入口

我觉得这是text-to-cad最可能率先在企业落地的场景。很多企业的标准件库有几千个系列化零件,以前设计师找零件是靠分类目录翻或者编号查,效率不高。如果把标准件库的建模过程预置成命令序列,并配上文本描述,再微调一个小模型,员工就能直接说“我需要一个M6长度30的半圆头螺栓”或者“给我一个宽40深30高25的塑料接线盒底座”,然后在模型里直接调用。

这个场景之所以容易落地,是因为企业的标准件库本身就是高度参数化的,命令序列天然存在,不涉及复杂的自由建模,而且检索和调用有明确的正确性标准。它其实是在给已有CAD系统装一个“自然语言搜索引擎”,比从头生成新零件要靠谱得多。

5.4 往后可以怎么玩

从我观察的趋势看,文本加草图、文本加图片的多模态输入会是下一波重点。很多零件用草图描述比文字精确得多,模型如果能理解“这张草图旋转后形成回转体”这类跨模态语义,就能极大扩展适用范围。另外,结合有限元分析反馈来迭代生成,比如“模型应力过大,把加强筋加高”,也是我很看好的方向,因为它让整个设计闭环可以对话式推进。

不过在这些真正成熟之前,最值得先做的是把基础链路打磨稳:怎么让模型更懂尺寸语义、怎么提升布尔运算成功率、怎么在命令序列层做设计意图的自动纠偏。基础不牢,后面任何花哨玩法都跑不远。

我个人实际操作下来的体会是,text-to-cad这个方向最有价值的地方,不在于它真的能一次生成一个多么复杂的工业零件,而在于它把“建模决策过程”变成了可对话、可修改、可追溯的东西。你让模型出一个法兰盘,它给你一段带着尺寸规划的建模步骤;你说厚了,它改一个数字重建,整个交互方式像是和一个熟悉CAD API的同事在交流。老实说,当前方案离端到端工业级还有不小的距离,尤其公差、材料、制造工艺这些语义,模型目前根本不懂。但这并不妨碍我们把它当作一个强力的“初始建模助手”。最后分享一个小技巧:无论你用哪个模型,都记得在提示词里要求它先输出plan再输出commands,这个两段式结构能显著降低复杂特征的遗漏率,我自己用下来一直很顺手。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询