Text-to-CAD全解析:用自然语言生成可制造三维模型

发布时间:2026/10/27 5:53:19
Text-to-CAD全解析:用自然语言生成可制造三维模型

最近大半年,我几乎把业余时间全泡在了 text-to-cad 这套技术路线里,从复现论文到实际出件,算是把这个方向从里到外摸了一遍。先给还不了解的朋友说清楚——text-to-cad 就是把一句自然语言描述,比如"做一个能夹在桌面边缘的 C 型支架,开口宽度 30 毫米,夹持深度 25 毫米,背面留两个直径 5 毫米的安装孔",自动变成一套可编辑、可制造的三维 CAD 模型。听起来很科幻,但这件事现在已经有了相当完整的开源工具链和商业化产品,不再是概念演示。

这个方向真正吸引我的地方在于,它把 CAD 建模的门槛一下子拉低了好几个量级。传统的参数化建模,你得先懂草图、约束、拉伸、切除、倒角这一整套操作逻辑;而 text-to-cad 让你只需要把需求说清楚,剩下的几何构建工作交给大语言模型和程序化建模库去完成。这篇文章我会从技术原理、主流工具、数据集构建一路讲到完整的实操过程和踩坑记录,适合正在评估这个方向的机械工程师、想做 3D 打印的创客,以及被建模效率问题折磨的设计师。不管你是想快速验证概念,还是打算在自己项目里接入这套能力,这篇文章应该都能给你一个清晰的路线图。

1. Text-to-CAD 到底在解决什么——先从一个建模痛点说起

1.1 一个需求到 STEP 文件的全链路

我在实际项目里最常遇到的一个需求场景,就是设计一个夹在桌面边缘的 C 型支架。传统 CAD 流程下,我至少得建三个草图、定义两处拉伸、做一次布尔切除,再把背面两个安装孔的位置和尺寸约束好,半小时起步,还得保证每一步的约束关系不冲突。但如果走 text-to-cad 的链路,整个过程就换了一套完全不同的思路。

第一步,自然语言描述会被大语言模型解析成一连串程序化建模指令,比如生成一个 U 型截面、按指定高度拉伸、在特定坐标位置布尔减掉两个圆柱体。第二步,这段指令交给 CadQuery 这样的 Python 建模库去执行——注意,不是让 AI 直接在三维空间里凭空画,而是让它生成一段描述几何操作顺序的程序。第三步,CadQuery 底层调用 OpenCascade 几何内核,在内存里完成实体构建,最后导出成 STEP 文件。STEP 文件是什么?它是工程软件之间交换三维模型的标准格式,可以直接导入 FreeCAD、Fusion 360、SolidWorks 做二次编辑。

这条链路最巧妙的地方在于:大语言模型不直接负责"想象"三维形状,而是负责"编排"建模步骤。它把一句模糊的自然语言,翻译成一串精确的、可执行的程序指令,几何精度完全由程序化建模库来保证。这种分工方式避开了大模型在空间几何推理上的先天短板,又充分发挥了它在代码生成上的绝对优势。

1.2 为什么这件事现在才真正火起来

其实"用文字生成三维模型"这个想法,早在深度学习火起来之前就有人提过,但一直做不成的核心原因有三个。

第一,大语言模型的代码生成能力在近几年才达到可用水平。早期基于规则和模板解析的方法,只能处理非常受限的句式,面对"开口宽度 30 毫米、背面留两个孔"这种包含多实体、多操作、多约束的复杂描述,基本就崩了。真正让这条路走通的,是 Llama、Mistral 这一代模型在代码理解与生成上的质变。第二,程序化建模生态的成熟度到了临界点。CadQuery 作为 Python 库,API 设计已经足够稳定和直观,而且它天然就是用代码描述建模操作,正好成了大语言模型与三维实体之间的理想桥梁。第三,数据集的构建和开源让模型微调成为可能。Text2CAD 这类研究项目公开了数万条"文本描述—程序代码—CAD 模型"的配对数据,没有这些数据,模型就只是会写 Python,但不知道怎么写 CAD 程序。

用个生活化的类比,让 AI 画一张图很容易,因为图像是连续的像素网格;但让 AI 精确理解一个零件的空间关系就很难,因为三维描述涉及尺寸、公差、布尔运算、约束体系,必须落到符号表达上。text-to-cad 找到的捷径不是让 AI 变聪明,而是让它学会调用工具——就像你不会要求施工队长亲手砌墙,只要求他会安排工人和材料。

1.3 价值边界:谁最需要它,以及它的能力上限

从我实际的使用感受来看,text-to-cad 最适合这四类场景:机械工程师在概念设计阶段快速验证结构可行性,创客设计 3D 打印外壳和简单机构,产品设计师做早期方案对比,以及 CAD 教学场景里给初学者演示建模逻辑。

但同时也要把话说明白,它的能力边界非常清晰。复杂装配体不要指望,涉及几十上百个零件的配合关系、运动学约束、公差累积,目前这条路线完全驾驭不了;自由曲面和高光顺曲面也不要指望,程序化建模本身就不擅长这类形状;依赖工艺经验的设计决策,比如拔模角度、加强筋布局、材料收缩率补偿,AI 更是一窍不通。它的定位是把你从"从零开始画图"的泥潭里拉出来,而不是替代你的工程判断力。

2. 三条技术路线与主流工具盘点

2.1 路线一:大语言模型直接生成程序化建模代码

这是目前工程性最强、也最值得投入时间研究的一条路线。以 Text2CAD 开源项目为代表,思路是用微调后的大语言模型吃进自然语言描述,直接输出 CadQuery 或类似程序化建模库的代码。模型只需要把自然语言正确地翻译成代码,几何精度完全由几何内核保证,所以容错率比纯生成式方案高得多。

为什么选择 CadQuery 而不是别的程序化建模工具?我在实际选型时反复对比过两三个备选方案。OpenSCAD 虽然也是代码建模,但它的 CSG 布尔逻辑和函数式语法对 LLM 来说生成难度更高,而且编辑体验不够直觉;FreeCAD 的 Python API 功能完整但接口复杂,模型容易生成一长串底层操作代码,可读性和可维护性都很差。CadQuery 的链式调用 API 和"先画草图、再拉伸、再切孔、再倒角"的工程思维几乎一一对应,大模型只需要学会这一套固定的 API 调用模式,就能稳定输出可用代码。

下面这段是 CadQuery 最典型的建模代码,我经常拿来验证模型是否真正理解了 API 调用的语义:

import cadquery as cq plate = ( cq.Workplane("XY") .rect(60, 40) # 在XY平面画60x40的矩形草图 .extrude(10) # 沿Z轴拉伸10毫米 .edges("|Z") # 选中所有平行于Z轴的边 .fillet(5) # 对这四条边导5毫米圆角 ) cq.exporters.export(plate, "plate_with_fillet.step")

每一行对应一个明确的建模操作,组合起来就是一个带圆角平板的完整实体。这种"一个自然语言短语对应一行 API 调用"的对应关系,正是大语言模型最擅长学习的模式。

2.2 路线二:三维扩散模型直接生成几何

这条路线模仿文生图的成功经验,用扩散模型直接生成三维几何数据,输出形式可以是体素、隐式场或者点云。优点是自由曲面能力很强,能生成一些程序化建模很难描述的有机形态;但缺点对工程师来说非常致命——生成结果是网格或者隐式场,不是精确的 B-rep 实体。

网格转 STEP 在工程上是一个艰难的逆过程,需要做曲面拟合、拓扑重建、精度控制,任何一个环节出错,模型就无法进入制造流程。即使转换成功,原始网格的逼近误差也已经烙进了几何里,公差要求稍微高一点就废了。我在评估这类方案时试过几个开源模型,结论是:如果你只是做可视化展示和游戏资产,这条路线完全够用;如果你要出加工件,它目前只能在"概念灵感参考"这个层面止步。

2.3 路线三:自然语言驱动的参数化特征树

第三条路线介于前两者之间,大模型输出的不是完整代码,而是一组结构化特征操作序列,比如"创建草图、拉伸、阵列、打孔",然后由 CAD 内核按序列重建模型。这种方案更接近人类工程师在 CAD 软件里的真实操作习惯,但实现难度也最高,因为特征之间的依赖关系、参考基准、约束传播都需要模型准确判断。

CAD-MLLM 这类多模态模型是这条路线的代表,它不只是吃文本,还能同时理解草图图像和特征树序列。从研究进展看,这条路线很诱人,但离稳定可用还有一段距离,主要问题是特征序列一长,模型的错误就开始累积,经常生成到第五六个特征就崩了。我个人的判断是,它未来可能是最有价值的路线,但现在还不是投入生产环境的好时机。

2.4 主流工具横向对比与选型建议

我在切换不同工具的过程中整理了一张对比表,方便你根据自己场景做选型:

工具/项目技术路线输出格式工程可用性适合人群
Text2CAD(开源)LLM 生成 CadQuery 代码STEP/B-rep较高想自建流程、做二次开发的工程师
Zoo(商业 SaaS)LLM+程序化建模STEP高需要稳定在线服务的团队
BlenderGPT(开源)LLM 生成 Blender Python 脚本网格低游戏资产、概念可视化
CadQuery(底层库)无,程序化建模本身STEP/B-rep高所有需要代码建模的人
CAD-MLLM(研究)多模态特征树生成特征序列中低研究者和技术前瞻者

我的建议其实很简单:想快速出成果,直接用 Text2CAD 微调模型的思路,在 CadQuery 上面套自己的提示词模板;想要商业级稳定服务,Zoo 这类产品做得比开源方案好很多,毕竟有前 Autodesk 团队在打磨;想深入做研发,就从 CadQuery 这个底层入手,它才是整个链条里最不可替代的环节。

3. 原理拆解:为什么说"让 LLM 写程序"是更聪明的做法

3.1 大模型的空间推理弱,但代码生成强

大语言模型在纯文本任务上的表现大家都看到了,但把它放到三维空间里,问题马上就暴露出来。你让它描述一个物体的外观特征,它可以说得头头是道;你让它给定两个零件之间的装配关系和间隙,它就会开始胡说八道。这是因为三维空间的精确推理需要持续的几何计算,而语言模型内部根本没有这个计算机制。

text-to-cad 的破局思路特别聪明:它不强迫语言模型学会三维推理,而是让它把问题翻译成程序代码,把几何计算外包给专门的几何内核。换句话说,大语言模型是翻译和编排者,CadQuery 加 OpenCascade 才是真正"做几何"的执行者。再打个比方,你自己画不好一座桥的施工图,但你知道施工规范,你能指挥施工队把桥建出来——大模型干的就是施工队长的活,它不需要亲手搬砖,但必须懂工序、会派活。

这也是为什么这条路线比"端到端直接生成几何"要稳得多。代码是离散的符号序列,大模型特别擅长生成,而符号序列在执行过程中又被几何内核严格校验,生成结果对不对、能不能形成一个封闭实体,运行一遍就知道,不需要靠"看起来像不像"来判断。

3.2 CadQuery 的建模逻辑:代码是如何一步步变成实体的

CadQuery 的核心理念是"工作平面 + 草绘 + 特征操作",这套逻辑和传统 CAD 软件高度一致,但表达方式完全是程序化的。它的每个建模步骤都可以在代码里精确复现,模型不是画出来的,而是算出来的。

一个 L 型支架的建模过程拆开来看:首先是选定工作平面,CadQuery 里用Workplane("XY")指定在全局坐标系下的参考面;然后是绘制草图,rect()、circle()这些方法画出封闭轮廓;接着是拉伸,extrude()把二维轮廓沿法向拉出厚度;再往下是特征操作,cut()做布尔减除、fillet()导圆角、hole()打孔。每一步操作的结果都是一个 B-rep 边界表示实体——所谓 B-rep,就是用顶点、边、面以及它们之间的拓扑关系精确描述三维物体,和网格那种用大量三角形逼近的方式有本质区别。

我初学 CadQuery 的时候最大的困惑是"代码怎么知道该往哪个方向拉伸、孔该打在哪"——答案全在 API 的语义里。Workplane("XY").rect().extrude(10)是在 XY 平面上画草图后沿 Z 轴方向拉伸;.faces(">Z").workplane().hole(4)是先选中朝正 Z 方向的顶面、建立新的工作平面、在那一面打孔。这种选择方式在代码里很直观,但模型生成时需要准确把握每个操作用在哪个面上,这也是实际使用中文本描述最容易出错的地方,后面我会专门讲。

3.3 数据集与评估机制:Text2CAD-10K 是怎么来的

任何一条数据驱动的技术路线,都绕不开数据集的质量。Text2CAD 项目公开的 Text2CAD-10K 数据集,包含了大约一万个来自大型 CAD 模型库的三维模型,以及配套的八万多条英文文本描述。文本描述不是凭空写的,而是采用了大模型合成加人工筛选的策略——先用大模型为每个模型生成多种粒度的描述语句,再人工过滤掉歧义、错误、过于笼统的样本,确保描述和模型的对应关系可靠。

评估一个 text-to-cad 系统做得好不好,不能只看它输出形状像不像,我实践下来至少有四个维度要看:文本匹配准确率——生成的模型是否符合自然语言描述中的属性;几何有效性——输出是否是封闭实体,有没有破面、自相交、非流形边;程序正确性——生成的 CadQuery 代码能否不报错地运行;制造可行性——模型壁厚、公差、可打印性是否在合理范围。

这里特别想提醒一点,很多研究者只看几何有效性和文本匹配,但作为工程师出身,我最看重的是制造可行性。一个几何完全有效但壁厚只有 0.1 毫米的支架,根本不具备任何生产价值。你在选模型和调整提示词的时候,一定要把"能不能造出来"这条标准放在脑子里。

3.4 为什么最终模型必须是 B-rep,而不是网格

这个问题我和很多做图形学的朋友争论过很多次。网格表示像一个用无数小三角面片堆出来的沙雕,远看挺像那么回事,但放大到微米级别,每个面都是平的,曲面全靠逼近,精度完全不够。B-rep 则是用 NURBS 曲面、边和顶点的精确数学定义来描述物体,一个圆柱面就是一个标准解析曲面,直径 90 毫米就是 90.0000 毫米,不是 89.9987 毫米。

工程制造为什么非 B-rep 不可?因为 CAM 加工路径计算需要精确曲面法向,公差分析需要精确几何边界,模流分析和有限元分析也都依赖高质量实体模型。STEP 格式保存的就是 B-rep 信息,这也是为什么所有 text-to-cad 工程化方案都以导出 STEP 为终点,而不是 STL 或 OBJ——前者是送进工厂的图纸,后者只是给屏幕看的模型。理解了这一层,你就能明白为什么当年很多文生 3D 项目火一阵就没了声音,因为它们生成的网格模型跨不过"从屏幕到车间"这道鸿沟。

4. 实操:从一句需求到能 3D 打印的手机支架

4.1 环境准备与模型加载

先说说我怎么搭的环境。硬件方面,一台带 8 GB 以上显存的显卡就够跑 7B/8B 量级的微调模型,没有独显纯 CPU 也能跑,只是生成一次可能要等三五分钟,体验会差一些。软件方面,Python 3.9 以上版本,CadQuery 建议直接装 0.7.0 以上的版本,API 更稳定,代码生成模型训练时通常也针对新版接口做的微调。

pip install cadquery # 或通过 conda-forge 安装 conda install -c conda-forge cadquery

模型权重我建议优先从 Hugging Face 拉取 Text2CAD 或同类微调模型的量化版本。这里有个容易忽略的细节,开源模型仓库里文本生成质量参差不齐,你最好先跑几个示例提示词,确认输出代码风格后再正式投入使用。我在初试阶段就被一个生成质量很差的量化模型坑过,输出的代码看着像 CadQuery,实际上全是 API 幻觉。

4.2 提示词模板:怎么把需求说清楚

我在跑了几十次实验之后,总结出一个稳定的提示词结构:先说整体用途,然后给关键尺寸,再描述结构特征,最后补充约束条件。这套模板看起来简单,但对生成质量有决定性的影响,下面是两组对比。

一个反例提示词是"帮我设计一个手机支架"——我实测下来模型输出一个四不像的实体,又宽又扁,完全没有考虑到支撑角度和底座稳定性。为什么会这样?因为"手机支架"这个描述太笼统,模型只能从训练数据里随机拼凑一个通用形状,而不是根据你的尺寸和结构要求针对性建模。

一个合格的正例提示词应该是:

Design a phone stand base. The base is 100 mm long, 60 mm wide, and 8 mm thick. Four mounting holes of diameter 4 mm are located at the four corners, with hole centers 10 mm from the edges. A support backplate is attached to the back side of the base, 30 mm tall and 5 mm thick, tilted at 75 degrees from the base plane.

这段描述包含了四个关键信息层级:对象、尺寸、特征位置、空间约束关系。尤其是"孔中心距离边缘 10 毫米""背板与底座呈 75 度"这种带具体数值的约束,模型就能把每个特征精确地落到位。如果你用的是中文提示词,建议先翻译成英文再喂给模型——目前开源微调模型对中文支持普遍一般,但描述中保留少量中文专有名词影响不大。

4.3 生成、渲染与导出

提示词准备好之后,流程就变成了一条流水线。我通常会先用一个简单的验证提示词确认模型可用,然后才把正式需求喂进去。模型输出 CadQuery 代码后,保存成.py脚本直接运行,如果报错,从报错信息里提取关键信息回馈给模型,让它自己修正。

这里有个迭代技巧值得多说一句:修正时不要直接把整段报错信息甩给模型,而是把报错信息中最核心的那一行提炼出来,配合出错位置附近的代码上下文,效果比我试过的所有其他方式都要好。比如常见的No target found for sketch错误,本质上是模型在某个工作平面上找不到可用的草图对象,直接让模型检查Workplane的选择逻辑,比让它重写整段代码要稳得多。

模型运行成功后,再用cq.exporters.export(result, "phone_stand_base.step")导出 STEP 文件。导出的 STEP 建议在 CadQuery 内置查看器里先渲染一次,确认没有明显的破面和开口,再说下一步。手机支架底座的 CadQuery 代码可以写成下面这样,这是一个有效的可直接运行版本:

import cadquery as cq base = ( cq.Workplane("XY") .box(100, 60, 8, centered=(True, True, False)) .faces(">Z") .workplane() .rect(80, 40) .vertices() .hole(4) ) cq.exporters.export(base, "phone_stand_base.step")

这段代码先创建一个 100×60×8 毫米的长方体底座,底面对齐到 Z=0,然后在上表面往下打四个直径 4 毫米的孔,孔位由 80×40 矩形框的四个顶点确定,自动居中分布。

4.4 在 FreeCAD 中二次编辑验证

拿到 STEP 文件后,我习惯导入 FreeCAD 做二次检查和后续处理。第一步是检查实体属性,看体积和表面积是否在合理范围;第二步是验证可制造性,我用切片软件把 STEP 转成 STL,检查壁厚是否足够;第三步才是正式出文件。FreeCAD 对 STEP 的导入支持很成熟,而且完全开源,适合作为 text-to-cad 流程的验证收尾环节。

这一步有个我在实际项目中反复踩过的教训:即使 CadQuery 渲染时看起来没问题,导入 FreeCAD 后也可能暴露出自相交或非流形边,原因通常是布尔运算的数值精度问题或者原始描述中的拓扑矛盾。所以无论如何,STEP 文件一定要经过第二款 CAD 软件验证再投入使用,这条铁律能帮你挡掉至少一半的批量返工。

5. 常见问题与避坑指南

5.1 问题速查表

我把这些天遇到的一线问题整理成了速查表,每个问题都对应实际操作中容易踩的坑:

现象可能原因解决办法
生成的代码一运行就报错CadQuery 版本和模型训练时不匹配固定 CadQuery 版本,通常 0.7.0 以上即可
导出的 STEP 在其他 CAD 打开后变形或打不开布尔运算生成了非流形几何用 FreeCAD 做实体检查,把复杂的多步布尔切割拆分成单步操作
模型少了孔洞或凸台特征文本描述没有提供几何约束信息提示词里补充"孔中心距边缘 X 毫米""高 X 毫米"这类离散约束
生成的模型尺寸偏差离谱模型混淆了毫米和英寸单位提示词中显式写"mm",并在生成代码里检查尺寸常量
输出的 CadQuery 代码看起来合理但渲染为空实体工作平面定位错误导致拉伸悬空让模型检查Workplane的引用面,必要时选择 "XY"/"XZ"/"YZ" 以外更明确的基准
先写"一个盒子"再补充细节,模型输出完全跑偏提示词中细节补充的方式干扰了整体几何结构把最终完整需求一次性写清楚,迭代时只改局部约束

5.2 几个我反复踩过的坑

第一个坑是提示词太笼统。我一开始偷懒,只写"生成一个机械支架",模型每次输出的形状都不重样,就是没有一个能用。后来我把需求拆成"底板 80×50×6,四个角开 4.5 毫米通孔,背面立板高 40、厚 4、倾斜 10 度",生成的模型立刻从抽象雕塑变成了可靠零件。你在写提示词的时候,不妨先想清楚:如果把这个需求发给一个初级工程师,他能照着画出来吗?如果你都觉得描述不清楚,AI 更不可能替你凭空创造。

第二个坑是修改策略。我试过把两版提示词完全不同地写,希望模型能融合出更好的结果,实践证明这个想法大错特错。模型对全新提示词的生成结果有很强的随机性,每次全量重写等于让模型重新发挥一次,上次成功的设计细节可能这次就丢了。正确的做法是保持主体描述不变,只修改需要调整的那一句,像调参数一样调提示词,成功率会稳定得多。

第三个坑是关于文本描述语言的。很多开源微调模型是用纯英文指令训练的,中文提示词生成的代码经常出现语法错误。我踩过几次坑之后养成了一个习惯:先用英文写正规描述,如果必须用中文,就在中文描述后附上一份英文翻译,让模型参考英文版执行命令。另外还要特别注意落进提示词里的单位,模型内部统一按毫米处理,但你描述"5 cm"的时候它可能直接当成 5 毫米用——所以在提示词里写"50 mm",不要写"5 cm",这是我实测最容易导致尺寸错误的细节。

5.3 迭代生成时保持"增量修正"思维

还有一个非常实用的经验,是关于模型输出的复用问题。如果你已经得到了一个基本可用的底座模型,想加一个加强筋或者调整孔位,不要重新描述一整个零件让模型重写,而是把现有 CadQuery 代码作为上下文喂给模型,告诉它"在现有代码基础上,添加一个位置为 X、尺寸为 Y 的加强筋"。代码增量的修改比从零生成的整机成功率高出非常多,原因是模型对局部修改的学习和理解成本远低于重新编排所有几何操作。

这个经验背后其实反映了模型的一个本质特点:它是语言模型,不是几何引擎。它不关心你的模型整体上是否完美,它只关心当前这段代码是否符合语法、是否符合你这次请求的语义。保持增量,就是让模型把注意力集中在局部任务上,避免它在全局几何关系上犯错误。

6. 最后说点个人体会

玩了大半年的 text-to-cad,我个人最直观的感受是:它不是一个替代 CAD 工程师的工具,而是一个把"从想法到雏形"这个阶段压缩到分钟级的加速器。真正需要经验和手艺的部分——公差设计、装配关系、制造工艺、材料选择——这套工具链短期内替代不了,但如果你只是想快速验证一个机构的运动逻辑,或者给 3D 打印做个外壳,现在这套工具链已经能帮上大忙了。

最后分享一个建议:别把 text-to-cad 当搜索引擎用,把它当实习生用。你给出的需求必须清楚到"能交代给一个靠谱的初级工程师"的程度,它才会给你一个及格以上的初稿;拿到初稿之后,该审查审查,该返工返工,该做工程化验证做验证。说清楚需求、给足尺寸、告诉它不要什么、然后检查它的作业、再给第二轮修改指令——这套循环流程跑顺了,你会发现自己省下来的时间远超预期。