资讯动态

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

发布时间:2026/10/26 7:28:33 来源:尧图企业网站定制
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80×60×20 的法兰盘中心开直径 30 的通孔四角各一个 M6 沉头孔”然后屏幕上直接出现一个可以旋转、可以导出、可以拿去加工的实体模型。这个画面在几年前还属于科幻范畴现在已经有了一批能跑通的原型工具和开源方案。text-to-cad 的核心就是把自然语言描述转成 CAD 能识别的几何数据最终落地成 STEP、GLB、STL 这类通用格式。它解决的问题很具体。传统 CAD 建模不管是 SolidWorks、中望 CAD 还是 FreeCAD你都得先学草图约束、拉伸、旋转、布尔运算这一套。一个简单的支架熟手也要十几分钟新手可能折腾一两个小时还画不出来。而 text-to-cad 想干的事是让“描述需求”和“生成几何”之间不再隔着软件操作这道墙。你描述得越清楚模型越接近你要的东西。适合关注这个方向的人其实比想象中多。做机械设计的工程师可以用它快速出概念模型省掉重复劳动做 3D 打印的玩家可以直接把想法变成 STL 去切片做前端或者游戏开发的需要 GLB 资产时也能用得上甚至做钣金、做建筑构件的人只要涉及参数化几何都能从中找到价值。关键词里出现的 STEP、GLB、STL 正好对应了三条主流落地路径STEP 走工程制造GLB 走可视化与渲染STL 走 3D 打印。我自己的判断是text-to-cad 现在还没到“一句话出成品”的程度但它已经能承担“从想法到初稿”这一段。把它当成一个不知疲倦的建模助手而不是替代设计师的黑盒心态就对了。下面我会把整个链路拆开从整体设计思路讲到具体实现再到踩过的坑尽量让你看完能自己动手跑一遍。2. 整体设计与技术路线拆解2.1 为什么不能直接让大模型“画图”很多人第一反应是现在多模态模型这么强直接让它输出一个三维模型不就行了实测下来这条路走不通。图像生成模型输出的是像素它不理解“这个孔必须和那个轴同心”这种几何约束。你让它画一个齿轮它可能画得很像但齿数、模数、压力角全是错的导出的 STL 拿去打印根本装不上。所以 text-to-cad 的主流思路不是“生成模型”而是“生成建模代码”。也就是说大模型负责把自然语言翻译成一段可执行的建模脚本再由几何内核去执行这段脚本算出真正的 B-rep 实体或网格。这个分工很关键语言模型擅长处理语义和意图几何内核擅长处理精确计算各干各的。这个思路下最终产出的模型精度取决于几何内核而不是模型本身。只要脚本写对了出来的 STEP 就是工程级精度可以进 CAM 加工。这也是为什么 text-to-cad 能同时输出 STEP、GLB、STL——它们只是同一个几何体的不同导出格式。2.2 三条主流技术路线对比目前能跑通的方案大致分三类我整理成表格方便对照路线核心工具输出格式精度上手难度适合场景代码驱动型CadQuery / build123dSTEP、STL工程级中机械零件、参数化构件网格生成型OpenSCAD / 网格脚本STL、GLB中等低3D 打印、概念模型云端 API 型各类在线生成服务STEP、GLB、STL视服务而定低快速验证、非核心资产代码驱动型的代表是 CadQuery它基于 OpenCASCADE 内核用 Python 描述几何。你写cq.Workplane(XY).box(80, 60, 20)就能得到一个长方体再链式调用.faces()、.hole()就能开孔。这种方式的优势是参数化程度极高改一个数字整个模型跟着变特别适合做系列化零件。网格生成型的代表是 OpenSCAD它用类似编程的方式做 CSG构造实体几何本质上是布尔运算堆出来的网格。它的好处是语法简单坏处是精度受限于网格分辨率做曲面和精细特征比较吃力。云端 API 型就是直接调服务把文字发过去拿回模型文件。这种方式最省事但可控性差复杂零件经常生成得似是而非而且涉及数据外传做正经工程项目要谨慎。2.3 我为什么最终选了 CadQuery 这条线试过几轮之后我把主力方案定在了 CadQuery 加本地大模型的组合上。原因有三点。第一CadQuery 的输出是真正的 B-rep 实体导出的 STEP 能被主流 CAD 软件打开并继续编辑这是工程落地的前提。第二它的 Python 接口对大模型很友好模型见过的 Python 代码多生成 CadQuery 脚本的准确率明显高于生成其他 DSL。第三整条链路可以完全本地跑不依赖外部服务数据不出机器。这里要说明一点CadQuery 和 build123d 是同一批人做的build123d 语法更现代但生态和资料还不如 CadQuery 丰富。新手我建议从 CadQuery 入手遇到瓶颈再考虑迁移。下面所有实操都以 CadQuery 为准。3. 核心细节解析与实操要点3.1 环境搭建把地基打牢环境这一步看着简单实际上坑最多。CadQuery 依赖 OpenCASCADE在 Windows 上装不好就是各种 DLL 报错。我的建议是直接用 conda 装别用 pip 硬扛。conda create -n text2cad python3.11 conda activate text2cad conda install -c conda-forge cadquery装完之后验证一下import cadquery as cq result cq.Workplane(XY).box(10, 10, 10) cq.exporters.export(result, test.step)能生成 test.step 就说明环境没问题。如果报OCP相关的错八成是 OpenCASCADE 版本冲突重装 conda 环境基本能解决。大模型这块本地跑的话推荐用支持代码生成的模型参数量 7B 到 14B 之间比较平衡。太小了代码写不对太大了消费级显卡扛不住。量化版本能进一步降低显存占用实测 4bit 量化后 14B 模型在 12G 显存上能跑。注意环境变量里如果有多个 Python 路径conda 激活后一定要确认which python指向的是新环境否则会出现“装了却 import 不到”的诡异情况。3.2 提示词工程让模型听懂人话text-to-cad 的效果七成取决于提示词。你不能直接甩一句“画个零件”就指望它出好东西。我的做法是给模型一个固定的系统提示把 CadQuery 的常用 API 和输出规范写进去。系统提示大概长这样你是一个 CAD 建模助手使用 CadQuery 生成 Python 脚本。 要求 1. 只输出可执行的 Python 代码不要解释。 2. 所有尺寸用毫米。 3. 使用 cq.Workplane 链式调用。 4. 最后用 cq.exporters.export 导出 STEP 和 STL。 5. 变量命名清晰关键尺寸用变量存储。用户输入则尽量结构化。比如“画一个法兰盘”太模糊改成“画一个外径 100、内径 40、厚度 10 的法兰盘沿圆周均匀分布 6 个直径 8 的螺栓孔分布圆直径 80”模型生成的脚本就靠谱得多。我总结了一个描述模板按这个顺序说命中率最高整体形状长方体、圆柱、法兰、支架主要尺寸长宽高、直径、厚度特征孔、槽、倒角、圆角特征位置和数量特殊要求对称、阵列、公差3.3 几何内核精度是怎么保证的CadQuery 底层是 OpenCASCADE这是一个工业级的几何内核和很多商业 CAD 用的是同一套底层技术。它处理的是 B-rep边界表示也就是用精确的数学曲面来描述几何体而不是用三角形网格去逼近。这个区别很关键。STL 是网格格式一个圆柱面会被切成很多小三角形切得越细越接近圆但永远不是真正的圆。而 STEP 保存的是“这是一个圆柱面半径 20轴线在这里”这样的精确描述。所以同一个模型STEP 文件可能只有几十 KBSTL 却有几 MB而且 STEP 放大后边缘依然光滑。导出的时候要注意STL 的精度由弦高和角度容差控制。默认值有时候太粗打印出来能看到明显的多边形棱角。可以在导出时调小容差cq.exporters.export( result, part.stl, tolerance0.01, angularTolerance0.1 )tolerance 是弦高单位毫米越小越精细angularTolerance 是角度容差单位弧度。这两个值调太小文件会爆炸一般 0.01 和 0.1 够用了。3.4 格式选择STEP、GLB、STL 各管一摊这三个格式经常被混用其实各有各的地盘。STEP 是工程交换格式几乎所有 CAD 软件都认。它的优势是精确、可编辑、能保留特征树部分情况。你要把模型发给加工厂或者后续还要在 SolidWorks 里改就导 STEP。STL 是 3D 打印的事实标准切片软件只认它。它只有三角面片没有单位、没有颜色、没有装配关系。导出前一定要确认单位是毫米否则打印出来尺寸差 25.4 倍。GLB 是 glTF 的二进制版本主打可视化和渲染。它支持材质、颜色、动画网页端加载特别方便。做产品展示、游戏资产、AR 预览就用它。CadQuery 本身不直接导 GLB一般先导 STL 或 OBJ再用 trimesh 或 Blender 转一道。import trimesh mesh trimesh.load(part.stl) mesh.export(part.glb)这一步转换会丢失精确几何但对可视化来说无所谓。4. 完整实操流程从一句话到三个格式4.1 需求描述与脚本生成假设我要做一个简单的安装支架底板 100×60×8上面立一块 100×50×8 的竖板竖板中心开一个直径 20 的孔底板四角各一个直径 6 的通孔。我把这段描述发给本地模型附上系统提示。模型返回的脚本大概是这样import cadquery as cq # 参数 base_l 100.0 base_w 60.0 base_t 8.0 wall_h 50.0 wall_t 8.0 hole_d 20.0 mount_d 6.0 mount_offset 10.0 # 底板 base cq.Workplane(XY).box(base_l, base_w, base_t) # 竖板立在底板后侧 wall ( cq.Workplane(XY) .box(base_l, wall_t, wall_h) .translate((0, base_w/2 - wall_t/2, base_t/2 wall_h/2)) ) # 合并 part base.union(wall) # 竖板中心孔 part ( part.faces(Y) .workplane() .hole(hole_d) ) # 底板四角安装孔 part ( part.faces(Z) .workplane() .rect(base_l - 2*mount_offset, base_w - 2*mount_offset, forConstructionTrue) .vertices() .hole(mount_d) ) cq.exporters.export(part, bracket.step) cq.exporters.export(part, bracket.stl, tolerance0.01, angularTolerance0.1)这段脚本能跑但有几个地方需要人工检查。第一竖板的位置对不对translate 的 Z 值是不是让底面刚好贴合底板顶面。第二faces(Y)选的是不是竖板朝前的那个面如果选错了孔会开在别的地方。第三四角孔的定位是不是真的在四角。4.2 脚本校验与修正模型生成的脚本不能盲信必须跑一遍看结果。我一般会加一段可视化代码直接在 Jupyter 里看from cadquery.vis import show show(part)如果环境不支持可视化就导出 STL 用系统自带的 3D 查看器打开。重点看三个东西整体比例对不对、特征位置对不对、有没有多余的实体。我遇到过最常见的问题是坐标系搞混。CadQuery 默认 Z 轴向上但很多人描述“竖板”时脑子里想的是 Y 轴向上。模型有时候会跟着错把竖板放倒。这时候不用重写改一下 translate 的参数就行。还有一个高频问题是布尔运算失败。两个实体如果只是面贴面没有真正相交union 可能报错或者产生非流形几何。解决办法是让它们稍微重叠一点比如竖板往下多伸 0.1mm 插进底板合并完再把多余部分切掉。这个技巧在网格建模里也常用叫“过盈合并”。4.3 导出与后处理脚本跑通之后导出三个格式。STEP 直接给 CAD 软件STL 给切片软件GLB 给展示用。导出 STL 的时候我习惯用 trimesh 再过一道检查网格是否封闭import trimesh mesh trimesh.load(bracket.stl) print(是否水密:, mesh.is_watertight) print(体积:, mesh.volume) print(包围盒:, mesh.bounds)is_watertight为 True 说明网格封闭3D 打印不会出问题。如果为 False多半是布尔运算留下了缝隙需要回 CadQuery 里修。转 GLB 的时候可以顺便加个材质mesh.visual.face_colors [180, 180, 180, 255] mesh.export(bracket.glb)这样在网页里加载出来就是灰色的金属感比默认的白色好看。4.4 参数化迭代text-to-cad 最大的价值不是一次生成而是快速迭代。支架做出来之后客户说“底板加宽到 120”你只需要改一个变量base_l 120重新跑脚本三个格式全部更新。这个过程几秒钟比在 CAD 软件里改草图快得多。我一般会把所有关键尺寸抽成变量放在脚本开头形成一个小型的参数表。更进一步可以用 JSON 或 YAML 存参数脚本读配置生成模型这样非技术人员也能改尺寸。import json with open(params.json) as f: p json.load(f) base_l p[base_l] base_w p[base_w] # ...这套做法在批量出图、系列化零件上特别香。关键词里提到的“python批量对cad修改”本质上就是这个思路的延伸。5. 常见问题与排查技巧实录5.1 模型生成失败的高频原因跑了几十次之后我把失败原因归了类做成速查表现象可能原因解决办法脚本报语法错模型输出了伪代码或中文标点在提示词里强调只输出纯 Pythonimport 报错环境没装 cadquery回到 3.1 检查 conda 环境布尔运算失败实体没有真正相交让实体过盈重叠 0.1mm孔开错位置面选择器选错用faces(Z)等明确指定方向导出 STEP 为空没有实体只有草图确认最后一步是实体操作STL 打印有破面网格不水密用 trimesh 检查并修复尺寸差 25.4 倍单位是英寸导出前统一转毫米5.2 面选择器最容易翻车的地方CadQuery 的面选择器是新手最大的坎。faces(Z)选的是 Z 方向最靠上的面faces(Z)是最靠下的faces(Y)是 Y 方向最靠前的。但“最靠前”是相对于当前工作平面说的如果你之前做过旋转或平移方向可能和你想象的不一样。我的经验是每做一步操作就打印一下当前实体的面数和包围盒确认状态print(面数:, part.faces().size()) print(包围盒:, part.val().BoundingBox())包围盒能告诉你实体在空间中的实际范围比凭感觉猜靠谱得多。如果发现实体跑到别的地方去了多半是某一步 translate 的参数写反了。还有一个技巧是用faces(cq.selectors.BoxSelector(...))按空间范围选面比方向选择器更精确。比如要选 Z 在 8 到 16 之间的所有面from cadquery import selectors part part.faces(selectors.BoxSelector((-100, -100, 8), (100, 100, 16)))5.3 大模型幻觉的应对大模型生成 CadQuery 代码时最常见的幻觉是编造不存在的 API。比如它会写cq.Workplane(XY).cylinder(10, 20)但 CadQuery 里圆柱的正确写法是.circle(10).extrude(20)或者.cylinder(height, radius)参数顺序还不一样。应对办法有两个。一是在系统提示里附上常用 API 的正确签名让模型照着抄。二是生成后先做静态检查用ast模块解析一下看有没有明显不存在的函数调用。更彻底的办法是维护一个 API 白名单生成后逐个比对。import ast allowed {Workplane, box, circle, extrude, hole, union, cut} tree ast.parse(code) for node in ast.walk(tree): if isinstance(node, ast.Attribute): if node.attr not in allowed: print(可疑调用:, node.attr)这个检查不能保证 100% 正确但能拦下大部分低级错误。5.4 性能优化别让脚本跑太久简单的零件脚本几秒就跑完但复杂模型——比如几百个孔的阵列、复杂的曲面——可能跑几分钟甚至卡死。我踩过的坑里最常见的是阵列数量写太大。模型看到“均匀分布”就给你来个 360 个孔几何内核直接跪。解决办法是在提示词里限制阵列数量或者生成后人工检查循环次数。另外CadQuery 的布尔运算很吃性能能一次 union 就不要分多次。把多个实体收集到列表里用union(*solids)一次性合并比循环 union 快好几倍。solids [make_pin(i) for i in range(20)] part solids[0].union(*solids[1:])还有一点导出 STL 时容差别调太小。0.001 的容差能让文件从几 MB 涨到几百 MB切片软件打开都费劲。0.01 对绝大多数 3D 打印场景足够了。5.5 与现有 CAD 工作流的衔接text-to-cad 生成的 STEP 能不能直接进 SolidWorks 或中望 CAD能但要注意版本。STEP 有 AP203、AP214、AP242 几个版本AP242 保留的信息最全支持颜色和装配。CadQuery 默认导 AP214一般够用。如果对方软件打不开试试指定版本cq.exporters.export(part, part.step, opt{write_pcurves: False})导入之后模型通常是一个“哑实体”没有特征树不能直接改尺寸。想改还得回脚本改参数重新生成。所以我的工作流是text-to-cad 出初稿和参数化版本需要精细调整的再进 CAD 软件做后期。两者不是替代关系是接力关系。关键词里有人问“sw 中 stl 转 stp”这其实是逆向工程的路子。STL 转 STEP 需要曲面重建精度损失很大能不做就不做。正确的做法是一开始就用 text-to-cad 直接生成 STEP跳过网格这一环。6. 进阶玩法与扩展方向6.1 批量生成与系列化零件把参数抽出来之后批量生成就是循环的事。比如做一整套不同长度的支架import cadquery as cq def make_bracket(length): base cq.Workplane(XY).box(length, 60, 8) # ... 其余建模逻辑 return base for L in [80, 100, 120, 150]: part make_bracket(L) cq.exporters.export(part, fbracket_{L}.step)这套逻辑配合配置文件能实现“改表出图”。做钣金、做型材、做标准件的人应该对这个场景很熟悉。关键词里的“金林钣金 cad 版”这类工具核心能力之一就是参数化批量出图text-to-cad 相当于用自然语言驱动了同样的流程。6.2 结合 3D 打印的闭环生成 STL 之后直接调切片软件的命令行接口能实现全自动。比如用 PrusaSlicer 的命令行prusa-slicer --export-gcode --load config.ini part.stl生成的 G-code 直接丢给打印机。整个链路从一句话到可打印文件中间不需要人工打开任何软件。当然实际打印前还是要人工检查一下模型但至少省掉了建模和切片两步。6.3 网页端预览GLB 格式在网页端加载特别方便用 three.js 几行代码就能转起来import * as THREE from three; import { GLTFLoader } from three/addons/loaders/GLTFLoader.js; const loader new GLTFLoader(); loader.load(bracket.glb, (gltf) { scene.add(gltf.scene); });这样客户在浏览器里就能 360 度看模型不用装任何软件。做定制化产品的这个体验提升很明显。6.4 局限性与边界说了这么多好处也得说说 text-to-cad 现在做不到什么。复杂曲面、自由造型、有机形态它基本无能为力。你让它画一个汽车外壳或者一个人像出来的东西没法看。这些场景还是得靠传统建模或者雕刻软件。装配体也是弱项。多个零件的配合关系、运动约束自然语言很难描述清楚模型也理解不了。目前 text-to-cad 最适合的是单体的、规则的、参数化的零件。还有就是精度要求极高的场景比如航空件、精密模具生成的模型只能当参考最终还是要工程师在专业软件里重新做。把它当成草稿工具而不是生产工具预期就对了。7. 我踩过的坑和几条实在建议折腾 text-to-cad 这段时间最大的体会是别指望它一步到位把它当成一个需要调教的助手。第一版脚本能跑通就谢天谢地剩下的靠迭代。我现在的习惯是先生成一个最简版本确认环境、导出、查看这条链路通了再逐步加特征。一次性描述太复杂模型容易顾此失彼。第二个体会是参数化思维比建模技巧更重要。写脚本的时候凡是可能变的尺寸都抽成变量哪怕现在用不上。等到客户要改的时候你会感谢自己当初多写的那几行。第三个是版本管理。生成的脚本和模型文件一定要用 git 管起来每次改参数都提交一次。text-to-cad 的迭代速度很快没有版本管理改着改着就不知道哪版是对的了。最后分享一个小技巧如果模型生成的脚本总是差一点别急着重新生成先手动改两行试试。很多时候问题很小比如少了一个.clean()或者面选择器方向反了。手动改比重新生成快得多而且改的过程能帮你理解 CadQuery 的工作方式。等你能一眼看出脚本哪里不对text-to-cad 对你来说就不再是黑盒而是一个真正顺手的工具了。

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

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

免费获取报价 →
↑