☰
text-to-cad 实战:从自然语言到参数化实体模型的完整链路
2026/10/8 16:32:16 网站建设 项目流程

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

第一次听到 “text-to-cad” 这个词,我脑子里蹦出来的画面是:对着电脑敲一句“给我画一个 80×60×10 毫米、四角带 M4 沉头孔的安装板”,然后 CAD 软件里就自动出现了一个可以旋转、可以导出 STEP 的实体模型。这个画面在几年前还属于科幻范畴,但现在它已经变成了一个真实可跑通的技术链路。所谓 text-to-cad,本质上就是用自然语言描述几何意图,由程序自动生成 CAD 模型文件,最终输出 STEP、GLB、STL 这类通用格式,直接进入后续的渲染、3D 打印、装配仿真流程。

这件事为什么值得单独拿出来讲?因为传统 CAD 建模的门槛并不在“想不想得到”,而在“会不会操作”。一个机械工程师脑子里很清楚自己要一个带拔模斜度的壳体,但他要在 SolidWorks 或中望 CAD 里点几十次鼠标、画草图、拉伸、倒角、抽壳。而 text-to-cad 想做的事情,是把这段“操作记忆”压缩成一句结构化描述,让程序去执行。它服务的人群很明确:需要快速验证结构想法的产品经理、做批量参数化零件的工程师、以及想把 AI 能力接进设计流程的开发者。

热搜词里同时出现了 cad下载、cad制图初学入门、sw 中 stl 转 stp、python 批量对 cad 修改这些词,说明关注这个方向的人跨度很大——既有刚装好 CAD 想入门的新手,也有已经在用 Python 脚本批量改图纸的老手。text-to-cad 恰好卡在中间:它既降低了入门者的第一道门槛,又给老手提供了自动化管线的新入口。下面我会把这条链路拆开,从整体设计思路一直讲到踩坑记录,尽量让不同基础的人都能拿走能用的东西。

2. 整体设计与技术路线拆解

2.1 为什么不是“直接生成网格”,而是优先走参数化实体

很多人第一反应是:让 AI 直接吐一个 STL 不就行了?STL 是三角网格,生成起来确实简单,一个神经网络输出顶点坐标就能拼出来。但实测下来,这条路在工程场景里问题很大。STL 只有表面三角形,没有“这是一个孔”“这是一个圆柱面”的语义信息,你拿到之后想改孔径、想加一个倒角,基本等于重新建模。热搜里那条“3dsmax2012 修复 stl 模型的 uv”就是典型的网格后处理噩梦——网格一旦生成,后续编辑成本极高。

所以 text-to-cad 的主流路线是先生成参数化实体,再按需导出。参数化实体在内部用边界表示(B-rep)或者构造实体几何(CSG)树来描述,每个特征都有明确参数。这样导出的 STEP 是带拓扑关系的实体格式,导出的 GLB 适合网页预览,导出的 STL 才用于 3D 打印。三种格式各司其职:

格式本质典型用途是否可参数化编辑
STEPB-rep 实体,带面/边/顶点拓扑跨软件交换、CNC 加工可以,导入后仍是实体
GLB二进制 glTF,含网格与材质网页 3D 预览、AR一般不行,偏展示
STL纯三角网格3D 打印、切片不行,只能整体缩放

我个人的经验是:只要下游还要改,就坚决走 STEP;只要下游只是看,就走 GLB;只有明确要打印,才导出 STL。这个判断顺序能省掉大量返工。

2.2 文本到几何的中间表示:为什么需要一层“结构化描述”

如果让大模型直接输出一段 Python 建模代码,看起来最省事,但稳定性很差。模型可能今天用box(),明天用Box(),参数顺序也可能变。更稳的做法是在自然语言和最终几何之间加一层中间表示,通常是一段 JSON 或类 DSL 的结构化描述。比如“一块 80×60×10 的板,四角各一个直径 4.5 的沉头孔”,中间表示大概长这样:

{ "type": "plate", "size": [80, 60, 10], "features": [ { "type": "hole", "pattern": "rectangular", "count": [2, 2], "diameter": 4.5, "counterbore": { "diameter": 8, "depth": 4.5 }, "margin": 8 } ] }

这层中间表示的价值在于:它把“理解语言”和“生成几何”解耦了。语言模型只负责把话翻译成 JSON,几何内核只负责把 JSON 变成实体。任何一边出问题,都能单独调试。而且 JSON 可以被程序校验,比如孔径不能为负、板厚必须大于沉头深度,这些规则在生成几何之前就能拦住错误。

2.3 几何内核选型:为什么绕不开 OpenCASCADE 这类库

生成参数化实体需要一个几何内核。市面上能用的开源内核里,OpenCASCADE(OCCT)是绕不过去的选择,它支持 B-rep、布尔运算、倒角、抽壳、STEP 读写,功能完整。热搜里那条“qopengl 加载 stl”和“qt5.15.2 读取 stl 模拟六轴机械臂”说明很多人已经在用 Qt + OpenGL 做可视化,而 OCCT 恰好能和这套技术栈配合:OCCT 负责几何计算,OpenGL 负责把三角面片画出来。

选 OCCT 的理由很实际:它导出的 STEP 兼容性好,中望 CAD、SolidWorks 都能正常打开;它的布尔运算虽然偶尔会失败,但至少有成熟的容差参数可以调。相比之下,一些轻量内核在简单形状上跑得飞快,一遇到复杂布尔就崩。如果你的目标是“能真正用于工程交换”,OCCT 是稳妥的起点。

3. 核心细节解析与实操要点

3.1 自然语言到结构化参数的映射规则

这一步是整个链路里最“玄”的部分,但也可以做得很工程化。我的做法是先定义一套受控的几何词汇表,再让语言模型在这个词汇表里做映射。词汇表覆盖常见特征:plate(板)、box(方块)、cylinder(圆柱)、hole(孔)、slot(槽)、fillet(圆角)、chamfer(倒角)、shell(抽壳)。每个特征有固定的参数名和单位约定,单位统一用毫米。

映射时要注意几个高频歧义点。第一是尺寸顺序:中文说“80 乘 60 乘 10”,到底是长宽高还是宽长高?我的约定是统一按[length, width, height],并且在提示词里明确要求模型输出带字段名的 JSON,而不是裸数组。第二是孔的位置描述:“四角”需要转换成具体的坐标,通常用“距边距”来表达,比如边距 8 毫米,程序再根据板尺寸算出四个孔心坐标。第三是沉头和 countersink 的区分,中文里都叫“沉头”,但一个是柱形沉孔,一个是锥形沉孔,必须在词汇表里分开。

提示:不要指望模型一次就把所有参数说对。实际做法是让模型输出 JSON 后,用一层校验脚本检查必填字段和数值范围,缺什么就追问什么,而不是直接拿去建模。

3.2 参数校验与几何可行性检查

JSON 拿到手不等于能建模。我踩过的最典型的坑是:模型给出“板厚 10 毫米,沉头深度 12 毫米”,数值上看着没问题,但几何上沉头比板还厚,布尔运算直接失败。所以建模之前必须做一轮几何可行性检查,规则包括:

  • 孔径必须大于 0,且小于所在面的最小边长;
  • 沉头深度必须小于板厚,锥形沉头的锥角通常在 82° 到 90° 之间;
  • 抽壳厚度必须小于最小外形尺寸的一半;
  • 圆角半径不能大于相邻边的最短长度。

这些规则用普通 Python 判断就能实现,不需要几何内核参与。把校验前置的好处是:错误在几毫秒内被拦住,而不是等到 OCCT 跑了几秒布尔运算之后才报一个看不懂的异常。热搜里“cad 里面 f 命令用不了”这类问题,很多时候就是圆角半径超限导致的,前置校验能提前给出人话提示。

3.3 从结构化参数到实体的建模顺序

建模顺序直接影响成功率。我的固定顺序是:先做主体,再做减材特征,最后做修饰特征。具体来说:

  1. 用plate或box生成基础实体;
  2. 用布尔减运算打孔、开槽;
  3. 最后加圆角、倒角、抽壳。

为什么圆角要放最后?因为圆角对相邻几何很敏感,如果先加圆角再打孔,孔可能会切到圆角面,导致圆角失效或产生碎面。把圆角放最后,前面的布尔运算都在规整的平面上进行,成功率高得多。这个顺序和手工建模的习惯是一致的,程序化建模同样适用。

3.4 导出环节的参数选择

导出 STEP 时,OCCT 提供了不同的精度模式。默认模式对大多数零件够用,但如果你的模型有很小的圆角或很细的槽,建议提高精度,否则 STEP 里的曲面会被简化成多段平面。导出 STL 时则要控制弦高偏差(linear deflection)和角度偏差(angular deflection),这两个参数决定了三角面片的密度。弦高设得太小,STL 文件会巨大;设得太大,圆柱面会变成明显的多边形。我的经验值是:普通零件弦高取 0.05 到 0.1 毫米,精密零件取 0.01 毫米,角度偏差统一取 0.5 弧度左右。

4. 完整实操流程与关键环节实现

4.1 环境准备与依赖安装

先把基础环境搭起来。我用的组合是 Python 3.10 + OCCT 的 Python 绑定。安装命令如下:

pip install cadquery ocp

CadQuery 是对 OCCT 的一层封装,语法比裸 OCCT 友好很多,适合快速验证。如果你要做更底层的控制,可以直接用OCP这个包,它是 OCCT 的原始 Python 绑定。热搜里“python 批量对 cad 修改”的需求,用 CadQuery 写脚本会非常顺手,因为它本身就是代码化建模。

注意:OCCT 相关包的版本要匹配,Python 3.10 和 3.11 对应的 wheel 不一样。装完之后先跑一个最小例子验证,别等到写了几百行才发现导入失败。

4.2 一个最小可跑通的例子

下面这段代码演示了从结构化参数生成一块带四角沉头孔的板,并导出 STEP 和 STL:

import cadquery as cq length, width, thickness = 80.0, 60.0, 10.0 hole_dia, cb_dia, cb_depth = 4.5, 8.0, 4.5 margin = 8.0 # 基础板 plate = cq.Workplane("XY").box(length, width, thickness) # 四角孔心坐标 xs = [-length/2 + margin, length/2 - margin] ys = [-width/2 + margin, width/2 - margin] points = [(x, y) for x in xs for y in ys] # 打沉头孔 result = ( plate.faces(">Z").workplane() .pushPoints(points) .cboreHole(hole_dia, cb_dia, cb_depth) ) # 导出 cq.exporters.export(result, "plate.step") cq.exporters.export(result, "plate.stl", tolerance=0.05)

这段代码跑通之后,你就有了一个完整的“参数到实体到文件”的闭环。接下来要做的,就是把前面说的 JSON 解析成这些参数,让语言模型来填。

4.3 把语言模型接进来的具体做法

我用的方式是两段式提示。第一段让模型把用户的话翻译成 JSON,第二段用程序校验 JSON,校验通过再建模。提示词里我会明确给出词汇表和字段说明,并要求模型只输出 JSON,不要输出解释。实测下来,这种受控方式比让模型自由发挥稳定得多。

举个实际例子,用户输入“做一个 100×50×5 的底板,中间开一个 20×10 的方槽,四角 M3 螺纹底孔”。模型输出的 JSON 里,方槽用slot特征,螺纹底孔按 M3 对应直径 2.5 毫米处理。程序拿到之后先校验:槽宽 10 毫米小于板宽 50 毫米,通过;孔径 2.5 毫米大于 0,通过;然后建模。整个过程从输入到 STEP 文件落地,大概两三秒。

4.4 批量生成与参数扫描

text-to-cad 真正体现价值的地方是批量。比如你要生成一系列不同长度的支架,长度从 50 到 200 毫米,步长 10 毫米。手工建模要改 16 次,程序化只需要一个循环:

for L in range(50, 201, 10): params = {"length": L, "width": 30, "thickness": 5} model = build_bracket(params) cq.exporters.export(model, f"bracket_{L}.step")

这种批量能力直接对应热搜里“python 批量对 cad 修改”的需求。区别在于,传统脚本改的是已有图纸的参数,而 text-to-cad 是从描述直接生成新模型,起点更靠前。

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

5.1 布尔运算失败怎么办

布尔运算失败是 OCCT 最常见的报错。原因通常有三类:面重合、容差过小、几何自交。排查顺序是:先看两个实体是否有完全重合的面,如果有,把其中一个稍微偏移 0.001 毫米;再看容差,OCCT 默认容差是 1e-7,如果模型尺寸很小,可以适当放大到 1e-6;最后检查是否有自交,比如抽壳之后内壁和外壁贴在一起。

提示:布尔失败时不要反复重试同一个参数,先打印出两个实体的包围盒,看看它们是否真的相交。很多时候问题出在坐标算错了,而不是内核的问题。

5.2 导出的 STEP 在别的软件里打开是空壳

这种情况通常是导出时只写了面片,没写实体拓扑。检查方法是看导出代码里用的是exportStep还是exportStl,前者才是实体。另外,如果模型本身是壳体(比如抽壳后的零件),STEP 里就是壳体,不是实心体,这是正常的。热搜里“sw 中 stl 转 stp”之所以麻烦,就是因为 STL 没有拓扑,转出来的 STEP 往往是一堆碎面,而 text-to-cad 直接生成实体,天然避开了这个问题。

5.3 中文描述里的单位歧义

“做一个 5 厘米的板”和“做一个 5 毫米的板”差十倍。我的处理方式是在提示词里强制要求模型把所有尺寸换算成毫米,并且在 JSON 里带unit: "mm"字段。如果用户没说单位,默认按毫米处理,同时在返回结果里提示“已按毫米解释,如需其他单位请说明”。这个默认值符合机械设计的习惯,热搜里“cad 制图初学入门”的教程也基本都以毫米为默认单位。

5.4 常见问题速查表

现象可能原因排查动作
布尔运算报错面重合或容差问题偏移 0.001mm 或放大容差
STEP 打开是空导出成了网格改用实体导出接口
圆柱面有棱角STL 弦高太大减小 linear deflection
圆角失败半径超过相邻边前置校验圆角半径
孔位置偏移边距算错打印孔心坐标核对
模型尺寸不对单位歧义强制统一为毫米

5.5 几个我踩过的坑

第一个坑是沉头孔方向。cboreHole默认从当前工作平面往下打,如果工作平面选错了面,沉头会打到反面去。解决办法是明确指定faces(">Z")这类选择器,不要依赖默认。

第二个坑是抽壳和圆角的顺序。我一开始先抽壳再加圆角,结果圆角把壳体的薄壁切穿了。后来改成先加外部圆角,再抽壳,问题消失。这个顺序和手工建模的经验完全一致。

第三个坑是批量生成时的文件覆盖。循环里如果文件名没带参数,后一个模型会覆盖前一个。建议文件名里带上关键尺寸,比如bracket_L100.step,方便追溯。

6. 这条链路还能怎么扩展

跑通基础链路之后,我试过几个扩展方向。一个是把 GLB 预览接进网页,用 three.js 加载导出的 GLB,用户输入文字后直接在浏览器里看到模型旋转,体验比下载 STEP 再打开软件好得多。热搜里“cad 快速看”的需求,用这种方式就能满足。

另一个方向是和现有 CAD 软件联动。比如把生成的 STEP 导入中望 CAD 或 SolidWorks 做进一步装配,或者用脚本批量替换装配体里的某个零件。热搜里“cad 图纸合并”和“cad 导入 layout 步骤详解”说明很多人有装配和出图的需求,text-to-cad 生成的零件可以作为装配的输入,而不是终点。

最后一个方向是加入约束求解。现在的链路是“描述到尺寸到几何”,还没有处理“这个孔必须和那个轴同心”这类约束关系。如果引入一个轻量约束求解器,就能从“画出来”进化到“画对”。这一步难度不小,但方向是清晰的。

我个人在实际操作中的体会是:text-to-cad 目前最靠谱的用法,不是替代工程师做复杂设计,而是把重复性的、参数化的零件生成自动化。它像一个不知疲倦的建模助手,你给它清晰的规则,它给你稳定的输出。至于那些需要创造性判断的设计决策,还是得人来拍板。把这条边界划清楚,用起来就顺手多了。

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

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

立即咨询