☰
text-to-cad实战:从自然语言到STEP模型的参数化生成
2026/10/8 5:41:20 网站建设 项目流程

1. 从一段文字到一张图纸:text-to-cad 到底在解决什么问题

第一次听到 “text-to-cad” 这个词,是在一个做机械设计自动化的群里。有人丢了一张截图,左边是一段自然语言描述——“一个 80x60x10 的底板,四角各开一个 M4 沉头孔,中心挖一个直径 30 的通孔”,右边直接生成了一张带尺寸标注的零件图,还能导出 STEP 文件。当时群里就炸了,做非标设计的朋友说这玩意儿要是靠谱,能省掉一半的重复建模时间。

text-to-cad,直译就是“文本转 CAD”。它的核心逻辑很直接:你用人话描述一个零件或者一个装配体的几何特征、尺寸约束、材料属性,系统把这套自然语言解析成结构化的几何参数,再驱动 CAD 内核生成三维模型,最后输出成通用的 CAD 格式文件。这里的关键词是CAD、STEP、URDF、G-code——它们分别代表了这条链路上不同的输出终点。

为什么这件事值得单独拿出来讲?因为传统 CAD 建模的流程是“人脑理解需求 → 人脑翻译成草图约束 → 手动拉伸切除 → 手动装配”。这个流程里,最耗时的不是软件操作,而是“翻译”和“重复”。一个标准件库里的法兰,改个孔径和孔数,就要重新画一遍;一套非标设备的支架,结构大同小异,只是尺寸不同,也要一个个建。text-to-cad 想干的事,就是把这部分重复劳动交给程序,让人只负责描述需求。

它适合谁?我梳理了一下,大概三类人最用得上。第一类是非标自动化工程师,每天面对大量“长得差不多、尺寸不一样”的零件,用文本模板批量生成能省大量时间。第二类是机器人方向的开发者,需要频繁生成 URDF 模型来做仿真,手写 URDF 的 link 和 joint 几何参数极其痛苦,用文本描述生成就顺很多。第三类是做参数化设计的产品经理或创客,不懂 CAD 软件的操作,但能说清楚自己想要什么形状,text-to-cad 降低了他们表达设计意图的门槛。

但这里要先泼一盆冷水:text-to-cad 不是“说一句话就出一个能直接加工的零件”。它目前的能力边界在于规则明确、特征可参数化的几何体。你让它生成一个“好看的手机壳”,它大概率给你一个方盒子;但你让它生成“一个 100x50x5 的板,上面均布 6 个直径 8 的通孔,孔间距 15”,它能做得又快又准。理解这个边界,后面的实操才不会跑偏。

2. 拆解 text-to-cad 的技术链路:从一句话到 STEP 文件

2.1 自然语言解析层:把“人话”变成“参数”

这一步是整个链路里最容易被低估的环节。很多人以为难点在三维建模,其实真正的坑在“理解”。自然语言描述天然带有歧义和省略。比如“一个带孔的板”,孔在哪?多大?几个?什么类型的孔?如果描述里没写,系统就得猜,猜错了模型就废了。

目前主流的做法有两种。一种是基于规则模板的解析,提前定义好一套语法结构,比如“尺寸 + 特征 + 约束”的句式,用户按模板填内容。这种方式准确率高,但灵活性差,用户必须学会“机器能听懂的话”。另一种是基于大语言模型的语义解析,把自然语言直接映射成结构化的 JSON 参数,再交给几何引擎。这种方式灵活,但存在幻觉问题——模型可能编造一个不存在的尺寸或者误解约束关系。

我在实际测试中的体会是:纯 LLM 解析适合做原型验证,生产环境一定要加一层规则校验。具体做法是,让 LLM 输出一个中间格式的参数字典,然后用一套校验规则去检查——尺寸是否为正数、孔是否在板的范围之内、约束是否矛盾。校验不通过的,要么让 LLM 重新生成,要么直接报错让用户补充描述。这个“LLM + 规则校验”的组合,比单纯依赖任何一方都稳。

还有一个细节:单位。自然语言里说“长 100”,是毫米还是厘米?如果系统不明确单位,生成的模型尺寸可能差 10 倍。我的做法是在解析层强制要求单位,或者在系统提示里写死“所有尺寸默认单位为毫米”,并在输出时显式标注。这个坑我踩过,生成的一个支架比预期大了十倍,导入仿真软件后直接穿模。

2.2 几何建模层:参数如何驱动出三维形状

解析出来的参数,要变成真正的三维几何,中间需要一个几何内核。常见的开源选择有OpenCASCADE(简称 OCCT),商业的有 Parasolid、ACIS。text-to-cad 项目里用 OCCT 的居多,因为它开源、功能全,能处理布尔运算、倒角、抽壳这些常见操作。

这一层的核心工作是特征映射。什么意思?就是把“沉头孔”这个语义,映射成 OCCT 里的一系列操作:先打一个通孔,再在孔口做一个锥形切除。把“均布”映射成一个环形阵列或者线性阵列的操作。把“中心挖通孔”映射成在指定坐标位置做圆柱体布尔减运算。

这里有个经验:特征映射的粒度要适中。太粗了,比如把“带孔板”直接映射成一个固定模板,灵活性就没了;太细了,比如把每个顶点坐标都让 LLM 生成,出错概率极高。我的建议是,把常见零件拆成“基体 + 特征”的组合。基体就是拉伸、旋转这些基本操作,特征是孔、槽、倒角、圆角这些修饰操作。LLM 只需要输出“基体类型 + 尺寸 + 特征列表 + 特征参数”,几何层负责把特征按顺序应用到基体上。

顺序很重要。先打孔再倒角,和先倒角再打孔,结果可能完全不同。所以解析层输出的特征列表必须是有序的,几何层按顺序执行。这个顺序在自然语言里往往没有明确说,需要根据工程常识来推断。比如“一个带倒角的板,上面有孔”,通常理解为先做板,再倒角,最后打孔。如果顺序反了,倒角可能会被孔打断,影响外观和功能。

2.3 格式输出层:STEP、URDF、G-code 各自的门道

模型建好了,输出成什么格式,取决于你要拿它干什么。这三个格式代表了三条不同的下游路径。

STEP是通用三维模型交换格式,几乎所有的 CAD 软件都能打开。它的特点是保留完整的边界表示(B-rep),精度高,适合后续在 SolidWorks、Fusion 360 里继续编辑,或者导入 CAM 软件做加工路径规划。text-to-cad 输出 STEP 时,要注意单位一致性和坐标系对齐。我遇到过导出的 STEP 在另一个软件里打开后方向不对,原因是建模时的坐标系和导出时的坐标系没有统一。解决办法是在建模阶段就约定好:Z 轴朝上,原点在零件底面中心或者一个明确的基准点上。

URDF是机器人领域描述模型的标准格式,全称是 Unified Robot Description Format。它描述的不是一个静态零件,而是一个带关节的装配体。每个 link 有视觉几何、碰撞几何、惯性矩阵,每个 joint 有类型、轴线、限位。text-to-cad 生成 URDF 的难点在于:惯性参数的计算。一个 link 的质量、质心、转动惯量,如果只靠文本描述,很难精确给出。常见的做法是,根据几何形状和指定的材料密度,用程序自动计算。比如一个长方体 link,给定长宽高和密度,转动惯量是有解析公式的,直接算就行。复杂形状可以用网格近似或者体素化来估算。

G-code是数控加工和 3D 打印的指令格式。从 text-to-cad 到 G-code,中间其实还缺了一步:工艺规划。你得决定用什么刀具、走刀路径怎么走、切削参数是多少。目前 text-to-cad 项目直接输出 G-code 的还比较少,更多是输出 STEP 后,再导入切片软件或者 CAM 软件生成。但如果要做闭环,可以在几何层之后加一个简单的工艺规则引擎,比如“通孔用钻孔循环,外形用轮廓铣削”,生成基础的 G-code 框架。这一步的复杂度很高,建议初期先不做,把 STEP 输出做稳。

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

3.1 环境准备与工具选型

要自己搭一个 text-to-cad 的原型,不需要一上来就搞大而全。我的建议是先用 Python 把链路跑通,核心依赖就三个:CadQuery(基于 OCCT 的 Python 建模库)、OpenAI API 或本地 LLM(做语义解析)、FastAPI(做接口服务)。

CadQuery 是我试过对开发者最友好的参数化 CAD 库。它的语法接近自然语言,比如cq.Workplane("XY").box(80, 60, 10).faces(">Z").workplane().hole(30)就能生成一个带中心孔的板。而且它直接支持导出 STEP、STL、DXF 等格式,省去了自己调 OCCT 接口的麻烦。

LLM 的选择看你的预算和网络条件。如果追求效果,用 GPT-4 级别的模型做解析,准确率明显高于小模型。如果考虑成本和数据隐私,可以用本地部署的开源模型,比如 CodeLlama 或者 Qwen 的代码版本,但需要自己写更详细的提示词和校验规则。我实测下来,对于结构清晰的零件描述,7B 级别的模型加上好的提示词,也能达到可用的程度。

FastAPI 负责把整个流程包成一个 HTTP 接口,接收文本描述,返回 STEP 文件的下载链接或者 Base64 编码。这样前端或者其他系统就能方便地调用。

3.2 提示词设计与参数校验

提示词是 text-to-cad 的“灵魂”。写得好,模型输出稳定;写得烂,天天给你编尺寸。我的提示词模板大概长这样:

你是一个 CAD 参数解析器。用户会用自然语言描述一个零件。 你需要输出一个 JSON 对象,包含以下字段: - unit: 单位,固定为 "mm" - base: 基体,包含 type(box/cylinder)、dimensions(长宽高或半径高度) - features: 特征列表,每个特征包含 type(hole/slot/fillet/chamfer)、position(坐标)、parameters(尺寸参数) - material: 材料名称,默认 "steel" 注意: 1. 所有尺寸必须是正数。 2. 孔的位置用相对于基体中心的坐标表示。 3. 如果用户描述模糊,选择最常见的工程默认值,并在 notes 字段说明。 4. 只输出 JSON,不要输出其他内容。

这个模板的关键在于约束输出格式和处理模糊性。我试过不加“只输出 JSON”这句话,模型会在 JSON 前后加一堆解释文字,解析起来很麻烦。加上之后,输出干净很多。

拿到 JSON 之后,必须做校验。我写了一个validate_params函数,检查项包括:尺寸是否为正、孔是否在基体范围内、特征之间是否冲突(比如两个孔重叠)、材料是否在支持列表里。校验不通过的,要么返回错误让用户修改描述,要么触发一次 LLM 重试,把错误信息作为反馈传回去。这个重试机制很管用,能把一部分模糊描述自动修正。

3.3 从参数到模型的代码实现

下面是一个简化的核心代码,展示从 JSON 参数到 CadQuery 模型的过程:

import cadquery as cq def build_model(params): base = params["base"] if base["type"] == "box": l, w, h = base["dimensions"] model = cq.Workplane("XY").box(l, w, h) elif base["type"] == "cylinder": r, h = base["dimensions"] model = cq.Workplane("XY").circle(r).extrude(h) else: raise ValueError("Unsupported base type") for feat in params["features"]: if feat["type"] == "hole": x, y = feat["position"] d = feat["parameters"]["diameter"] model = model.faces(">Z").workplane().center(x, y).hole(d) elif feat["type"] == "fillet": r = feat["parameters"]["radius"] model = model.edges("|Z").fillet(r) # 其他特征类型类似处理 return model def export_step(model, filename): cq.exporters.export(model, filename, exportType="STEP")

这段代码里,faces(">Z")表示选择 Z 方向最高的那个面作为工作平面,center(x, y)把工作平面原点移到指定位置,hole(d)打一个直径 d 的通孔。这些操作都是 CadQuery 的标准用法,文档里有详细说明。

实际项目中,特征的处理要复杂得多。比如沉头孔,需要先打一个通孔,再在孔口做一个锥形切除。CadQuery 里可以用cboreHole或者cskHole直接实现,但需要传入正确的参数。我的做法是,在特征映射层把“沉头孔”翻译成 CadQuery 的cskHole(diameter, cskDiameter, cskAngle),参数从 JSON 里取。

还有一个容易忽略的点:坐标系。CadQuery 默认的 Z 轴是朝上的,但有些 CAD 软件默认 Y 轴朝上。导出 STEP 时,如果下游软件用的是不同的坐标系约定,模型方向就会不对。解决办法是在导出前做一次旋转变换,或者在文档里明确说明坐标系约定。我一般会在生成的 STEP 文件里附带一个 README,写明“Z 轴朝上,原点在底面中心”。

3.4 批量生成与模板化

单个零件生成跑通之后,最有价值的是批量生成。非标设计里,经常有一组零件,结构相同,只是尺寸不同。这时候可以用一个 CSV 或者 Excel 文件,每行是一组参数,循环调用生成函数,批量输出 STEP 文件。

我做过一个测试:一个包含 50 个不同尺寸法兰的列表,用 text-to-cad 批量生成,从解析到导出 STEP,总共花了不到 3 分钟。如果手动建模,一个法兰大概 5 分钟,50 个就是 4 个多小时。这个效率提升是实打实的。

模板化的另一个好处是版本管理。每个零件的描述文本和生成的参数 JSON 都可以存进 Git,改了什么一目了然。传统 CAD 文件是二进制的,diff 起来很痛苦,文本描述就友好多了。

4. 实操中踩过的坑与排查技巧

4.1 常见问题速查表

问题现象可能原因排查方法解决方案
生成的模型尺寸明显不对单位解析错误检查 JSON 里的 unit 字段和数值在提示词里强制单位,校验时检查数值范围
孔的位置偏了坐标系理解不一致对比 JSON 坐标和模型实际位置统一约定原点位置,在提示词里说明
导出 STEP 后打不开文件写入不完整或格式错误用文本编辑器看文件头是否为 ISO-10303检查导出函数的参数,确保 exportType 正确
LLM 输出不是合法 JSON提示词约束不够强打印原始输出看格式加“只输出 JSON”约束,用 JSON 修复库兜底
特征顺序导致模型错误特征列表顺序不对逐步执行特征,看哪一步出错在解析层按工程常识排序,或让用户显式指定
复杂形状生成失败OCCT 布尔运算失败查看异常信息简化形状,分步生成,或换用网格建模

4.2 几个让我印象深刻的坑

第一个坑是“孔打穿了不该打穿的地方”。有一次描述里写“在板上打一个深 5 的孔”,LLM 解析成了通孔,结果把 10 厚的板打穿了。问题出在“深”这个词的歧义——是孔的总深度还是从表面往下的深度?后来我在提示词里明确:如果用户说“深 X”,默认是从表面往下的深度,如果 X 大于板厚,则视为通孔。这个规则写进去之后,类似问题就没再出现。

第二个坑是“倒角把孔口削掉了”。一个零件先打了孔,然后对整个外边缘倒角,结果倒角操作把孔口附近的材料也削掉了一块。原因是倒角选择边的时候,把孔口的边也选进去了。解决办法是在选择边时加过滤条件,只选外轮廓的边,不选内部特征的边。CadQuery 里可以用edges("|Z")选平行于 Z 轴的边,或者用edges("%CIRCLE")排除圆形边。

第三个坑是“URDF 的惯性矩阵不对”。生成 URDF 时,我一开始随便填了一个单位矩阵作为惯性,结果在仿真里机器人一动就飞出去了。后来老老实实根据几何形状和密度计算惯性矩阵,才稳定下来。对于长方体,惯性矩阵是对角阵,对角线元素是m/12 * (h^2 + d^2)这样的公式。这个计算不难,但不能省。

4.3 提升生成成功率的几个技巧

技巧一:给示例。在提示词里放一两个输入输出的例子,LLM 的解析准确率会明显提升。比如给一个“80x60x10 的板,中心打直径 30 的通孔”对应到完整 JSON 的例子,模型就能学会这种映射关系。

技巧二:分步解析。不要指望一次调用就拿到完美的 JSON。可以拆成两步:第一步让 LLM 提取所有尺寸和特征关键词,第二步再让 LLM 把这些关键词组织成结构化参数。两步之间可以加人工确认或者规则校验,降低出错概率。

技巧三:缓存常用零件。对于反复出现的标准件,比如 M4 沉头孔、M6 螺纹孔,可以把它们的参数和对应的 CadQuery 代码缓存起来,下次直接调用,不用再走 LLM 解析。这样既快又稳。

技巧四:可视化预览。生成 STEP 之前,先导出一张 PNG 预览图,让用户确认形状对不对。CadQuery 支持导出 SVG 或者用cq.exporters.export导出 STL 后用其他库渲染。多一步确认,少很多返工。

5. 从 text-to-cad 到实际生产:还差什么

5.1 公差与配合:文本描述难以覆盖的领域

text-to-cad 目前能处理的是理想几何,但实际生产中,公差和配合才是决定零件能不能用的关键。一个孔标注“直径 10”,加工出来可能是 10.02,也可能是 9.98。如果这个孔要和一个轴配合,公差没定好,要么装不进去,要么太松。

自然语言里描述公差很别扭。你可以说“直径 10 的孔,公差 H7”,但 LLM 不一定理解 H7 的含义,也不一定能把它映射成具体的上下偏差。我的做法是,在参数 JSON 里加一个tolerance字段,用标准公差等级表示,然后在几何层不处理公差,只在输出的 STEP 文件里附带一个公差表。下游的 CAM 软件或者加工师傅根据公差表来决定加工精度。

配合的描述更复杂。“轴和孔间隙配合”这种话,需要查表才能确定具体的公差带。目前 text-to-cad 项目很少涉及这一块,更多是生成理想模型,公差由后续工艺保证。如果你要做的是直接驱动机床的项目,公差处理是绕不过去的坎,建议单独做一个公差引擎。

5.2 装配体与运动约束

单个零件生成只是第一步,真正的挑战是装配体。一个机构由多个零件组成,零件之间有装配关系,有的固定,有的可以转动或滑动。用自然语言描述装配关系,比描述单个零件难得多。

比如“一个齿轮箱,输入轴和输出轴平行,中心距 50,齿轮模数 2,齿数比 3:1”。这句话里包含了多个零件的几何参数和它们之间的位置约束。目前的 LLM 能提取出关键词,但很难直接生成完整的装配体模型。

一个可行的路径是:先用 text-to-cad 生成各个零件,再用一个单独的装配描述来定义零件之间的约束。装配描述可以用简化的语法,比如“part A 的孔中心与 part B 的轴中心对齐,距离 50”。然后几何层根据这些约束计算每个零件的变换矩阵,组装成装配体。URDF 天然适合描述这种带关节的装配体,所以机器人领域的 text-to-cad 项目往往直接输出 URDF。

5.3 与现有 CAD 工作流的集成

text-to-cad 生成的文件,最终要融入现有的设计流程。常见的集成方式有三种。

第一种是作为插件。在 SolidWorks、Fusion 360 里装一个插件,输入文本描述,直接在当前文档里生成特征。这种方式用户体验最好,但开发成本高,需要熟悉各个 CAD 软件的 API。

第二种是作为独立服务。text-to-cad 跑在一个服务器上,设计师通过网页或者命令行提交描述,下载 STEP 文件,再手动导入 CAD 软件。这种方式开发简单,适合快速验证。

第三种是作为批处理工具。把 text-to-cad 集成到 CI/CD 流程里,每次设计参数变更,自动生成新的模型文件,推送到版本库。这种方式适合参数化程度高的产品线。

我目前用的是第二种,因为最灵活,不依赖特定 CAD 软件。等流程稳定了,再考虑做插件。

5.4 一个实际案例:批量生成非标支架

最后分享一个我实际做过的案例。需求是为一套自动化设备生成 20 个不同尺寸的 L 型支架。每个支架的底板长宽、立板高度、安装孔位置都不同,但结构完全一样。

传统做法是一个个画,大概需要半天。用 text-to-cad 的做法是:先写一个支架的模板描述,把可变尺寸用占位符表示。然后从 Excel 里读取 20 组参数,循环替换占位符,调用生成函数,批量导出 STEP。整个过程写代码加调试花了两个小时,但生成只用了两分钟。而且以后再有类似需求,改改 Excel 就能复用。

这个案例让我确信,text-to-cad 的价值不在于替代设计师,而在于把设计师从重复劳动里解放出来。它适合处理“结构固定、尺寸变化”的零件,不适合处理“结构创新、形态复杂”的设计。认清这个边界,用对地方,效率提升是实实在在的。

如果你也想试试,我的建议是从一个最简单的零件开始——一块带孔的板。把从描述到 STEP 的链路跑通,再逐步增加特征类型和复杂度。不要一上来就搞装配体,那个坑太深。先把单零件的生成做稳,再考虑扩展。

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

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

立即咨询