ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

text-to-cad实战指南:用LLM+参数化脚本生成可编辑工程模型

text-to-cad实战指南:用LLM+参数化脚本生成可编辑工程模型

最近整理手头的自动化建模流程时,被反复问到的一个词就是 text-to-cad。聊到后面发现很多人把它理解成“输入一句话,软件直接吐出一个三维模型”,然后打开CAD一看,什么都改不了,只能干瞪眼。这个理解不能说全错,但离工程可用还有很长一段距离。

text-to-cad的关键并不是“从文本变出模型”,而是“从文本变出可以继续编辑、可以出图、可以加工的参数化模型”。这篇文章我想从一个实际干过自动化建模的人的角度,把我踩过坑之后总结出来的思路、工具链和提示词模板整理出来,给正在研究这个方向、或者只是想用AI辅助画图的读者一个参考。

1. text-to-cad到底在做什么

1.1 一句话理解:文本是需求,脚本是图纸

如果让我用一句话解释text-to-cad,我会说:它不是在“画”模型,而是在把一句话需求翻译成一段参数化建模脚本,再由脚本生成几何实体。

传统的CAD建模过程是设计者把脑子里的尺寸、约束、特征一个个手动建出来。第一步建基准,第二步画草图,第三步拉伸,第四步打孔,反复循环。text-to-cad想省掉的是中间那部分重复劳动:你直接告诉系统“我要一个直径80毫米、厚度10毫米、边上分布6个安装孔的法兰盘”,系统把这句话翻译成特征操作序列,然后自动输出一个参数化三维模型。

所以这里的核心不是“文本生成三维数据”有多神奇,而是“文本到几何约束”的转换质量有多高。约束转换到位了,后面建模全是确定性操作,根本不存在随机性。换句话说,整条链路里只有“语义解析”这部分是AI在做,几何生成部分是普通代码在老老实实执行。

1.2 三个常见误区

先说第一个误区:text-to-cad不是“文生图”。你可能用过各种AI绘画工具,输入“一个法兰盘”确实能生成一张以假乱真的图片。但图片只是二维像素排列,没有尺寸、没有坐标系、没有特征树,导入SolidWorks或CAD软件之后就是一张贴图,没法拉伸成实体,更没法标注尺寸。工程上要的是B-rep实体或者至少是封闭的STEP曲面,而不是像素。

第二个误区:不是只能生成简单的方块、圆柱。现阶段的text-to-cad确实对简单机械零件效果好,比如法兰、支架、壳体、齿轮,但并不意味着它只能做这些。它真正擅长的是“规则清晰、重复度高、有明确参数”的零件。只要你能把需求拆解成参数表,哪怕特征是几十步建模操作,也能生成。难的是那些造型高度自由、靠曲面雕塑出来的消费电子产品外壳,那种更适合用雕刻笔刷和曲面工具手工做。

第三个误区:不是要取代设计师。我自己用了这么长时间的感受是,text-to-cad更像一个“参数化建模写码加速器”,它把设计者从枯燥的重复操作里解放出来,但设计思路、公差选择、材料工艺这些决策还是要人来定。AI生成的模型在复杂工况下未必合理,所以它更适合做前置方案快速验证,而不是最终交付物。

1.3 它真正适合谁

老实说,不是所有金字都需要这工具。哪些人适合用text-to-cad?我觉得有三类:

第一类是机械工程师和自动化工程师,日常大量画标准件、板件、支架,这些零件特征重复、参数固定,用文本生成效率非常高。第二类是产品设计初期的方案评审人员,想快速出几个结构差异明显的版本给领导或客户看,不需要手动一点点调。第三类是像我这样经常写自动化脚本的人,需要在代码里动态批量生成零件模型,比如要根据不同孔径、不同板厚出几十个变体,手动画会画崩溃,用text-to-cad脚本批量跑就舒服多了。

如果你只是偶尔画个简单图形,或者画图纯属娱乐,那老老实实打开CAD软件手动建模可能更快,不建议折腾这套工具链。

2. 核心技术原理:文本怎么变成可编辑模型

2.1 从自然语言到几何约束的两次翻译

整个text-to-cad流程可以拆成两层翻译。

第一层是自然语言到约束表。例如“法兰盘外径80毫米”,LLM要理解“外径”指的是圆形轮廓的直径,“80”是数值,“毫米”是单位,最终提取出约束项:草绘圆直径80。这一层靠大语言模型的语义理解能力,效果好不好完全取决于你给的需求描述是否结构化。你会发现我在这篇文章里反复强调“提示词要结构化”,就是因为这一层太容易产生歧义。

第二层是约束表到几何操作序列。例如外径80、中心孔16、螺栓孔6个分布在R30圆周,这套约束可以转化为传统建模软件里的特征树:画一个直径80的圆、拉伸10毫米、在顶面画中心圆、切除材料、再使用圆周阵列生成6个螺栓孔。这层转化本来需要人手动操作,text-to-cad的聪明之处是让模型直接输出一个封装好的参数化脚本,把特征树变成代码,代码执行后生成实体。

为什么强调“脚本”而不是“直接生成实体”?因为脚本保留了生成过程,保留了参数。改了直径数字重新运行,模型自动更新,这和CAD软件里改特征树参数的设计思路一致。这就是可编辑性的根本来源。

2.2 B-rep和参数化特征树才是CAD的灵魂

稍微懂点三维内核的人知道,CAD文件里真正存储的并不只是一堆三角形网格,而是边界表示(B-rep)和参数化特征历史。

B-rep记录的是每个面、每条边的拓扑连接关系,以及面背后的数学曲面方程。一个圆柱面不是几千个小三角片拼出来的,而是一个精确的圆柱曲面方程,所以它可以在数控加工软件里直接生成刀路,精度能达到微米级。这是现实制造和3D打印、游戏渲染本质上的区别。

参数化特征树则记录了“先拉伸还是先旋转”“孔位是固定的还是阵列出来的”“圆角多大”这些历史信息。修改特征树里某个数值,软件会重新计算后面的所有特征。text-to-cad想要真正替代传统建模,就必须保住这两样东西:精确B-rep几何和可修改的参数特征。

这也是我为什么明确反对“让AI生成一个STL网格文件”的做法。STL只有一堆无序三角面,没有拓扑、没有曲面、没有特征树。工程软件拿到STL只能看一眼造型,别说改尺寸,连精准测量都做不到。所以在选技术路线时,优先考虑能输出STEP格式的方案,STEP里面携带的B-rep几何是能直接进加工流程的。

2.3 当前主流技术路线对比

目前市面上做text-to-cad的方案大致分三条路线,各有各的适用场景,我用自己的话给你梳理下:

技术路线代表思路输出结果可编辑性精度适用阶段
LLM直接生成参数化脚本LLM编写CadQuery、OpenSCAD、FreeCAD宏代码脚本+STEP实体高高零件设计、批量变体
扩散模型生成体素或点云训练生成模型输出体素占用场网格/体素模型低低概念造型、灵感探索
隐式场/生成式B-rep重建生成面片关系并重建拓扑B-rep候选模型中中科研探索,工程应用还早

从我个人的实践感受来说,最稳健、最能立刻落地的是第一条路线,LLM加参数化脚本的组合。好处有三个:一是LLM本身写代码的能力已经很强了,尤其是CadQuery这类语义清晰的Python库;二是脚本出错时可以逐行调试,你能看到它到底错在哪里;三是脚本天然可复用,换个尺寸参数又能生成一个新的模型。

扩散模型的路线我也关注过,优点是自由造型能力强,不需要你精确描述约束,说一句“一个像水滴一样的花瓶底座”它就能出个大概。但问题是输出的是体素或网格,拿不到光滑曲面方程,也不能进参数化设计流程。目前更适合做前期灵感参考,离真正出工程图还很远。

3. 实操落地:用LLM加参数化脚本跑通一个真实零件

3.1 工具链选择

我现在最常用的组合是“大语言模型 + CadQuery”。选CadQuery而不是直接用SolidWorks API或者FreeCAD宏,原因很现实:CadQuery是纯Python库,安装简单,底层基于OpenCascade,生成的几何精度和SolidWorks这一级别的商业内核是同一档次。

装起来就一条命令:

pip install cadquery

装完以后它自带一套基于构建顺序的建模语法,核心理解三个概念就够了:Workplane就是当前的工作平面,类似CAD软件里的草图平面;box、circle这类函数就是画基本体素和草图元素;extrude、cutBlind、hole就是特征操作,拉伸、切除、打孔。

如果你平时用的是FreeCAD,也可以让LLM生成FreeCAD的Python宏,它也能批处理,但API没那么稳,同一个操作在不同版本里写法经常变。相比之下CadQuery的文档和社区活跃度都要好一些,这是我很长一段时间里实际测试得到的体感。

3.2 案例:一个法兰盘

我拿一个最典型的机械零件讲流程。需求是“生成一个法兰盘,外径80毫米,厚度10毫米,中心孔直径16毫米,6个螺栓孔均布在直径30毫米的圆周上,孔径6.6毫米”。

直接把这段话交给LLM,它大概率会生成类似下面这样的CadQuery代码:

import cadquery as cq # 直径80mm、高10mm的圆盘 flange = cq.Workplane("XY").circle(40).extrude(10) # 中心孔直径16mm,用切除的方式从顶面贯通 flange = flange.faces(">Z").workplane().circle(8).cutBlind(-10) # 6个螺栓孔,分布在半径30mm的圆周上,孔径6.6mm flange = flange.faces(">Z").workplane().polarArray(30, 0, 360, 6).circle(3.3).cutBlind(-10) # 导出STEP,方便导入SolidWorks、FreeCAD等软件 cq.exporters.export(flange, "flange.step")

如果你不熟悉CadQuery,我给这段代码做个注释式的讲解。

第一步是创建外径80的圆柱体:circle(40)画的圆直径80,extrude(10)沿Z轴拉伸10毫米。第二步是打中心孔:先选中顶面(faces(">Z")代表法线指向Z正方向的那个面),然后在新平面上画一个半径8的圆,cutBlind(-10)表示沿Z负方向切除10毫米深,正好切穿整个法兰。第三步是打螺栓孔:polarArray(30, 0, 360, 6)在半径30的圆上均匀生成6个点,从0度开始间隔60度,然后每个点画半径3.3的圆再切除。

这几行代码跑完,内存里就是一个精确的B-rep实体模型。最终导出成STEP文件,这个文件拿给SolidWorks、中望CAD、FreeCAD都能打开,并且能直接做测量和标注尺寸。

polarArray(30, 0, 360, 6)生成的是6个点,不是7个,这一点写过遍历代码的人都懂,最后一个点放在300度而不是360度,避免重复,所以不会出现多一个孔的情况。

你可能会说,这代码看起来挺简单的,似乎不一定要用AI。但注意,这是让一个完全不懂CadQuery的人也能操作的前提:他只需要用自然语言描述零件特征,代码是AI补全的。如果产品参数变化,比如外径改成100,螺栓孔改成8个,只要在提示词里改几个数字,AI又会生成新代码,几秒钟就能重新出模型,这个效率提升就很明显了。

3.3 提示词写法:把需求写成参数表

text-to-cad成不成功,一半取决于模型,另一半取决于你怎么描述需求。我试过非常口语化的描述“给我做个支架,厚度别太厚”,效果惨不忍睹,LLM输出一个随机的板子,尺寸也乱写。后来改为结构化描述,成功率明显提升。

这是我现在常用的提示词模板,你可以直接复制修改:

请用 CadQuery 生成一段 Python 代码,要求如下: - 零件名称:法兰盘 - 轮廓形状:圆形 - 外径:80mm - 厚度:10mm - 中心孔:直径16mm,贯穿 - 螺栓孔:6个,均匀分布在半径30mm的圆周上,孔径6.6mm - 坐标系:默认Z轴朝上,底面在Z=0 - 输出:完整可运行的Python代码;并在代码后说明主要尺寸和推荐加工工艺

这个提示词的本质是把自然语言转成一张参数表,让LLM无从发挥“自由创意”。你要知道LLM不是你肚子里的蛔虫,你说“薄一点”它不知道是3毫米还是5毫米。但如果你明确说“厚度5毫米”,它就能准确建模。

还有一个细节:如果描述里包含“两边”“斜角”“左右对称”这种方向性词汇,建议在提示词里补充坐标说明,比如“沿X方向拉伸”“关于YZ平面对称”。这样可以避免模型把方向搞反,减少返工。

3.4 从生成到交付的完整流程

我实际跑通的项目,文本到最终出图大概是这样一个流程:

第一步,需求确认和参数整理。这一步不要偷懒,把外形尺寸、孔位、公差、材质全部列成表。第二步,把参数表扔给LLM生成CadQuery脚本。第三步,本地执行脚本,生成STEP文件,同时打印日志。第四步,用FreeCAD或CAD看图软件打开STEP做视觉检查,重点看孔位对不对、有没有干涉、厚度是否合理。第五步,把验证过的STEP文件导入SolidWorks或者专业的CAD软件,补充公差、表面粗糙度等制造信息,最后出工程图。

这个流程看起来挺繁琐,但每一步都有明确目的。前两步解决“建模效率”,第三步到第五步解决“工程可信度”。AI生成的模型如果不经过人眼检查就拿来加工,老工程师肯定要骂人,我也见过不检查直接导致孔位偏移的翻车案例。

4. 常见问题与排查实录

4.1 布尔运算失败或生成的模型是空壳

这是我最早踩的坑:生成的代码执行了,日志也没有报错,但打开STEP文件一看,模型是空的或者只有一点点碎面。后来排查发现大多不是布尔运算本身失败,而是CadQuery的版本环境问题,或者是对象没有正确合并。

CadQuery的建模有个习惯:很多操作会返回新的对象,你如果不把它重新赋值给原变量,比如写成:

base = cq.Workplane("XY").box(80, 60, 10) base.union(boss) # 忘了赋值

那base实际还是原来的底板,合并结果被丢弃了。这看着像是低级错误,但LLM偶尔也会犯,尤其是上下文长了以后变量名搞混。解决办法是在提示词里明确要求“每次操作后都要把结果赋值给新变量并返回”,人检查代码的时候也优先看有没有漏掉赋值。

另一个常见情况是用cutBlind切孔时深度写错,比如板厚10毫米,你写了cutBlind(-8),结果顶部还剩2毫米材料,看起来就是一个没有贯穿的盲孔,如果还指望螺栓穿过去,那就出问题了。所以检查STEP的时候要来回旋转视角,或者直接做剖面检查。

4.2 孔位和坐标方向搞反

方向问题是text-to-cad里最容易翻车的。比如要在顶面打孔,LLM写成了在底面打孔,或者在侧面打孔,看上去孔的数量和直径都对,方向反了。

排查方法很简单:看代码里faces(">Z")、faces("<Z")这种面选择语句。>Z表示Z正方向的面,<Z表示Z负方向的面。还有一个技巧是把工作平面改到可见方向,比如先workplane()再circle,就不会误操作到隐藏面。

如果孔位方向反复不对,我建议在提示词里加上一句“优先从顶面开始打孔,顶面法线方向为Z正方向”。这样虽然有点教条,但能显著降低出错率。

4.3 尺寸“幻觉”和单位混乱

LLM生成代码时,有概率在尺寸上自作聪明,你明明说外径80,它生成一个半径80,直径直接翻倍。这个我碰到过不止一次,尤其是在提示词里既有直径又有半径的场合,模型容易混淆。

解决办法是统一在提示词里写明“直径和半径请严格按我的描述,不要自动转换”。这句话听起来很傻,但实际很有效。另一个更容易忽视的问题是单位:CadQuery默认是毫米,如果你在提示词里写“5cm”,模型可能理解成5毫米也可能理解成50毫米,最好全部换算成毫米再写进提示词。

我习惯在生成的STEP文件里用测量工具抽查三个关键尺寸:外形最大尺寸、孔径、中心距。三次抽查过了,基本就可以放心使用。

4.4 生成的模型不可编辑

有人拿着text-to-cad生成的STEP文件,回到SolidWorks里想改一下孔距,结果发现整个模型变成一个整体,没有特征树,根本没法改。这是STEP文件的特性导致的,不是text-to-cad的问题。

如果目标是可编辑,有两条路:一条是在提示词里要求LLM同时输出CadQuery脚本,所有的修改直接改脚本里的参数再重新生成;另一条是把CadQuery脚本里的参数抽象成变量,做一个简单的参数界面,以后只改界面上几个数字就行。我更推荐前者,简单直接。

另外别想着“让LLM直接生成一个带特征树的SolidWorks文件”,这类私有格式的交换非常麻烦,生成的可靠性差,不值得折腾。

4.5 常见问题速查表

症状可能原因排查方法和对策
模型为空或只有碎面对象未重新赋值、版本API不一致检查union和cut操作返回值,更新CadQuery版本
孔位偏移或方向不对面选择语句用错、坐标系理解偏差改用faces(">Z")明确顶面,旋转视角检查
尺寸整体放大或缩小直径半径混用、单位不清提示词统一毫米制,生成后抽查三个关键尺寸
模型不可编辑STEP文件无特征树保留脚本参数化,修改脚本而不是改STEP
布尔运算报错两个实体没有相交或恰好相切检查几何间隙,用intersect做诊断
代码运行报NameError提示词里对象名定义不清要求模型先写变量清单再写代码

5. 关于这个方向,我的一些实在话

text-to-cad这个方向我从带有怀疑态度,到现在把它真正放进日常工具链,前后折腾了不短的时间。我的体会是:它的价值不在“生成模型的瞬间”,而在“参数化流程的复用”。

当你面对的不是一个法兰盘,而是一整批需要用不同孔径、不同板厚、不同孔位组合的产品变型时,手动画图是最容易出错、最耗时的环节。text-to-cad让你用文本描述替代手动操作,一次搭好模板,后续几百个变体都是几秒钟的事。这种批量生产力的提升,是单纯的“AI画图展示”完全比不了的。

当然它也有明显的边界:自由曲面造型它做不了;涉及复杂装配逻辑和运动约束的,也没有成熟方案;真实制造里的工艺考虑,比如壁厚均匀性、脱模斜度、应力集中,它更是一窍不通。所以我的建议是把它定位成一个“快速生成参数化毛坯”的工具,毛坯出来了,后面该修的修,该补的补,最终还是工程师说了算。

最后分享一个小技巧:在你让LLM生成CadQuery代码之前,先让它用三句话描述它理解的零件结构,比如“底板是一个长方体,上面有两个圆形凸台,底部有四个安装孔”。这一步能提前暴露理解偏差,比生成完再检查省事得多。我在实际使用中靠这一步减少了一半以上的返工,你可以试试。

RELATED READING

延伸阅读

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