☰
text-to-cad 实战:从自然语言到 STEP/STL/GLB 三维模型生成全链路解析
2026/10/8 19:43:24 网站建设 项目流程

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

第一次听到 "text-to-cad" 这个词,很多人会下意识觉得它是个噱头——用一句话就能生成 CAD 模型?这听起来像是把设计师十几年的功夫一笔勾销。但真正在机械设计、工业建模或者 3D 打印这条线上摸爬滚打过的人,看到这个词的第一反应往往不是怀疑,而是"终于有人来啃这块硬骨头了"。

我做了十多年结构设计和三维建模,日常打交道最多的就是各种格式的模型文件:STEP、STL、GLB、IGES、OBJ。每次接到一个新需求,从脑子里有个模糊的形状,到最终能拿去加工或者打印的文件,中间要经历草图、拉伸、倒角、装配、导出这一长串流程。哪怕只是改一个孔径、挪一个安装位,都得重新打开软件、找到特征树、一层层点进去。text-to-cad 想做的事情,本质上是把"描述"和"几何"之间的那道墙给拆掉——你用自然语言说清楚你要什么,系统直接给你吐出可用的三维模型文件。

这件事的价值不在于"取代设计师",而在于把重复性、模板化的建模劳动压缩掉。举个很实际的例子:做非标设备的朋友经常要画各种支架、法兰、连接件,这些东西结构高度相似,只是尺寸和孔位不同。以前的做法是建一个参数化模板,每次改参数、重新生成、导出。现在如果 text-to-cad 能理解"一个 80x80 的角铝支架,两侧各两个 M6 沉头孔,中心一个 30mm 通孔",直接生成 STEP 文件,那省下来的时间就是实打实的。

关键词里出现的 STEP、GLB、STL 这三个格式,恰好对应了 text-to-cad 输出环节最核心的三条路径。STEP 是工业界的通用交换格式,精度高、带 B-rep 实体信息,适合后续在 SolidWorks、中望 CAD、UG 这些软件里继续编辑;STL 是 3D 打印的通用格式,只有三角面片,没有特征信息,但胜在兼容性无敌;GLB 则是 Web 和 AR/VR 场景的主力,轻量、带材质、能直接在浏览器里渲染。一个成熟的 text-to-cad 工具,必须能根据用户的下游用途,把同一份几何数据导出成不同格式,而不是只给一个"看起来像"的模型。

这篇文章适合谁看?如果你是做机械设计、产品结构、3D 打印服务、或者在做 AI 辅助设计工具开发的,这里面的内容应该能帮你少走不少弯路。如果你只是好奇"文字生成 CAD"到底靠不靠谱,我也会把它的能力边界、常见坑、以及实际能落地的操作流程讲清楚。我不会给你画大饼,只讲我实际试过、踩过、验证过的东西。

2. 文字如何变成几何:text-to-cad 的底层链路拆解

2.1 从自然语言到结构化参数:语义解析这一步决定了上限

text-to-cad 的第一道关卡,是把人话翻译成机器能理解的参数。这一步听起来简单,实际上是最容易翻车的地方。你说"一个圆柱体,直径 50,高 100",这没问题,参数明确。但如果你说"一个差不多拳头大小的圆柱",系统就懵了——"拳头大小"到底是多大?不同的人拳头尺寸差很多。

所以真正能用的 text-to-cad 系统,在语义解析层通常会做几件事。第一,建立领域词表和同义词映射。比如"沉头孔"和"埋头孔"是一回事,"通孔"和"贯穿孔"是一回事,"倒角"和"倒边"在很多场景下指的是同一个操作。第二,做单位推断和默认值填充。如果你没说单位,系统要根据上下文猜是毫米还是英寸;如果你没说壁厚,系统要给一个合理的默认值,而不是直接报错。第三,做约束提取。你说"两个孔对称分布",系统要能理解这是关于中心面的对称约束,而不是随便放两个孔。

我实测过几个开源的 text-to-cad 方案,发现一个规律:凡是语义解析做得粗糙的,后面几何生成再强也白搭。因为参数错了,模型就是错的,精度再高也没用。反过来,如果语义解析能把用户的模糊描述补全成一套完整的参数集,哪怕几何生成用的是比较基础的建模内核,出来的东西至少是可用的。

这里有个很实用的经验:如果你在开发或者使用 text-to-cad 工具,一定要在语义解析层加一个"参数确认"环节。系统解析完你的描述后,先把提取到的参数列出来让你确认,比如"检测到以下参数:长度 80mm、宽度 80mm、孔径 6mm、孔数 4、沉头角度 90 度,是否正确?"这一步看似多余,实际上能挡掉后面 80% 的返工。

2.2 参数化建模内核:为什么 OpenCASCADE 是绕不开的选择

语义解析出参数之后,下一步就是把这些参数变成真正的三维几何。这一步需要一个建模内核,而在这个领域,OpenCASCADE 几乎是开源方案里唯一能打的选择。

OpenCASCADE 是一套开源的 B-rep 建模内核,支持实体建模、布尔运算、倒角、抽壳、放样这些 CAD 核心操作。它的优势在于成熟、稳定、文档相对齐全,而且能直接导出 STEP 格式。你在 FreeCAD、KiCad 的 3D 查看器、以及很多工业软件里看到的建模能力,底层都是 OpenCASCADE 在撑着。

但 OpenCASCADE 有个很现实的问题:学习曲线陡峭。它的 API 设计是典型的 C++ 风格,对象生命周期管理、异常处理、坐标系变换这些都需要花时间啃。如果你只是想快速验证 text-to-cad 的想法,直接用 OpenCASCADE 可能会被它的复杂度劝退。

我的建议是分两条路走。如果你要做的是工业级、需要精确 B-rep 实体的应用,那 OpenCASCADE 是绕不开的,老老实实啃文档、写测试用例。如果你只是想快速出原型、验证语义到几何的映射逻辑,可以先用 Python 的 cadquery 或者 build123d 这类高层封装库。cadquery 底层也是 OpenCASCADE,但 API 友好很多,写起来像在写脚本:

import cadquery as cq result = (cq.Workplane("XY") .box(80, 80, 10) .faces(">Z").workplane() .hole(30) .faces(">Z").workplane() .rect(60, 60, forConstruction=True) .vertices().cboreHole(6, 12, 6) ) cq.exporters.export(result, "bracket.step")

这段代码做的事情就是:创建一个 80x80x10 的方块,中心打一个 30mm 通孔,四角打四个 M6 沉头孔,最后导出 STEP。如果 text-to-cad 系统能把自然语言解析成这样的参数化脚本,那整个链路就通了。

2.3 网格化与格式转换:STL 和 GLB 的生成逻辑

STEP 文件生成之后,如果你要拿去 3D 打印或者放到网页上展示,还需要转成 STL 或 GLB。这一步的核心操作是网格化——把 B-rep 实体表面离散成三角面片。

网格化的质量直接决定了 STL 文件的可用性。这里有个关键参数叫"线性偏差"和"角度偏差"。线性偏差控制的是曲面被三角面片逼近时的最大误差,角度偏差控制的是相邻面片之间的最大角度变化。这两个值设得越小,网格越精细,文件越大,但形状越接近原始实体。设得太大,圆柱会变成多边形,球体会变成多面体,打印出来就是一层层的棱角。

我一般给 3D 打印用户的建议是:线性偏差设 0.01mm 到 0.05mm,角度偏差设 5 到 10 度。这个范围能在文件大小和精度之间取得比较好的平衡。如果是大尺寸模型,比如 300mm 以上的零件,线性偏差可以放宽到 0.1mm,否则文件会大到切片软件都打不开。

GLB 的生成逻辑稍微不同。GLB 是 glTF 的二进制版本,它需要的不只是几何,还有材质、法线、UV 坐标这些渲染相关的信息。从 STEP 转 GLB,通常要经过 STL 或者 OBJ 作为中间格式,然后再用 trimesh、assimp 这类库做转换。这里有个坑:STEP 里的颜色和材质信息在转网格的过程中很容易丢失,如果你需要保留外观,得在转换前把材质信息单独提取出来,转换后再重新绑定。

3. 格式选型实战:STEP、STL、GLB 到底该用哪个

3.1 STEP 的不可替代性:为什么工业场景必须用它

在 text-to-cad 的输出环节,STEP 是唯一能保留完整 B-rep 实体信息的格式。这意味着什么?意味着你拿到 STEP 文件之后,可以在 SolidWorks 里打开它,看到完整的特征树,能继续倒角、打孔、做装配。而 STL 和 GLB 做不到这一点,它们只有三角面片,没有特征信息,你没法在 STL 上"把孔径从 6mm 改成 8mm",只能重新建模。

我遇到过很多次这种情况:客户发来一个 STL 文件说"把这个孔改大一点",我只能苦笑。STL 改孔,本质上是在网格上重新挖洞、补面,操作起来极其麻烦,而且精度很难保证。如果当初给的是 STEP,改孔就是几秒钟的事情。

所以 text-to-cad 系统如果面向的是工业设计、机械制造、模具这些场景,STEP 必须是默认输出格式。STL 和 GLB 只能作为辅助格式,用于预览、打印或者展示。

但 STEP 也有它的麻烦之处。STEP 文件体积通常比 STL 大,传输和存储成本更高。而且不同软件对 STEP 的兼容性有差异,有时候在 SolidWorks 里打开正常的 STEP,到中望 CAD 里就报错。这通常是因为 STEP 的版本不同,或者建模内核的容差设置不一致。我的经验是,导出 STEP 时尽量用 AP214 或者 AP242 协议,这两个版本的兼容性最好。

3.2 STL 的精度陷阱:为什么你的打印件总是有棱角

STL 是 3D 打印领域的事实标准,几乎所有的切片软件都支持。但 STL 的精度问题,是新手最容易踩的坑。

前面提到过,STL 是三角面片网格,曲面的精度取决于网格密度。如果你在 text-to-cad 系统里生成 STL 时没有正确设置网格参数,出来的圆柱可能只有 12 个面,打印出来就是一个十二边形,而不是圆。这个问题在打印小尺寸零件时特别明显,因为切片软件会进一步放大网格的缺陷。

我自己的做法是,在 text-to-cad 的导出环节,给 STL 设置一个基于模型尺寸的自适应网格策略。具体来说,线性偏差取模型包围盒对角线的 0.1% 到 0.5%,角度偏差取 5 到 15 度。这样小模型自动获得高精度,大模型不会因为网格过密而文件爆炸。

还有一个容易被忽略的点:STL 文件没有单位。STL 的坐标值就是纯数字,切片软件默认按毫米处理。如果你的 text-to-cad 系统内部用的是米或者英寸,导出 STL 时一定要做单位换算,否则打印出来的尺寸会差 25.4 倍或者 1000 倍。这个坑我见过太多次了,每次都是打印到一半才发现尺寸不对,浪费材料和时间。

3.3 GLB 的轻量化优势:网页展示和 AR 预览的首选

GLB 在 text-to-cad 的输出场景里,主要承担的是"展示"和"交互"的角色。它的优势很明显:文件小、加载快、支持材质和动画、浏览器原生支持。如果你要把生成的模型嵌入到网页里让客户旋转查看,或者放到 AR 应用里做预览,GLB 是最合适的选择。

但 GLB 的几何精度通常不如 STEP 和 STL。因为 GLB 面向的是实时渲染,面片数量需要控制,太精细的网格会导致帧率下降。所以从 STEP 转 GLB 时,通常会有意识地降低网格密度,牺牲一点精度换取流畅的交互体验。

这里有个实操建议:如果你的 text-to-cad 系统要同时输出 STEP、STL、GLB 三种格式,不要用同一条网格化流水线。STEP 直接导出,STL 用高精度网格,GLB 用低精度网格加材质。这样每种格式都能发挥它的优势,而不是互相将就。

格式核心用途精度文件大小可编辑性推荐场景
STEP工业交换最高(B-rep)中等完整特征机械设计、模具、后续编辑
STL3D 打印取决于网格较大无特征切片打印、快速原型
GLB网页/AR 展示中等最小无特征在线预览、AR 交互、展示

4. 把 text-to-cad 跑起来:从环境搭建到第一个模型

4.1 环境准备:Python 生态是最快路径

如果你要自己搭一套 text-to-cad 的验证环境,Python 是目前最省事的选择。cadquery 和 build123d 这两个库把 OpenCASCADE 的复杂度封装掉了大半,让你能用比较直观的方式描述几何。

安装 cadquery 很简单:

pip install cadquery

但这里有个坑:cadquery 依赖 OpenCASCADE 的二进制库,在 Windows 上通常没问题,在 Linux 上可能需要额外装一些系统依赖,比如 libgl1、libglu1-mesa 这些。如果你用 Docker,建议基于 python:3.10-slim 镜像,然后手动装依赖,不要用 alpine 镜像,因为 OpenCASCADE 在 musl libc 上编译很麻烦。

装完之后,跑一个最简单的测试:

import cadquery as cq # 创建一个 50x50x50 的立方体 box = cq.Workplane("XY").box(50, 50, 50) # 导出 STEP cq.exporters.export(box, "test.step") # 导出 STL,设置网格精度 cq.exporters.export(box, "test.stl", tolerance=0.01, angularTolerance=0.1)

如果这两行导出都成功了,说明环境没问题。接下来就可以把自然语言解析的结果映射到 cadquery 的 API 调用上。

4.2 语义到代码的映射:一个可落地的实现思路

text-to-cad 的核心难点在于,自然语言的表达方式太多了,而 cadquery 的 API 是固定的。你需要一个中间层,把"在四个角打 M6 沉头孔"这种描述,翻译成.vertices().cboreHole(6, 12, 6)这样的调用。

我的做法是定义一个 JSON schema 来描述几何特征,然后写一个解释器把 JSON 转成 cadquery 代码。比如:

{ "type": "box", "length": 80, "width": 80, "height": 10, "features": [ { "type": "hole", "position": "center", "diameter": 30, "through": true }, { "type": "cbore_hole", "position": "corners", "diameter": 6, "cbore_diameter": 12, "cbore_depth": 6 } ] }

然后写一个函数,把这个 JSON 转成 cadquery 的链式调用。这样做的好处是,语义解析层只需要负责把自然语言转成这个 JSON,几何生成层只需要负责把 JSON 转成 cadquery 代码,两层解耦,各自可以独立迭代。

实际写的时候,你会发现有些特征用 cadquery 表达很自然,有些则很别扭。比如"阵列"操作,cadquery 有.rarray()和.polarArray(),但如果你要的是沿一条曲线阵列,就得手动计算每个实例的位置。这时候就需要在 JSON schema 里设计更灵活的表达方式,或者在解释器里做特殊处理。

4.3 导出环节的实测参数:STEP、STL、GLB 各怎么设

导出这一步,参数设置直接决定了输出文件能不能用。我把实测下来比较稳的参数列一下。

STEP 导出基本不需要额外参数,cadquery 的export函数默认就是 AP214 协议。如果你需要 AP242,可以指定:

cq.exporters.export(box, "test.step", opt={"write_pcurves": False})

STL 导出需要关注tolerance和angularTolerance两个参数。我的经验值:

  • 小零件(< 50mm):tolerance=0.005,angularTolerance=0.1
  • 中等零件(50-200mm):tolerance=0.02,angularTolerance=0.2
  • 大零件(> 200mm):tolerance=0.1,angularTolerance=0.3

GLB 导出 cadquery 本身不支持,需要先导出 STL 或 OBJ,然后用 trimesh 转换:

import trimesh mesh = trimesh.load("test.stl") mesh.export("test.glb")

trimesh 会自动处理材质和法线,但如果你需要更精细的控制,比如设置材质颜色、添加环境光,就得用 pygltflib 手动构建 glTF 结构。这一步比较繁琐,建议只在必要时才做。

注意:STL 导出时如果 tolerance 设得太小,文件会急剧膨胀。我见过一个 100mm 的零件,tolerance 设成 0.001,STL 文件超过 200MB,切片软件直接卡死。所以精度和文件大小之间一定要做权衡。

5. 踩坑记录:text-to-cad 实际落地时最容易翻车的几个地方

5.1 单位混乱:一个让所有尺寸都错位的隐形杀手

单位问题是 text-to-cad 里最隐蔽、也最致命的坑。自然语言里,用户可能说"直径 50",但没说单位。系统默认按毫米处理,但如果用户心里想的是厘米,出来的模型就小了 10 倍。

更麻烦的是,不同格式对单位的处理方式不一样。STEP 文件内部有单位定义,可以明确是毫米还是英寸。STL 没有单位,切片软件默认按毫米。GLB 也没有单位,但 glTF 规范建议用米。如果你在导出时不做换算,同一个模型导出成三种格式,尺寸会完全对不上。

我的解决方案是在系统内部统一用毫米作为基准单位,所有输入都先转成毫米,所有输出也按毫米处理。如果用户明确说了英寸,就在解析层做换算。导出 STL 和 GLB 时,在文件名或者元数据里标注单位,避免后续混淆。

5.2 布尔运算失败:为什么你的模型总是"破面"

布尔运算是 CAD 建模里最常用的操作,也是最容易出问题的操作。两个实体做差集,如果它们的表面有共面、相切或者微小间隙,布尔运算就可能失败,或者产生破面。

在 text-to-cad 场景里,这个问题特别常见。因为用户描述的特征往往是理想化的,比如"在方块中心打一个通孔",但实际建模时,孔的位置可能刚好和方块的某个边对齐,导致布尔运算时出现退化面。

我的应对策略是:在布尔运算之前,先做一次几何清理。具体来说,检查所有实体的容差,确保没有微小边和微小面;如果两个实体有共面,稍微偏移一点,避免完全重合;布尔运算之后,用isValid()检查结果是否有效,如果无效就回退到上一步,调整参数重试。

result = box.cut(hole) if not result.val().isValid(): # 稍微偏移孔的位置,避免共面 hole = hole.translate((0.001, 0, 0)) result = box.cut(hole)

这个 0.001mm 的偏移在视觉上完全看不出来,但能解决大部分布尔运算失败的问题。

5.3 网格化参数不当:STL 文件打不开或者打印失败

STL 文件打不开,通常有两个原因:一是文件太大,切片软件内存不够;二是网格有错误,比如非流形边、法线方向不一致、孔洞。

非流形边是指一条边被超过两个三角面片共享,这在正常的实体网格里不应该出现。如果出现,说明网格化过程中有 bug,或者原始 B-rep 实体本身有问题。法线方向不一致会导致切片软件分不清内外,打印出来的东西是空心的或者错位的。

我的做法是,STL 导出之后,用 trimesh 做一次检查:

import trimesh mesh = trimesh.load("test.stl") print("是否水密:", mesh.is_watertight) print("是否流形:", mesh.is_winding_consistent) print("体积:", mesh.volume)

如果is_watertight是 False,说明网格有孔洞,需要修复。trimesh 提供了fill_holes()方法,但修复效果取决于孔洞的大小和形状。如果孔洞太大,最好回到 B-rep 层面重新检查实体是否有效。

5.4 格式转换丢信息:STEP 转 STL 之后特征全没了

这是很多人第一次用 text-to-cad 时最困惑的地方:明明 STEP 文件里有完整的特征树,转成 STL 之后,所有特征都消失了,只剩下一个网格。

这不是 bug,这是 STL 格式的固有特性。STL 只存储三角面片,不存储特征信息。所以如果你需要后续编辑,一定要保留 STEP 文件,STL 只作为打印或者展示的副本。

同理,STEP 转 GLB 也会丢失特征信息,而且还会丢失 B-rep 的精确曲面,变成三角面片逼近。如果你在网页上展示一个圆柱,放大之后看到的是多边形,这就是网格化的结果。要改善这个问题,只能提高网格密度,但会增加文件大小。

我的建议是,在 text-to-cad 系统里,始终保留一份 STEP 作为"母版",STL 和 GLB 都是从母版派生出来的"副本"。任何修改都回到母版上做,然后重新导出副本。这样能保证数据的一致性和可追溯性。

6. 从能用到好用:text-to-cad 的进阶优化方向

6.1 参数化模板库:让常用结构一键生成

text-to-cad 如果每次都要从零解析自然语言,效率其实不高。更实用的做法是,把常用的结构做成参数化模板,用户只需要填参数,不需要重新描述。

比如法兰、支架、齿轮、轴承座这些标准件,结构是固定的,变化的只是尺寸。你可以预定义一套模板,每个模板对应一组参数。用户说"生成一个 80mm 的法兰",系统直接调用法兰模板,填入 80mm,生成模型。

这样做的好处是,生成速度快、结果稳定、不容易出错。而且模板可以不断积累,覆盖的场景越来越多,系统的实用性就越强。

我在实际项目里,会把模板分成几个层级:基础几何体(方块、圆柱、球)、常用特征(孔、槽、倒角、螺纹)、标准件(法兰、齿轮、轴承)、行业专用件(钣金件、注塑件、型材)。每个层级都有对应的参数 schema 和生成逻辑,上层可以组合下层,形成更复杂的结构。

6.2 自然语言的多轮交互:一次说不清楚就分几次说

单轮的自然语言输入,信息量有限,很难一次把复杂模型描述清楚。更好的方式是支持多轮交互,用户可以先说一个大概,系统生成一个初步模型,然后用户再补充细节,系统增量修改。

比如:

  • 用户:"生成一个 100x100 的底板"
  • 系统:生成 100x100x5 的方块
  • 用户:"四角加 M6 沉头孔"
  • 系统:在四角添加沉头孔
  • 用户:"中心加一个 40mm 的通孔"
  • 系统:在中心添加通孔

这种交互方式更接近人类设计师的工作习惯,也更容易处理复杂模型。实现上,需要系统维护一个"当前模型状态",每次用户输入都基于当前状态做增量修改,而不是重新生成。

6.3 与现有 CAD 软件的集成:不要重复造轮子

text-to-cad 不需要取代 SolidWorks、中望 CAD 这些软件,它更适合作为这些软件的前端或者插件。用户用自然语言快速生成一个初步模型,导出 STEP,然后在专业软件里做精细调整。这样既发挥了 text-to-cad 的速度优势,又保留了专业软件的精度和功能。

集成的技术路径通常有两种:一是通过文件交换,text-to-cad 生成 STEP,用户在 CAD 软件里打开;二是通过 API 直接调用 CAD 软件的建模内核,实时同步。第一种方式简单可靠,适合大多数场景;第二种方式体验更好,但需要 CAD 软件开放 API,实现成本较高。

我目前更推荐第一种方式。STEP 作为工业标准,兼容性足够好,而且用户已经习惯了文件交换的工作流。等 text-to-cad 的能力足够强、用户信任度足够高之后,再考虑深度集成。

6.4 精度与性能的平衡:不是所有场景都需要最高精度

text-to-cad 系统在设计时,很容易陷入"精度越高越好"的误区。但实际上,不同场景对精度的要求差别很大。网页展示用的 GLB,精度差不多就行,重要的是加载快、交互流畅。3D 打印用的 STL,精度要够,但也不能太高,否则文件太大。工业交换用的 STEP,精度必须最高,因为后续还要做加工。

所以系统应该根据输出格式和用途,自动调整精度策略。用户不需要手动设置一堆参数,只需要说"这个模型是用来打印的"或者"这个模型要拿去加工",系统自动选择合适的精度和格式。

我在实际使用中,会把精度策略分成三档:预览级(GLB,低精度)、打印级(STL,中精度)、制造级(STEP,高精度)。用户选择用途,系统自动匹配。这样既降低了使用门槛,又保证了输出质量。

7. 一些实际使用中的体会

text-to-cad 这个概念听起来很未来,但实际用下来,它更像是一个"加速器"而不是"替代品"。它能把从想法到初步模型的时间从几小时压缩到几分钟,但后续的精细调整、装配验证、工艺检查,还是得靠人来做。

我自己的用法是:先用 text-to-cad 快速生成一个概念模型,导出 STEP,然后在 SolidWorks 里打开,基于这个模型做详细设计。这样比从空白草图开始快很多,尤其是对于结构比较规整的零件。

另外,自然语言的描述能力其实很有限。你说"一个好看的支架",系统没法理解"好看"是什么。但你说"一个 L 型支架,竖板 80x60,横板 60x40,厚度 5mm,竖板两个 M6 孔,横板一个 20mm 通孔",系统就能准确生成。所以用 text-to-cad 的关键是学会"像工程师一样描述",把模糊的需求翻译成明确的参数。

最后分享一个小技巧:如果你经常生成类似的结构,把成功的描述保存下来,做成模板或者快捷短语。下次直接调用,比重新描述快得多。我自己的模板库里已经攒了几十个常用描述,覆盖了大部分日常需求,效率提升非常明显。

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

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

立即咨询