资讯动态

text-to-cad 实战:从自然语言到 STEP 与 URDF 的 Python 流水线

发布时间:2026/10/27 21:52:28 来源:尧图企业网站定制
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 “text-to-cad” 这个词很多人脑子里浮现的画面大概是对着电脑敲一行字比如“一个长宽高 100×60×30 毫米、四角带 M4 沉头孔的安装底板”然后软件“唰”地一下吐出一个可以旋转查看的三维模型。这个画面在几年前还属于科幻范畴但现在已经有一批开源项目和商业工具在认真做这件事了。text-to-cad 的核心目标非常直白——把自然语言描述转换成计算机辅助设计CAD能识别的几何数据最终落地成 STEP、STL、URDF 这类标准格式文件让下游的仿真、3D 打印、机器人建模等环节可以直接消费。它解决的问题其实很现实。传统 CAD 建模的门槛不在于“想不出形状”而在于“把想法翻译成软件操作”这一步太耗时。一个熟练的 SolidWorks 或中望 CAD 用户画一个带孔法兰盘可能要十分钟但一个只懂业务、不懂建模的工程师描述这个法兰盘只需要一句话。text-to-cad 想做的就是吃掉这中间的翻译成本。适合关注这个方向的人包括做机器人仿真的工程师需要批量生成 URDF 模型、做参数化设计的机械从业者、研究 LLM 与几何推理交叉领域的技术人以及想用 Python 把设计流程自动化的开发者。需要先泼一盆冷水目前的 text-to-cad 远没有达到“说人话就出精确工程图”的程度。它更擅长生成概念级、结构相对规整的几何体对于复杂曲面、装配约束、公差标注这些真正的工程难点仍然需要人工介入。所以把它定位成“设计流程的加速器”而不是“设计师替代品”心态会稳很多。下面我会从整体架构、核心格式、实操流程到踩坑经验把这条链路完整拆一遍。2. 整体架构与方案选型为什么是 Python STEP URDF 这套组合2.1 三种主流技术路线的取舍逻辑在动手之前得先想清楚“文本怎么变成几何”这件事有哪几条路可走。我梳理下来大致是三类各有各的适用边界。第一类是基于代码生成Code-as-Representation。核心思路是让大模型输出一段建模脚本比如 CadQuery、OpenSCAD 或 build123d 的 Python 代码然后执行这段代码得到几何体。这条路的最大优势是可解释、可复现、可参数化——你拿到的不只是一个模型而是一段能改参数的源码。缺点是模型必须能用代码描述遇到自由曲面就抓瞎。第二类是基于几何原语拼接。让模型输出一系列基本体长方体、圆柱、球的位置、尺寸、旋转再通过布尔运算组合。这条路实现简单但表达能力有限稍微复杂点的形状就拼不出来。第三类是基于隐式表示或神经场直接回归出点云或 SDF。学术味最浓但工程落地最难生成结果往往不可编辑对下游 CAD 流程不友好。我最终选择第一类为主、第二类为辅原因很直接工程场景要的是“能改、能导出、能进仿真”而不是“看起来像”。一段 CadQuery 脚本生成的 STEP 文件可以无缝导入 FreeCAD、中望 CAD 或者任何支持 STEP 的软件还能直接喂给 URDF 导出器做机器人模型。这个链路是通的而神经场那条路目前还断在“如何转成 B-rep”这一步。2.2 为什么锁定 STEP 和 URDF 两个输出格式输出格式的选择直接决定了这个项目能服务哪些下游场景。STEP.step/.stp是 ISO 10303 标准下的三维数据交换格式几乎是所有正经 CAD 软件的“普通话”。你用它导出别人用中望 CAD、SolidWorks、Fusion 360 都能打开而且保留 B-rep 边界表示尺寸精确、可继续编辑。这是给机械设计和 3D 打印准备的。URDFUnified Robot Description Format则是机器人领域的 XML 描述格式描述的是“连杆关节”的树状结构配合可视化网格通常是 STL 或 DAE使用。做机器人仿真的人对这个格式再熟悉不过——导入 CoppeliaSim、Gazebo、PyBullet 都靠它。text-to-cad 如果能直接吐出 URDF意味着你可以用一句话描述一个机械臂的连杆尺寸和关节类型然后立刻在仿真环境里跑起来。这个价值对做机器人快速原型的人来说是巨大的。提示STEP 和 URDF 不是二选一的关系。一个典型的做法是先用 CadQuery 生成实体并导出 STEP同时把同一批几何体导出为 STL 网格再写一个 URDF 文件引用这些网格。这样一套几何数据同时服务设计和仿真两条线。2.3 Python 生态的不可替代性选 Python 几乎是必然的。CadQuery 本身就是 Python 库build123d 也是trimesh 处理网格是 PythonURDF 的解析和生成有 urdfpy、yourdfpy 这些库连调用大模型 API 都是 Python 最顺手。整个链路从“文本解析”到“代码生成”到“几何构建”到“格式导出”可以全部在一个 Python 进程里完成不需要在多个软件之间倒腾文件。更关键的是 Python 让参数化变得自然。比如用户说“生成一个直径 50 毫米、厚度 10 毫米的法兰盘中心孔直径 20 毫米均布 6 个直径 6 毫米的螺栓孔”模型生成的代码里这些数字都是变量用户改一个数字重新执行就能得到新模型。这种“文本→参数→几何”的映射用 Python 表达是最清晰的。3. 核心细节解析文本如何被翻译成可执行的建模代码3.1 提示词工程把模糊描述逼成结构化参数text-to-cad 最容易翻车的地方不是几何构建而是文本理解。用户说“一个大一点的盒子”这个“大一点”到底是多大没有默认单位、没有参照物模型只能瞎猜。所以第一步必须做的是提示词工程把自然语言里的模糊量词逼成结构化参数。我的做法是在系统提示里强制模型输出 JSON字段包括几何类型、尺寸参数、单位、特征列表。比如输入“一个 100x60x30 的底板四角打 M4 孔”期望输出类似{ type: plate, dimensions: {length: 100, width: 60, thickness: 30}, unit: mm, features: [ {type: hole, diameter: 4.5, count: 4, position: corners, inset: 8} ] }注意这里 M4 孔我映射成了直径 4.5 毫米因为 M4 是螺纹公称直径实际过孔要留间隙这是机械常识。模型不一定知道这个所以需要在提示里补充“M 系列螺纹孔按公称直径加 0.5 毫米作为过孔直径”。这类领域知识的注入是 text-to-cad 能不能用于实际工程的分水岭。注意单位缺失是最常见的坑。我现在的策略是——如果用户没写单位默认按毫米处理同时在返回结果里明确标注“已按毫米解释”。如果用户写了“米”或“英寸”必须做单位换算否则导出的 STEP 尺寸会差 25.4 倍这种错误在装配时是灾难性的。3.2 从 JSON 到 CadQuery 代码的映射规则拿到结构化 JSON 之后下一步是把它翻译成 CadQuery 代码。这一步我建议用模板 规则的方式而不是再让大模型自由发挥。原因很简单几何构建代码一旦出错往往不是报错而是静默生成错误形状调试成本极高。用确定性模板能大幅降低不确定性。以底板为例CadQuery 的核心代码大概长这样import cadquery as cq length, width, thickness 100, 60, 30 hole_d, inset 4.5, 8 result ( cq.Workplane(XY) .box(length, width, thickness) .faces(Z) .workplane() .rect(length - 2*inset, width - 2*inset, forConstructionTrue) .vertices() .hole(hole_d) ) cq.exporters.export(result, plate.step)这段代码的逻辑是先在 XY 平面建一个长方体选中顶面在顶面建立一个工作平面画一个比底板小一圈的构造矩形取它的四个顶点作为孔位然后打孔。forConstructionTrue表示这个矩形只是用来定位不参与最终几何。这种“用构造几何定位特征”的写法是 CadQuery 的惯用法比手动算四个角的坐标要可靠得多。3.3 参数校验在生成几何之前拦住错误我踩过最深的坑是模型生成了一个厚度为负数的板CadQuery 直接抛异常整个流程中断。后来我加了一层参数校验在生成代码之前先检查数值合理性。校验规则包括所有尺寸必须为正数孔径不能大于所在面的最小边长孔间距不能小于孔径的 1.5 倍否则孔会连在一起圆角半径不能超过相邻边的一半。这层校验看起来啰嗦但它把大量“几何上不可能”的输入挡在了建模之前用户体验提升非常明显。与其让用户看到一个莫名其妙的 CadQuery 报错不如直接告诉他“你要求的 6 个直径 10 毫米的孔在 40 毫米宽的面上放不下最小需要 60 毫米宽”。4. 实操过程从零搭一条 text-to-cad 流水线4.1 环境准备与依赖安装先把环境搭起来。我用的 Python 3.10太新的版本有些几何库还没跟上。核心依赖是 CadQuery、trimesh、yourdfpy 和 openai或任何兼容的模型接口。python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install cadquery trimesh yourdfpy numpyCadQuery 的安装在某些平台上需要编译 OCP 绑定如果 pip 装不上可以考虑用 condaconda install -c conda-forge cadquery。这一步卡住的人不少尤其是 Windows 上缺 C 构建工具的情况。如果遇到编译错误先装 Visual Studio Build Tools勾选“使用 C 的桌面开发”。提示如果你只是想快速验证想法可以用 CadQuery 的 Docker 镜像省去环境配置的麻烦。但长期开发还是建议本地装调试方便。4.2 文本解析模块的实现文本解析模块的职责是把用户输入变成结构化 JSON。我用的是“系统提示 few-shot 示例”的方式。系统提示里写清楚支持的几何类型、参数命名规范、单位约定然后给三到五个示例覆盖常见场景板、轴、法兰、简单装配。关键技巧是在提示里明确列出“不支持的请求”比如“不支持自由曲面”“不支持装配约束求解”“不支持公差标注”。这样模型遇到超纲请求时会主动说明而不是硬编一个错误的几何出来。我实测下来明确边界比模糊承诺的满意度高得多因为用户知道什么能做、什么不能做预期是清晰的。解析结果拿到后先过一遍 3.3 节的参数校验通过后再进入代码生成。4.3 几何构建与 STEP 导出代码生成模块用 Jinja2 模板每种几何类型一个模板。底板、圆柱、法兰、简单支架这几类覆盖了大部分概念设计需求。生成代码后用exec()执行拿到 CadQuery 的 Workplane 对象然后导出。import cadquery as cq def build_and_export(params, out_path): code render_template(params) # Jinja2 渲染 local_ns {cq: cq} exec(code, local_ns) solid local_ns[result] cq.exporters.export(solid, out_path) return out_path导出 STEP 时有个细节CadQuery 默认导出的 STEP 单位是毫米这符合大多数工程场景。如果你的输入是英寸记得在导出前把几何缩放 25.4 倍或者在 CadQuery 里用cq.Unit做单位转换。我见过有人导出后发现模型大了 25 倍就是因为单位没对齐。4.4 URDF 生成从实体到机器人描述URDF 的生成要复杂一些因为它描述的是“连杆关节”的树结构而不是单个实体。我的做法是让用户用文本描述一个简单的串联机构比如“一个两连杆机械臂第一段长 200 毫米第二段长 150 毫米关节都是旋转关节”。解析后为每个连杆生成一个简单的几何体通常是圆柱或长方体作为可视化网格导出为 STL然后写 URDF 文件引用这些网格并定义关节的原点和轴向。robot namearm link namelink1 visual geometry mesh filenamelink1.stl/ /geometry /visual /link joint namejoint1 typerevolute parent linkbase/ child linklink1/ origin xyz0 0 0.1 rpy0 0 0/ axis xyz0 0 1/ /joint /robot生成后一定要在 CoppeliaSim 或 PyBullet 里加载验证一遍。我遇到过 URDF 里关节原点写错导致机械臂在仿真里直接穿模的情况。URDF 本身不会报错但仿真时会露馅所以验证环节不能省。5. 常见问题与排查技巧实录5.1 几何构建阶段的典型故障问题现象可能原因排查与解决CadQuery 抛ValueError: Null TopoDS布尔运算结果为空通常是孔位超出实体范围检查孔位坐标和实体边界加参数校验导出的 STEP 在 CAD 里打开是空文件导出对象不是实体而是草图或线框确认result是 Workplane 且包含 solid用result.val()检查模型尺寸差 25.4 倍单位混淆英寸当毫米统一在解析阶段转成毫米导出前再确认孔打在了错误的面工作平面选择错误用faces(Z)明确指定方向避免用默认面圆角导致几何失败圆角半径大于相邻边限制圆角半径不超过最短边的一半5.2 文本解析阶段的坑最常见的是模型“自作主张”补充参数。比如用户说“一个法兰盘”没给尺寸模型可能自己编一个直径 100 毫米。这在演示时看着挺好但实际用起来很危险因为用户以为是自己没说的部分被合理默认了结果拿到一个完全不符合预期的模型。我的处理是关键尺寸缺失时必须追问不允许静默默认。只有非关键参数比如倒角大小才允许用默认值并在输出里注明。另一个坑是多义描述。“打几个孔”里的“几个”到底是几个这种必须追问。我现在的策略是维护一个“必须明确”的参数清单缺失就返回追问而不是猜。5.3 URDF 导入仿真环境的注意事项URDF 导入 CoppeliaSim 时最常见的报错是网格文件路径找不到。URDF 里的filename是相对路径相对于 URDF 文件所在目录。如果你把 URDF 和 STL 放在不同目录一定要写对相对路径或者用package://形式需要配置资源路径。还有一个隐蔽的坑STL 网格的坐标系原点。CadQuery 导出的 STL 原点在几何中心还是角落取决于建模时的定位。如果 URDF 里假设原点在连杆一端但 STL 原点在中心装配出来就会错位。我的做法是导出 STL 前统一把几何体平移让原点落在关节连接处这样 URDF 的 origin 写起来最直观。提示PyBullet 加载 URDF 时可以用p.connect(p.GUI)可视化检查比在 CoppeliaSim 里调快得多。先用 PyBullet 验证几何和关节轴向再进 CoppeliaSim 做完整场景。6. 参数化扩展与批量生成思路text-to-cad 真正体现价值的地方不是生成单个模型而是批量生成参数化变体。比如你要做一系列不同长度的支架传统方式是一个个改尺寸重画而用这套流水线你只需要准备一个文本列表或者一个参数表循环调用生成函数即可。lengths [100, 150, 200, 250] for L in lengths: params {type: bracket, length: L, width: 40, thickness: 5} build_and_export(params, fbracket_{L}.step)这种批量能力在机器人仿真里特别有用——你要为不同规格的机械臂生成 URDF或者为强化学习环境生成大量随机尺寸的物体手工建模根本不可能而 text-to-cad 流水线几秒钟就能跑完一批。扩展方向上我建议优先做两件事一是建立几何模板库把常见零件类型板、轴、法兰、支架、齿轮毛坯的模板沉淀下来文本解析只需要匹配到模板并填参数二是接入尺寸约束求解让用户可以用“A 是 B 的两倍”这种相对描述而不是只能给绝对值。这两步做完实用性会上一个台阶。7. 我在实际项目里踩过的几个真实坑说几个文档里不会写、但实际做的时候一定会遇到的教训。第一个是浮点数精度。CadQuery 内部用浮点运算当你做大量布尔运算后偶尔会出现极薄的面或者几乎重合的边导致后续操作失败。我的经验是在关键尺寸上做圆整比如把 33.333333 圆整到 33.33能显著降低几何失败的频率。别小看这个我有一批模型就是因为这个原因随机失败排查了两天才定位到。第二个是大模型的“幻觉尺寸”。你让它生成一个“标准 M8 螺栓”它可能给你一个直径 8 毫米、长度 50 毫米的圆柱但真实 M8 螺栓的头部尺寸、螺纹长度都有标准。如果下游要拿这个模型做装配干涉检查就会出问题。所以涉及标准件时我现在的做法是查表而不是靠模型生成把标准件库作为外部数据源接进来。第三个是导出文件的命名和版本管理。批量生成时如果文件名冲突后面的会覆盖前面的而且没有任何提示。我现在的做法是文件名里带上参数哈希或者时间戳同时在日志里记录每次生成的参数和输出路径方便回溯。这个习惯在调试阶段救过我好几次。最后分享一个提高解析准确率的小技巧让用户用“字段式”描述而不是“散文式”描述。比如与其说“我想要一个大概这么长的板子”不如引导用户填“长度___ 宽度___ 厚度___”。我在界面上做了一个结构化输入框用户填完再拼成文本送给模型解析准确率比纯自由文本高出一大截。text-to-cad 的“text”不一定是自由文本结构化的文本也是文本而且更可靠。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑