尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

text-to-cad 实战:从自然语言到 STEP 参数化建模全链路

text-to-cad 实战:从自然语言到 STEP 参数化建模全链路 1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80x60x20 的法兰盘中心开 30 的通孔四角各一个 M6 沉头孔”然后屏幕上直接出现一个可以导出 STEP 的实体模型。这个画面在几年前还属于科幻范畴但现在它已经是一条能跑通的技术链路了。text-to-cad 本质上是一套把自然语言描述翻译成参数化 CAD 几何的生成流程最终产物通常是 STEP、GLB 或 STL 这类通用三维格式。它要解决的核心痛点很明确传统 CAD 建模门槛高、重复劳动多一个标准件可能要画十几分钟而用文字描述只需要几秒钟。我接触这个方向是因为手头有一批非标零件需要快速出模型给下游做仿真。以前的做法是打开 CAD 软件拉伸、打孔、倒角一步步来几十个零件下来人都麻了。后来我开始研究怎么用代码和语言模型把这段流程自动化踩了不少坑也总结出一套相对稳定的做法。这篇文章适合三类人看一是想了解 text-to-cad 技术原理的工程师二是想自己动手搭一套生成流程的开发者三是做机械设计、工业设计、3D 打印相关工作的从业者想看看这个方向能不能落到自己的实际业务里。需要先说明一点text-to-cad 目前不是一个开箱即用的成熟商业软件它更像是一种技术范式由大语言模型、几何内核、参数化脚本三部分拼起来。不同团队实现方式差异很大有的走“LLM 生成 CadQuery 代码”的路线有的走“LLM 输出 JSON 参数再喂给模板”的路线还有的用扩散模型直接生成网格。下面我会把这几条路线的取舍、核心实现细节、实操步骤和踩坑经验都摊开讲清楚。2. 技术路线选型为什么大多数人最终选了“代码生成”这条路2.1 三条主流路线的对比与取舍text-to-cad 的实现方式我大致归为三类。第一类是代码生成路线让大语言模型把自然语言翻译成 CadQuery、OpenSCAD 或 build123d 这类参数化建模脚本再执行脚本得到实体最后导出 STEP。第二类是参数填充路线预先做好一批参数化模板比如法兰、齿轮、支架模型只负责从文字里抽取尺寸和特征填进模板。第三类是直接生成路线用扩散模型或神经场直接输出网格顶点得到 STL 或 GLB。这三条路线的差异我用一个表格说清楚路线代表工具输出格式精度可编辑性实现难度代码生成CadQuery LLMSTEP/STL高精确到微米强脚本可改中参数填充自建模板库STEP高中受模板限制低直接生成扩散模型STL/GLB低网格粗糙弱难参数化高我自己最终选了代码生成路线原因很实际。参数填充路线虽然稳但模板覆盖不了非标件一旦遇到没见过的形状就歇菜。直接生成路线看着酷但出来的网格面数爆炸、尺寸不准拿去 3D 打印还行拿去加工或者做仿真根本没法用。代码生成路线的好处是几何精度由几何内核保证LLM 只负责写脚本写错了还能人工改改完就是标准 STEP 文件下游 CAD 软件全能打开。提示如果你只是想做 3D 打印的摆件直接生成路线够用但只要涉及配合尺寸、装配、加工必须走代码生成或参数填充网格模型的精度撑不住。2.2 为什么 STEP 是绕不开的交付格式热词里出现了 STEP、GLB、STL 三个格式这里必须掰扯清楚它们的定位。STL 是三角网格只有表面没有拓扑尺寸精度取决于网格密度适合 3D 打印和渲染但不适合做参数化编辑。GLB 是 glTF 的二进制版本主打轻量化和 Web 展示带材质和动画适合做产品预览页面。STEP 是真正的边界表示B-rep实体格式保留了面、边、顶点的拓扑关系任何主流 CAD 软件都能打开并继续编辑。text-to-cad 的完整链路我建议是LLM 生成脚本 → 几何内核执行 → 导出 STEP 作为主交付 → 按需转 STL 或 GLB。STEP 是源头STL 和 GLB 是派生物。很多人一上来就想直接生成 STL结果发现改一个孔位要重新生成整个网格效率极低。而 STEP 模型在 CAD 里改一个尺寸重新导出 STL 只要几秒钟。2.3 几何内核的选择OCCT 几乎是唯一答案代码生成路线里几何内核基本锁定 OpenCASCADE简称 OCCT。CadQuery、build123d、FreeCAD 底层都是它。OCCT 提供了完整的 B-rep 建模能力布尔运算、倒角、抽壳、放样、扫掠全都有。Python 生态里通过 cadquery 或 OCP 绑定调用。选它的理由很简单开源、跨平台、精度可靠、社区活跃而且导出的 STEP 文件兼容性极好中望 CAD、SolidWorks、Fusion 360 都能正常读取。我试过用 Blender 的 bmesh 做参数化精度和拓扑质量差太多做出来的东西没法当工程件用。也试过用 trimesh 直接操作网格同样卡在精度上。绕了一圈还是回到 OCCT。所以如果你要搭 text-to-cad先把 CadQuery 或 build123d 跑通这是地基。3. 核心实现细节从文字到脚本的关键环节3.1 提示词工程怎么让 LLM 写出能跑的建模脚本这是整个链路里最玄学也最关键的一环。LLM 写 CadQuery 代码最常见的翻车方式有三种一是 API 记错比如把Workplane.hole()的参数顺序搞反二是坐标系混乱孔打到了错误的位置三是单位搞错把毫米当厘米。我摸索出来的做法是给模型喂一份精简的 API 参考而不是让它凭记忆写。具体操作上我会在系统提示里固定几件事明确使用 CadQuery 2.x 语法、明确所有尺寸单位为毫米、明确原点在零件底面中心、要求输出完整可执行脚本并附带cq.exporters.export()导出语句。然后给两到三个 few-shot 示例覆盖拉伸、打孔、倒角这几个高频操作。实测下来加了示例之后一次通过率能从三成提到七成以上。# 系统提示里附带的示例片段 import cadquery as cq result ( cq.Workplane(XY) .box(80, 60, 20) # 长宽高单位 mm .faces(Z).workplane() .hole(30) # 中心通孔 .faces(Z).workplane() .rect(60, 40, forConstructionTrue) .vertices().cboreHole(6, 12, 6) # M6 沉头孔 ) cq.exporters.export(result, flange.step)注意不要指望 LLM 一次写对复杂零件。我的做法是让它先写简单版本跑通后再逐步加特征。一次要求太多特征出错概率指数上升。3.2 参数抽取从模糊描述里抠出精确尺寸用户说“一个大一点的圆盘”这个“大一点”到底是多大text-to-cad 必须把模糊语言转成确定数值。我的处理策略是双通道LLM 负责抽取明确出现的数字和特征对于缺失的尺寸走一套默认值规则或者反问用户。比如“圆盘”默认直径 100mm、厚度 10mm如果用户说“小圆盘”就缩到 50mm。这里有个经验让 LLM 输出结构化 JSON 比让它直接写代码更稳。JSON 里放shape、dimensions、features三个字段尺寸缺失就留空由后处理逻辑补默认值。这样即使 LLM 抽错了也能在 JSON 层面拦截和修正不至于直接生成一堆错误代码。{ shape: flange, dimensions: {outer_diameter: 100, thickness: 10, bore: 30}, features: [ {type: through_hole, diameter: 30, position: center}, {type: counterbore, diameter: 6, count: 4, pattern: rectangular} ] }3.3 脚本执行与沙箱安全跑通不可信代码LLM 生成的代码本质上是不可信输入直接exec()跑在主机上有风险。我的做法是放进子进程或者容器里执行限制执行时间和内存禁止网络访问和文件系统写入除了指定的输出目录。CadQuery 本身是纯计算库不涉及网络所以沙箱配置相对简单。用subprocess加超时控制就能挡住大部分问题。执行完还要做几何校验检查生成的实体是不是有效的solid.isValid()、体积是否为正、有没有自相交。我遇到过 LLM 写出布尔运算顺序错误导致实体为空的情况如果不校验直接导出下游拿到一个空 STEP 文件会一脸懵。4. 完整实操流程手把手搭一条可复现的生成链路4.1 环境准备与依赖安装先把基础环境搭起来。Python 3.10 以上CadQuery 用 conda 装最省事因为 OCCT 的二进制依赖在 pip 下偶尔会有兼容问题。conda create -n text2cad python3.10 conda activate text2cad conda install -c conda-forge cadquery pip install openai pydantic装完先验证一下import cadquery as cq box cq.Workplane(XY).box(10, 10, 10) print(box.val().Volume()) # 应该输出 1000.0体积对得上说明几何内核正常。这一步别跳过我见过有人装完直接跑生成结果报错报了半天最后发现是 OCCT 版本冲突。4.2 提示词模板与调用封装把系统提示、few-shot 示例、用户输入拼成一个完整的请求。我用 OpenAI 兼容接口temperature 设 0.2降低随机性。关键是把 API 参考和示例放在系统消息里用户描述放在用户消息里。SYSTEM_PROMPT 你是 CadQuery 建模专家。根据用户描述生成完整可执行的 Python 脚本。 要求 1. 使用 cadquery 2.x 语法单位毫米 2. 原点在零件底面中心 3. 脚本末尾必须导出 STEP 到指定路径 4. 只输出代码不要解释 def build_prompt(user_text): return [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_text} ]4.3 执行、校验与格式转换拿到脚本后写进临时文件子进程执行超时设 30 秒。执行成功就校验实体然后导出 STEP。转 STL 和 GLB 用 CadQuery 自带的导出器或者 trimesh 都行。import subprocess, tempfile, os def run_script(code, out_step): with tempfile.NamedTemporaryFile(w, suffix.py, deleteFalse) as f: f.write(code) path f.name try: r subprocess.run([python, path], capture_outputTrue, timeout30) if r.returncode ! 0: raise RuntimeError(r.stderr.decode()) finally: os.unlink(path) return out_stepSTL 导出时注意设置合适的线性偏差linear deflection和角度偏差angular deflection。偏差太大网格粗糙太小文件巨大。我一般用线性偏差 0.1mm、角度偏差 0.2 弧度兼顾精度和体积。cq.exporters.export(result, part.stl, tolerance0.1, angularTolerance0.2) cq.exporters.export(result, part.glb)4.4 一个完整案例从描述到 STEP 文件假设用户输入“画一个 120x80x15 的安装板四角各一个直径 8 的通孔孔中心距边缘 10mm板中心开一个 40x40 的方孔。”LLM 生成的脚本大致是这样import cadquery as cq plate ( cq.Workplane(XY) .box(120, 80, 15) .faces(Z).workplane() .rect(100, 60, forConstructionTrue) .vertices().hole(8) .faces(Z).workplane() .rect(40, 40).cutThruAll() ) cq.exporters.export(plate, mounting_plate.step)跑完导出的 STEP 文件用中望 CAD 打开尺寸、孔位、方孔全部正确。整个过程从输入文字到拿到文件不到 20 秒。同样的零件手工画熟练工也要五到八分钟。这就是 text-to-cad 的价值所在——把重复性建模变成一次性描述。5. 常见问题与排查技巧实录5.1 生成脚本报错的典型原因我把踩过的坑整理成一张速查表基本覆盖了八成以上的报错报错现象根本原因解决办法AttributeError: no attribute holeAPI 版本不匹配锁定 CadQuery 2.x提示词里写明版本实体体积为 0布尔运算顺序错误检查 cut 和 union 的先后先加后减孔位置偏移坐标系原点理解错误统一约定原点在底面中心提示词强调STEP 打开是空文件导出前实体无效加isValid()校验无效则重新生成尺寸差 10 倍单位混淆提示词强制毫米输出后做量纲检查5.2 精度与网格质量的平衡STL 导出参数是新手最容易忽略的地方。默认参数导出的网格往往面数过多或者过少。面数过多文件几十兆面数过少曲面变成多边形。我的经验是平面特征为主的零件用 0.1mm 线性偏差足够曲面多的零件降到 0.05mm。角度偏差统一 0.2 弧度这个值对圆柱面的细分比较合理。另外STL 是网格格式导出后如果要做 UV 展开或者修复那是另一套流程。热词里提到的“3dsmax 修复 STL 模型的 UV”就是下游环节的事text-to-cad 阶段只要保证几何正确、网格密度合理就行。5.3 批量生成时的稳定性技巧单件生成和批量生成是两回事。批量跑的时候LLM 偶尔会抽风写出语法错误的代码如果不做重试整批就断了。我的做法是失败自动重试三次每次把上一次的错误信息拼回提示词让模型自我修正。实测下来第一次失败第二次成功的比例不低三次之后还失败的基本就是描述本身有歧义需要人工介入。还有一个技巧把常用零件做成缓存。同样的描述第二次请求直接返回缓存结果省 token 也省时间。对于标准件库这种高频重复的场景缓存命中率能到一半以上。6. 落地场景与后续扩展方向text-to-cad 目前最适合的场景我总结为三类。第一类是标准件和非标件的快速出图比如法兰、支架、连接板描述清楚尺寸就能生成省去大量重复建模。第二类是参数化产品配置客户在网页上选尺寸、选孔位后台实时生成 STEP 供下载这在定制家具、钣金加工行业很有价值。第三类是教学和原型验证学生用文字描述几何体立刻看到三维结果理解参数和形状的关系。后续扩展上我觉得有两个方向值得投入。一是多轮对话式建模用户说“把孔改大一点”系统理解上下文后修改脚本重新生成而不是从头再来。二是与仿真链路打通生成的 STEP 直接喂给有限元前处理省去中间格式转换。这两个方向我都试过原型技术上可行工程化还需要打磨。最后分享一个我在实际使用中的体会text-to-cad 不是要取代 CAD 工程师而是把工程师从重复劳动里解放出来。真正复杂的曲面造型、装配关系、工程图标注还是得靠人。但那些“画个板子打几个孔”的活交给它干又快又稳。把省下来的时间花在真正需要判断力的地方这才是这套工具的正确用法。
返回列表