ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Text-to-CAD:用自然语言和CadQuery代码生成可编辑3D模型的实战指南

Text-to-CAD:用自然语言和CadQuery代码生成可编辑3D模型的实战指南

1. 一句话需求变三维模型,text-to-cad到底解决了什么问题

不知道你有没有经历过这种场景:脑子里已经有了一个零件的大致形状,比如“一个带四个安装孔的圆形法兰”“一根一端有内螺纹的铝合金管”,但要把它变成能拿去3D打印或者送厂加工的CAD文件,还得老老实实坐在建模软件前,拉草图、加约束、拉伸切除、倒角……一套流程下来,快则半小时,慢则半天。

text-to-cad这条技术路线,就是想把这个过程直接压缩成一句话。你只需要用自然语言描述自己想要的零件,系统会结合大语言模型和参数化建模工具,生成一个真正可编辑、可测量、可以导出的CAD模型,而不仅仅是一张效果图或者一个封闭的三角网格。它输出的可以是STEP、STL,也可以是CadQuery脚本,方便后续二次修改。

这个方向对三类人最有价值:一是经常做快速原型验证的硬件工程师,二是大量制作定制零件的3D打印玩家,三是在自动化设计流程里需要批量生成标准件的开发者。它不一定能替代传统CAD软件,但能帮你把那些重复度高、逻辑清晰的建模需求交给代码去完成。本质上看,text-to-cad是“文本描述→程序化建模代码→三维几何体”这样一条链路,中间的关键翻译者,就是如今已经相当成熟的大语言模型。

2. 为什么说“代码生成”才是聪明的落地方式

2.1 直接让大模型“画”出模型,听起来很美,实际很难做

最早大家做文本生成三维模型,都是走“文本→图像生成中间态→三维重建”或者“文本→隐式神经场”这条路。确实有demo能生成一些类似椅子、桌子的点云或网格,但真拿到工程软件里就发现完全没法用:网格是三角形拼起来的,没有圆角参数、没有特征树、没有尺寸标注,更不用说把孔位改了之后整个零件自动更新。

工程上需要的CAD模型,核心是特征和参数。拉伸、旋转、倒角、打孔,这些操作背后都对应着明确的几何约束。让大语言模型直接输出网格,等于绕开了几何逻辑,只给了结果不给过程。过程一旦缺失,后续修改就变成重新生成一遍,设计就成了“不可控的一次性输出”。

2.2 代码生成路线把“写几何”变成“写程序”

text-to-cad目前比较成熟的思路,是让大模型输出一段程序化的建模脚本,再由脚本引擎执行生成CAD模型。这里说的“代码”,在多数场景下是CadQuery或OpenSCAD脚本。

CadQuery是一个基于Python的参数化建模库,它的设计理念和传统CAD的“特征建模”几乎一一对应:你可以用Workplane对象做拉伸,用.holes()打孔,用.edges().fillet()做圆角,写出来的每一行代码都对应一个特征操作。大模型训练数据里包含大量这类代码,因此它天然擅长生成CadQuery脚本,而不是直接生成STEP文件。

把建模变成代码还有一个额外的好处:版本管理和批量修改变得非常容易。一套CadQuery脚本传一个参数进去,就能生成不同尺寸的法兰盘。这比在图形界面里手动拖动控制柄来改尺寸要可靠得多,尤其适合标准件库、BOM管理这类场景。

2.3 常见工具链对比

目前做text-to-cad主要会接触到这几个工具,我按自己的使用经验整理了一下:

工具建模方式语言适合场景缺点
CadQuery程序化特征建模Python机械零件、装配体、批量参数化学习门槛稍高,需要懂基本编程
OpenSCADCSG实体建模自研脚本语言简单几何体、参数化设计圆角和复杂曲面处理弱
Zoo Text-to-CAD在线文本转CadQueryPython快速验证提示词效果需要联网、受API响应影响
Blender + bpy多边形建模为主Python偏向外观原型,非精密机械件不适合直接出工程数据

我个人最推荐刚接触text-to-cad的人从CadQuery上手,原因有两条:一是它和传统CAD的思维方式高度接近,逻辑上容易迁移;二是它生成的STEP文件带精确边界表示,导入FreeCAD或者Fusion 360之后可以直接继续编辑,不会像网格那样“读到一堆三角形”。

3. 完整实操:从一句描述到一个可以加工的零件

3.1 先装好本地环境

先提醒一句:虽然像Zoo这样的在线工具能帮你快速体验,但真要拿text-to-cad到自己的工作流里,本地环境必须自己搭。这里用Python加CadQuery方案,干净且可控。

安装其实很简单,前提是你已经装好了Python 3.9以上的版本,接着执行这样几步:

pip install cadquery pip install jupyter

装完之后强烈建议装一个VS Code的Jupyter插件,直接在notebook里写CadQuery脚本,执行完立刻能看到三维预览,比一次次跑命令行舒服太多。

你以为到这儿就结束了?没有。CadQuery虽然能生成几何,但默认情况下它并不会自动调起一个三维查看器。想最直观地检查模型,还有一个小工具要装,叫cq-editor,它相当于CadQuery的专属IDE,左侧写代码,右侧实时渲染,是目前text-to-cad调试环节里体验很好的组合。

3.2 准备一个高质量的提示词

这一步是整个流程里最值得花心思的地方。很多人第一次用text-to-cad生成出来的模型压根没法看,并不是工具不行,而是提示词给得太模糊。

举个例子,如果你只写“帮我做一个法兰盘”,大模型大概率会生成一个什么尺寸都不明确的圆盘;但如果你写“生成一个外径80mm、内径40mm、厚度10mm的圆形法兰盘,在直径60mm的圆周上均匀分布4个直径为6mm的贯通孔,所有锐边倒角0.5mm”,生成出来的东西立刻就能用。

这里有一个比较少人提到的技巧:提示词里尽量把“相对描述”换成“绝对尺寸”。比如不要写“厚一点的板子”,要写“厚度12.5mm”;不要写“几个螺丝孔”,要写“6个M4通孔,沿直径50mm的圆均布”。原因是语言模型对模糊量词的理解经常飘忽不定,但对数字的感知相对可靠。单位也要写清楚,默认情况下CadQuery使用毫米,但如果你习惯英制,请务必在提示词里说“单位是英寸”。

3.3 用LLM生成CadQuery代码

写好提示词之后,把下面这段作为模板方式丢给大模型:

请用CadQuery生成一个零件,要求如下: 外径80mm,内径40mm,厚度10mm的圆形法兰盘; 在直径60mm的圆周上均匀分布4个直径为6mm的贯通孔; 所有锐边倒角0.5mm; 代码需要包含完整的CadQuery工作平面操作; 输出代码后,用一句话解释每个主要特征对应的代码段。

一个合格的模型会返回类似这样的代码:

import cadquery as cq # 创建外径80、内径40、厚度10的法兰盘 result = ( cq.Workplane("XY") .circle(80 / 2) .extrude(10) .faces(">Z") .circle(40 / 2) .cutBlind(-10) # 从顶面挖出内孔 .faces(">Z") .workplane() .pushPoints([(60 / 2, 0), (0, 60 / 2), (-60 / 2, 0), (0, -60 / 2)]) .hole(6) .edges("|Z") .fillet(0.5) )

这里顺便解释下代码里的关键点:.circle()创建的是二维轮廓,.extrude()负责拉伸成实体,.faces(">Z")选取顶面,.pushPoints()一次在圆周上放置四个点,然后.hole(6)在这四个点上打出直径6mm的孔,最后.edges("|Z")选取竖边并倒一个0.5mm的圆角。

3.4 验证、检查、迭代

生成代码之后,最忌讳的事情就是“看一眼觉得没问题就直接拿去切片”。我踩过最大的坑,是模型表面看起来完全正常,但导入切片软件发现内孔实际没有打通——原因是Cut操作时方向写反了。text-to-cad生成的是程序化模型,它最大的特点是可复现,但这也意味着代码里一个符号的错误会直接决定整个零件是否可用。

所以每次生成完第一件事,是在cq-editor里旋转视角、切换显示模式检查几个关键维度。尤其是孔径、壁厚、孔的位置,用测量工具逐个核对。如果发现孔偏了,不要重新描述整个零件,只需要在提示词里追加一句修正,比如“四个通孔应该均匀分布在直径60mm的圆上,目前角度位置有偏移,请修正”,大模型通常能理解增量修改,这比从头再来高效得多。

4. 高级玩法:从单一零件走向参数化系列

4.1 给模型加可调参数

text-to-cad比较吸引人的地方,是同一段代码可以衍生出不同规格的零件。一个法兰盘,只要把外径、孔径、孔数、厚度这些关键值从硬编码变成变量,你手里就拥有了一整个法兰盘系列。

实际做参数化时,我习惯在CadQuery脚本顶部定义一个配置段,把所有关键尺寸集中管理:

import cadquery as cq # 参数集中管理 outer_diameter = 80 inner_diameter = 40 thickness = 10 hole_circle_diameter = 60 hole_count = 4 hole_diameter = 6 fillet_radius = 0.5 # 计算孔的位置角度 import math angles = [360 / hole_count * i for i in range(hole_count)] ...

这样写完之后,想生成一个外径100、6个孔的法兰盘,只需要改上方两个值,然后重新执行脚本。配合ChatGPT或者本地大模型,你甚至可以让它自动生成一套参数配置,再跑一遍脚本,相当于让代码帮你完成系列化设计。

4.2 多实体与装配体思路

单零件玩熟之后,很多人自然会想尝试装配体。CadQuery里可以通过Workplane叠加多个实体,也可以用cq.Compound把它们组合起来。text-to-cad现在处理多零件装配的能力还不是很强,但有个技巧可以绕过去:把装配拆成多个独立零件分别生成,再在提示词里约定好配合尺寸。

比如要做一个“内孔直径25mm的轴承座”,先在提示词里规定轴承孔径是25,然后生成座子;再规定配合轴的直径是24.9(留0.1mm间隙),生成轴。分别导出STEP再导入FreeCAD里装配,比一次性让模型生成一个完整装配体要可靠得多。nl这是一个非常实在的建议,我自己试过直接生成装配体,结果零件之间发生干涉的情况非常频繁,因为大模型难以在一次推理中同时协调多个零件的空间关系。

4.3 批量生成场景的工程化

如果你需要一次生成20种尺寸的支架、50种规格的垫片,手写提示词已经不够了。此时可以把提示词做成模板,用脚本循环调用大模型API。

我自己的做法是:先写出一个基准提示词,把尺寸作为变量,然后用Python脚本读取一个尺寸表格,逐行替换变量并调用大模型接口,再把返回的代码保存到对应文件夹,接着统一执行CadQuery脚本导出STL。整套流程跑下来,一个小时生成上百个零件完全可行。

这样做最大的价值不是省时间,而是把设计过程变成了数据驱动:尺寸表格就是产品规格表,提示词模板就是设计规则。以后客户改一个尺寸,你甚至不用打开CAD,改表格里一行数字,重新跑一遍流程就能拿到新模型,这对小批量定制业务效率提升明显。

5. 实操中经常踩的坑和排查办法

5.1 生成的模型总是“差一点”:提示词精度不足

这是最常见的问题,症状表现为:模型大致形状对,但孔位偏了、倒角没了、壁厚错了。原因基本都是提示词里缺少量化和空间关系的描述。前面我已经提过要写绝对尺寸和明确位置关系,这里再补充一个技巧:用“相对特征”来描述。比如“孔距离上表面5mm”比“孔在中间”要明确得多,因为大模型对“中间”的理解不够稳定,但对“距离xxx面xx mm”这种带参考基准的描述准确率会高很多。

5.2 代码能执行,但导入其他软件报错

CadQuery生成的STEP文件大多数时候是没问题的,但偶尔导入Fusion 360或SolidWorks会提示“几何不完整”或“面缺失”。我研究过,多数情况是模型里有非常细小的碎面,尤其是小圆角、薄壁特征附近。解决办法在生成阶段就要控制:提示词里不要同时要求“极小的圆角”和“极薄的壁体”。圆角半径小于0.2mm、壁厚小于1mm时,生成出错率会显著升高。如果必须做小特征,我建议把圆角拆到CAD软件里手工处理,而不是让text-to-cad一把梭。

5.3 孔没有贯通

孔未贯通的情况我已经提到过一次。这句话单独拿出来说,是因为它太容易被忽略。有时你看到的代码里确实有.hole()操作,但它通常会挖穿当前工作平面以下的所有材料;如果工作平面选错了,比如选到了内孔底面上,孔可能只挖了一半。检查方法很简单:生成之后用Ctrl+Z级别的历史操作回退看每步特征,确认孔特征的位置。如果发现自己不太会看特征树,也可以直接用CadQuery的.val().isValid()做一次布尔运算自检,看有没有报“几何体无效”的异常信息。

5.4 生成速度慢到无法接受

不少在线text-to-cad工具在高峰期响应很慢,一次生成要等一分多钟。你要是反复修改提示词,那种体验真的很消磨耐心。我之前也遇到过类似的情况,后面改成自建方案:把任务拆成“离线批量生成代码+本地渲染”,不再依赖在线工具逐步反馈。也就是说,先用大模型一次性生成所有零件的脚本,再统一在本地执行CadQuery,这样只有在代码出错时才需要调用大模型做针对性修复,交互次数能从二十几次降到两三次。

5.5 快速验证小技巧:输出格式选择

如果你打算3D打印,导出STL几乎够用;如果你还要机加工,务必选STEP。CadQuery对STEP支持很好,因为它本身就是精确建模内核。这里有一个很多新手不知道的细节:STL是三角网格,转成STL之后就不要指望还能编辑了,所以建议把CadQuery脚本保存成.py文件作为源文件,STL和STEP都作为成品输出。三个文件保留一套,才算形成一个完整的设计闭环。

我顺手整理了一份快速排查表,遇到问题可以直接对照:

现象可能原因解决办法
外形对但孔位偏提示词缺少角度或相对位置描述补充“孔沿直径xx的圆均布”
倒角缺失特征选择边不对在提示词中写明“对顶面外边界倒角”
导入SolidWorks报错碎面过多调大圆角半径,或减少薄壁特征
孔没有打通工作平面选择错误改用faces(">Z")再执行孔操作
尺寸整体偏大单位混乱在提示词中明确“是否毫米”

6. 我认为这条技术路线的边界在哪里

最后聊点实操之外的感受。

我用了大概两个月的时间,把text-to-cad从“玩具”阶段推进到能处理日常零件生成的阶段,最大的感知是:它的能力边界比想象中宽,但取代不了设计师。它真正擅长的是标准件、简单结构件、参数化系列件——那些高度规则、边界清晰的建模任务;它目前还做不了的是复杂的曲面造型、需要大量美学判断的产品外观,以及需要深入考虑加工工艺的精密结构。

所以我对它的定位是“设计师手边的一块快捷板”:你和它打交道,就像是和一个刚毕业、理解力强但是经验少的助理打交道——你把需求说得越具体,它产出得越准确;你如果只给一句“做个好玩的东西”,那大概率得到的也是没法用的东西。提高text-to-cad可用性最重要的能力,不是写代码,而是把你的需求翻译成机器能理解的精确语言。

如果你正打算入坑,我建议先从最简单的零件开始,比如一个带孔的法兰盘、一个L型支架,跑通整个流程后再逐步增加特征复杂度。等你习惯了“描述需求→生成代码→检查修改”这个循环,再回头看自己过去手动建模的那些重复劳动,会发现自己多出了一个值得信任的自动化助手。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进