ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

text-to-cad 实战:从自然语言到 STEP/STL 的参数化建模流水线

text-to-cad 实战:从自然语言到 STEP/STL 的参数化建模流水线 1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80 毫米见方的法兰盘中心开 30 毫米通孔四角各一个 M6 沉头孔”然后屏幕上直接出现一个可以旋转、可以导出、可以丢进切片软件或者丢进装配体的三维实体。这个画面在几年前还属于“想想就好”但最近一两年随着大模型在代码生成和结构化数据生成上的能力越来越稳这条路已经真的能走通了。text-to-cad直译就是“文本转 CAD”。它的核心逻辑并不神秘把自然语言描述翻译成 CAD 软件能理解的建模指令或者中间格式最终产出一个标准的三维模型文件。这里的关键词是CAD、STEP、GLB、STL。CAD 是目标领域STEP 是精确的边界表示格式GLB 是适合展示和轻量交互的网格格式STL 则是3D打印和快速预览最常用的三角面片格式。这四个词基本覆盖了从“设计”到“展示”再到“制造”的完整链路。它解决的是什么问题说白了就是建模门槛和重复劳动。传统 CAD 建模你得先学草图约束、拉伸切除、旋转阵列一套组合拳下来画个简单的支架可能也要十几分钟。如果是批量改参数、批量生成相似结构那更是体力活。text-to-cad 的思路是你把需求用大白话讲清楚让程序去干那些重复的、有规律的建模动作。适合谁来参考三类人一是经常需要出简单结构件的工程师二是做3D打印但不太会建模的创客三是想把自己产品里的“参数化配置”做成在线工具的开发者。我实测下来这条路目前最稳的落地方式不是让 AI 直接操作 CAD 软件的图形界面而是让它生成建模脚本或者中间几何描述再用成熟的几何内核去执行。下面我就按自己踩过的坑把整套思路拆开讲。2. 整体方案怎么选三条路线和它们的取舍2.1 路线一自然语言转 OpenSCAD 脚本OpenSCAD 是一门基于代码的实体建模语言语法接近编程非常适合让大模型生成。你给它一句描述它输出类似cube([80,80,10]); translate([40,40,0]) cylinder(d30,h10);这样的代码OpenSCAD 引擎负责渲染成实体并导出 STL、STEP 等格式。这条路线最大的好处是可控。生成的代码你可以逐行检查参数错了直接改数字不用重新跟模型对话。而且 OpenSCAD 是纯脚本没有图形界面的状态问题特别适合自动化流水线。缺点是它只支持实体建模曲面和复杂倒角比较吃力做机械零件够用做有机造型就力不从心。2.2 路线二自然语言转 CadQuery 脚本CadQuery 是基于 Python 的 CAD 脚本库底层用的是 OpenCASCADE 几何内核。相比 OpenSCAD它能生成真正的 B-rep 实体导出的 STEP 文件质量更高适合后续做工程分析和精密加工。我个人的偏好是如果最终要 STEP优先选 CadQuery。因为它导出的 STEP 是精确边界表示圆就是圆不是多边形逼近。而 OpenSCAD 导出的 STEP 本质上还是网格转过去的精度会打折扣。CadQuery 的代码结构也更接近工程思维比如Workplane(XY).box(80,80,10).faces(Z).workplane().hole(30)读起来就像在描述加工步骤。2.3 路线三自然语言转中间 JSON再由后端渲染这条路线是把大模型的输出限制在一个自定义的 JSON schema 里比如{ type: box, size: [80,80,10], holes: [...] }然后后端用 Three.js 或者 Python 的 trimesh 去生成 GLB 和 STL。好处是前端展示极其轻量GLB 可以直接在浏览器里转适合做在线配置器。缺点是 JSON schema 要自己设计复杂结构表达起来会越来越臃肿而且导出的 STEP 需要额外走一遍转换。三条路线的对比如下路线输出格式精度适合场景开发难度OpenSCAD 脚本STL、OFF、CSG网格级3D打印、简单结构低CadQuery 脚本STEP、STL、DXFB-rep 精确机械零件、工程图中JSON 中间层GLB、STL网格级在线展示、配置器中高我最后选的是CadQuery 为主、OpenSCAD 为辅的混合方案。简单件走 OpenSCAD 快速出 STL需要 STEP 的走 CadQuery。下面重点讲 CadQuery 这条线因为它的坑最多价值也最大。3. 核心细节拆解从提示词到可执行脚本的关键环节3.1 提示词怎么写才能让模型输出可用的建模代码很多人一上来就写“画一个法兰盘”结果模型返回一段伪代码或者直接给你一段文字描述。问题出在约束不够。我总结了一个提示词模板实测下来成功率能到八成以上你是一个 CAD 脚本生成器。请用 CadQuery 的 Python API 生成一个三维实体。要求只输出 Python 代码不要解释。代码以import cadquery as cq开头。最终结果赋值给变量result。所有尺寸单位为毫米。结构描述一个 80x80x10 的方形底板中心有一个直径 30 的通孔四角各有一个直径 6.5 的通孔孔中心距边缘 10 毫米。这个模板里最关键的是第 3 条和第 5 条。第 3 条保证输出可以被程序直接exec拿到结果第 5 条把几何关系用数字说死避免模型自由发挥。我试过不加第 5 条模型会自己“脑补”一个孔距结果每次生成都不一样根本没法用。3.2 几何内核的选择为什么是 OpenCASCADECadQuery 底层用的是 OpenCASCADE这是一个工业级的几何内核CATIA、SolidWorks 这些软件的内核虽然各有不同但 OpenCASCADE 在开源领域是事实标准。它的强项是布尔运算稳定和STEP 读写可靠。这里有个细节值得说STL 是三角面片没有“圆”的概念一个圆孔在 STL 里是很多个小三角形拼出来的。而 STEP 是精确几何圆就是数学意义上的圆。所以如果你要拿模型去做 CNC 加工必须走 STEP如果只是 3D 打印STL 就够了。text-to-cad 的流水线里我建议同时导出 STEP 和 STLSTEP 存档STL 打印。3.3 参数化设计让同一个脚本生成不同规格text-to-cad 真正有价值的地方不是生成一个死模型而是生成带参数的脚本。比如上面那个法兰盘我可以让模型输出这样的代码import cadquery as cq length 80 width 80 thickness 10 center_hole 30 corner_hole 6.5 edge_offset 10 result ( cq.Workplane(XY) .box(length, width, thickness) .faces(Z) .workplane() .hole(center_hole) .faces(Z) .workplane() .rect(length - 2*edge_offset, width - 2*edge_offset, forConstructionTrue) .vertices() .hole(corner_hole) )这段代码里所有尺寸都是变量。你改一个数字重新跑一遍就能得到新规格。这才是 text-to-cad 对工程师的真正意义把一次性的建模动作变成可复用的参数化模板。注意让大模型输出带变量的代码时一定要在提示词里明确“把尺寸定义为变量并放在代码开头”否则它默认会写死数字。4. 实操过程从零搭一条 text-to-cad 流水线4.1 环境准备与依赖安装我用的环境是 Python 3.10 CadQuery 2.4。CadQuery 的安装稍微有点讲究因为它依赖 OpenCASCADE 的二进制包。最稳的方式是用 condaconda create -n text2cad python3.10 conda activate text2cad conda install -c conda-forge cadquery如果你不想用 condapip 也能装但有时候会因为 OCCT 版本问题报错。我踩过一次坑pip 装完 import 的时候提示libGL找不到后来发现是服务器没装图形库补一个apt install libgl1就好了。大模型接口这块我用的是通用的 HTTP 调用方式不绑定具体厂商。核心就是把提示词发过去拿到返回的文本提取其中的 Python 代码块。4.2 代码提取与安全执行大模型返回的内容经常带 markdown 代码块标记比如 python 开头。你需要写一个提取函数import re def extract_code(text): pattern rpython\s*(.*?) match re.search(pattern, text, re.DOTALL) if match: return match.group(1).strip() return text.strip()拿到代码后不要直接exec因为模型可能生成死循环或者删文件的代码。我的做法是限制命名空间def run_cadquery(code): namespace {} exec(code, {__builtins__: __builtins__}, namespace) return namespace.get(result)更严格的做法是用RestrictedPython或者单独起一个子进程设置超时。我实测下来CadQuery 脚本一般几秒内就跑完了设个 30 秒超时足够。4.3 导出 STEP、STL、GLB 三种格式拿到result对象后导出就很简单了from cadquery import exporters exporters.export(result, output.step) exporters.export(result, output.stl)GLB 稍微麻烦一点CadQuery 不直接支持。我的做法是先把 STL 用 trimesh 读进来再转成 GLBimport trimesh mesh trimesh.load(output.stl) mesh.export(output.glb)这里有个细节STL 导出时可以设置公差公差越小网格越密文件越大。3D 打印一般设 0.01 毫米就够了在线展示可以设 0.1 毫米减小体积。4.4 一次完整的生成记录我拿“一个 100x60x8 的安装板四角 R5 圆角中心开两个直径 8 的孔孔距 40 毫米”做了一次完整测试。提示词发过去模型返回了这样的代码import cadquery as cq length 100 width 60 thickness 8 fillet_radius 5 hole_dia 8 hole_spacing 40 result ( cq.Workplane(XY) .box(length, width, thickness) .edges(|Z) .fillet(fillet_radius) .faces(Z) .workplane() .pushPoints([(-hole_spacing/2, 0), (hole_spacing/2, 0)]) .hole(hole_dia) )跑完之后STEP 文件 12KBSTL 文件 48KBGLB 文件 22KB。用 CAD 软件打开 STEP圆角和孔位都对。唯一的小问题是模型把孔放在了 X 轴方向我原本想的是 Y 轴方向但这是描述歧义不是代码错误。后来我在提示词里加了“孔沿 X 轴排列”就准确了。5. 常见问题与排查技巧实录5.1 模型生成的代码跑不通怎么办这是最常见的问题。大模型生成的 CadQuery 代码有时候会调用不存在的 API比如.circle()在 CadQuery 里其实是.hole()或者.cboreHole()。我的排查顺序是先看报错行号定位到具体 API。去 CadQuery 官方文档查这个 API 的正确签名。把错误信息和正确用法一起塞回给大模型让它重写。我整理了一个高频错误对照表错误写法正确写法说明.circle(10).hole(10)打孔用 hole.extrude(10).extrude(10)需先有草图草图要在 workplane 上.fillet(5).edges().fillet(5)必须先选边.translate([10,0,0]).translate((10,0,0))参数用元组5.2 导出的 STEP 打开是空白的这种情况一般是布尔运算失败实体变成了空集。原因通常是两个体没有正确相交或者相减。我的经验是在 CadQuery 里尽量用链式调用不要手动做复杂的布尔运算。如果必须做先导出中间结果看一眼确认每一步都有实体。还有一个可能是单位问题。CadQuery 默认单位是毫米但如果你从 STL 转 STEPSTL 可能是英寸或者米转出来尺寸会差 25.4 倍。所以从源头就用 CadQuery 直接生成 STEP不要走 STL 中转。5.3 生成速度太慢怎么优化大模型生成代码本身很快几秒钟。慢的是 CadQuery 的几何运算复杂模型可能要十几秒。优化手段有三个减少倒角和圆角数量这些操作最耗计算。降低 STL 导出精度展示用 0.1 毫米公差。把常用模型缓存起来相同参数直接读缓存文件。我实测下来一个带 8 个圆角和 12 个孔的板件CadQuery 运算大概 3 到 5 秒完全可以接受。5.4 怎么保证生成的模型符合加工要求这是 text-to-cad 目前最大的短板它不懂工艺。比如它不知道 3D 打印的悬垂角不能超过 45 度不知道 CNC 刀具的最小半径。我的做法是在提示词里加工艺约束比如“所有内角圆角半径不小于 3 毫米以适应 6 毫米铣刀”。另外生成后一定要人工过一遍用 CAD 软件检查壁厚和干涉。提示如果你要做批量生成建议把工艺规则写成检查函数在导出前自动跑一遍比如最小壁厚检查、孔深径比检查。6. 这条流水线还能怎么扩展我现在把 text-to-cad 用在了两个场景里。一个是内部工具销售拿到客户需求输入几句话直接生成 STEP 发给客户确认省掉了建模环节。另一个是在线配置器用户在前端选参数后端调 CadQuery 生成 GLB浏览器里实时预览确认后导出 STL 去打印。后续我打算把装配体也加进来。目前 text-to-cad 主要生成单个零件但实际产品往往是多个零件装配在一起。CadQuery 支持Assembly对象可以给每个零件加位置约束。难点在于让大模型理解装配关系比如“轴插入孔中端面贴合”。我试过用“位置旋转”的 JSON 描述效果还行但还不够稳。另一个方向是反向生成给一个 STEP 文件让模型反推出参数化脚本。这个对老图纸数字化很有用但目前准确率一般复杂曲面基本没戏。简单回转体和板件可以试试。最后分享一个小技巧如果你经常生成同类零件可以建一个代码片段库把常用的结构法兰、支架、齿轮坯写成模板让大模型只负责填参数而不是从零写代码。这样成功率和速度都会大幅提升。我现在的做法是维护一个templates/目录每个模板一个.py文件大模型只需要输出参数字典剩下的交给模板渲染。实测下来生成成功率从六成提到了九成以上。
返回列表