首页 / 资讯中心 / 文章详情

Text-to-CAD:用文本驱动几何,实现参数化建模自动化

Text-to-CAD:用文本驱动几何,实现参数化建模自动化 ★ FEATURED ARTICLE
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 “text-to-cad” 这个词很多人脑子里浮现的画面大概是对着电脑说一句“给我画个法兰盘”然后屏幕上就自动出现一个带螺栓孔的 STEP 模型。这个想象不算离谱但也不完全准确。我做了几年参数化建模和自动化脚本实际接触下来text-to-cad 更准确的定位是——用自然语言或结构化文本描述驱动 CAD 内核自动生成几何模型、装配关系或工程文件。它不是一个单一软件而是一类工作流的统称核心价值在于把“人手动点鼠标建模”变成“文本描述→程序解析→几何生成→格式导出”的自动化链路。这件事为什么值得关注因为传统 CAD 建模有一个很现实的痛点重复性劳动太多。比如你要画一百个不同尺寸的法兰每个法兰的孔数、孔径、外径、厚度都不一样手动建模意味着打开草图、画圆、拉伸、打孔、阵列、导出一套流程走一百遍。而 text-to-cad 的思路是你只需要维护一张参数表或者一段描述文本剩下的交给脚本和 CAD 内核去跑。对于做机械设计、建筑构件、钣金展开、甚至电路板外形定义的人来说这意味着从“操作工”变成“规则制定者”。那它适合谁我总结下来有三类人最应该关注第一类是经常做系列化产品的结构工程师产品外形相似但尺寸参数不同用 text-to-cad 可以批量出图第二类是做仿真前处理的 CAE 工程师需要把 CAD 模型转成 URDF 或 STEP 再导入仿真环境手动操作容易出错自动化更稳第三类是做创客和 DIY 的爱好者想用代码生成个性化零件比如定制支架、外壳、转接件。哪怕你只是刚学 CAD 制图入门了解这套思路也能帮你少走很多弯路因为你会意识到CAD 不只是画图工具它还可以是一个可编程的几何引擎。这篇文章我会从整体设计思路、核心细节、实操过程、常见问题四个层面把 text-to-cad 这条链路拆开讲清楚。涉及的关键词包括 CAD、STEP、URDF、G-code也会顺带聊到 cad 插件、python 批量对 cad 修改、cad 转 pdf 这些实际工作中绕不开的环节。你不需要有很深的编程基础但需要对三维建模的基本概念有一点了解比如草图、拉伸、布尔运算、坐标系。如果这些词你听着陌生也没关系我会用生活化的类比来解释。2. 整体设计与思路拆解为什么是“文本驱动几何”2.1 核心思路把几何参数从鼠标操作中解放出来传统 CAD 建模的本质是什么是你用鼠标在图形界面里告诉软件这里画一个圆那里拉伸 10 毫米这个孔阵列 6 个。这些操作背后其实都是数值和约束只不过你是用交互的方式输入的。text-to-cad 做的事情就是把这些数值和约束用文本或代码表达出来让程序去执行。打个比方手动建模就像你亲手捏一个泥人每捏一下都要自己动手text-to-cad 就像你写一份泥人制作说明书上面写着“头直径 5 厘米手臂长 10 厘米腿长 12 厘米”然后交给一个机器人去捏。说明书可以反复用改一个数字就能生成一个新泥人。这个“说明书”可以是 JSON、YAML、Python 脚本也可以是一段自然语言描述取决于你用的工具链。为什么这种思路越来越流行因为产品迭代的速度要求变了。以前一个产品生命周期可能几年现在可能几个月就要改一版。如果每次改版都要手动重建模型时间根本不够用。而文本驱动的模型改一个参数就能重新生成版本管理也方便因为文本文件可以用 Git 管理谁改了什么一目了然。2.2 方案选型不同工具链的取舍逻辑text-to-cad 不是某一个固定工具而是一类方案的集合。根据你的需求不同选型差别很大。我把它分成三个层次层次典型方案适合场景优点缺点脚本层Python CadQuery / FreeCAD Scripting参数化零件、批量出图灵活、可编程、社区活跃需要学 API插件层CAD 插件 宏命令在现有 CAD 里自动化不用换软件、上手快受限于宿主软件文本解析层自然语言 LLM CAD 内核快速原型、非专业用户门槛低、直观精度和稳定性待提升我个人的建议是如果你要做严肃的工程化批量生产优先选脚本层比如 CadQuery 或 FreeCAD 的 Python API。原因很简单脚本层的可控性最强你能精确控制每一个几何特征也能把结果导出成 STEP、STL、URDF、G-code 等各种格式。插件层适合你已经深度绑定某个 CAD 软件的情况比如你公司全员用中望 CAD那你就用它的插件体系做自动化。文本解析层目前更适合做概念验证真正落地到生产还需要人工校验。这里要特别提一下STEP 和 URDF 的区别。STEP 是通用的三维模型交换格式几乎所有的 CAD 软件都能打开适合做制造和存档。URDF 是机器人领域用的统一机器人描述格式它不仅包含几何外形还包含关节、连杆、坐标系、惯性矩阵等信息。如果你做的是机器人仿真比如导入 CoppeliaSim那 URDF 就是刚需。很多人卡在“urdf 导入 coppeliasim”这一步往往是因为 URDF 里的坐标系和网格文件路径没写对。text-to-cad 的思路可以帮你自动生成这些文件减少手动配置的错误。2.3 为什么文本描述比纯代码更友好有人会问既然都是写代码为什么不直接写 Python 脚本还要搞自然语言描述这个问题我一开始也想过。后来发现自然语言描述的价值在于降低门槛和加快原型速度。比如你对一个非编程背景的机械工程师说“写个 Python 脚本生成法兰”他可能直接放弃但你说“描述一下法兰的尺寸和孔位”他能立刻说出来。text-to-cad 的自然语言层就是把这个描述转成代码让不写代码的人也能享受自动化的好处。当然自然语言描述目前有个硬伤歧义。你说“打几个孔”到底是几个你说“厚一点”到底多厚所以实际落地时通常需要一套结构化的模板来约束描述。比如part: flange outer_diameter: 120 inner_diameter: 60 thickness: 10 bolt_holes: count: 6 diameter: 12 circle_diameter: 90这种半结构化文本既比纯代码好写又比纯自然语言精确。我实测下来这是目前最稳的折中方案。3. 核心细节解析与实操要点从文本到几何的关键环节3.1 几何内核的选择OpenCASCADE 还是别的text-to-cad 的底层需要一个几何内核来真正生成三维形状。目前开源领域用得最多的是OpenCASCADECadQuery 和 FreeCAD 都基于它。为什么是它因为 OpenCASCADE 支持 B-Rep边界表示法能精确表达圆柱、圆角、倒角这些工程特征导出的 STEP 文件质量也高。相比之下一些基于网格的建模库虽然轻量但做不了精确的工程图。如果你只是做视觉展示网格模型够用但如果你要出工程图、做 CNC 加工、生成 G-code那就必须用 B-Rep 内核。这一点在选型时就要想清楚不然后面转格式会非常痛苦。我踩过的坑是早期用了一个网格建模库生成模型结果导出 STEP 时全是三角面片加工师傅根本没法用只能推倒重来。3.2 参数化建模的核心约束与特征树text-to-cad 生成的模型最好是一棵特征树而不是一个死掉的几何体。什么意思就是你的模型应该保留“先画草图、再拉伸、再打孔”这样的历史记录这样后面改参数时只需要改草图尺寸后面的特征会自动更新。CadQuery 和 FreeCAD 都支持这种工作流。举个例子你要生成一个带孔的板子import cadquery as cq result ( cq.Workplane(XY) .box(100, 60, 10) .faces(Z) .workplane() .hole(8) )这段代码的意思是在 XY 平面上做一个 100x60x10 的盒子然后选顶面打一个直径 8 的孔。如果你后面想把板子改成 120x80x12只需要改box里的参数孔的位置和大小会自动适应。这就是参数化的威力。注意不是所有 text-to-cad 工具都保留特征树。有些工具生成的是“死几何”改参数只能重新生成整个模型。选型时要确认这一点否则后期修改会很麻烦。3.3 坐标系与单位最容易翻车的地方我见过太多人卡在坐标系和单位上。CAD 软件通常默认毫米但有些仿真软件默认米。URDF 里如果单位搞错机器人模型导入 CoppeliaSim 后会变成巨人或者蚂蚁。text-to-cad 生成模型时一定要在文本描述里明确单位比如units: mm然后在导出 URDF 时程序自动把毫米转成米。这个转换看起来简单但手动做的时候很容易漏。我建议在脚本里写一个统一的单位转换函数所有导出格式都走这个函数避免各处不一致。另外坐标系的原点位置也很关键。对于旋转体原点最好放在旋转轴上对于机器人连杆原点最好放在关节处。text-to-cad 的文本描述里应该包含原点定义比如origin: [0, 0, 0] axis: [0, 0, 1]这样生成的模型在装配和仿真时才能对得上。3.4 导出格式的取舍STEP、URDF、G-code 各管什么text-to-cad 的最终产出通常是某种文件格式。不同格式用途完全不同选错了等于白干。格式用途特点注意事项STEP制造、存档、跨软件交换精确 B-Rep体积小不同软件对 STEP 版本支持不同URDF机器人仿真、运动学包含关节和连杆信息需要配套网格文件G-codeCNC 加工、3D 打印刀具路径指令依赖后处理器STL3D 打印、快速预览网格模型简单精度受网格密度影响PDF图纸交付、评审二维投影需要配置视图和标注我一般的工作流是先用 text-to-cad 生成 STEP 作为主模型然后根据需要导出 URDF 做仿真或者导出 STL 做 3D 打印最后用 CAD 软件出 PDF 图纸。G-code 通常是在 CAM 软件里生成的但如果你做的是简单的 2.5D 加工也可以直接从 text-to-cad 脚本里生成。提示导出 URDF 时网格文件建议用 STL 或 DAE 格式不要用 STEP。因为 URDF 的视觉和碰撞网格通常用网格格式STEP 在仿真环境里加载慢且容易出问题。4. 实操过程与核心环节实现手把手跑通一条链路4.1 环境准备Python 与 CadQuery 的安装我以 CadQuery 为例演示一条完整的 text-to-cad 链路。为什么选它因为它是纯 Python 的安装简单文档也还算清楚。首先你需要一个 Python 环境建议用 3.9 或以上版本。然后安装 CadQuerypip install cadquery如果你要用 FreeCAD 的 API安装会麻烦一些因为 FreeCAD 本身是个大软件Python 模块需要单独配置。CadQuery 的好处是轻量装完就能用。安装完成后跑一个最简单的测试import cadquery as cq result cq.Workplane(XY).box(10, 10, 10) cq.exporters.export(result, test.step)如果当前目录下出现了test.step说明环境没问题。这一步看似简单但我见过不少人卡在依赖冲突上尤其是 Windows 环境下 OpenCASCADE 的 DLL 加载失败。遇到这种情况建议用 conda 创建独立环境conda create -n cadquery python3.10 conda activate cadquery conda install -c conda-forge cadqueryConda 会自动处理二进制依赖比 pip 稳很多。4.2 从文本描述到参数化模型假设我们要生成一个简单的法兰盘。文本描述如下part: flange units: mm outer_diameter: 120 inner_diameter: 60 thickness: 10 bolt_holes: count: 6 diameter: 12 circle_diameter: 90然后写一个 Python 脚本读取这个描述并生成模型import yaml import cadquery as cq import math with open(flange.yaml, r) as f: spec yaml.safe_load(f) outer_r spec[outer_diameter] / 2 inner_r spec[inner_diameter] / 2 thickness spec[thickness] hole_count spec[bolt_holes][count] hole_r spec[bolt_holes][diameter] / 2 circle_r spec[bolt_holes][circle_diameter] / 2 result ( cq.Workplane(XY) .circle(outer_r) .circle(inner_r) .extrude(thickness) ) for i in range(hole_count): angle 2 * math.pi * i / hole_count x circle_r * math.cos(angle) y circle_r * math.sin(angle) result ( result.faces(Z) .workplane() .center(x, y) .hole(spec[bolt_holes][diameter]) ) cq.exporters.export(result, flange.step)这段代码的逻辑很直白先画外圆和内圆拉伸成环然后在顶面上按圆周阵列打孔。跑完之后你会得到一个flange.step用任何 CAD 软件都能打开。这里的关键点是孔的位置用三角函数计算而不是手动输入坐标。这样当你改孔数时位置会自动重新分布。这就是参数化的好处。4.3 导出 URDF 并导入 CoppeliaSim如果你做机器人仿真下一步就是把模型转成 URDF。URDF 本质上是一个 XML 文件描述连杆和关节。一个最简单的 URDF 长这样?xml version1.0? robot nameflange_robot link namebase_link visual geometry mesh filenameflange.stl scale0.001 0.001 0.001/ /geometry /visual collision geometry mesh filenameflange.stl scale0.001 0.001 0.001/ /geometry /collision /link /robot注意scale那里因为 STL 是毫米单位而 URDF 默认米所以要乘以 0.001。这个细节如果漏了导入 CoppeliaSim 后模型会大一千倍。生成 URDF 的脚本可以这样写import cadquery as cq # 先生成模型 result cq.Workplane(XY).circle(60).circle(30).extrude(10) cq.exporters.export(result, flange.stl) # 再写 URDF urdf_content ?xml version1.0? robot nameflange_robot link namebase_link visual geometry mesh filenameflange.stl scale0.001 0.001 0.001/ /geometry /visual collision geometry mesh filenameflange.stl scale0.001 0.001 0.001/ /geometry /collision /link /robot with open(flange.urdf, w) as f: f.write(urdf_content)然后把flange.urdf和flange.stl放在同一个目录下在 CoppeliaSim 里通过Plugins URDF import导入。如果一切正常你会看到法兰盘出现在场景里。如果看不到先检查网格路径和 scale。4.4 生成 G-code 的简化路径G-code 通常是在 CAM 软件里生成的但如果你只是做简单的钻孔或切割也可以直接从 text-to-cad 脚本里生成。比如你要在一个板子上钻六个孔G-code 大概长这样G21 ; 单位设为毫米 G90 ; 绝对坐标 G0 X45 Y0 Z5 ; 移动到第一个孔上方 G1 Z-12 F100 ; 下钻 G0 Z5 ; 抬刀 G0 X22.5 Y38.97 ; 移动到第二个孔 G1 Z-12 F100 G0 Z5 ; ... 重复其余孔 M30 ; 程序结束你可以用 Python 根据孔位自动生成这段代码import math hole_count 6 circle_r 45 depth 12 lines [G21, G90] for i in range(hole_count): angle 2 * math.pi * i / hole_count x circle_r * math.cos(angle) y circle_r * math.sin(angle) lines.append(fG0 X{x:.2f} Y{y:.2f} Z5) lines.append(fG1 Z-{depth} F100) lines.append(G0 Z5) lines.append(M30) with open(drill.gcode, w) as f: f.write(\n.join(lines))这个脚本生成的 G-code 可以直接喂给支持标准 G-code 的 CNC 或 3D 打印机。当然实际加工前一定要在仿真软件里验证路径避免撞刀。5. 常见问题与排查技巧实录5.1 模型导出后打不开或者显示异常这是最常见的问题。原因通常有三个单位不对、坐标系不对、文件版本不兼容。我遇到过一次导出的 STEP 在 SolidWorks 里打开是空白的后来发现是模型的原点跑到了很远的地方视图缩放后看不到。解决办法是在导出前把模型移动到原点附近result result.translate((0, 0, 0))或者用cq.Workplane的center方法重新定位。另一个常见原因是 STEP 版本有些老软件只支持 AP203不支持 AP214。CadQuery 默认导出 AP214如果对方打不开可以指定版本cq.exporters.export(result, model.step, exportTypeSTEP, opt{write_pcurves: False})5.2 URDF 导入 CoppeliaSim 后模型不可见这个问题我帮人排查过好几次。九成以上的原因是网格文件路径不对或者scale 没设对。URDF 里的filename是相对路径相对于 URDF 文件所在目录。如果你把 URDF 和 STL 放在不同目录就会找不到。另外CoppeliaSim 对 DAE 格式的支持比 STL 好如果 STL 显示异常可以试试导出 DAE。还有一个坑是碰撞网格和视觉网格不一致。有些仿真环境要求碰撞网格必须是凸体如果你的模型有凹槽碰撞检测会出问题。解决办法是用简单的几何体做碰撞比如用圆柱代替法兰盘。5.3 批量修改 CAD 模型时脚本报错用 Python 批量对 CAD 修改时最常见的错误是特征选择失败。比如你写faces(Z)想选顶面但模型旋转后顶面变成了侧面脚本就找不到面了。解决办法是用更稳健的选择器比如按面积选、按法向选或者给特征命名。另一个坑是内存泄漏。CadQuery 在循环里生成大量模型时如果不及时释放内存会爆。建议每生成一批就清理一次import gc gc.collect()如果模型特别复杂可以考虑用多进程并行生成每个进程独立处理一个零件。5.4 常见问题速查表问题现象可能原因排查方法解决方案STEP 打开空白模型远离原点在 CAD 里缩放至全部导出前平移到原点URDF 导入不可见网格路径错误检查 URDF 里的 filename用绝对路径或同目录模型尺寸差 1000 倍单位不一致检查 scale 和单位声明统一转成米脚本报错找不到面特征选择器不稳定打印面法向和面积改用面积或法向选择G-code 撞刀安全高度不够仿真验证路径抬刀高度设为 5mm 以上批量生成内存爆对象未释放监控内存占用定期 gc.collect()提示每次改完脚本先用一个小模型测试确认没问题再跑批量。我吃过亏跑了一晚上结果发现参数写错全部重来。5.5 几个容易被忽略的实操心得第一个心得文本描述里一定要写注释。比如outer_diameter: 120 # 单位mm对应客户图纸A-102。过几个月回头看没有注释你根本不知道这个数字是哪来的。第二个心得版本控制要用起来。text-to-cad 的文本文件非常适合用 Git 管理。每次改参数都提交一次出问题可以回滚。比手动改 CAD 文件然后另存为final_v2_really_final.step强太多了。第三个心得导出前先做几何检查。CadQuery 有result.val().isValid()可以检查模型是否有效。如果无效通常是布尔运算出了问题比如两个实体没有正确合并。这时候要检查草图是否闭合、拉伸方向是否正确。第四个心得不要追求一次到位。text-to-cad 的脚本是迭代出来的。先跑通最简单的版本再逐步加特征。我见过有人一上来就写几百行脚本结果调试到崩溃。正确的做法是先画一个圆导出看看再加一个孔导出看看再加阵列导出看看。每一步都验证最后组合起来。6. 这条链路还能怎么扩展跑通基础链路之后你会发现 text-to-cad 的想象空间比预想的大。比如你可以把文本描述接到一个 Web 表单上让客户自己填参数后台自动生成 STEP 文件供下载。这在定制化产品里非常实用客户不需要装 CAD 软件也不需要懂建模填几个数字就能拿到模型。你还可以把 text-to-cad 和 3D 打印切片软件结合起来。生成 STL 后自动调用切片引擎输出 G-code直接发送到打印机。整个流程从“客户下单”到“开始打印”可以做到无人值守。我试过用 Python 调用 Cura 的命令行接口效果还不错就是切片参数需要仔细调。另一个方向是和仿真工具链集成。比如生成 URDF 后自动导入 CoppeliaSim 或 Gazebo跑一轮运动学仿真验证关节范围和碰撞情况。如果仿真通过再导出 STEP 去加工。这样可以在设计阶段就发现干涉问题省下反复打样的成本。如果你做的是钣金件text-to-cad 还可以自动生成展开图。CadQuery 有sheetmetal模块可以定义折弯半径和 K 因子直接输出展开后的 DXF 文件。这对做钣金加工的人来说是个福音因为手动展开又慢又容易错。最后再分享一个小技巧如果你经常需要把 CAD 转 PDF可以用 CadQuery 的exporters.export配合svg或dxf格式先生成二维投影再用其他库转 PDF。虽然不如专业 CAD 软件的工程图模块强大但对于简单的评审和存档足够了。我现在的做法是text-to-cad 生成 STEP 作为主文件同时自动生成一份 PDF 预览图发给客户确认外形确认后再出正式图纸。这样来回沟通的效率高了很多。
阅读完成 · 觉得有帮助?
咨询建站