资讯动态

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

发布时间:2026/10/26 7:19:28 来源:尧图企业网站定制
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80 毫米见方的法兰盘中心开 30 毫米通孔四角各一个 M6 沉头孔”然后屏幕上直接出现一个可以旋转、可以导出、可以丢进切片软件或者丢进装配体的三维实体。这个画面在几年前还属于科幻范畴现在已经有了一批能跑通的原型工具和开源方案。text-to-cad 的核心就是把自然语言描述转换成 CAD 可识别的几何数据最终落地成 STEP、GLB、STL 这类通用格式。它解决的问题很具体。传统 CAD 建模不管是 SolidWorks、中望 CAD、Fusion 360 还是 FreeCAD都需要人手动拉伸、切除、倒角、打孔。一个简单的支架熟手也要十几分钟一批尺寸不同、结构相同的零件改参数改到怀疑人生。text-to-cad 想干的事情是让“描述”直接变成“几何”把重复性的、规则明确的建模工作交给程序。适合关注这个方向的人其实很广做机械设计的工程师、搞创客和 3D 打印的玩家、做参数化建模的程序员、以及需要批量生成模型做仿真或展示的团队。我实测下来目前 text-to-cad 并不是“一句话生成任意复杂模型”的魔法它更像是一个“自然语言到参数化脚本”的翻译层。你描述得越结构化、越接近工程语言出来的结果越靠谱。热词里出现的 STEP、GLB、STL正好对应了它的三条主要出口STEP 给传统 CAD 做后续编辑GLB 给网页和 AR 做轻量展示STL 给 3D 打印和切片。理解这三者的差异是玩转 text-to-cad 的第一课。2. 整体设计思路为什么是“翻译层”而不是“生成器”2.1 自然语言到几何的三条技术路线我梳理了一下目前能见到的 text-to-cad 实现大致分成三条路线每条路线的取舍逻辑完全不同。第一条是大模型直接生成 CAD 脚本。你给模型一段描述它输出一段 OpenSCAD、CadQuery 或者 build123d 的代码再由这些库去执行、生成几何。这条路线的优点是可控、可复现、可版本管理生成的脚本你能读、能改、能参数化。缺点是模型必须懂这些 DSL 的语法描述稍微模糊一点生成的代码就跑不通。第二条是大模型生成中间表示再转几何。比如让模型输出一段结构化的 JSON描述“基体是长方体尺寸 80x80x10中心有一个圆柱形孔直径 30贯穿”然后由后端程序解析 JSON 调用几何内核。这条路线的容错性更好因为 JSON 的 schema 是你自己定的模型只需要填字段不需要写代码。缺点是表达能力受 schema 限制遇到 schema 没覆盖的特征就抓瞎。第三条是端到端的神经几何生成直接输出点云、网格或者隐式场。这条路学术味最浓但工程上最难用因为生成的网格往往拓扑混乱、尺寸不准、没法参数化编辑。做展示可以做正经设计不行。我个人的判断是现阶段真正能落地的 text-to-cad基本都走前两条路线而且往往是“大模型 参数化脚本”的混合体。原因很简单工程领域对尺寸精度和可编辑性的要求远高于对“生成多样性”的要求。你生成一个好看的椅子模型没用你要的是孔位对得上、公差算得准、能导出 STEP 进装配体。2.2 为什么出口格式选 STEP、GLB、STL这三个格式不是随便选的它们对应三种完全不同的下游需求选错了会直接卡住后续流程。格式本质典型用途关键特点STEP边界表示B-rep实体传统 CAD 编辑、装配、出图保留精确几何和拓扑可参数化修改GLB三角网格 材质网页展示、AR、游戏引擎轻量、带材质、加载快但不可精确编辑STL纯三角网格3D 打印、切片、仿真前处理只有表面三角形无单位无材质我踩过的一个坑早期我用一个工具生成了模型直接导出 STL 丢进切片软件结果尺寸差了十倍。原因是 STL 本身不携带单位信息有的工具默认按毫米有的按米切片软件又默认按毫米读。后来我养成了习惯text-to-cad 生成后先导出 STEP 确认尺寸再导出 STL 去打印。STEP 里单位是明确的能帮你验证几何到底对不对。另一个坑是 GLB 的精度。GLB 是网格格式曲面会被三角化一个圆柱面可能被切成几十个平面。如果你拿 GLB 去做后续的布尔运算或者精确装配误差会累积。所以我的原则是要编辑走 STEP要展示走 GLB要打印走 STL三者不要混用。2.3 参数化脚本为什么是核心资产在 text-to-cad 的整个链路里我认为最有价值的不是那句自然语言而是它翻译出来的参数化脚本。自然语言是一次性的脚本是可以反复用的。你把“80 毫米法兰盘”改成“100 毫米法兰盘”只需要改一个变量不用重新描述一遍。这也是我为什么倾向于选择 CadQuery 或 build123d 这类 Python 参数化库作为后端。它们的代码可读性好社区活跃能直接导出 STEP 和 STL。OpenSCAD 也不错但它的语言更偏声明式复杂模型的代码组织起来比较费劲。下面是一段典型的 CadQuery 代码描述一个带中心孔和四个角孔的板import cadquery as cq length 80.0 width 80.0 thickness 10.0 center_hole_d 30.0 corner_hole_d 6.0 corner_offset 10.0 result ( cq.Workplane(XY) .box(length, width, thickness) .faces(Z).workplane() .hole(center_hole_d) .faces(Z).workplane() .rect(length - 2*corner_offset, width - 2*corner_offset, forConstructionTrue) .vertices().hole(corner_hole_d) ) cq.exporters.export(result, flange.step) cq.exporters.export(result, flange.stl)这段代码里所有尺寸都是变量。你让大模型生成这样的代码比让它直接生成几何要靠谱得多。因为代码的语法是确定的几何内核会帮你处理布尔运算、倒角、抽壳这些容易出错的细节。3. 核心细节解析从描述到几何的关键环节3.1 描述的结构化把“人话”翻译成“工程话”大模型对自然语言的理解能力很强但它对工程语义的把握需要你引导。我总结了一个描述模板实测下来生成的脚本成功率明显更高。模板包含五个要素基体形状、总体尺寸、特征列表、特征位置、单位与公差。举个例子不要写“画一个带孔的方块”而要写“创建一个长方体基体长 80 毫米宽 60 毫米高 20 毫米在顶面中心创建一个直径 30 毫米的贯穿圆孔在顶面四角各创建一个直径 6 毫米、深 10 毫米的盲孔孔中心距边缘 10 毫米”。后者虽然啰嗦但模型能准确提取出每一个参数。这里有个经验尺寸尽量用数字位置尽量用坐标系或相对基准描述。说“左边那个孔”模型可能理解成 X 负方向也可能理解成 Y 负方向歧义就来了。说“孔中心位于 X-30, Y20”就没有歧义。如果模型支持直接在描述里带上坐标系约定比如“以基体底面中心为原点Z 轴向上”。3.2 几何内核的选择为什么精度是生命线text-to-cad 生成的脚本最终要交给几何内核去执行。常见的开源内核有 OpenCASCADEOCCTCadQuery 和 build123d 都基于它。OCCT 的布尔运算能力很强但偶尔会在复杂倒角或薄壁特征上失败。商业内核如 Parasolid、ACIS 更稳但不开源。我遇到过一次典型的布尔运算失败一个带内凹圆角的壳体抽壳之后再做倒角OCCT 直接报错。排查后发现是抽壳后的壁厚在某些位置小于倒角半径几何上不可行。解决办法是把倒角半径改小或者调整抽壳顺序。这件事给我的教训是text-to-cad 生成的脚本一定要在几何层面做可行性检查不能盲信大模型的输出。实操中我会加一层校验生成脚本后先跑一遍捕获异常如果失败把错误信息回传给大模型让它修正。这个“生成-执行-反馈-修正”的循环比一次性生成的成功率高得多。一般两到三轮就能收敛。3.3 单位与坐标系的坑单位问题我在前面提过这里再展开说。STEP 文件在头部会声明单位通常是毫米。STL 没有单位声明只有一堆三角形坐标。GLB 按 glTF 规范默认单位是米。这三个格式混用的时候单位换算必须手动处理。我的做法是在参数化脚本里统一用毫米导出 STEP 时保持毫米导出 STL 时也按毫米导出 GLB 时乘以 0.001 转成米。这样每个下游工具拿到的都是它期望的单位。如果你不做这个转换GLB 在网页里显示会大一千倍或者小一千倍看起来就像模型消失了。坐标系也是类似。CAD 里常见的约定是 Z 轴向上但 glTF 和很多游戏引擎是 Y 轴向上。导出 GLB 的时候如果不做坐标变换模型会躺倒。我一般会在导出前加一个旋转把 Z-up 转成 Y-up。这个细节看起来小但不处理的话展示效果直接崩。4. 实操过程搭一个能跑的 text-to-cad 流水线4.1 环境准备与依赖安装我用的技术栈是 Python CadQuery 一个大模型 API。CadQuery 的安装推荐用 conda因为它的依赖里有 OCCTpip 装有时候会缺库。conda create -n text2cad python3.11 conda activate text2cad conda install -c conda-forge cadquery pip install openai如果你不想用 conda也可以试试 pip 安装 cadquery-ocp但我在 Windows 上遇到过 DLL 缺失的问题conda 省心很多。装完之后跑一句import cadquery不报错环境就算通了。大模型这边我用的是支持函数调用或者结构化输出的接口。核心思路是让模型输出一段符合 schema 的 JSON再由我的程序把 JSON 转成 CadQuery 代码。这样做的好处是模型不需要懂 CadQuery 语法只需要填参数出错概率低。4.2 描述解析与 JSON schema 设计我设计的 schema 大概长这样{ base: { type: box, length: 80.0, width: 60.0, height: 20.0 }, features: [ { type: hole, face: top, position: [0, 0], diameter: 30.0, depth: through }, { type: hole, face: top, position: [-30, 20], diameter: 6.0, depth: 10.0 } ], unit: mm }这个 schema 覆盖了最常见的基体加特征模式。基体支持 box、cylinder、sphere特征支持 hole、slot、fillet、chamfer。位置用二维坐标表示在指定面上深度用数值或 through 表示贯穿。把这段 schema 作为提示词的一部分给大模型让它把用户描述填进去。实测下来只要用户描述不是特别离谱填充准确率能到八成以上。剩下的两成靠执行反馈来修。4.3 JSON 到 CadQuery 的转换转换层是我自己写的核心是一个递归函数根据 feature 类型调用不同的 CadQuery 方法。下面是一个简化版import cadquery as cq def build_from_spec(spec): base spec[base] if base[type] box: wp cq.Workplane(XY).box(base[length], base[width], base[height]) elif base[type] cylinder: wp cq.Workplane(XY).cylinder(base[height], base[radius]) for feat in spec[features]: if feat[type] hole: wp wp.faces(Z).workplane() wp wp.pushPoints([tuple(feat[position])]) if feat[depth] through: wp wp.hole(feat[diameter]) else: wp wp.cboreHole(feat[diameter], feat[diameter], feat[depth]) elif feat[type] fillet: wp wp.edges(|Z).fillet(feat[radius]) return wp这段代码里faces(Z)表示选 Z 方向最高的面pushPoints把工作平面移动到指定位置hole打贯穿孔cboreHole打沉头孔。这些 API 是 CadQuery 的标准用法文档里有详细说明。转换完之后导出 STEP 和 STLresult build_from_spec(spec) cq.exporters.export(result, output.step) cq.exporters.export(result, output.stl)如果要 GLBCadQuery 本身不直接支持我会先用 trimesh 读 STL再导出 GLBimport trimesh mesh trimesh.load(output.stl) mesh.export(output.glb)4.4 执行反馈与自动修正这一步是让整个流水线“能自己爬起来”的关键。我把执行过程包在 try-except 里捕获异常后把错误信息和原始 spec 一起回传给大模型让它输出修正后的 spec。def generate_with_retry(description, max_retries3): spec llm_parse(description) for i in range(max_retries): try: result build_from_spec(spec) return result, spec except Exception as e: spec llm_fix(spec, str(e)) raise RuntimeError(多次修正后仍失败)实测下来大部分失败是尺寸矛盾比如孔比基体还大或者特征顺序问题先倒角后打孔导致倒角被切掉。把错误信息给模型它通常能自己调整。我遇到过一个案例用户描述“在圆柱侧面打一个径向孔”模型一开始把孔打在了顶面执行没报错但几何不对。这种“不报错但结果错”的情况反馈机制救不了需要人工检查。所以我的流程里始终保留一步生成后导出 STEP用 CAD 软件打开肉眼确认。5. 常见问题与排查技巧实录5.1 生成失败类问题速查现象可能原因排查方法解决思路脚本执行报错尺寸矛盾或特征顺序错看异常堆栈定位到具体操作回传错误让模型修正布尔运算失败几何不可行薄壁、自交检查壁厚与倒角半径关系调整参数或改变操作顺序导出 STEP 为空工作平面选错打印实体包围盒修正 faces 选择器STL 尺寸不对单位不一致对比 STEP 与 STL 包围盒统一按毫米导出GLB 显示躺倒坐标系约定不同检查 Y-up 与 Z-up导出前旋转模型这个表是我踩坑踩出来的基本覆盖了八成以上的常见问题。其中“布尔运算失败”最隐蔽因为报错信息往往很底层看不懂。我的经验是遇到布尔失败先简化模型把倒角、抽壳这些容易出问题的特征去掉确认基体和孔没问题再逐个加回来定位到具体是哪个特征导致的。5.2 尺寸精度与公差处理text-to-cad 生成的模型尺寸精度取决于几何内核和导出格式。STEP 是精确的STL 是三角化的精度取决于弦高公差。CadQuery 导出 STL 时可以指定 tolerance 参数cq.exporters.export(result, output.stl, tolerance0.01)tolerance 越小三角面越密文件越大但曲面越光滑。做 3D 打印一般 0.01 到 0.05 毫米够用。做仿真可能要更小。我一般先用默认值生成看效果再调。公差方面text-to-cad 目前不会自动加公差。如果你要打孔配轴得自己在描述里写“孔径 6.1 毫米轴径 5.9 毫米”这种带公差的尺寸。指望模型理解“H7 配合”这种工程语义目前还不现实。5.3 复杂模型的拆解策略一句话生成复杂装配体目前基本做不到。我的策略是分而治之把复杂模型拆成多个简单零件每个零件单独生成最后在 CAD 里装配。比如一个带电机座、联轴器、底板的机构我会分别生成三个零件导出三个 STEP再在 FreeCAD 或 SolidWorks 里组装。这样做还有个好处每个零件的脚本可以独立复用。底板换个尺寸只改底板的脚本电机座不动。这比一次性生成整个装配体要灵活得多。5.4 批量生成与参数扫描text-to-cad 真正体现价值的地方是批量生成。比如你要做一系列不同长度的支架长度从 50 到 200 毫米步长 10 毫米。手动建模要建 16 个用脚本就是一个循环for length in range(50, 201, 10): spec base_spec.copy() spec[base][length] length result build_from_spec(spec) cq.exporters.export(result, fbracket_{length}.step)十几秒跑完16 个 STEP 文件整整齐齐。这种场景下text-to-cad 的效率优势是碾压性的。热词里出现的“python 批量对 cad 修改”说的就是这个思路。你甚至可以把描述也参数化让大模型针对每个尺寸生成不同的特征组合做设计空间的探索。6. 工具选型与生态现状6.1 开源方案对比我试过几个开源方案各有侧重。CadQuery 的 Python API 最成熟文档全社区活跃适合做后端。build123d 是 CadQuery 的“精神续作”API 更 Pythonic但生态还在建设。OpenSCAD 适合做纯声明式的参数化模型但复杂模型代码难维护。FreeCAD 有 Python 控制台可以脚本化但它的 API 比较啰嗦。如果你要从零搭 text-to-cad我推荐 CadQuery 起步。它的学习曲线平缓遇到问题搜得到答案。等熟悉了再考虑 build123d 或者直接调 OCCT。6.2 大模型的选择与提示词工程大模型这边我试过几个主流接口。关键不是模型多大而是它能不能稳定输出结构化 JSON。支持 function calling 或者 JSON mode 的接口会省很多事。提示词里我会明确写“只输出 JSON不要输出任何解释文字”并且给出完整的 schema 和两个示例。这样模型的输出格式基本不会跑偏。还有一个技巧把常见的几何操作写成 few-shot 示例。比如给一个“打贯穿孔”的示例一个“打盲孔”的示例一个“倒圆角”的示例。模型看到示例后填充新描述时会更准确。这比单纯描述 schema 有效得多。6.3 与现有 CAD 工作流的衔接text-to-cad 生成的 STEP可以直接导入 SolidWorks、中望 CAD、Fusion 360 做后续编辑。我通常的流程是text-to-cad 生成基础几何导出 STEP导入 CAD 软件做倒角、圆角、工程图这些精细活。这样分工程序干重复性的粗活人干创造性的细活。如果你用的是 FreeCAD还可以直接用 Python 脚本控制把 text-to-cad 的脚本和 FreeCAD 的宏结合起来实现全自动流水线。热词里提到的“cad 快速看”“cad 图纸合并”其实都可以用类似的脚本化思路来加速。7. 我踩过的坑与实操心得第一个坑是过度信任模型的几何理解。有一次我描述“在板的四个角各打一个孔”模型把孔打在了四条边的中点。原因是“角”这个词在它的训练数据里有时指 corner有时指 edge。后来我改成“孔中心距相邻两边各 10 毫米”就再没出过错。这件事让我明白工程描述要消除一切歧义宁可啰嗦不要含糊。第二个坑是忽略了几何可行性。我让模型生成一个“壁厚 2 毫米、内圆角半径 5 毫米”的壳体脚本执行直接失败。因为内圆角半径大于壁厚几何上不可能。模型不懂这个约束它只管填参数。后来我在 schema 里加了一条校验规则内圆角半径必须小于最小壁厚。这种领域约束得靠人提前定义。第三个坑是导出格式选错。早期我图省事所有下游都用 STL结果做装配的时候发现孔位对不上因为 STL 的三角化让圆柱孔变成了多边形。后来改成装配用 STEP打印用 STL展示用 GLB各司其职问题就没了。最后一个心得是text-to-cad 不是替代 CAD而是 CAD 的前置加速器。它帮你把想法快速变成可编辑的几何省掉从零建模的时间。但精细调整、公差标注、工程图出图还是得靠传统 CAD。把两者结合起来用效率提升最明显。我现在做新项目都是先用 text-to-cad 生成基础模型再导入 CAD 精修整体时间能省一半以上。

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

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

免费获取报价 →
↑