☰
text-to-cad 实战:从自然语言到 STEP 参数化实体建模全链路
2026/10/9 14:43:44 网站建设 项目流程

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

第一次听到 text-to-cad 这个词,很多人脑子里浮现的是"对着电脑说一句话,屏幕上就蹦出一个零件"。这个想象不算离谱,但也不完全准确。text-to-cad 的本质,是把自然语言描述转换成结构化的三维几何数据,最终落地成 CAD 软件能打开、能编辑、能加工的文件格式,比如 STEP、GLB、STL 这些。它解决的核心痛点很朴素:传统建模太慢了。

做过机械设计或者产品结构的人都有体会,画一个带孔的法兰盘,从草图、拉伸、打孔、倒角到出图,熟手也得十几分钟。如果只是要一个概念验证用的粗略模型,这个时间成本高得离谱。text-to-cad 想干的事情,就是把这十几分钟压缩到几十秒——你用文字描述"一个直径 80 毫米、厚 10 毫米、中心有 30 毫米通孔、边缘均布 6 个 8 毫米螺栓孔的圆盘",系统直接吐出对应的三维模型文件。

这里有个关键区分必须说清楚:text-to-cad 生成的不是网格模型,而是参数化实体模型。这两者的差别,决定了它能不能真正进入工程流程。网格模型(比如 STL)本质上是一堆三角面片的集合,你没法直接改它的尺寸参数;而参数化实体(比如 STEP)保留了特征树和尺寸约束,生成之后还能继续在 CAD 里编辑。这就是为什么 STEP 格式在 text-to-cad 领域被反复提及——它是工程可用性的分水岭。

适合关注这个方向的人大致分三类。第一类是产品经理和工业设计师,需要快速把想法变成可视化的三维草模,用于沟通和评审。第二类是机械工程师,想用文字驱动的方式批量生成标准件或者变型件,省掉重复劳动。第三类是开发者和技术爱好者,想搞清楚这背后的技术链路,自己搭一套或者做二次开发。不管你是哪一类,理解 text-to-cad 的能力边界和实现路径,都比盲目追工具更有价值。

2. 拆解 text-to-cad 的技术链路:文字是怎么变成 STEP 文件的

2.1 自然语言理解层:把"人话"翻译成结构化参数

text-to-cad 的第一步,是把一段自由文本解析成机器能处理的参数集合。比如"一个长 100、宽 50、高 20 的长方体,顶面中心有个直径 10 的圆孔",系统需要提取出:基体类型是长方体,尺寸是 100×50×20,特征是顶面中心通孔,孔径 10。这一步通常靠大语言模型(LLM)来完成,因为它擅长从非结构化文本里抽取实体和关系。

但这里有个坑:LLM 输出的参数格式必须严格约束。如果你只是让模型"理解"这段话,它可能给你一段自然语言回复;但你需要的是 JSON 或者类似的结构化数据,字段名、单位、坐标系定义都得固定。实践中常见的做法是设计一套 schema,比如:

{ "base_shape": "box", "dimensions": {"length": 100, "width": 50, "height": 20}, "features": [ {"type": "hole", "face": "top", "position": "center", "diameter": 10, "depth": "through"} ], "unit": "mm" }

这套 schema 的设计质量,直接决定了后面几何生成的成败。字段太粗,表达不了复杂特征;字段太细,LLM 容易填错。我的经验是,先支持最基础的拉伸体、旋转体、孔、倒角这几类特征,把 schema 打磨稳定,再逐步扩展。一上来就想支持曲面放样、扫掠,基本会陷入调试泥潭。

2.2 几何内核层:参数怎么变成真正的三维实体

拿到结构化参数之后,就需要几何内核来干活了。这一步是整个链路里技术门槛最高的部分。常见的开源几何内核有 OpenCASCADE(简称 OCCT),商业的有 Parasolid、ACIS。text-to-cad 项目绝大多数会选择 OpenCASCADE,因为它开源、功能全、对 STEP 格式支持好。

几何内核做的事情,用大白话说就是:根据你给的参数,计算出这个实体的每一个面、每一条边、每一个顶点的精确数学表达。比如一个圆柱孔,内核会生成一个圆柱面方程,并计算出它和长方体顶面的交线。这些计算涉及大量的边界表示(BRep)操作,精度要求极高——差 0.001 毫米,在后续布尔运算里就可能报错。

提示:如果你自己搭 text-to-cad 原型,强烈建议直接用 Python 的cadquery或者build123d库,它们底层封装了 OpenCASCADE,把常见的建模操作抽象成了链式调用,能省掉大量底层调试时间。

2.3 格式导出层:STEP、GLB、STL 各自的分工

模型在内存里建好之后,要导出成文件。这时候不同格式的用途就体现出来了:

格式本质典型用途是否保留参数
STEP边界表示实体工程交换、CAM 加工是(保留 BRep)
STL三角网格3D 打印、快速预览否
GLB三角网格+材质Web 展示、AR/VR否

STEP 是工程领域的通用交换格式,几乎所有 CAD 软件都能读。STL 是 3D 打印的事实标准,但它只有网格,没有特征信息。GLB 则是给网页和移动端展示用的,带材质和光照信息,适合做产品展示页。

导出这一步看似简单,其实有个常见问题:网格精度设置。STL 导出时需要指定弦高偏差(chord tolerance)和角度偏差(angular tolerance),设得太粗,圆孔变成多边形;设得太细,文件体积爆炸。一般 3D 打印场景,弦高设 0.01 到 0.05 毫米比较合适,具体看零件尺寸。

3. 动手搭一个最小可用的 text-to-cad 流程

3.1 环境准备:Python 生态是当前最省事的选择

如果你想快速验证 text-to-cad 的可行性,Python 是目前最现实的起点。核心依赖就两个:一个大语言模型的 API(用来做文本解析),一个几何建模库(用来生成实体)。几何库我推荐cadquery,它的 API 设计比较直观,文档也相对完整。

安装很简单:

pip install cadquery pip install openai

cadquery自带 OpenCASCADE 的绑定,装完就能用。如果你在 Windows 上遇到编译问题,可以考虑用 conda 安装,conda install -c conda-forge cadquery通常更稳。

3.2 文本解析:给大模型一套严格的输出模板

这一步的关键是 prompt 设计。你不能只说"帮我解析这段话",而要给出明确的输出格式要求。我常用的模板大致是这样:

import json from openai import OpenAI client = OpenAI() SYSTEM_PROMPT = """你是一个 CAD 参数解析器。用户会用自然语言描述一个三维零件, 你需要输出严格的 JSON,格式如下: { "base_shape": "box" | "cylinder", "dimensions": {...}, "features": [...], "unit": "mm" } 只输出 JSON,不要任何解释。""" def parse_description(text): response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": text} ], temperature=0 ) return json.loads(response.choices[0].message.content)

temperature=0很重要,它让输出尽量确定,减少随机性。另外,实际使用中一定要加异常处理,因为模型偶尔会输出带 markdown 代码块的 JSON,需要先清洗再解析。

3.3 几何生成:用 cadquery 把参数变成实体

拿到 JSON 之后,就可以调用 cadquery 建模了。下面是一个处理"带孔长方体"的示例:

import cadquery as cq def build_model(params): if params["base_shape"] == "box": d = params["dimensions"] model = cq.Workplane("XY").box(d["length"], d["width"], d["height"]) for feat in params["features"]: if feat["type"] == "hole" and feat["face"] == "top": model = (model.faces(">Z").workplane() .hole(feat["diameter"])) return model raise ValueError("Unsupported shape")

这段代码的逻辑很直白:先建一个长方体,然后选中顶面,在中心打一个通孔。faces(">Z")是 cadquery 的选择器语法,意思是选 Z 方向最靠上的面。这种链式写法比传统 CAD 的 API 友好很多。

3.4 导出与验证:STEP 和 STL 一起出

模型建好之后,导出两种格式:

model.val().exportStep("output.step") model.val().exportStl("output.stl", tolerance=0.01)

导出之后,一定要用 CAD 软件或者在线查看器打开验证。我踩过的坑是:模型在代码里没报错,但导出的 STEP 在某些软件里显示为空,原因是实体没有正确闭合(non-manifold)。这种情况通常出现在布尔运算之后,解决办法是在导出前调用model.val().isValid()检查有效性。

4. 实测中最容易翻车的几个环节

4.1 单位混乱:毫米和米混用导致模型大得离谱

这是新手最常犯的错误。大语言模型在解析时,如果你没说单位,它可能默认按米来理解,结果一个"直径 80"的圆盘变成了直径 80 米。解决办法有两个:一是在 prompt 里强制要求输出单位字段,二是在几何生成前做一次单位归一化,统一转成毫米。

注意:STEP 文件本身不强制单位,但大多数 CAD 软件默认按毫米读取。如果你的模型导出后在软件里尺寸差了 1000 倍,八成就是单位问题。

4.2 特征定位歧义:"中心"到底是哪个中心

"顶面中心有个孔"这句话,人听起来没歧义,但机器需要明确定义。是顶面的几何中心?还是相对于某个基准点的中心?如果零件本身不对称,这两种理解会给出完全不同的结果。实践中,我建议在 schema 里把位置定义成相对于面中心的偏移量,默认 (0, 0),这样既简单又不容易出错。

4.3 布尔运算失败:孔打在了错误的位置

当孔的位置超出了基体范围,或者孔和已有的特征重叠,布尔运算会失败。cadquery 在这种情况下可能不报错,但生成的实体是无效的。我的做法是在每次布尔运算后检查实体有效性:

result = model.cut(hole_solid) if not result.val().isValid(): raise RuntimeError("Boolean operation produced invalid solid")

这个检查会增加一点运行时间,但能帮你快速定位问题,避免错误累积到导出阶段才发现。

4.4 STL 网格精度:圆孔变成六边形

前面提过网格精度的问题,这里再强调一次。默认的 STL 导出参数往往偏粗,一个直径 10 毫米的孔可能只用了 8 个三角面片来近似,看起来就是个多边形。对于需要 3D 打印的零件,这个精度不够。把tolerance设到 0.01 毫米,angularTolerance设到 0.1 弧度,通常能得到比较光滑的曲面,文件体积也在可接受范围内。

5. 从原型到可用:几个值得投入的优化方向

5.1 建立常用零件模板库

如果你的使用场景集中在某几类零件,比如法兰、支架、齿轮坯,与其每次都让大模型从零解析,不如预先定义好模板,让模型只负责填充参数。这样既提高了准确率,又加快了生成速度。模板库可以用 YAML 或者 JSON 维护,每个模板对应一段 cadquery 建模函数。

5.2 加入尺寸合理性校验

大模型有时候会给出物理上不合理的参数,比如孔径大于零件本身。在生成几何之前,加一层校验逻辑,检查关键尺寸之间的关系。比如孔直径必须小于所在面的最小边长,壁厚不能小于某个阈值。这层校验不需要很复杂,但能挡掉大部分明显错误。

5.3 支持多轮修改

真正好用的 text-to-cad 工具,应该支持"在刚才那个模型基础上,把孔改成 4 个"这样的增量修改。实现方式是把上一轮的参数 JSON 保留下来,让大模型基于它做修改,而不是重新解析。这样用户体验会好很多,也更接近真实的建模工作流。

5.4 批量生成与参数扫描

这是 text-to-cad 相比手工建模最大的优势场景。比如你需要生成 20 个不同长度的支架,只需要准备一个参数表,循环调用建模函数即可。配合 Python 的循环和文件命名规则,几分钟就能出一整套模型。这种批量能力在标准件库建设、产品系列化设计中非常实用。

6. 关于格式选择的一些实战体会

回到 STEP、GLB、STL 这三个格式,我在实际项目里的选择逻辑是这样的:只要下游还要做工程处理,一律出 STEP。STEP 保留了完整的边界表示,可以被 SolidWorks、中望 CAD、Fusion 360 等软件读取和继续编辑。如果只是给客户看效果,出 GLB,文件小、加载快、带材质。如果要 3D 打印,出 STL,但记得调精度。

有一个细节值得注意:从 STL 转回 STEP 是很麻烦的,因为网格转实体需要重建曲面,这个过程叫"逆向工程",工具贵且效果不稳定。所以能出 STEP 的时候千万别只出 STL,不然后面想改都改不了。这也是为什么 text-to-cad 项目里,STEP 导出能力是核心竞争力之一。

另外,如果你生成的模型要导入到某些特定软件里,比如中望 CAD 或者浩辰 CAD,建议导出前确认一下 STEP 的版本。AP214 和 AP203 是两个常见版本,前者支持颜色和图层,后者更基础。大多数情况用 AP214 就行,兼容性够好。

7. 我在这条路上踩过的几个坑

第一个坑是过度依赖大模型的几何理解能力。早期我试过让模型直接输出 cadquery 代码,而不是结构化参数。结果模型经常写出语法正确但几何错误的代码,比如把hole()用在了错误的工作平面上。后来改成"模型只负责解析参数,几何生成用固定代码",稳定性大幅提升。这个分工原则很重要:让大模型做它擅长的语义理解,把几何计算交给确定性的代码。

第二个坑是忽略了坐标系定义。不同 CAD 软件对"上"的方向定义不一样,有的 Z 轴向上,有的 Y 轴向上。如果你的模型要跨软件使用,最好在导出前确认坐标系约定,必要时做一次旋转。我遇到过一次模型导入后整个躺倒的情况,排查了半天才发现是坐标系差异。

第三个坑是没有做输入清洗。用户输入的文字里可能带各种奇怪字符、全角标点、甚至换行符,直接丢给大模型会影响解析质量。加一个简单的文本预处理,把全角转半角、去掉多余空白,能明显提升解析成功率。

第四个坑是文件命名和版本管理。批量生成模型的时候,如果命名规则不清晰,很快就会分不清哪个文件对应哪组参数。我的做法是把关键参数编码进文件名,比如flange_D80_t10_hole30_6x8.step,一眼就能看出规格。配合一个简单的 CSV 记录表,追溯起来很方便。

这套流程跑通之后,生成一个中等复杂度的零件大概需要 10 到 30 秒,其中大部分时间花在大模型 API 调用上。如果对速度有要求,可以考虑本地部署小模型做解析,或者把常用描述缓存起来。几何生成本身其实很快,通常不到一秒。

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

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

立即咨询