news 2026/10/8 14:23:00

text-to-cad 实战:从自然语言到 STEP 参数化建模全链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
text-to-cad 实战:从自然语言到 STEP 参数化建模全链路

1. 从一句话到三维模型:text-to-cad 到底在解决什么问题

第一次听到 text-to-cad 这个词,我脑子里蹦出来的画面是:对着电脑敲一句“给我画一个 80x60x20 的法兰盘,中心开 30 的通孔,四角各一个 M6 沉头孔”,然后屏幕上直接出现一个可以导出 STEP 的实体模型。这个画面在几年前还属于科幻范畴,但现在它已经是一条能跑通的技术链路了。text-to-cad 本质上是一套把自然语言描述翻译成参数化 CAD 几何的生成流程,最终产物通常是 STEP、GLB 或 STL 这类通用三维格式。它要解决的核心痛点很明确:传统 CAD 建模门槛高、重复劳动多,一个标准件可能要画十几分钟,而用文字描述只需要几秒钟。

我接触这个方向是因为手头有一批非标零件需要快速出模型给下游做仿真。以前的做法是打开 CAD 软件,拉伸、打孔、倒角一步步来,几十个零件下来人都麻了。后来我开始研究怎么用代码和语言模型把这段流程自动化,踩了不少坑,也总结出一套相对稳定的做法。这篇文章适合三类人看:一是想了解 text-to-cad 技术原理的工程师,二是想自己动手搭一套生成流程的开发者,三是做机械设计、工业设计、3D 打印相关工作的从业者,想看看这个方向能不能落到自己的实际业务里。

需要先说明一点:text-to-cad 目前不是一个开箱即用的成熟商业软件,它更像是一种技术范式,由大语言模型、几何内核、参数化脚本三部分拼起来。不同团队实现方式差异很大,有的走“LLM 生成 CadQuery 代码”的路线,有的走“LLM 输出 JSON 参数再喂给模板”的路线,还有的用扩散模型直接生成网格。下面我会把这几条路线的取舍、核心实现细节、实操步骤和踩坑经验都摊开讲清楚。

2. 技术路线选型:为什么大多数人最终选了“代码生成”这条路

2.1 三条主流路线的对比与取舍

text-to-cad 的实现方式,我大致归为三类。第一类是代码生成路线:让大语言模型把自然语言翻译成 CadQuery、OpenSCAD 或 build123d 这类参数化建模脚本,再执行脚本得到实体,最后导出 STEP。第二类是参数填充路线:预先做好一批参数化模板(比如法兰、齿轮、支架),模型只负责从文字里抽取尺寸和特征,填进模板。第三类是直接生成路线:用扩散模型或神经场直接输出网格顶点,得到 STL 或 GLB。

这三条路线的差异,我用一个表格说清楚:

路线代表工具输出格式精度可编辑性实现难度
代码生成CadQuery + LLMSTEP/STL高,精确到微米强,脚本可改中
参数填充自建模板库STEP高中,受模板限制低
直接生成扩散模型STL/GLB低,网格粗糙弱,难参数化高

我自己最终选了代码生成路线,原因很实际。参数填充路线虽然稳,但模板覆盖不了非标件,一旦遇到没见过的形状就歇菜。直接生成路线看着酷,但出来的网格面数爆炸、尺寸不准,拿去 3D 打印还行,拿去加工或者做仿真根本没法用。代码生成路线的好处是:几何精度由几何内核保证,LLM 只负责写脚本,写错了还能人工改,改完就是标准 STEP 文件,下游 CAD 软件全能打开。

提示:如果你只是想做 3D 打印的摆件,直接生成路线够用;但只要涉及配合尺寸、装配、加工,必须走代码生成或参数填充,网格模型的精度撑不住。

2.2 为什么 STEP 是绕不开的交付格式

热词里出现了 STEP、GLB、STL 三个格式,这里必须掰扯清楚它们的定位。STL 是三角网格,只有表面没有拓扑,尺寸精度取决于网格密度,适合 3D 打印和渲染,但不适合做参数化编辑。GLB 是 glTF 的二进制版本,主打轻量化和 Web 展示,带材质和动画,适合做产品预览页面。STEP 是真正的边界表示(B-rep)实体格式,保留了面、边、顶点的拓扑关系,任何主流 CAD 软件都能打开并继续编辑。

text-to-cad 的完整链路,我建议是:LLM 生成脚本 → 几何内核执行 → 导出 STEP 作为主交付 → 按需转 STL 或 GLB。STEP 是源头,STL 和 GLB 是派生物。很多人一上来就想直接生成 STL,结果发现改一个孔位要重新生成整个网格,效率极低。而 STEP 模型在 CAD 里改一个尺寸,重新导出 STL 只要几秒钟。

2.3 几何内核的选择:OCCT 几乎是唯一答案

代码生成路线里,几何内核基本锁定 OpenCASCADE(简称 OCCT)。CadQuery、build123d、FreeCAD 底层都是它。OCCT 提供了完整的 B-rep 建模能力:布尔运算、倒角、抽壳、放样、扫掠,全都有。Python 生态里通过 cadquery 或 OCP 绑定调用。选它的理由很简单:开源、跨平台、精度可靠、社区活跃,而且导出的 STEP 文件兼容性极好,中望 CAD、SolidWorks、Fusion 360 都能正常读取。

我试过用 Blender 的 bmesh 做参数化,精度和拓扑质量差太多,做出来的东西没法当工程件用。也试过用 trimesh 直接操作网格,同样卡在精度上。绕了一圈还是回到 OCCT。所以如果你要搭 text-to-cad,先把 CadQuery 或 build123d 跑通,这是地基。

3. 核心实现细节:从文字到脚本的关键环节

3.1 提示词工程:怎么让 LLM 写出能跑的建模脚本

这是整个链路里最玄学也最关键的一环。LLM 写 CadQuery 代码,最常见的翻车方式有三种:一是 API 记错,比如把Workplane.hole()的参数顺序搞反;二是坐标系混乱,孔打到了错误的位置;三是单位搞错,把毫米当厘米。我摸索出来的做法是给模型喂一份精简的 API 参考,而不是让它凭记忆写。

具体操作上,我会在系统提示里固定几件事:明确使用 CadQuery 2.x 语法、明确所有尺寸单位为毫米、明确原点在零件底面中心、要求输出完整可执行脚本并附带cq.exporters.export()导出语句。然后给两到三个 few-shot 示例,覆盖拉伸、打孔、倒角这几个高频操作。实测下来,加了示例之后一次通过率能从三成提到七成以上。

# 系统提示里附带的示例片段 import cadquery as cq result = ( cq.Workplane("XY") .box(80, 60, 20) # 长宽高,单位 mm .faces(">Z").workplane() .hole(30) # 中心通孔 .faces(">Z").workplane() .rect(60, 40, forConstruction=True) .vertices().cboreHole(6, 12, 6) # M6 沉头孔 ) cq.exporters.export(result, "flange.step")

注意:不要指望 LLM 一次写对复杂零件。我的做法是让它先写简单版本,跑通后再逐步加特征。一次要求太多特征,出错概率指数上升。

3.2 参数抽取:从模糊描述里抠出精确尺寸

用户说“一个大一点的圆盘”,这个“大一点”到底是多大?text-to-cad 必须把模糊语言转成确定数值。我的处理策略是双通道:LLM 负责抽取明确出现的数字和特征,对于缺失的尺寸,走一套默认值规则或者反问用户。比如“圆盘”默认直径 100mm、厚度 10mm,如果用户说“小圆盘”就缩到 50mm。

这里有个经验:让 LLM 输出结构化 JSON 比让它直接写代码更稳。JSON 里放shape、dimensions、features三个字段,尺寸缺失就留空,由后处理逻辑补默认值。这样即使 LLM 抽错了,也能在 JSON 层面拦截和修正,不至于直接生成一堆错误代码。

{ "shape": "flange", "dimensions": {"outer_diameter": 100, "thickness": 10, "bore": 30}, "features": [ {"type": "through_hole", "diameter": 30, "position": "center"}, {"type": "counterbore", "diameter": 6, "count": 4, "pattern": "rectangular"} ] }

3.3 脚本执行与沙箱:安全跑通不可信代码

LLM 生成的代码本质上是不可信输入,直接exec()跑在主机上有风险。我的做法是放进子进程或者容器里执行,限制执行时间和内存,禁止网络访问和文件系统写入(除了指定的输出目录)。CadQuery 本身是纯计算库,不涉及网络,所以沙箱配置相对简单。用subprocess加超时控制就能挡住大部分问题。

执行完还要做几何校验:检查生成的实体是不是有效的(solid.isValid())、体积是否为正、有没有自相交。我遇到过 LLM 写出布尔运算顺序错误导致实体为空的情况,如果不校验直接导出,下游拿到一个空 STEP 文件会一脸懵。

4. 完整实操流程:手把手搭一条可复现的生成链路

4.1 环境准备与依赖安装

先把基础环境搭起来。Python 3.10 以上,CadQuery 用 conda 装最省事,因为 OCCT 的二进制依赖在 pip 下偶尔会有兼容问题。

conda create -n text2cad python=3.10 conda activate text2cad conda install -c conda-forge cadquery pip install openai pydantic

装完先验证一下:

import cadquery as cq box = cq.Workplane("XY").box(10, 10, 10) print(box.val().Volume()) # 应该输出 1000.0

体积对得上,说明几何内核正常。这一步别跳过,我见过有人装完直接跑生成,结果报错报了半天,最后发现是 OCCT 版本冲突。

4.2 提示词模板与调用封装

把系统提示、few-shot 示例、用户输入拼成一个完整的请求。我用 OpenAI 兼容接口,temperature 设 0.2,降低随机性。关键是把 API 参考和示例放在系统消息里,用户描述放在用户消息里。

SYSTEM_PROMPT = """你是 CadQuery 建模专家。根据用户描述生成完整可执行的 Python 脚本。 要求: 1. 使用 cadquery 2.x 语法,单位毫米 2. 原点在零件底面中心 3. 脚本末尾必须导出 STEP 到指定路径 4. 只输出代码,不要解释 """ def build_prompt(user_text): return [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_text} ]

4.3 执行、校验与格式转换

拿到脚本后,写进临时文件,子进程执行,超时设 30 秒。执行成功就校验实体,然后导出 STEP。转 STL 和 GLB 用 CadQuery 自带的导出器或者 trimesh 都行。

import subprocess, tempfile, os def run_script(code, out_step): with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f: f.write(code) path = f.name try: r = subprocess.run(["python", path], capture_output=True, timeout=30) if r.returncode != 0: raise RuntimeError(r.stderr.decode()) finally: os.unlink(path) return out_step

STL 导出时注意设置合适的线性偏差(linear deflection)和角度偏差(angular deflection)。偏差太大网格粗糙,太小文件巨大。我一般用线性偏差 0.1mm、角度偏差 0.2 弧度,兼顾精度和体积。

cq.exporters.export(result, "part.stl", tolerance=0.1, angularTolerance=0.2) cq.exporters.export(result, "part.glb")

4.4 一个完整案例:从描述到 STEP 文件

假设用户输入:“画一个 120x80x15 的安装板,四角各一个直径 8 的通孔,孔中心距边缘 10mm,板中心开一个 40x40 的方孔。”

LLM 生成的脚本大致是这样:

import cadquery as cq plate = ( cq.Workplane("XY") .box(120, 80, 15) .faces(">Z").workplane() .rect(100, 60, forConstruction=True) .vertices().hole(8) .faces(">Z").workplane() .rect(40, 40).cutThruAll() ) cq.exporters.export(plate, "mounting_plate.step")

跑完导出的 STEP 文件,用中望 CAD 打开,尺寸、孔位、方孔全部正确。整个过程从输入文字到拿到文件,不到 20 秒。同样的零件手工画,熟练工也要五到八分钟。这就是 text-to-cad 的价值所在——把重复性建模变成一次性描述。

5. 常见问题与排查技巧实录

5.1 生成脚本报错的典型原因

我把踩过的坑整理成一张速查表,基本覆盖了八成以上的报错:

报错现象根本原因解决办法
AttributeError: no attribute 'hole'API 版本不匹配锁定 CadQuery 2.x,提示词里写明版本
实体体积为 0布尔运算顺序错误检查 cut 和 union 的先后,先加后减
孔位置偏移坐标系原点理解错误统一约定原点在底面中心,提示词强调
STEP 打开是空文件导出前实体无效加isValid()校验,无效则重新生成
尺寸差 10 倍单位混淆提示词强制毫米,输出后做量纲检查

5.2 精度与网格质量的平衡

STL 导出参数是新手最容易忽略的地方。默认参数导出的网格往往面数过多或者过少。面数过多文件几十兆,面数过少曲面变成多边形。我的经验是:平面特征为主的零件用 0.1mm 线性偏差足够,曲面多的零件降到 0.05mm。角度偏差统一 0.2 弧度,这个值对圆柱面的细分比较合理。

另外,STL 是网格格式,导出后如果要做 UV 展开或者修复,那是另一套流程。热词里提到的“3dsmax 修复 STL 模型的 UV”就是下游环节的事,text-to-cad 阶段只要保证几何正确、网格密度合理就行。

5.3 批量生成时的稳定性技巧

单件生成和批量生成是两回事。批量跑的时候,LLM 偶尔会抽风写出语法错误的代码,如果不做重试,整批就断了。我的做法是失败自动重试三次,每次把上一次的错误信息拼回提示词,让模型自我修正。实测下来,第一次失败第二次成功的比例不低,三次之后还失败的,基本就是描述本身有歧义,需要人工介入。

还有一个技巧:把常用零件做成缓存。同样的描述第二次请求直接返回缓存结果,省 token 也省时间。对于标准件库这种高频重复的场景,缓存命中率能到一半以上。

6. 落地场景与后续扩展方向

text-to-cad 目前最适合的场景,我总结为三类。第一类是标准件和非标件的快速出图,比如法兰、支架、连接板,描述清楚尺寸就能生成,省去大量重复建模。第二类是参数化产品配置,客户在网页上选尺寸、选孔位,后台实时生成 STEP 供下载,这在定制家具、钣金加工行业很有价值。第三类是教学和原型验证,学生用文字描述几何体,立刻看到三维结果,理解参数和形状的关系。

后续扩展上,我觉得有两个方向值得投入。一是多轮对话式建模,用户说“把孔改大一点”,系统理解上下文后修改脚本重新生成,而不是从头再来。二是与仿真链路打通,生成的 STEP 直接喂给有限元前处理,省去中间格式转换。这两个方向我都试过原型,技术上可行,工程化还需要打磨。

最后分享一个我在实际使用中的体会:text-to-cad 不是要取代 CAD 工程师,而是把工程师从重复劳动里解放出来。真正复杂的曲面造型、装配关系、工程图标注,还是得靠人。但那些“画个板子打几个孔”的活,交给它干,又快又稳。把省下来的时间花在真正需要判断力的地方,这才是这套工具的正确用法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 14:20:18

MonkeyCode实践:AI编程从失控到企业级流水线

前几天研发周会上,有个同事很兴奋地演示他新写的模块——用AI编程工具,一个下午搞定了平时两三天的活。代码评审的时候,我翻了翻他提交的内容,发现几个边界条件没处理,依赖版本也引错了,还有一段逻辑明显是…

作者头像 李华
网站建设 2026/10/8 14:17:49

某纯电牵引车整车控制系统

一、整车控制系统VCU主要功能 VCU接收来自驾驶员的开关信号,如钥匙开关信号、油门位置、刹车、档位、制动等等,然后通过计算和处理,来实现对整车驱动控制及其它控制功能。1、电机控制: 通过接收驾驶员指令,以及整车相关…

作者头像 李华
网站建设 2026/10/8 14:12:54

YOLO模型过拟合的早期预警信号与应对策略:验证集mAP开始下降时该做什么

导读:你花了三天三夜调优YOLO模型,训练集mAP一路飙升到0.85,满心欢喜地准备上线——结果验证集mAP在第80轮突然掉头向下,最终测试效果惨不忍睹。这不是你运气差,而是你错过了过拟合的早期预警信号。本文结合Ultralytics官方文档、YOLO11/YOLO26最新训练实践及工业部署一线…

作者头像 李华