☰
Text-to-CAD实战指南:从自然语言到参数化模型的工程化落地
2026/10/8 19:56:24 网站建设 项目流程

text-to-cad 这两年被各路AI社区炒得火热,但真正上手跑过一遍的人,恐怕心里都清楚:这个领域远没有到“一句prompt直接出工业级图纸”的成熟度。我前前后后折腾了差不多小半年,把主流的开源方案都试了一遍,踩了不少坑,也趟出了一些门道。想着把这些经验整理出来,给想入坑的朋友指个方向,省得重复交学费。

这篇东西不搞虚的,直接聊聊text-to-cad到底能干什么、主流技术路线怎么选、端到端跑通一个方案需要哪些步骤,以及我在实操中遇到的典型问题和排查思路。你如果是做机械结构、3D打印、工业设计或者想给自家产品加个AI建模入口的,这篇文章应该能帮你省不少时间。

1. 先把概念捋清楚:text-to-cad 解决的到底是什么问题

1.1 核心需求解析:从自然语言到参数化几何

先说人话。text-to-cad,字面意思就是“用文字生成CAD模型”。但你真去用了之后会发现,它跟AI画图完全是两码事。Stable Diffusion生成的是像素矩阵,输出的是图片,你做错了顶多多抽几次卡。而text-to-cad生成的是精确的几何拓扑和参数化特征,输出的是STEP、STL、BREP这种能被CAM软件、3D打印机、CAE仿真软件直接消费的数据结构。

这里的核心难点在于:自然语言是模糊的、非结构化的,而CAD模型是精确的、约束驱动的。比如你说“给我来一个M6的螺栓”,人的工程师会默认你知道螺距、头型、杆长、倒角这些信息。但模型没有这个常识,它必须要从海量数据里学会“M6”这个词背后对应的ISO标准几何参数。所以text-to-cad真正要解决的不是“生成一个看起来像的东西”,而是“生成一个能进产线的东西”。

1.2 传统建模流程的三大痛点

我做了十几年结构设计,传统建模流程有多痛苦,心里太有数了。第一是效率瓶颈。一个稍微复杂的支架零件,从画草图到拉伸切除到倒角,熟练工也得半小时以上,大部分时间都花在了重复性的几何操作上。第二是知识断层。很多老师傅脑子里有方案,但不太熟悉具体软件命令,或者反过来,刚毕业的学生熟悉软件但缺乏工程判断,这种know-how和工具之间的鸿沟,直接导致设计迭代慢。第三是标准化成本高。企业里明明有零件库,但设计师经常找不到或者懒得找,直接新建模型,导致一个简单的法兰盘在公司内部可能有好几个版本,给后面的采购和加工挖坑。

text-to-cad想动的是这个蛋糕:把设计师从重复劳动里解放出来,让“口述设计意图”变成一种可落地的输入方式。

1.3 直接可落地的应用场景

两年观察下来,有几个场景是确实跑得通的。

  • 标准件和通用件建模:螺栓、螺母、轴承座、支架、法兰,这类几何相对规整、参数化程度高的零件,text-to-cad表现最好。我实际测过,生成一个GB标准的六角螺栓,配合校验脚本,可以直接出加工图。
  • 概念方案快速验证:在项目预研阶段,用自然语言描述一个大致的结构形式,比如“底板长200宽150,四角M8沉头孔,中间开直径40的轴孔”,直接生成初始几何,放入装配体做布局验证,比手动建模快一个数量级。
  • 非专业建模人员的辅助工具:很多创客、电子工程师、甚至是采购,他们不需要精通SolidWorks,但需要快速得到一个可以3D打印的壳体模型。text-to-cad把门槛降到了“会说就能建”。

2. 技术路线详解:三条大路条条通罗马

2.1 基于大型语言模型的生成式CAD框架

这条线是目前学术圈的主流,也是产业化最被看好的方向。代表工作是AutoGPT的早期形态在CAD领域的延伸,以及2023年以来陆续出现的多个基于Transformer的CAD生成模型。其核心思路是把CAD建模过程序列化。

具体来说,不再把模型生成看成“从无到有造一个实体”,而是看成“预测一系列建模操作指令”。类似你录了一个宏,回放这个宏就得到了模型。模型输入是文本描述,输出是一个命令序列(比如“创建草图、画直线、加尺寸约束、拉伸、倒角”),然后由一个解释器把这些命令在OpenCascade这种几何内核上执行,最终产出BREP实体。

这条路线的好处是可解释性极强。生成错了,你能看到是哪一步命令出了问题,改起来也方便,因为它是参数化的。坏处是对数据需求极大且生成复杂拓扑困难。业内公开的ABC数据集、Fusion 360 Gallery数据集,虽然包含了几百万个模型,但基本以机械零件为主,一旦涉及自由曲面造型,模型就抓瞎了。

2.2 基于扩散模型的体素与点云生成路线

另一条路子是用扩散模型直接生成离散的几何表示,比如体素(Voxel)或者点云(Point Cloud),然后再通过曲面重建算法(比如Marching Cubes、Poisson Reconstruction)或者逆向工程软件转成CAD可用的BREP面片。

这条线的优势在于对自由曲面和高复杂度形状表现好,看起来跟AIGC在图像领域的成功路径最接近。但问题同样明显:一是离散表示天生缺少参数化信息,你拿到一个点云,但它没法直接编辑改尺寸,得用Geomagic这类软件做逆向,这又是个费工夫的活儿。二是精度很难保证,体素分辨率受限,重建出来的曲面在关键配合面处可能差个几十丝,这在实际制造里是不可接受的。

所以我个人的判断是:这条路线更适合做造型参考和概念探索,离真正的产品结构设计还有距离。

2.3 程序化模板与大模型参数抽取的混合方案

第三种方案,也是我在实际项目里用得最多的,是让大模型只负责“语义理解+参数抽取”,把几何生成交给预定义的程序化模板。

什么意思呢?先手工用OpenCascade或者CadQuery写好一批参数化零件模板,比如“带法兰的轴套(flanged_bushing)”,定义了长度、外径、内径、法兰直径、螺栓孔数量这些参数。然后让大模型去理解用户输入的自然语言,从里面抽取出这些参数的值。抽出来之后填充到模板里,程序跑一遍就生成模型。

这个方案虽然“不智能”,但胜在极其可靠。因为几何拓扑是预先验证过的,怎么都不会破面,参数也受约束检查保护,数值合法才生成,不合法就报错让大模型重新抽。工业场景里,稳定的下限比惊艳的上限更重要。你给客户演示的时候,十次出十个不同的螺栓,远不如十次出十个一模一样的合格螺栓来得有说服力。

3. 端到端实操:跑通一个text-to-cad项目的完整记录

3.1 环境准备与工具链选型

我建议你按照下面这套组合来搭建环境,都是我实测跑过没问题的。

组件推荐选型说明
大模型底座GPT-4o / Claude 3.5(支持function calling)本地跑开源模型也可以,但参数抽取准确性差距明显,建议先用API跑通再考虑私有化
几何内核OpenCascade 7.6.0(通过CadQuery 2.x封装)CadQuery的API设计比直接用OCC友好得多,特别适合程序化建模
中间表示JSON结构化输出大模型输出原始文本有太多不确定性,必须约束为JSON schema
程序化模板CadQuery的Parameterized 类把常用零件类型写成类,实例化时传参即可
校验层OpenCascade的BOPCheck(布尔运算检查)生成后自动做几何有效性验证,防止“看起来没问题一布尔运算就崩”

安装的时候有一个特别容易踩的坑:CadQuery的版本和Python版本严格绑定。我一开始在Python 3.12上pip install cadquery,结果装的是预发布版本,一堆API对不上。后来老老实实建了Python 3.10的venv才解决。强烈建议你先用虚拟环境隔离,别直接装在系统Python里,不然改天装个别的依赖,分分钟把你的cadquery环境搞崩。

3.2 数据准备与模板代码实现

如果你想复现我这个方案,核心是把“文本参数抽取”和“几何生成”分开。下面是我为法兰支架(flange_bracket)写的模板类骨架:

import cadquery as cq class FlangeBracket: """参数化法兰支架模板 参数: base_length: 底板长度 (mm) base_width: 底板宽度 (mm) plate_thickness: 底板厚度 (mm) flange_height: 法兰立板高度 (mm) hole_diameter: 安装孔径 (mm) hole_count: 安装孔数量 boss_diameter: 中心凸台直径 (mm) """ def __init__(self, **kwargs): # 参数合法性检查:这一步是防大模型乱来的关键 required = ["base_length", "base_width", "plate_thickness", "flange_height", "hole_diameter", "hole_count"] for k in required: if k not in kwargs: raise ValueError(f"Missing required parameter: {k}") self.base_length = float(kwargs["base_length"]) self.base_width = float(kwargs["base_width"]) self.plate_thickness = float(kwargs["plate_thickness"]) self.flange_height = float(kwargs["flange_height"]) self.hole_diameter = float(kwargs["hole_diameter"]) self.hole_count = int(kwargs["hole_count"]) self.boss_diameter = float(kwargs.get("boss_diameter", 20.0)) # 参数合理性约束 assert 20 <= self.base_length <= 500, "Base length out of range" assert 10 <= self.base_width <= 300, "Base width out of range" assert 2 <= self.plate_thickness <= 20, "Plate thickness out of range" def build(self): """生成 CadQuery 模型""" # 底板 base = (cq.Workplane("XY") .box(self.base_length, self.base_width, self.plate_thickness) .edges("|Z").fillet(3.0)) # 立板 flange = (cq.Workplane("XZ") .center(0, self.plate_thickness / 2) .moveTo(-self.base_width / 2, 0) .lineTo(-self.base_width / 2, self.flange_height) .lineTo(self.base_width / 2, self.flange_height) .lineTo(self.base_width / 2, 0) .close() .extrude(self.base_length / 2 - self.base_width / 2 + 10)) # 合并 result = base.union(flange).translate((0, 0, self.plate_thickness / 2)) # 打孔(含沉头) for x in range(self.hole_count): offset = (self.base_length / 2 - 20) * (0.5 if x % 2 == 0 else -0.5) result = (result.faces(">Z") .workplane() .center(offset, self.base_width / 2 - 15) .hole(self.hole_diameter)) return result

这里面有几点设计心得值得单独说一下。参数合法性检查看起来是个小事,但大模型的AI幻觉不是闹着玩的,它真的会给你抽出一个长为0.5mm的“底板”、负数的“孔距”。没有这层校验,你的模型会在执行到中途时直接内核崩溃,而且报错信息晦涩难懂,你根本不知道是大模型的错还是代码的错。有了这个检查,报错一目了然——参数错了就回去改prompt,代码的问题再单独修。

第二个心得是用中文写docstring对当前的开源模型反而更好用。很多国产大模型对中文指令的意图理解明显强于英文,我在选择底层模型时专门做了对比测试。同一个法兰支架的prompt描述,中文格式的参数抽取准确率能高出近15个百分点,尤其是处理“沉头孔”“加强筋”这类本土工程词汇时。

3.3 大模型提示词与Function Calling配置

我试验过两种对接方式:纯粹的提示词输出JSON,以及配合Function Calling。结论是Function Calling碾压后者,强烈建议你不要偷懒,直接上Function Calling。

直接让大模型输出JSON的问题是输出稳定性差。它经常给你多一个注释,少一个尾括号,或者在JSON外面包一层json的Markdown代码块标识。本来解析JSON就是小事,但当你批处理几百个请求时,任何一点不确定性都会被放大成一个需要人工干预的“特殊情况”。Function Calling的大模型输出是结构化的工具调用参数,你不用解析,直接用返回的arguments字典即可。

下面是一个关键Prompt模板,我调了很多版,目前收敛到这个版本效果最稳定:

你是一个机械设计专家,任务是理解用户的文本描述,并抽取参数化CAD模型的参数。 用户描述可能不完整或不精确,你需要: 1. 基于机械设计常识补齐缺失参数(如标准件默认尺寸、常用厚度等) 2. 将自然语言中的工程表达(如“两个手指宽的厚度”)转换为标准公制尺寸 3. 如果描述存在矛盾或严重违反工程常识,请指出并返回错误码 请通过调用 add_part 函数来提交你的结果,所有参数必须是合法的JSON格式。

这里的要点是“允许模型补全缺失参数”,实测下来这个指令对可用性提升巨大。用户往往只会说“我要一个安装板,四角打孔”,他不会告诉你板厚应该取3mm还是5mm。如果模型不补全,你得返回去问他,体验就断了。补全后生成的模型虽然可能不完全符合他预期,但至少是一个“合理”的结果,用户在此基础上微调,比从零开始画快得多。

3.4 后处理与格式导出

模型生成后,还有一个重要环节是导出格式的选择。这一步如果选错了,轻则下游软件打不开,重则加工时尺寸对不上。

输出格式适用场景关键参数
STEP (AP214)后续在SolidWorks/Fusion 360里做结构设计、装配单位固定为毫米,注意不要选AP203(它不支持颜色和高级几何)
STL3D打印、快速原型注意弦偏差(Chord Tolerance),一般设置0.1mm够用,精细件设0.05mm
AMF3D打印多材质树结构格式,现在切片软件支持度一般
SVG/DXF激光切割、二维出图导出前要先将3D模型投影到对应平面

我在CadQuery里导出STEP的实战代码如下:

# 构建模型 bracket = FlangeBracket( base_length=120, base_width=60, plate_thickness=5, flange_height=80, hole_diameter=8.5, hole_count=4, boss_diameter=30 ) model = bracket.build() # 导出STEP(推荐AP214格式,兼容性最好) cq.exporters.export(model, "output/bracket.step", exportType=cq.exporters.ExportTypes.STEP, opt={"write_pcurves": True}) # 导出STL(3D打印用,控制网格密度) cq.exporters.export(model, "output/bracket.stl", exportType=cq.exporters.ExportTypes.STL, opt={"tolerance": 0.1, "angularTolerance": 0.5})

值得注意的一点是write_pcurves这个选项。如果你生成的STEP文件要在NX或Creo里打开,建议打开这个开关,它能写入参数曲线信息,后续做圆角或曲面分析时更精确。但代价是文件体积会变大30%左右,如果只是给SolidWorks用,关掉它也没关系。

4. 实际踩坑记录:text-to-cad项目最常见的五个拦路虎

4.1 几何破面与自相交问题

破面是text-to-cad新手遇到最多的问题。现象是模型在CadQuery里看好好的,一导出STEP到SolidWorks里就报“面与面之间不存在有效连接”。

这个问题的根源在于大模型抽出来的几何参数之间可能存在微小冲突。比如它生成了一个孔径等于板宽的螺纹孔,在布尔运算的容差范围内产生了自相交。解决思路分两层:

  • 第一层:在模板的参数约束(Parameter Constraints)里写死边界条件,比如孔径必须小于板宽的1/3,凡是超出范围的请求直接拒绝生成,不给内核留任何出错机会。
  • 第二层:如果非做不可的复杂模型,在合并实体之前,先对每个子实体独立执行validate()方法检查,再把问题实体单独打回给大模型重新抽取参数。

4.2 语义歧义与隐含约束缺失

这是最让我头疼的一类问题。用户说“一个带法兰的轴套,内径12,壁厚2”,模型抽出来一个没有倒角的直筒子,没做任何工艺特征。用户不满:“我要的是轴套,怎么连退刀槽都没有?”

这里的问题不是模型不懂“轴套”是什么,而是它没有把“轴套”的隐含默认属性映射到参数上。解决方案是在大模型Prompt里增加“工艺性补全”指令,比如“请为所有旋转体零件添加0.5mm的倒角”“请在轴承配合面处添加1mm×1mm的退刀槽”。加了之后效果立竿见影,生成模型的实用度上升了一个台阶。但要注意,不能过度补全,否则会增加后续加工成本。

4.3 坐标原点和装配基准的混乱

text-to-cad生成单个零件没问题,但一旦进入装配体,基准问题就来了。大模型对“法兰的底面应该与配合面重合”这种装配约束是完全没有概念的。生成的零件原点可能飘在空中,也可能是实体中心。

我的自定义方案是:在模板里硬编码建模基准。比如所有底座类零件,一律以底面中心为原点构建,所有轴套类零件,一律以旋转轴为Z轴,左端面中心为原点。这样在装配时,只需要用“同轴心”“重合”这类基础配合就能快速约束。更进阶的方案是让模板生成时顺带写一段XML的装配约束描述文件,直接让下游装配程序读取应用。

4.4 单位制混淆问题

这个问题极其隐蔽,因为它在模型层完全不报错。用户说“做一个直径50的齿轮”,大模型理解可能是毫米单位的50mm,但生成的模型如果是英寸单位,导出STEP时数据是对的,但下游CAM软件一识别,变成了1.97英寸的齿轮,意味着你要重新调整整个刀具路径。

做量产件时的教训是:在生成环节强制锁定单位。CadQuery里用cq.Workplane("XY").units("mm")显式声明,exports/export的路径上再加一道单位断言,确保所有参数都是毫米值。别指望用户描述里写了一段“所有尺寸均采用毫米”就能约束一切,机器不会自动帮你换算。

4.5 大模型临时抽风与流式输出的复活机制

就算你做了上面所有防御,大模型还是会有抽风的时候。比如直接把“M8螺栓”理解成“直径8mm的圆柱体”,导致生成的CAD模型完全不是螺纹件。这类问题不能靠硬编码防御,需要一种“错误恢复机制”。

我的做法是设计一个二次校验通道:模型生成STEP后,脚本自动解析STEP文件里的几何基本体数量(圆柱体、平面、球面),与模板预期的数量做对比。偏差超过20%就判定生成失败,自动重新调用大模型并附上错误日志,让它自省后重试。实测重试一次的成功率在60%以上,第二次基本能稳。这个机制虽然糙,但对于把流程控制在无人值守状态,非常重要。

5. 把text-to-cad用出价值:我的经验和扩展方向

text-to-cad目前的状态,把它当“全能自动画图大师”肯定要失望,但把它当“参数抽取器+程序化建模执行器”,确实能解决不少实际问题。我个人的使用体会是,最有价值的定位是:让大模型去承担它擅长的“理解意图、抽取参数、判断合理性”,让OpenCascade去承担它擅长的“精确计算、拓扑稳定、格式转换”,各司其职,这样才能把AI的能力和CAE的专业性结合起来。

如果你的业务方向是做定制化零件批量报价平台,这个技术直接给你省掉了一个售前工程师80%的建模时间——只需要让客户用大白话描述需求,系统自动出图、算料、估价。如果你是个独立创客,想快速验证一个结构想法,text-to-cad加一台3D打印机,正好能把你从“画图两小时打印半小时”的窘境里解放出来。

后续值得你重点关注的扩展方向有三个:一是多模态输入,把图片和自然语言结合起来,比如“像这张图一样的外形,但改成一个油箱”,当前端到端模型还不成熟,但混合方案里已经可以做了。二是批量生成与变体管理,用text-to-cad生成一个零件的几百个变体,并结合一个筛选器,挑出满足设计约束和工艺约束的最优解,这是个非常实用的场景。三是与CAE仿真打通,自动生成的模型直接进入有限元分析流程,搞一个“说一句我要一个轻量化支架,直接输出拓扑优化结果”的闭环,一旦做通,这个领域才真正称得上改变范式。

这条路还早,但不影响你现在就开始吃螃蟹。先跑通一个小场景,从最简单的零件模板开始,攒好你的参数化模板库,这比什么论文都值钱。

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

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

立即咨询