☰
text-to-cad实战:从自然语言到STEP/URDF/G-code的自动化建模指南
2026/10/26 15:37:45 网站建设 项目流程

CAD 这行当有个老笑话:画图两小时,改图一整天。尤其是做参数化建模、机器人仿真或者机械结构设计的朋友,最烦的往往不是设计本身,而是把脑子里的尺寸关系一遍遍手动敲进软件里。text-to-cad 这个方向,说白了就是让机器替你干这层“翻译”的活——你用自然语言描述一个零件、一个连杆、一个支架,系统直接吐出可用的 CAD 文件,比如 STEP、URDF 或者 G-code。它解决的是从“想法”到“可制造/可仿真模型”之间那段最枯燥的体力劳动,适合机械工程师、机器人开发者、做批量零件生成的程序员,以及被重复建模折磨到想砸键盘的 CAD 老手。

我接触这个方向有一段时间了,从最早用脚本批量改尺寸,到后来尝试用大模型直接生成几何体,中间踩的坑能写满一个笔记本。下面就把我对 text-to-cad 这套东西的理解、实操路径和避坑经验完整拆一遍,尽量说人话,让刚入门的朋友也能照着走一遍。

1. 先搞清楚 text-to-cad 到底在解决什么问题

1.1 传统 CAD 建模的痛点在哪里

传统 CAD 工作流是“人脑理解需求 → 人手操作软件 → 软件生成几何”。这个链条里,人手操作那一段是最大的瓶颈。画一个简单的法兰盘,熟练工也要点几十次鼠标;如果要做一系列尺寸不同、结构相同的零件,比如 20 个不同长度的连杆,那基本就是复制粘贴加改参数的无限循环。更麻烦的是,一旦设计意图变了,比如孔径从 8mm 改成 10mm,所有相关图纸都得手动同步,漏一个就是生产事故。

我见过不少团队用 Excel 表格驱动 CAD,本质上就是想解决这个问题,但配置起来极其繁琐,而且一旦模型复杂一点,表格和几何之间的映射关系就乱成一锅粥。text-to-cad 的思路是把这层映射交给语言模型或者规则引擎,你只需要说“给我一个长 120mm、宽 60mm、厚 8mm 的板,四角各一个 M6 通孔”,系统就自动生成对应的几何体。这背后的核心价值不是“炫技”,而是把工程师从重复劳动里解放出来,让他们专注在真正需要判断力的设计决策上。

1.2 text-to-cad 的三种典型实现路径

目前市面上能见到的 text-to-cad 方案,大致可以分成三类,每类的技术门槛和适用场景差别很大。

第一类是基于模板和参数映射的方案。你预先做好一个参数化模型,把关键尺寸暴露成变量,然后用自然语言解析器把“长 120、宽 60”这样的描述映射到变量上。这类方案最稳,生成的结果完全可控,适合批量生产标准件。缺点是灵活性有限,只能处理预先定义好的结构。

第二类是基于代码生成的方案。系统把自然语言转成 OpenSCAD、CadQuery 或者 build123d 这类代码,再执行代码生成几何体。这类方案灵活度高,能处理比较复杂的逻辑,比如“在圆周上均匀分布 8 个孔”这种带循环的操作。缺点是对模型的代码能力要求高,生成的代码偶尔会跑不通,需要人工修。

第三类是基于深度学习直接生成几何的方案。这类方案用神经网络直接输出点云、网格或者 B-rep 表示,理论上最通用,但实际上目前还很不成熟,生成的几何经常有自交、破面、尺寸不准的问题,工业上基本没法直接用。我个人的建议是,如果你要做实际项目,优先考虑前两类,第三类可以关注但别急着上生产。

1.3 为什么 STEP、URDF、G-code 是三个关键输出格式

text-to-cad 生成的东西最终要落到具体格式上,不同格式对应不同的下游用途,这个必须搞清楚。

STEP是通用 CAD 交换格式,几乎所有主流 CAD 软件都能读,适合做机械设计、出工程图、交给加工厂。它的特点是保留精确的 B-rep 几何,尺寸准确,但文件结构复杂,解析起来比较重。

URDF是机器人领域的事实标准,用来描述机器人的连杆、关节、运动学关系。做 ROS 仿真、CoppeliaSim 导入、运动规划都离不开它。URDF 本身是 XML 格式,几何可以用简单的 box、cylinder、mesh 表示,重点是关节的父子关系和坐标系变换。

G-code是数控加工和 3D 打印的指令格式,本质是一堆运动指令。text-to-cad 生成 G-code 通常意味着系统直接输出了加工路径,跳过了传统 CAM 环节。这个方向目前还比较早期,适合简单的 2.5D 加工或者 FDM 打印。

提示:选输出格式之前先想清楚下游是谁。给加工厂就出 STEP,做机器人仿真就出 URDF,自己打样就出 STL 或 G-code。格式选错,后面全是返工。

2. 核心细节解析:从一句话到三维模型中间发生了什么

2.1 自然语言解析:把“人话”拆成结构化参数

text-to-cad 的第一步永远是把自然语言变成机器能理解的结构化数据。比如“一个直径 50mm、高 30mm 的圆柱,中心有一个直径 10mm 的通孔”,解析后应该得到一个类似这样的结构:

{ "shape": "cylinder", "params": { "diameter": 50, "height": 30 }, "features": [ { "type": "hole", "diameter": 10, "position": "center", "through": true } ] }

这一步的难点在于自然语言本身有歧义。“直径 50”可能指外径也可能指内径,“中心”可能指几何中心也可能指重心。实际做的时候,我建议在提示词里强制要求模型输出结构化 JSON,并且对关键字段做校验。如果模型输出的 JSON 解析失败,就让它重试,重试三次还不行就报错给用户,别硬着头皮往下走。

另一个坑是单位。用户说“长 100”,到底是毫米还是厘米?我的做法是在系统提示里明确默认单位是毫米,并且要求用户如果用了其他单位必须显式说明。这个规则看起来简单,但能避免大量低级错误。

2.2 几何构建:用代码还是用内核

解析出结构化参数之后,下一步是真正生成几何体。这里有两个主流选择:用代码驱动 CAD 内核,或者直接调用几何库。

用代码驱动的典型代表是 CadQuery 和 build123d,它们底层调的是 OpenCASCADE 这个几何内核。你写 Python 代码描述几何,内核负责算出精确的 B-rep。这种方式的优点是几何质量高,能直接导出 STEP,适合做正经的机械零件。缺点是学习曲线陡,而且内核偶尔会出一些奇怪的 bug,比如布尔运算失败、圆角报错。

直接调用几何库的典型代表是 trimesh、numpy-stl 这类,它们操作的是网格,速度快、依赖轻,但精度有限,不适合做需要精确尺寸的零件。我一般用它们做快速预览或者可视化,正式输出还是走 OpenCASCADE 那条路。

如果你要做机器人模型,URDF 的几何通常用简单的 box、cylinder、sphere 就够了,不需要精确的 B-rep。这时候直接用 XML 模板填充参数就行,没必要上重型内核。

2.3 参数校验:别让模型生成一个负半径

这是很多人容易忽略的一步。语言模型生成参数的时候,偶尔会给出物理上不可能的值,比如负半径、零高度、孔比零件还大。如果不做校验,后面几何构建直接崩,报错信息还特别难懂。

我的做法是在参数进入几何构建之前,加一层校验逻辑。对于每个参数,定义它的合法范围,比如半径必须大于 0,高度必须大于 0,孔径必须小于外径。校验不通过就返回明确的错误信息,告诉用户哪个参数有问题、应该是什么范围。这比让 OpenCASCADE 抛一个“Standard_Failure”要友好得多。

另外,参数之间的约束也要检查。比如“在直径 50 的圆盘上打 8 个直径 10 的孔”,孔的总面积不能超过圆盘面积,孔间距不能小于某个最小值。这些约束用简单的几何计算就能搞定,但能挡掉大量无效输入。

2.4 输出格式转换:STEP、URDF、G-code 各自的坑

生成几何之后,导出成目标格式。这一步看起来简单,实际上每个格式都有坑。

STEP 导出的主要问题是坐标系和单位。OpenCASCADE 默认单位是毫米,但有些下游软件默认是米,导入之后模型会大一千倍或者小一千倍。我的做法是在导出时显式设置单位,并且在文件名或者元数据里标注清楚。

URDF 导出的坑主要在关节定义。URDF 要求每个关节有明确的父子连杆、关节类型、旋转轴、位置和姿态。如果 text-to-cad 只生成了几何,没生成运动学关系,那 URDF 是没法用的。做机器人模型的时候,我建议把运动学参数也纳入自然语言描述的范围,比如“连杆 1 和连杆 2 之间是旋转关节,绕 Z 轴旋转,关节位置在连杆 1 的末端”。

G-code 导出的坑最多。G-code 依赖具体的机床和刀具参数,同样的几何,用不同的刀具、不同的进给速度,生成的 G-code 完全不同。text-to-cad 直接生成 G-code 目前只适合非常简单的场景,比如平面切割或者简单的 2.5D 铣削。复杂三维曲面还是老老实实走 CAM 软件。

3. 实操过程:搭一个能跑的 text-to-cad 流水线

3.1 环境准备与工具选型

要搭一套能用的 text-to-cad 流水线,我推荐的技术栈是这样的:

  • 语言模型:用支持结构化输出的模型,能稳定返回 JSON。本地跑还是调 API 看你的数据敏感度和预算。
  • 几何内核:CadQuery 或者 build123d,底层都是 OpenCASCADE,Python 生态好。
  • URDF 处理:直接用 Python 的 XML 库拼字符串,或者用 urdfpy 这类库。
  • G-code 生成:简单的用 Python 手写,复杂的接 CAM 库。
  • Web 框架:FastAPI 或者 Flask,把整个流程包成一个 HTTP 接口。

安装 CadQuery 的时候注意,它依赖 OpenCASCADE 的 Python 绑定,在 Windows 上偶尔会有编译问题。我建议用 conda 装,比 pip 稳。如果只是做 URDF,不需要精确几何,那依赖可以极简,一个 Python 加标准库就够了。

conda create -n text2cad python=3.10 conda activate text2cad conda install -c conda-forge cadquery pip install fastapi uvicorn

3.2 提示词设计与结构化输出

提示词是整套系统的灵魂。我的经验是,提示词里必须包含四样东西:角色定义、输出格式、单位约定、示例。

角色定义让模型知道自己是个 CAD 参数解析器,不是聊天机器人。输出格式强制 JSON,并且给出字段说明。单位约定明确默认毫米。示例给一两个,让模型照着格式来。

下面是我实际用的一段提示词模板:

你是一个 CAD 参数解析器。用户会用自然语言描述一个三维零件,你需要把它解析成 JSON。 输出格式: { "shape": "cylinder | box | sphere | ...", "params": { ... }, "features": [ ... ] } 所有尺寸默认单位是毫米。如果用户指定了其他单位,在 params 里加 "unit" 字段。 示例输入:一个边长 40mm 的立方体 示例输出:{"shape": "box", "params": {"length": 40, "width": 40, "height": 40}, "features": []} 现在解析:{user_input}

实测下来,加了示例之后,模型输出格式的稳定性能提升一大截。另外,温度参数建议调低,0.1 到 0.3 之间,太高了模型会自由发挥,输出一些奇怪的形状。

3.3 几何生成代码的编写要点

拿到结构化参数之后,用 CadQuery 生成几何。下面是一个生成带孔圆柱的完整示例:

import cadquery as cq def build_cylinder(diameter, height, hole_diameter=None): result = cq.Workplane("XY").circle(diameter / 2).extrude(height) if hole_diameter: result = result.faces(">Z").workplane().hole(hole_diameter) return result # 生成并导出 model = build_cylinder(50, 30, 10) cq.exporters.export(model, "output.step")

这段代码看起来简单,但有几个细节要注意。faces(">Z")是选 Z 方向最高的那个面,hole()默认是通孔。如果要做盲孔,得用cboreHole或者手动切。导出 STEP 的时候,CadQuery 默认单位是毫米,一般不用改。

如果要做一系列零件,把上面的函数参数化,外面套一个循环,就能批量生成。我做过一个项目,用这种方式一次生成 200 多个不同尺寸的支架,每个导出 STEP,总共花了不到两分钟。手动画的话,两天都画不完。

3.4 URDF 生成与 CoppeliaSim 导入实操

做机器人模型的时候,URDF 是绕不开的。text-to-cad 生成 URDF 的关键是把几何和运动学关系都描述清楚。下面是一个两连杆机械臂的 URDF 示例:

<robot name="two_link_arm"> <link name="base_link"> <visual> <geometry> <cylinder radius="0.05" length="0.1"/> </geometry> </visual> </link> <link name="link1"> <visual> <geometry> <box size="0.3 0.05 0.05"/> </geometry> </visual> </link> <joint name="joint1" type="revolute"> <parent link="base_link"/> <child link="link1"/> <origin xyz="0 0 0.1" rpy="0 0 0"/> <axis xyz="0 0 1"/> <limit lower="-3.14" upper="3.14" effort="10" velocity="1"/> </joint> </robot>

生成 URDF 的时候,单位是米,不是毫米,这个一定要记住。我见过太多人因为单位搞错,导入 CoppeliaSim 之后模型要么大得看不见,要么小成一个点。

导入 CoppeliaSim 的步骤是:先确保 URDF 文件和相关 mesh 文件放在同一个目录,然后在 CoppeliaSim 里用Plugins → URDF import选择文件。如果模型显示不出来,先检查单位,再检查 mesh 路径是不是相对路径。CoppeliaSim 对绝对路径支持不好,尽量用相对路径。

3.5 G-code 生成的简化路径

G-code 这块我只建议做简单场景。比如你要切一块 100mm × 80mm 的板,中间挖一个直径 30mm 的圆,G-code 可以这样生成:

def generate_gcode_circle(cx, cy, radius, feed=300): lines = ["G21", "G90", "G17"] lines.append(f"G0 X{cx + radius} Y{cy}") lines.append("G1 Z-1 F100") # 用多段直线逼近圆 import math steps = 72 for i in range(1, steps + 1): angle = 2 * math.pi * i / steps x = cx + radius * math.cos(angle) y = cy + radius * math.sin(angle) lines.append(f"G1 X{x:.3f} Y{y:.3f} F{feed}") lines.append("G0 Z5") return "\n".join(lines)

这段代码生成的是用直线逼近圆的路径,精度取决于步数。72 步对于一般加工够用了,要求高就加到 360 步。注意 G-code 里的坐标是机床坐标系,跟 CAD 坐标系可能不一样,实际用之前一定要在仿真软件里跑一遍。

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

4.1 模型生成失败或几何异常

这是最常见的问题,表现是代码跑通了但导出的模型是空的、破面的、或者尺寸完全不对。排查思路按这个顺序来:

先检查参数。把解析出来的 JSON 打印出来,看看数值是不是合理。负半径、零高度、孔比零件大,这些都会导致几何构建失败。

再检查布尔运算。OpenCASCADE 的布尔运算偶尔会失败,尤其是圆角和孔相交的时候。如果报错,试着调整运算顺序,或者把复杂特征拆成多步。

最后检查导出。有时候几何是好的,但导出 STEP 的时候坐标系有问题。用 CAD 软件打开导出的文件,看看模型在不在原点附近,尺寸对不对。

问题现象可能原因解决方法
模型为空参数为负或零加参数校验,拒绝非法值
破面布尔运算失败调整运算顺序,简化特征
尺寸差 1000 倍单位不一致导出时显式设置单位
导入 CoppeliaSim 不显示mesh 路径错误用相对路径,检查文件位置
G-code 跑飞坐标系不匹配在仿真软件里先验证

4.2 自然语言歧义导致的错误

用户说“打一个孔”,没说孔径,模型可能瞎猜一个值。用户说“在边上”,没说哪条边,模型可能选错。这类问题的根本解法是在提示词里要求模型遇到不确定的信息时主动追问,而不是瞎猜。

我的做法是在 JSON 输出里加一个"clarification_needed"字段,如果模型觉得信息不足,就把这个字段设为 true,并列出需要补充的信息。前端拿到这个响应之后,弹个框让用户补充。这样虽然多一轮交互,但能避免大量错误。

另一个技巧是给常见术语建立同义词表。比如“通孔”和“贯穿孔”是一个意思,“沉头孔”和“埋头孔”是一个意思。解析之前先做一轮术语归一化,能减少模型的困惑。

4.3 批量生成时的性能问题

批量生成几百个零件的时候,如果每个都重新启动一次几何内核,速度会非常慢。我的优化经验是:把几何内核的初始化放在进程启动时做一次,后面所有生成请求复用同一个内核实例。CadQuery 支持这种用法,能省掉大量重复初始化时间。

另外,导出 STEP 是 IO 密集型操作,可以用多线程并行。但注意 OpenCASCADE 不是线程安全的,多线程导出的时候每个线程要有自己的内核实例,或者加锁串行化。我一般用进程池而不是线程池,每个进程独立的内核,互不干扰。

如果生成量特别大,建议加一个任务队列,把生成请求排队处理,避免一次性把内存打满。生成结果存到对象存储或者本地磁盘,前端通过任务 ID 查询进度和下载结果。

4.4 踩过的坑与独家避坑技巧

说几个我实际踩过的坑,都是文档里不会写的。

第一个坑是浮点数精度。自然语言里说“直径 33.33”,解析成浮点数之后,几何内核算出来的圆可能不是完美的圆,导出 STEP 之后有些软件会报“非流形”警告。我的做法是对关键尺寸做圆整,保留两位小数,避免无限小数。

第二个坑是中文单位混用。用户可能说“长 10 公分”,也可能说“长 10cm”,还可能说“长 100mm”。解析的时候要把这些统一成毫米。我维护了一个单位换算表,公分、厘米、cm、毫米、mm、米、m 都覆盖到,解析时先做单位归一化。

第三个坑是 URDF 的惯性矩阵。做机器人仿真的时候,URDF 里如果不定义惯性矩阵,CoppeliaSim 会用默认值,导致动力学仿真结果完全不对。text-to-cad 生成 URDF 的时候,最好根据几何形状和假设的密度自动算一个惯性矩阵填进去。圆柱的惯性矩阵有现成公式,直接套就行。

第四个坑是 G-code 的进给速度。生成的 G-code 如果不指定进给速度,机床可能用默认值,要么太慢效率低,要么太快撞刀。我的做法是根据材料和刀具给一个保守的默认值,并且在注释里标明,让操作员自己调。

5. 扩展方向:text-to-cad 还能怎么玩

5.1 结合参数化模板做批量定制

text-to-cad 最有价值的场景之一是批量定制。比如做家具设计,客户给一堆尺寸需求,系统自动生成对应的柜体模型。这时候不需要模型从零理解自然语言,而是预先做好参数化模板,模型只负责把需求映射到模板参数上。这样生成的结果质量稳定,速度也快。

我做过一个类似的实验:预先用 CadQuery 写好一个参数化的置物架模型,暴露宽度、高度、层数、板厚四个参数。然后用语言模型解析客户的自然语言需求,映射到这四个参数上,批量生成 STEP 文件。整个过程从需求到成品文件,一个置物架不到 10 秒。

5.2 与仿真流程打通

生成的 URDF 可以直接喂给仿真环境,做运动学验证。更进一步,可以把仿真结果反馈回生成环节,形成闭环。比如生成的机械臂模型在仿真里发现关节会自碰撞,系统自动调整连杆长度或者关节限位,重新生成。这个方向目前还在探索阶段,但潜力很大。

5.3 从 CAD 到 CAM 的自动化

G-code 生成是 text-to-cad 往制造端延伸的关键一步。目前的做法还比较粗糙,主要是简单路径生成。未来如果能结合工艺知识库,根据材料、刀具、机床自动生成合理的加工策略,那价值就大了。不过这块涉及的知识面很广,不是单纯的语言模型能搞定的,需要跟 CAM 软件深度集成。

5.4 反向:从 CAD 到文本

text-to-cad 的反向操作也很有意思:给一个 CAD 模型,自动生成它的自然语言描述。这个在图纸管理、模型检索、无障碍访问等场景都有用。实现思路是用几何分析提取特征,再用语言模型组织成描述。目前精度还一般,但作为辅助工具已经能用了。

我个人在实际操作中的体会是,text-to-cad 这套东西目前最适合的场景是“结构相对固定、参数变化频繁”的零件生成。如果你的设计每次都是全新的拓扑结构,那语言模型帮不上太多忙,还是得人工画。但如果你的设计是在一个模板上改尺寸、改数量、改布局,那 text-to-cad 能省掉你 80% 的重复劳动。最后再分享一个小技巧:生成 STEP 的时候,文件名里带上关键参数,比如bracket_L120_W60_H8.step,后面检索和版本管理会方便很多,这个习惯我坚持了两年,省了无数次翻文件夹的时间。

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

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

立即咨询