text-to-cad 这个方向,最近真的是把不少人的时间吃掉了。说得直白点,就是你在输入框敲一句大白话,比如“做一个120毫米长、80毫米宽、10毫米厚的矩形板,四角倒半径5的圆角,中心打个直径12的孔”,后台直接给你生成一个带尺寸、带特征树、能继续编辑参数的实际 CAD 模型文件,而不是一张渲染出来的效果图。这就跟平时那些文生图工具完全不是一个物种了——它生成的是实体边界表示的几何体,能直接丢进参数化 CAD 软件里继续加工、装配和出工程图。
我自己的理解是,text-to-cad 真正解决的并不是“让 AI 学会画图”,而是“让不熟悉建模操作的人,也能把脑子里的设计意图变成真实可用的三维零件”,同时让熟练的建模师把大量重复性的草图拉伸、挖孔、倒角动作交给自然语言去驱动。如果你之前用过文本转图像的工具但还没接触过这个方向,或者你现在正琢磨着怎么把大模型接入你的设计流程,这篇文章可以帮你把里面的门道一次看透。
1. 从“文生图”到“文生CAD”,思路上的关键一跳
1.1 传统建模方式和一条新增路线
传统上用三维软件建模,基本是两条路。一条是交互式建模,你打开某个参数化 CAD 软件,选草图平面,画矩形,标尺寸,拉伸出实体,再继续选面打孔。这种操作最大的成本是“软件操作经验”,一个刚上手的人光是把草图完全约束搞清楚,就得折腾好几个下午。另一条是程序化建模,用脚本来描述几何,比如常见的代码式 CAD 工具,把“长方体、圆柱、布尔减除”写成一段脚本,改参数就重新生成。
text-to-cad 则是在程序化建模外面再包一层大语言模型翻译器。它的核心链路是:用户输入自然语言,大模型理解意图并抽取关键参数,然后把这些参数组织成一段可执行的建模代码,由底层的几何内核去实际构建三维实体。等于说,大模型在这里扮演的是一个“能听懂人话的参数化建模师傅”,它先替你读懂需求,再帮你把建模师傅要用的指令逐条写出来。
这里有个很重要的认知:text-to-cad 并没有发明一种新的几何内核,也没有重新发明建模方式。它做的是把过去需要人手动完成的“意图到指令”这一步自动化了。所以这类项目通常跑得通,本质上是站在了成熟内核的肩膀上。
1.2 为什么不走网格生成的路线
你看现在市面上很多“文生3D”的项目,生成的是一层网格模型(mesh),本质是一堆三角形拼出来的表面。这种模型用来做游戏资产、做展示动画完全没问题,视觉效果很唬人,但拉到工业设计流程里就废了:你不能从网格里重新提取一张带约束的草图,不能对它做精确的圆角半径修改,孔位公差更是无从谈起,更别说直接下到数控机床去加工。
而 CAD 场景里要求的实体模型(B-rep 边界表示),记录的是面、边、顶点之间的拓扑关系,以及构建这个实体的历史特征。你拿到的不只是一个“壳”,而是一串可以回溯的构建过程:第几步拉伸、第几步打孔、第几步倒角,每一步的参数都能改。这就像一个是“照片”,一个是“源文件”。Photoshop 能直接改源文件的图层,但它改不了照片里的像素;工程上多数时候要的是源文件,这就是 text-to-cad 坚持走实体建模路线的根本原因。
一句话总结:网格模型适合给人看,CAD 实体模型适合给机器加工。text-to-cad 选择的后者,目标场景也天然地从“展示”迁移到了“制造”。
1.3 核心管线拆解
把这类系统拆开看,主体环节大致是五个:
第一,自然语言输入处理。大语言模型接收一整段描述,识别出里面和几何造型有关的实体,比如“板”“管”“支架”,以及约束条件“长、宽、高、直径、孔距、圆角”。第二,中间表示生成。模型需要决定用哪些建模操作来表达这个零件,是把模型当作“拉伸出来的板”还是“旋转出来的轴”,这个拓扑思路会直接影响最终模型能不能成形。第三,代码脚本生成。把中间表示翻译成某个参数化建模库的 API 调用序列,这一步相当于把设计思路落到具体语法上。第四,内核执行和校验。几何内核真的去执行这些操作,生成实体,同时检查拓扑是否有效,有没有自相交,布尔运算是否成功。第五,格式导出与后处理。把结果导出成 STEP、STL 这类通用格式,供下游 CAD 软件打开。
这个管线里,最容易被忽视的是第四步。因为大语言模型生成的脚本经常带着“想当然”的成分——尺寸正负号搞反、孔位落在实体外面、倒角半径大过板厚,这些在脚本阶段根本看不出来,只有丢到内核里去执行,让几何自己“撞一下墙”,才能暴露问题。这也是为什么这类项目都需要一个很扎实的验证层,而不是模型输出什么就信什么。
2. 让大模型能“理解尺寸”的实操要点
2.1 输入解析:把一句话拆成几何要素
我试过几次之后就发现,模型能不能生成正确结果,第一步就卡在它有没有把你的话拆明白。比如你输入“做一个带四个耳朵的圆盘底座”,这句话里“圆盘”是主体形状,“四个耳朵”是附加特征,但“耳朵”长什么样、多厚、分布角度多少,全部没有定义。这种时候模型就面临一个选择:是凭默认值瞎猜,还是主动向你确认。
实际项目里常见的做法是给模型预设一套默认约定。比方说,如果没有特别说明,模型默认生成实体以原点为中心对称放置,默认草图平面是 XY 平面,默认拉伸方向是 Z 轴正方向,默认长度单位是毫米。有了这些默认约定,模型在解析输入时就有了基准坐标参考系,生成的代码才能保持一致,而不是这次朝左、下次朝右。
在解析几何要素的时候,我自己的经验是重点关注四类信息:主形体类型、关键尺寸、特征位置、特征数量。主形体类型决定了使用哪种建模策略,比如“板、块类”优先考虑拉伸,“轴、管类”优先考虑旋转,“壳体类”可能需要抽壳操作。关键尺寸包括长、宽、高、直径、壁厚这些,缺省的话要么用合理默认值,要么在代码里用变量名留出待定参数。特征位置通常依赖坐标或相对关系,比如“中心”“距左端 10 毫米”,这类信息最容易出错,需要在提示词里明确表达成坐标或偏移量。特征数量则直接关联到后续的阵列或者重复操作。
2.2 默认约定和坐标系统一
坐标系统一这件事,听起来像基本功,实际操作里翻车率极高。同一个零件,有人描述成“前面板上开四个孔”,有人描述成“沿 X 轴等距分布”,如果模型没有全局统一的坐标系语义,就会把孔开到你根本想不到的位置。
我在做提示词模板时,会把坐标系约定直接写死在系统提示里:以模型中心为原点,X 向右,Y 向上,Z 朝向观察者;板类零件默认底面位于 XY 平面,拉伸方向朝 +Z;孔的位置如果没有特殊说明,一律理解为在正面视图上给出二维坐标。这样规定之后,模型的输出空间就被压缩到一个可预测的范围内,后续出错的概率骤减。
另一个容易被忽略的点是对称性。大多数机械零件至少有一个对称面,text-to-cad 系统应该先尝试识别对称特征,然后只让模型生成对称的一部分,再通过镜像操作补齐。理由是:第一,大模型单独生成“对称的另一半”时,很容易在位置上产生微小偏差,导致整体配合度下降;第二,通过代码层面的镜像操作,可以保证几何严格对称,不需要额外校验。这属于典型的“少让模型做一步,就少一类出错机会”的工程思维。
2.3 单位、方向和特征树顺序
单位问题是 text-to-cad 场景里一个不显眼但杀伤力巨大的坑。大模型本身没有物理直觉,它不知道你口中的“10”到底是 10 毫米还是 10 英寸。一旦单位理解错位,生成的模型要么整体放大 25.4 倍,要么小到看不见。
我习惯在代码生成的时候,把单位硬编码进 API 调用里。比如某个开源参数化建模库的 API 默认以毫米为单位,那么脚本里就不需要额外声明;但如果用户输入里明确写了“英寸”,就要在生成代码前先做一次换算。与其相信模型会在代码里写对单位,不如在系统层面统一约定“毫米是唯一合法单位”,并在提示词里特别注明所有尺寸都按毫米解析。
特征树顺序则是另一个需要提前规划的事。同样是生成一块带孔板,你可以先拉伸板再打孔,也可以先生成孔后拉伸成异形件,两种路径结果上可能一样,但后续可编辑性完全不同。经验之谈是:先定主形体轮廓,再做减材操作,最后做修饰操作。也就是先拉伸或旋转出毛坯,然后打孔、挖槽,最后倒角、圆角。这个顺序最符合多数机械零件的制造工艺,也最容易被下游软件继续编辑。如果模型把圆角放在布尔运算之前,很可能因为圆角区域被后续切掉而导致失败的连锁反应。
2.4 提示词设计:用结构化的方式提问
大模型能不能做对事,很大程度取决于你问得有多清楚。我在二三十次测试之后总结出一个很实用的提示词模板,它把一段模糊需求转成结构化描述:
- 物体类型:矩形板
- 外形尺寸:长 120 毫米,宽 80 毫米,厚 10 毫米
- 修饰特征:四角倒圆角,半径 5 毫米
- 孔特征:中心一个通孔,直径 12 毫米
- 默认就按这个格式:先说主体,再说外形尺寸,再说修饰和孔。
用这种结构化句式,模型的解析成功率明显高于自由描述。还有一个技巧是每条特征前面加一个“目标”动词,比如“创建一个”“切除一个”“倒一个”,把操作意图直接映射到代码指令上。这个细节很有效,因为大模型训练语料里“创建一个孔”和“画一个孔”背后的代码操作其实不同,前者映射的是打孔指令,后者可能映射成草图圆而不是切除。
如果你在用支持多轮对话的实现,还可以在用户输入模糊时让模型主动追问。比如“板上的‘四个耳朵’你想要多厚?分布在圆周还是直边?”一次确认比十次返工节省太多时间。
3. 动手复现一个完整的建模流程
3.1 从自然语言到执行代码的完整示例
纸上谈兵没有意思,我实操时候最常用的例子,就是下面这个带法兰的轴套。我拿真实跑通的完整流程给你拆开看。
输入的自然语言是这样的:“创建一个以原点为中心、轴向沿 Z 的轴套,底座是一个直径 60 毫米、厚度 8 毫米的法兰盘,中间是外径 30 毫米、内径 16 毫米、长度 50 毫米的管体,法兰盘上均布 4 个直径 6 毫米的通孔,孔心距圆心 24 毫米,最后整体外轮廓倒角 1 毫米。”
大模型先把它转成一个结构化的建模方案:底座用旋转还是拉伸?这里底座是圆盘,管体是圆柱,如果直接拉伸两个圆再合并,生成的模型特征树是两个拉伸特征加一个布尔并集;如果整体画一个草图再旋转,特征树就是一个旋转特征。用旋转特征明显更简洁,也更符合轴套件的成形方式——车削件,天然是一根回转体。这就是模型在中间表示阶段做的最重要决策。
接着生成代码。框架大体是这样的:
# 用某开源参数化建模库的 Python API 风格写出的示意代码 import cadlib as cl # 1. 旋转生成法兰和管体的整体外形轮廓 profile = cl.Sketch("XZ") profile.polyline([ (0, 0), (30, 0), # 管体外壁起点 (30, 50), # 管体顶部 (15, 50), # 管体顶部内壁 (15, 8), # 法兰上表面内侧 (0, 8) # 法兰中心线位置 ]) profile.close_axis() # 闭合到旋转轴 body = profile.revolve(axis="Z", angle=360) # 2. 挖出管体内孔 inner = cl.Cylinder(radius=8, height=50, pos=(0, 0, 25), dir="Z") body = body.cut(inner) # 3. 法兰盘上均布四个孔 for angle in [0, 90, 180, 270]: hole = cl.Cylinder(radius=3, height=20, pos=(24 * cos(angle), 24 * sin(angle), 8), dir="Z") body = body.cut(hole) # 4. 外轮廓倒角 body = body.chamfer(edges="outer_edges", length=1) body.export("flange_bushing.step")注意,第一步的旋转轮廓只画了一半,因为是绕 Z 轴旋转的,闭合到旋转轴,内核会自动生成完整回转体。内孔用一个单独的圆柱做布尔减除,四个均布孔用 loop 循环生成。最后倒角是针对外轮廓所有相交棱线做的。
这套代码生成逻辑里,隐藏着一个关键细节:草图轮廓和布尔操作之间是有前后依赖的。如果第一步就把内孔画进草图,旋转出来就是一个管体而不是实心体再挖孔,虽然最终形状相似,但特征树语义完全不同。真实的制造场景里,一个零件的特征树会直接决定后续出工程图时剖视图的表现,所以这种顺序上的选择不是强迫症,是实用考量。
3.2 一步步读完执行日志
我实际操作时,会开启内核的详细日志模式,每执行一个算子就输出一行状态。这样我能清楚看到每个环节实际发生了什么。
执行日志大致长这样:
第一行,解析草图轮廓,识别到四个顶点、三条直线段和一个轴端点,判定轮廓闭合,创建旋转特征。第二行,执行旋转,生成的实体包含 2 个面、1 条棱边,拓扑校验通过。注意这里生成的是没挖孔前的实心轴套。第三行,创建内孔圆柱,执行布尔减除,成功,实体面数增加,出现内腔。第四行,循环创建四个孔圆柱,逐个减除,四步都成功。第五行,执行倒角,识别到外轮廓顶部一圈棱边,共 12 条边,倒角长度 1,完成。
这个日志看起来平平无奇,但如果你调试过类似系统,就知道每一步都可能跳出一堆异常。年轻的爱好者第一次跑的时候,最容易卡在第三步:布尔减除失败。日志会提示“target solid is not valid after boolean operation”,也就是减完之后实体拓扑不合法。这种情况十有八九是因为第二步生成的实体内腔和后续减除体之间存在共面接触,产生了退化面。
面对这种问题,我的处理方式是在内核执行之前先做一个“实体有效性预检”,对每一个布尔操作体判断体积和包围盒是否正常,对可疑情况提前调整坐标系偏移量。比如内孔高度我写成 50.001 毫米而不是 50 毫米,微小的贯穿量能避开共面退化,这是老手才知道的土办法。
3.3 验证和导出:体积、视图、格式
生成结果不能只看“长得像”,要验证它真的可用。我的验证三板斧是:体积验算、剖面检查、格式兼容性测试。
体积验算很简单。对于上述轴套,手算一下:法兰盘体积是 π × 30² × 8,减去四个孔 π × 3² × 8 × 4;管体体积是 π × 15² × 50 减去 π × 8² × 50,加上倒角削减的一小部分。然后用内核接口读出实体的体积属性,和理论值对比。实测下来,只要布尔运算成功,体积误差通常在 0.1% 以内,说明几何没有明显畸变。
剖面检查则是为了验证内部特征。我在导出之前,先用代码生成一个沿轴线的剖面视图,看看内孔是不是完全贯穿,法兰背面的孔口有没有因为倒角而变形。这一步能发现很多体积验算发现不了的问题,比如内孔和法兰面交界处生成了意外的凸台。
最后是格式兼容性。我一般会同时导出 STEP 和原生模型两种格式,STEP 用于跨软件交换,原生格式用于继续编辑。然后把这个 STEP 文件导入到几款不同的参数化 CAD 软件里,确认打开时不报错、不丢面。这一步是检验生成结果能否进入真实工作流的最终关卡。有些模型在自研内核里看着完美,一导入到商业软件里就出现破面或者特征树解析失败,那就说明生成代码里某些拓扑结构习惯和下游软件不兼容,这种问题只能靠多轮跨软件测试来修正。
3.4 更复杂的装配体场景扩展
单零件跑通之后,自然就想做装配体。text-to-cad 在装配体场景里,我目前看到的路线是两个:一是生成多个零件后做“虚拟装配”,即靠坐标位置关系把零件摆到正确相对位置;二是生成一个“联动参数”的多零件脚本,改一个主尺寸,其他零件的相关尺寸自动跟着变。
第二种路线对代码结构的要求高很多。我试过一个配对的公母接头,公接头外径 20 毫米,母接头内径必须配合成 20.1 毫米间隙。如果分开写两个零件的代码,间隙值只能写死;如果做成参数联动,那么脚本里就有两个变量,name_dim = 20,clearance = 0.1,母接头内径变量计算为 name_dim + clearance。这样后续修改公接头外径为 25,母接头内径自动变成 25.1。
这种参数联动的思路,做单个零件时体会不到,但一进装配场景就变成刚需。大模型在生成这类跨零件依赖代码时,经常出现“公接头改了,母接头没改”的情况,所以我的建议是在提示词阶段就把联动关系写成无歧义的公式,而不是依赖模型自己去理解“配合”这个模糊语义。
4. 常见问题与排查技巧实录
4.1 高频错误速查表
实操了上百次之后,我把踩过的坑整理成一张速查表,照着排查能节省大量时间。
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 生成的模型是个空壳或片体 | 草图轮廓未闭合、拉伸类型选成了曲面 | 强制闭合轮廓,校验草图线段首尾相连 |
| 孔位乱跑,不在预期位置 | 坐标系理解不一致或漏了基准点 | 固定原点约定,孔坐标写成显式数值 |
| 圆角或倒角失败 | 半径值接近或超过壁厚 | 限制圆角半径小于最小壁厚的50% |
| 整体尺寸被放大了约25.4倍 | 英寸/毫米单位识别错误 | 系统内强制毫米,提示词写入单位约定 |
| 布尔减除后实体消失 | 被减体与目标体重叠异常或共面 | 给减除体增加微小贯穿量 |
| 生成代码语法错、API用错 | 缺少数例参考,模型不熟悉库调用 | 加入小样本示例,配检索增强 |
| 零件很多碎面、缝合失败 | 边界表示生成时存在退化边 | 微调几何参数,避开共点共线 |
| 导出STEP后导入CAD软件丢面 | 拓扑结构存在非流形边 | 在导出前做实体合法性修复 |
这张表的价值在于,它把“凭感觉试错”变成了“按清单排查”。我是从上到下逐项检查,能在十分钟内定位大部分问题的根因。
4.2 几何内核报错故障排查思路
几何内核报错是最让人头大的。因为它不像语法错误那样有明确的报错行号,很多提示是“operation failed”这种说了等于没说的信息。
我的排查思路分四层。
第一层查拓扑预备条件。布尔运算前,两个实体不能有共面接触,不能正好相切,不能有完全重叠的边。我会在代码里对每个参与布尔运算的实体先做“干涉检测”,获取它们的相交体积和相交面数量,把潜在危险点提前暴露。
第二层查容差设置。几个开源内核默认的建模容差在 1e-5 到 1e-7 毫米之间,如果你的设计里有微小圆角或者细小特征,本身就小于容差,内核会直接判死。这种情况解决办法是调整容差参数,或者干脆把微小特征改成装饰性倒角放在最后一步。
第三层查操作顺序。同一个零件换一个构建顺序,结果可能天差地别。我的习惯是“先做加材料,再做减材料,修饰放最后”,这条规则能避开大量中途失败。
第四层查布尔操作类型。有些内核里“union”和“fuse”的行为细节不同,后者可能保留原始面,前者直接合并成单一实体。当输出模型存在多余内部面时,检查代码用的是融合还是合并,换一个语义试试。
按这四层顺序排查,基本没有解不开的内核异常。
4.3 让模型稳定可用的“避坑锦囊”
最后分享几个让 text-to-cad 系统稳定可用的经验,可能比前面所有参数都值钱。
第一个锦囊:把用户输入和代码生成之间加一层“参数抽取校验”。不要直接让大模型输出代码,而是让它先输出一套结构化的 JSON 参数,比如 shape_type、main_dimensions、hole_list、chamfer_config。这一步单独校验参数是否在合法范围内,比如长宽高大于 0、孔位在包围盒内、圆角半径合理。校验通过后再把 JSON 拼接到预设的建模模板代码里。这样做的好处是显著降低模型生成非法代码的概率,因为它不用在生成代码的同时思考几何正确性,而是把两步拆开各干各的。
第二个锦囊:建立常用零件的“模板库”。把平板、法兰、轴套、支架、壳体这些高频零件预先写好带参数占位符的建模脚本。用户的自然语言进来,模型只需要抽取参数,匹配最近的模板,然后把参数填进去。这个方案比每次从零生成代码稳定得多,就像一个老画师先有半成品模板再调整细节,出活率和质量都远超白纸起稿。
第三个锦囊:永远把生成结果当“初稿”而不是“成品”。我在实操中得到的最大认知是,text-to-cad 的输出适合作为设计起点,而不是可以直接下发车间的图纸。它帮你把 80% 的重复建模时间省掉了,但最后那 20% 的工艺性调整——比如退刀槽是否合适、公差标在哪面、粗糙度要求——仍然需要专业设计者把关。这里的正确用法是把它当作一个“高级草图工具”,快速出方案,再人工精修。
第四个锦囊:批量生成时一定要做烟雾测试。假如你需要用批处理生成几百个零件,建议先随机抽取 10% 跑一遍完整流程,检查成功率和常见失败模式,再决定是否全量跑。别指望大模型在批量场景下的表现跟单次生成一致,实际测试中批量模式的成功率往往比单次低 5~10 个百分点,原因可能是上下文变长后注意力分散。
第五个锦囊:给自己留一个“人工审核通道”。系统再智能,也会有几何怪胎产生。一个负责任的工作流里,应该做一个可视化界面,把生成的每个模型截图缩略图排列出来,操作者快速扫一眼,把有明显问题的直接毙掉,而不是逐个大模型对话框里翻代码。
我在实际使用中最大的体会,是这个方向还在快速生长,但你不需要等它完全成熟再动手。把它当作一个能听懂人话的高级建模助手,先解决简单常规零件,再逐步扩展复杂曲面和装配场景,投入产出比非常高。最后说一个小窍门:无论你用什么实现方案,一定要在系统提示词的末尾加一句“如果用户的描述缺少关键尺寸,请使用你内置的合理默认值,并在代码注释中注明”,这句话能减少一半因为模糊需求导致的死循环,实测非常管用。