最近我在处理一批机械结构件的参数化建模需求时,发现一个有点反直觉的现象:用大模型直接生成 3D 模型,速度和视觉效果都已经很好了,但真正进入工程流程时会被卡住。因为生成出来的模型往往是“被烘烤好的网格”,好看,却不好改,更没法回到建模树里调整一个圆角、一个壁厚,或者把装配体拆成独立可编辑的零件。
另一条路线完全不同:让大模型写建模代码。不直接输出一个 .obj 网格,而是输出 OpenSCAD、CadQuery 或者 Python 脚本,由这些代码在本地编译、渲染成可编辑的三维实体。这条路线看起来不如“一句话生成一个模型”炫酷,但它解决的是更关键的问题——可编辑性和可分解性。这正好是标题里“自带可编辑零件分解”的核心含义。
这篇文章我会用实际操作来聊聊这条路线真正适合哪些场景,以及从提示词到可编辑零件模型之间,到底还有哪些坑。
1. 先理解一下:大模型做 3D 建模,为什么要把模型变成代码
1.1 传统 AI 生成 3D 模型的本质问题
先不讨论哪家生成质量更高,只说数据格式。
传统文生 3D、图生 3D 方案,输出结果几乎都是网格模型。网格模型本质上是一堆顶点、边和三角形面片拼出来的外壳快照。它对“形状”的表达非常直观,但对“设计意图”几乎是盲区。
举个例子。你让一个文生 3D 工具生成一个“M6 法兰连接件”,它可能给你一个看上去很光滑的圆盘,圆盘上分布着几个孔。但这个圆盘中心孔直径到底是不是 20 毫米?四个螺栓孔的分布圆直径是多少?孔位之间的角度误差是否满足装配要求?这些信息在生成网格时并没有真正被计算,只是视觉上“看起来像”。
任何一个机械工程师拿到这种模型,都只能对照实物重新建模。因为网格模型里没有参数,没有特征树,没有“这个孔是沉头孔”这种语义信息。它记录的是结果,不是过程。
所以传统 AI 生成 3D 的真正痛点不是“生成得不够像”,而是“生成完没法进入下游流程”。改一个孔径,等于把整个模型打回重做;拆一个零件,等于手工切割网格。对于想要把 AI 嵌入实际工作流的人来说,这几乎不可用。
1.2 代码生成模型:把建模变成程序执行
代码驱动建模完全不同。
大模型输出的是源代码,这段代码定义了模型的全部几何信息和构建过程。执行代码时,建模软件会重新计算一遍构造过程,得到精确的实体模型。模型不是被“画”出来的,而是被“算”出来的。
在 OpenSCAD 里,模型可以定义成这样:
// 法兰盘主体 module flange(outer_d, inner_d, thickness) { difference() { cylinder(h = thickness, r = outer_d / 2); cylinder(h = thickness + 0.1, r = inner_d / 2); } }这段代码表达的含义非常明确:先创建一个外径为 outer_d 的圆柱,然后减掉一个中心孔圆柱。以后要改外径,只需要修改参数 outer_d 的值。如果你需要同一零件的不同规格,调用同一个 module 传不同参数就行。
这就是我一直想强调的判断:
用大模型做 3D 建模,真正有价值的不是“生成快”或者“生成像”,而是把设计意图从“死网格”变成“活程序”。
程序可以重新执行,参数可以调整,模块可以复用,代码可以进入版本管理。这才有可能从一次性的视觉生成,升级成可维护的建模工作流。
过去这条路线之所以少见,一方面是因为程序化建模本身有学习门槛,另一方面是因为大模型写代码的能力不够稳定。但现在已经不一样了。大模型在生成 OpenSCAD、CadQuery 这类代码时,训练语料相对充足,输出质量已经达到“可以进入工程纠正流程”的水平。
2. 代码驱动建模的技术组合,以及零件分解是怎么实现的
2.1 三条主流路线:OpenSCAD、CadQuery、Python 建模脚本
如果你打算尝试代码驱动 3D 建模,第一步不是写提示词,而是先选建模后端。大模型本质上是一个能写代码的建模助理,你选哪门“建模语言”,直接决定输出能不能落地。
常见选择有这几条:
| 方案 | 语言形态 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| OpenSCAD | 声明式 CSG 建模语言 | 3D 打印结构件、参数化外形验证 | 语法简单,几何逻辑直观,大模型生成成功率高 | 不适合复杂曲面和精细外观 |
| CadQuery | Python 库 | 机械零件、需要导出 STEP 的 CAD 流程 | 基于真实 B-Rep 内核,能导出标准 CAD 格式 | 学习曲线稍高,链式 API 报错不如 OpenSCAD 直观 |
| trimesh / Python | Python 库 | 网格布尔、批量变体生成 | 灵活,容易接入批量数据处理流程 | 编辑性弱于参数化建模 |
| Blender bpy | Python API | 结构件加渲染、动画辅助 | 生态大,可视化强 | 官方 API 变动频繁,大模型生成时容易踩版本坑 |
从个人经验来看,如果你只是想验证“大模型写建模代码”这条路是否可行,首选 OpenSCAD。原因很简单:语法足够简单,逻辑就是几何组合,而且大部分报错信息能直接告诉你哪里有问题。
如果目标是和机械加工、仿真流程衔接,CadQuery 会更合适。它能导出 STEP、STL 等格式,和传统 CAD 生态的兼容性更好。
2.2 可编辑零件分解的本质是模块化代码
很多人在看到“自带可编辑零件分解”这个描述时,会以为大模型输出的是一个已经被切割好的网格零件列表。其实不是。
可编辑零件分解真正落地时,通常发生在两个层面。
第一个层面是代码层面的分解。建模代码中每个零件都是一个独立 module 或函数,并且显式定义了相对坐标的变换。这样每个零件在逻辑上都是独立单元,可以单独编译导出,也可以重新排列。
第二个层面是构建层面的分解。生成代码时同时生成一个“零件清单”,声明每个零件的名称、属性、装配偏移、旋转角度。这本质上是一个层次化数据模型。后期可以像操作树状结构一样操作零件。
举个例子。要建模一个“带底座和顶部法兰的阀体”,大模型生成的代码结构可以是这样的:
def base(): # 底座结构 pass def valve_body(): # 阀体主体 pass def top_flange(): # 顶部法兰 pass def assembly(): # 调用 base() + valve_body() + top_flange() # 用 transform 指定相对位置 pass表面看都是代码,但核心在于:每个零件都可以单独修改、单独测试、单独导出。这是网格模型完全做不到的。
当你修改 valve_body 的某个尺寸时,不需要手动调整顶部的翻边位置。因为装配关系是通过代码里的空间变换定义的,重新编译一次,翻边位置会自动跟随更新。这就是“可编辑”和“可分解”真正价值所在。
3. 从提示词到可编辑零件模型:一条可执行的老实路线
3.1 先拆分需求,而不是让大模型“自由发挥”
想要让大模型生成可用的代码模型,第一件事不是写提示词,而是拆需求。
建议按照下面这个顺序来拆:
- 确定建模后端和输出格式。
- 把模型拆成语义部件:主件、子件、孔、槽、圆角、装配基准。
- 给关键尺寸定义变量名。
- 描述零件之间的装配偏移。
- 明确输出的约束条件:单位、公差、哪些尺寸必须保持参数关系。
一个提示词,不能是“帮我生成一个机器人”这种一句话需求。更接近工程实践的写法是下面这样:
请用 OpenSCAD 编写一个参数化法兰连接件模型。 设计要求: - 外径变量 outer_d,默认 50mm - 内径变量 inner_d,默认 20mm - 厚度变量 thickness,默认 8mm - 螺栓孔数量变量 bolt_num,默认 4 - 螺栓孔分度圆直径 bolt_circle_d,默认 38mm - 螺栓孔直径 bolt_d,默认 5.5mm - 所有孔必须均匀分布在分度圆上 - 每个零件定义为独立 module - 导出前需要保证布尔运算不发生共面错误这个提示词给了大模型明确的变量、关系和默认值。相比“生成一个法兰盘”,这种写法的质量和成功率会高很多。
3.2 让每个零件都可以独立编辑
在提示词里还要加上模块化要求。比如:
“将每个零件作为独立 module 定义,并在 assembly() 中通过 translate/rotate 完成装配,不修改基础模块的尺寸关系。”
为什么要强调这一点?因为如果大模型把所有几何都写在一个大函数里,生成一个“实心的整体模型”,那就失去了可零件分解的意义。加上模块化要求后,后续改孔位、改外径、改螺栓数量,都只需要修改参数,而不需要改装配逻辑。
这是提示词和使用者之间的分工问题。大模型负责生成代码,你负责定义工程结构。不要指望它自动理解“这里需要一个可编辑零件”,除非你明确写出来。
3.3 最小可行示例:从单个零件到装配体
下面给出一个 OpenSCAD 示例,展示代码建模输出会是什么形态。这个代码结构不一定只由大模型生成,但它是一种常见输出结果。
module flange(outer_d, inner_d, thickness, bolt_num, bolt_circle_d, bolt_d) { difference() { cylinder(h = thickness, r = outer_d / 2, $fn = 64); cylinder(h = thickness + 0.1, r = inner_d / 2, $fn = 64); // 分布螺栓孔 for (i = [0 : bolt_num - 1]) { angle = i * 360 / bolt_num; translate([cos(angle) * bolt_circle_d / 2, sin(angle) * bolt_circle_d / 2, -0.05]) cylinder(h = thickness + 0.1, r = bolt_d / 2, $fn = 32); } } }这个代码里有几个特别值得注意的点。
孔的高度要略大于厚度,这是为了在布尔减运算时避免共面误差。$fn 分段数设置得越高,圆柱越接近真正的圆形,但渲染和编译会越慢。分度圆上的孔通过角度计算均匀分布,而不是手工指定每个孔的坐标,这样当 bolt_num 改成 6 时,孔位会自动重排。
如果要生成一个带底座的装配体,大模型还需要生成一个 assembly 模块:
module assembly() { flange(outer_d = 50, inner_d = 20, thickness = 8, bolt_num = 4, bolt_circle_d = 38, bolt_d = 5.5); translate([0, 0, 12]) cylinder(h = 20, r = 15, $fn = 48); }这里就是“零件分解”的关键:每个零件模块是独立的,装配时仅通过 translate/rotate 进行空间变换。这样在代码层面就维护了一个装配树。
3.4 实际执行时先从单零件验证
不要一上来就生成整个装配体。更稳妥的做法是:先让大模型写一个基础零件,渲染确认几何形状正确,再逐步加上孔、倒角和装配关系。
这样做的好处是,当报错发生时,能够快速定位错误发生在哪个模块。如果一开始就是一个几百行的大装配体,报错时你会面对一大段代码,很难判断是语法问题、几何问题还是参数问题。
当生成的模型出现尺寸不对时,只需要改一两个变量;出现定位不对时,只需要调整 translate;出现布尔运算失败时,通常需要检查两个曲面是否完全共面,或者精度参数是否太低。
4. 网格生成和参数化代码的真正分水岭
4.1 网格模型为什么难以修改
网格模型是顶点、边、三角形面的集合。要在网格模型上修改一个孔的直径,你需要移动孔周围一圈顶点的坐标,重新计算法线,处理可能出现的三角形退化。如果没有原始建模信息,这几乎等同于手工重建。
代码模型则把参数暴露在源码里。修改一个变量,整个模型在重新编译时同步更新。对于需要反复调整的设计场景,这种方式要可靠得多。
这也是为什么很多人第一次用代码建模时会觉得“不习惯”:你不再通过鼠标拖拽来修改模型,而是通过修改参数和逻辑来改变模型。但一旦接受这种思维方式,批量修改和版本管理就会变得非常高效。
4.2 为什么代码生成方式更依赖“理解力”而不是“绘画天赋”
传统 AI 生成是“画出形状”,代码生成是“编写算法”。
所以,大模型在写建模代码时表现出的能力,其实和它在软件开发中的表现更接近:它擅长组合常用函数、生成常见模式,但你需要给它足够的约束,它才能保证逻辑正确。
你给它的提示词越接近一份“程序需求文档”,它输出的结果就越接近一个“可运行程序”。反过来,如果你给它的提示词还是“设计一个漂亮的工业产品”,它大概率会生成一个中规中矩、但不一定满足工程需要的代码。
这也是为什么很多“AI 生成 3D 模型”的演示最终翻车。不是模型不够漂亮,而是没有形成可供编辑的源文件。缺少源代码,就没有真正的可编辑性,也没有零件分解的可能。
4.3 零件分解的真正意义不止是“拆开看”
“自带可编辑零件分解”的价值需要说透:它不是雕花式的视觉亮点,而是让设计流程可逆转、可追踪、可复用。
当你在装配体中修改一个零件的尺寸,其他关联零件是否能够同步更新?如果用网格模型拼装,修改一个零件,几乎等于整体回到原点重做。如果是代码装配体,每个零件的体积、重心、装配偏移都可以程序化查询,可以直接导出成 STEP 给加工或仿真环节,也可以版本化记录设计演进。
从长期使用体验看,真正让人愿意坚持用代码建模的原因,不是因为它看起来“AI”,而是因为它把设计协作方式变成了一种工程师能理解、能 review、能回滚的文本文件协作方式。模型文件从二进制黑盒变成了可阅读的源代码。
5. 实操中常见的症状、原因和排查链路
5.1 症状一:代码能编译,但模型是空的
这是新手最容易遇到的问题。代码没有直接报错,但渲染结果里什么都没有。
排查顺序:
- 先看是不是没有调用 module。在 OpenSCAD 里,如果你只定义了 module 但没有在文件顶层调用,渲染结果自然为空。
- 再看是不是所有尺寸值都被布尔运算减掉了。比如
outer_d和inner_d设置成了近似值,导致环形部分厚度接近零。 - 再看是不是没有写
difference()里的保留部分。常见的错误是difference(){ cylinder(...); cylinder(...); }中两个圆柱半径相等,导致整个实体被完全减掉。
这种情况,首先检查代码层,然后检查参数层,基本都能定位。
5.2 症状二:几何正确,但装配错位
如果每个零件单独渲染都是对的,但放在一个 assembly 里就乱了,问题通常出在两个地方。
第一是坐标系基准不一致。每个零件模块内部使用的坐标原点,和装配时使用的原点是否一致?如果不一致,装配变换就会偏移。
第二是旋转轴理解错误。在 OpenSCAD 里,默认坐标系 X 向右、Y 向后、Z 向上。转一个 90 度,到底是绕 X 轴还是绕 Y 轴,需要自己在脑内模拟一遍。
更稳妥的排查方式:先用简单的立方体替换每个零件模块,验证装配变换是否正确,再替换回真实几何。
5.3 症状三:尺寸和想象不一致
最常见的原因有三个:单位不一致、直径半径混用、plus 或者 offset 加得不对。
在提示词里我通常建议明确写上“外径变量 outer_d”,然后代码里用r = outer_d / 2,而不是让模型自己决定。半径和直径在工程里是两种完全不同的语言,一旦默认理解不一致,出来就是两倍尺寸的模型。
另一个常见的坑是补偿值。比如你为了让布尔运算不产生共面,把孔的高度加了 0.1。但如果这个 0.1 的补偿方向弄反了,模型会多出一条 0.1mm 的台阶。这个量级在视觉渲染里几乎看不出来,但在 3D 打印或加工时是致命误差。
5.4 症状四:布尔运算报错
大多数时候是几个曲面完全共面。例如两个圆柱体底面完全在同一个平面上,做 difference 运算时,建模内核无法判断哪个面在前。
解决办法很简单:让被减的体稍微多出一点点厚度,比如thickness + 0.1或者thickness + 0.05。这个 0.05 到 0.1 的“过盈量”能有效避免 CGAL 精度相关问题。
如果问题依然存在,尝试增加 $fn 分段数。分段数太低时,圆柱其实是棱柱,近似的面之间更容易产生拓扑错误。
5.5 一个通用的排查顺序
无论遇到什么类型的模型异常,建议都按照下面这个顺序来排:
- 看现象:是编译失败、渲染为空、尺寸错误,还是位置偏移?
- 看代码:模块是否被调用、参数是否合法、括号和函数名是否正确。
- 看输入:单位是什么、直径半径是否混用、默认值是否合理。
- 看环境:当前 OpenSCAD / CadQuery / Python 的版本是否和代码用的函数匹配。
- 看参数:精度、分段数、布尔运算的过盈量是否设置得当。
- 最后再判断工具边界:当前后端是否支持你要表达的几何形状。
这个顺序的好处在于,你每一步都只检查一个变量。不要一上来就去改参数,因为你可能还没确认代码逻辑是通的。
6. 适用的场景、需要避开的场景,以及工程化落地建议
6.1 适合什么场景
从实际落地角度看,代码驱动建模最合适的有这四类场景。
第一类:非标零件参数化。比如要做一个尺寸可调的支架、连接件、法兰盘。用参数变量控制关键尺寸,改动起来极其高效。
第二类:3D 打印前的结构验证。OpenSCAD 生成的 STL 可以直接进入切片软件,适合快速验证外壳、紧固件安装位和装配关系。
第三类:教学案例。代码本身就是建模过程的文档,学生可以直接阅读几何构造步骤,比看网格模型更容易理解建模逻辑。
第四类:批量规格变体。比如需要生成不同尺寸的产品系列,只要把参数值批量传进去重新编译一次,就能得到一整套模型。这是手工建模很难做到的。
6.2 不适合什么场景
必须把边界说清楚,否则容易误判。
不适合有机曲面和高精度外观设计。比如人物手办、动物形态、自由曲面汽车外观。这些场景需要雕塑式的建模能力,代码描述会非常痛苦。
不适合极复杂的装配体。如果一个装配体有成百上千个零件,代码文件会变得极长,生成和调试都变得困难。这种场景下传统 CAD 的装配模块仍然更合适。
不适合需要精细视觉美感的设计。代码建模能保证几何正确,但很难做出流线型、富有设计感的曲面外观。它的优势在结构,不在颜值。
6.3 如果要长期使用,还需要补哪些工程能力
如果你只是想体验一下,OpenSCAD 加一段提示词就够了。但要是打算把它放进正式项目,还需要补四块拼图。
第一块是版本控制。把模型代码放进 Git 仓库。这样每次设计变更都有记录,回滚方便,多人协作时也能知道谁改了什么。
第二块是自动编译测试。写一个脚本,每次提交代码后自动运行建模编译器,确认没有报错,并导出标准格式文件。这比手动打开编辑器检查可靠得多。
第三块是参数清单文档化。把每个变量的含义、允许范围、默认值写清楚。代码读得懂,但参数含义如果不记录,一个月后你自己都会忘。
第四块是 CAD 后处理衔接。如果目标是加工或仿真,还需要考虑如何从代码模型导出 STEP、IGES 等标准格式,以及如何处理单位、坐标和公差。
这些不是大模型能帮你解决的,属于工程化基本功。你可以让大模型生成代码,但工程流程需要自己搭起来。
6.4 回到长期价值
从整个行业演进的大方向看,代码驱动建模不一定要取代传统 CAD,也不太可能彻底取代手工建模。但它确实打开了另一条路径:让几何生成从“手工绘制”推进到“程序化生成 + AI 辅助”的新阶段。这个阶段里,模型不再是静态的网格快照,而是可编辑、可复用、可版本化的工程资产。
用大模型写代码做 3D 建模,本质上是把大模型当成一个非常熟悉建模语言、但偶尔需要你检查逻辑的协作工程师。你的工作不是替它写每一行代码,而是把需求拆清楚、把边界定清楚、把验证流程跑通。
下一步最值得先做的事,不是去追更多花哨功能,而是找一个你实际需要的小零件,用最小提示词跑通一次从需求到代码再到实体文件的完整流程。先跑通,再优化,最后再考虑批量化和自动化。这一步走扎实了,后面才谈得上真正的工程效率提升。