用大模型写代码做高精度3D建模,这个方向最近值得认真看。它解决的并不是“文字直接生成一个能看的模型”,而是让大模型把自然语言需求转成可执行的建模脚本,再由脚本程序生成高精度、参数化、可编辑的三维实体。核心价值一句话:模型不是一次性生成的贴图,而是“代码即模型”,可以改尺寸、拆零件、进CAD、出工程图。
这个思路绕开了直接生成三维网格的路线。传统AI生成模型通常输出点云、隐式场或网格,视觉上很像,工程上却很难用。代码生成路线把大模型最擅长的需求理解和代码生成,与程序化建模的精确几何计算、参数化、可重复执行结合起来。后面我会按这个路径拆一遍:先讲原理和对比,再讲环境、实测、零件分解、常见排查,最后给落地建议。
1. 先看清楚:为什么是“写代码建模”而不是“直接生成模型”
1.1 传统AI生成3D模型的短板在哪里
在计算机图形学里,AI生成三维内容主要有几条路线:文字或图片生成点云、生成隐式神经场再提取网格、直接生成三角网格,以及这两年比较热的三维扩散模型。这些方法在可视化、概念设计、游戏资产预览里效果不错,但一旦进入工程场景,短板非常明显。
第一个问题是拓扑不可控。直接生成的网格往往有密集且无序的三角形,边缘不整齐,表面可能有自交、空洞、非流形边。做渲染可以,做3D打印切片、有限元仿真、CNC加工都会出问题。你很难把这个网格直接丢给一个CAM软件去加工,因为几何内核不接受这种“看着像但内部乱”的网格。
第二个问题是不具备参数化关系。传统生成模型出来的是一堆顶点坐标和面索引,你想改一个孔的直径,实际上代码里没有“孔直径”这个概念。它只是表面形状近似,不是一套有逻辑的建模特征。想精确修改,只能重新生成或手工修复,成本很高。
第三个问题是无法拆零件。复杂机械结构由多个零件装配而成,每个零件有独立的约束、配合关系和公差。直接端到端生成一个整体网格,模型里没有零件分层,也就谈不上“可编辑零件分解”。即便在后处理里做网格分割,也很难把每个零件的语义、尺寸、装配约束完整还原出来。
传统生成方法并不是没有价值。在概念设计、数字内容创作、游戏资产草稿这些对精度要求不高的场景里,它依然有不可替代的位置。但如果你要的是一个能编辑、能制造、能进入生产流程的三维模型,直接生成网格这条路目前走不通。
1.2 代码生成路线的底层逻辑
代码生成路线的做法完全不同。你不让大模型输出三维文件,而是让它输出一段建模脚本,比如CadQuery的Python代码、OpenSCAD脚本,或者Blender的Python API代码。建模脚本里明确定义了从哪里开始画草图、拉伸多少、倒角半径多少、哪个部分是一个独立函数。
程序化建模的精度由几何内核保证,长度就是长度,角度就是角度,导出的STEP文件可以直接被专业CAD软件识别。关键是,代码里的所有数字都是可以改的参数。把变量放在文件顶部,改一个数字,整个模型的尺寸、装配关系都跟着更新。
这就是“大模型写代码做高精度3D建模”的真正含义:大模型负责把模糊需求翻译成结构和参数,程序化建模负责把代码变成实体。AI不直接做几何,而是做“需求转代码”。这一层转移让精度和可编辑性重新回到传统CAD的体系里。
从计算机图形学的角度看,这相当于把“三维内容生成”拆成了两个子任务:语义理解由大模型完成,几何计算由确定性算法完成。大模型不需要知道一条NURBS曲线的数学细节,它只需要知道什么时候调用extrude、fillet、union这些操作。这样既避免了生成式模型在几何精度上的天然劣势,也保留了AI处理自然语言的能力。
1.3 谁适合用这个方案
第一类是机械设计和产品设计的人。要做结构件、外壳、支架、法兰这类规则几何,用这个方案可以快速从一段文字得到一个能修改的CAD模型。第二类是自动化设计方向的开发者。把大模型接到参数化建模库上,实现“需求-代码-模型”的流水线。第三类是计算机图形学的研究者。代码生成提供了一个新的比较对象,它不跟网格生成比谁的表面更平滑,而是比谁的输出更接近工程可用。
如果你只是想要一个好看的雕塑模型,那这个方案不适合。它最适合的,是几何关系明确、需要精确尺寸、需要后续编辑和拆分的场景。下面这张表能更直观地看到两种路线的差异。
| 对比维度 | 直接生成三维网格 | 大模型写代码建模 |
|---|---|---|
| 输出形式 | 点云、mesh、隐式场 | 可执行脚本、参数化模型 |
| 几何精度 | 近似,依赖网格密度 | 高精度,基于几何内核 |
| 可修改性 | 差,难改单一尺寸 | 好,改参数即可 |
| 零件分解 | 需要事后网格分割 | 代码结构天然分层 |
| 工程可用性 | 偏可视化、游戏资产 | 可进CAD/CAM流程 |
| 适合形状 | 有机曲面、自由形态 | 规则机械件、结构件 |
所以,如果你要处理的是“一个带安装孔的电机支架,孔距可以调”,代码生成明显更靠谱。如果你要的是“一个像鲸鱼一样的摆件”,那还是交给三维扩散模型更合适。
2. 环境准备:跑通自然语言到三维脚本需要哪些条件
2.1 大模型怎么接入
先解决一个问题:用哪个大模型。这里不绑定任何具体厂商。你只需要一个代码生成能力较强的大模型,可以是云端API,也可以本地部署。两者的区别主要在数据隐私、延迟、显存资源和成本。
如果是学习验证,我建议优先用API方式,因为流程短,不容易在环境准备阶段被劝退。等确认整个链路没问题,再考虑把模型部署到本地。本地部署需要关注模型大小、量化方式和推理框架,显存不够就把量化等级降一档,但代码生成质量可能略有下降。这里没有“一定最好”的选择,只有“够用”和“不够用”。
需要注意的是,大模型只负责生成脚本,它自己不执行脚本。真正把模型跑出来的是本地的CAD内核。所以即便你本地部署了一个很小的模型,只要它能稳定生成格式正确的脚本,建模效果就不会受影响。反而是那些代码生成能力强、但你不方便接入的云端模型,如果因为网络、费用、数据边界问题没法用,那就等于零。先把能稳定接入的方式确定下来,再考虑“更好的模型”。
2.2 建模内核怎么选
目前常见的选择有三个。
CadQuery,Python库,基于OpenCascade几何内核,能用Python写参数化实体建模,适合机械零件、装配体,导出STEP/STL/AMF,精度很高。缺点是安装体积大,环境依赖稍重。
OpenSCAD,用类似编程语言的方式描述CSG模型,适合规则几何和布尔运算,文件小、启动快,有命令行接口,适合批量处理。缺点是不太适合复杂曲面,界面也相对简陋。
Blender Python API,适合做可视化、动画、游戏资产和复杂表面建模,也能参数化,但工程精度和特征树不如专门CAD工具。
我个人做高精度结构件的验证,会优先用CadQuery。原因是它的建模思路更接近传统CAD:先画草图,再拉伸、旋转、开孔、倒角。而且Python生态方便接入大模型、做自动化校验和批量生成。如果你以前用过OpenSCAD,也可以继续用,只要大模型会写这门语言就行。
2.3 最小环境配置
这里给一个可以照做的参考。安装Python 3.9或更高版本,创建虚拟环境,安装CadQuery和相关依赖。如果用OpenSCAD,就去官网下载对应安装包,并把命令行工具加入PATH。开发环境用VS Code就可以,装好Python扩展,有代码提示,排查大模型生成的脚本会方便很多。
执行下面几条命令可以做基础验证:
python --version python -m venv venv source venv/bin/activate # Windows用 venv\Scripts\activate pip install cadquery python -c "import cadquery; print(cadquery.__version__)"openscad --version如果import cadquery报错,先看是不是虚拟环境没激活,再看Python位数、网络源。CadQuery安装包比较大,因为它包含完整的几何内核,这是正常现象,不是卡死。磁盘预留2到3GB会比较稳。
还要说明一下资源占用。单纯运行CadQuery脚本,8GB内存的开发机完全够用,CPU建模也不会很慢。真正吃资源的是“本地部署大模型”这一步。如果你打算本地推理一个代码生成模型,尽量准备16GB以上内存,并根据显存选择合适尺寸的量化模型。如果只是通过API调用,本地不需要额外的GPU资源。
这里最容易踩的坑是环境没隔离。有人直接把CadQuery装进系统Python,后来又装了其他版本库,结果互相冲突。我建议所有测试都在虚拟环境里做,哪怕只是学习,也要养成这个习惯。后面批量跑的时候,环境隔离能省掉大量“在我电脑上明明能跑”的问题。
3. 第一次实测:从文字需求到高精度模型
3.1 写好提示词的三个要素
第一次测试别一上来就让大模型生成“一个复杂的减速器”。先选一个简单但带有特征的单零件,比如带法兰套筒。这意味着你的提示词必须包含三样东西:产品角色、几何需求、输出格式。
- 产品角色:告诉模型你是一个程序化建模工程师,使用CadQuery。
- 几何需求:外径、内径、高度、法兰尺寸、是否圆角。
- 输出格式:每个零件是函数,参数放顶部,导出STEP和STL,只给代码不要解释。
写清楚单位也很重要。CAD里单位错了会非常麻烦。我会在提示词里显式写“所有尺寸单位默认为毫米”。这样可以减少很多后期返工。
很多人忽略了一个细节:大模型并不知道你要的文件名是什么。你不指定,它就可能生成model.py、part.py、result.step。第一次测试时,建议在提示词里把文件名固定下来,比如“导出文件名为flange_sleeve.step和flange_sleeve.stl”,这样执行后找文件更直观。
3.2 生成CadQuery脚本并执行
下面是一个提示词示例:
你是一个CadQuery建模工程师。请根据以下需求生成Python脚本。 需求:带法兰套筒,法兰直径60mm,厚度5mm;套筒外径40mm,内径30mm,高度15mm。 要求: 1. 每个特征拆成独立函数,便于编辑。 2. 所有参数放在脚本顶部。 3. 生成后导出STEP和STL文件。 4. 只输出可运行代码,不要额外解释。大模型返回代码后,保存为flange_sleeve.py,执行:
python flange_sleeve.py如果一切正常,目录下会出现flange_sleeve.step和flange_sleeve.stl。代码主体大致长这样,但不是唯一写法:
import cadquery as cq # 参数区 flange_d = 60.0 flange_t = 5.0 sleeve_od = 40.0 sleeve_id = 30.0 sleeve_h = 15.0 def make_flange(): return cq.Workplane("XY").circle(flange_d / 2).extrude(flange_t) def make_sleeve(): return ( cq.Workplane("XY") .circle(sleeve_od / 2) .circle(sleeve_id / 2) .extrude(sleeve_h) ) def assemble(): flange = make_flange() sleeve = make_sleeve().translate((0, 0, flange_t)) return flange.union(sleeve) if __name__ == "__main__": result = assemble() cq.exporters.export(result, "flange_sleeve.step") cq.exporters.export(result, "flange_sleeve.stl")这段代码你不一定完全照抄,只是用来理解“零件函数 + 装配 + 导出”的结构。实测时,大模型生成的代码可能略有不同,但只要结构对,能跑通就算成功。
3.3 怎么判断结果是否合格
判断一个生成模型是否合格,有几个标准。
第一,脚本能否无错执行,这是底线。第二,导出后能否被CAD软件正常打开,而不是一个空文件。第三,尺寸是否和需求一致。用FreeCAD、CAD Assistant或者其他软件打开STEP,测量一下套筒内外径和法兰厚度。第四,修改参数后重新运行,模型是否按预期更新。第五,检查零件树。如果导出的STEP里能区分法兰、套筒这两个实体,说明“零件分解”初步生效。
实测时最容易出现的错误是:大模型生成了看起来很完整的代码,但执行时因为API拼写错误、对象名错误而报错。这不是大模型能力不足,而是代码生成场景中常见的“幻觉API”问题。后面会专门说排查方法。
还有一点经验:第一次跑通后,不要立刻清理脚本。先复制一份留档,然后把参数改掉,比如法兰直径改成80mm,再跑一次。这样做是为了确认代码真的和参数联动,而不是恰好生成了一段写死的几何体。如果改参数后模型没变化,说明这段代码不具备可编辑性,需要回到提示词重新约束。
4. 自带可编辑零件分解的实现思路
4.1 零件分解的本质是代码结构化
标题里的“可编辑零件分解”其实不是指模型生成后进行网格分割,而是在代码层面预先定义好零件边界。每个零件是一个函数或对象,有自己的参数、坐标系和建模步骤,装配体由这些零件组合而成。
这样带来的好处是:你可以单独修改某个零件,而不影响其他零件;也可以把某个零件导出成独立文件,单独加工或仿真。这和大模型直接生成一个整体网格有本质区别。网格分割是事后猜测,代码结构是设计时就确定的。
要让大模型具备这个能力,核心在提示词约束。你要告诉它:不要把所有特征写进一个执行到底的长函数里,要按照零件维度拆分。很多模型默认会写“一段到底”的代码,因为这样看起来流畅。但工程要求恰恰相反:每个零件的边界要清晰,函数要短,参数要集中。
4.2 如何约束大模型输出零件清单
我常用的做法,是在提示词里加一段“交付要求”。比如:
交付要求: - 先输出零件清单,每个零件一行:零件名、功能、关键尺寸。 - 每个零件一个独立Python函数。 - 单独写一个assemble函数,把零件按装配关系组合。 - 每个函数都接受参数,参数默认值放在顶部。 - 不要把一个零件内部的多个特征拆到多个顶层函数,也不要跨文件。这样大模型就不太会把零件写散,也不会把多个零件揉成一个复合体。它输出的代码天然带“零件树”,后面的装配、导出、文档生成都方便。
这里的关键不是提示词越长越好,而是要把“边界”说清楚。到底什么算一个零件,什么算一个特征,不同人理解完全不同。比如“底座”和“底座上的螺丝孔”是零件与特征的关系,不是两个零件。漏掉这层说明,模型可能把每个孔都当成一个零件,最后生成一大堆零碎函数。
注意:不要把零件和特征混为一谈。零件是装配级别,特征是零件级别。这个边界在提示词里写得越明确,输出越可控。
4.3 一个典型装配体示例
拿一个简单“L型支架”来举例。支架由底板、立板和加强筋组成。结构如下:
def make_base(): # 底板 pass def make_vertical(): # 立板 pass def make_rib(): # 加强筋 pass def assemble(): base = make_base() vertical = make_vertical() rib = make_rib() return base.union(vertical).union(rib)实际运行时,每个函数内部是CadQuery的建模步骤。因为每个零件都是独立函数,你可以只改make_rib的尺寸,然后重新执行脚本,装配体自动更新。你甚至可以只导出某个零件的STEP文件,做到零件级交付。
真正的装配体还需要考虑相对位置。CadQuery里可以用translate、rotate,OpenSCAD可以用translate和rotate组合。如果零件很多,建议在每个函数里把坐标系先定义好,例如“零件原点放在自己的左下角”,这样装配时对接更清晰。
再提醒一点:装配体的实体如果通过布尔合并,导出的STEP里可能变成一个整体,肉眼看不到零件层级。如果希望保留零件树,可以导出成STEP装配,或者在文档里额外记录每个零件的尺寸和变换关系。这取决于你的下游需要。很多3D打印切片软件只需要一个STL整体;但机械加工、BOM清单、装配仿真,需要的是独立零件数据。
5. 对比传统方法:精度、可编辑性、复用能力
5.1 几何精度与拓扑质量
传统AI生成三维模型,通常输出三角网格。网格的精度取决于面数,面数越多越接近真实形状,但文件变大、计算变慢,而且表面仍然是离散近似。代码生成路线走的是CSG和B-rep,几何体由精确曲面和实体定义。圆柱就是一个精确圆柱,而不是几百个三角形拼出来的近似圆柱。
这一点在“高精度”这个词上尤其重要。如果你要3D打印一个零件,孔的直径是8.05mm还是8.10mm,直接影响装配是否顺利。网格生成的模型需要再重建曲面才能用于制造,而代码生成的模型本身就是CAD原生数据。
从计算机图形学的角度说,网格生成关心“看得像不像”,代码生成关心“尺寸对不对”。这两个目标在工程场景里完全不是一回事。一个模型就算视觉上非常逼真,只要关键尺寸偏差超过公差,就没法进入生产流程。
5.2 修改、复用和批量
传统生成方法里,你改一个模型通常需要重新推理。生成式模型没有“改一个参数”的概念,想要一个尺寸不同的变体,只能重新给条件,结果还不一定连续。代码生成模型则完全不同,所有尺寸都是变量。你只需要批量替换参数文件,就能生成一系列规格。
例如要生成10种不同法兰直径的套筒,写个循环改参数就行,而不是让大模型重新生成10次。这让它非常适合产品系列化设计和自动化批量建模。
批量生成时要注意,不是简单把参数写进循环就完事。还要考虑文件命名、输出目录、日志记录、失败重试。比如批量跑20个配置,跑到第15个报错,如果没有日志,你就不知道前面哪些成功了,哪些失败了。所以在批量之前,一定要先把单条任务跑稳,再谈并发和自动化。
5.3 与网格生成和扩散模型的边界
代码生成也不是万能的。复杂有机形状,比如人物头像、雕塑、树木、地形,用代码去描述会非常困难。这时候网格生成、神经辐射场、三维扩散模型反而更合适。换句话说,这两类方法不是替代关系,而是分工关系:规则机械件用代码生成,自由曲面用直接生成,中间层可以用Blender脚本和程序化几何过渡。
成本上也可以做一些对比。传统生成需要GPU推理,代码生成主要消耗token,以及本地脚本执行。如果你的大模型是API,成本主要是token;如果是本地部署,则主要看显存和推理时间。对于批量建模,token消耗会比网格生成小很多,因为代码本身短,而网格顶点数据非常大。这个判断可以作为一个方向参考,实际成本以你的环境和计费方式为准。
我建议不要陷入“哪种方法更强”的争论。实际项目通常不是纯机械件,也不是纯有机曲面,而是两者混合。一个产品外壳可能是自由曲面,但内部卡扣、螺丝柱、定位孔全是规则特征。这时候可以先用三维扩散模型生成外壳概念,再用代码生成内部结构件,最后在Blender或CAD里合成。关键不是信仰某条路线,而是清楚每种方案适合哪一层。
6. 踩坑记录:常见报错与排查顺序
6.1 脚本能生成但执行报错
这是最高频的问题。现象:大模型给出了完整代码,看起来逻辑没问题,但python xxx.py一执行就报错。常见原因包括:模块没装、API拼写错误、参数类型不匹配、CadQuery版本差异、文件路径不存在。
排查顺序不要乱。先看报错第一行,是ModuleNotFoundError还是AttributeError还是TypeError。如果是模块问题,检查环境;如果是属性问题,把报错中的API名称复制到文档或搜索引擎里查一下,确认这个版本里到底有没有这个方法。很多“幻觉API”就是在这里暴露的。
不要在报错后直接让大模型重新生成一版,那样可能换一种错法。先把报错信息原样贴回去,让它针对性修复,同时提供你本地的CadQuery版本。给模型足够上下文,修复效率会高很多。
6.2 模型尺寸和单位不对
有时候脚本能运行,也导出了文件,但打开后尺寸离谱。比如本来40mm的圆,变成了40英寸,或者因为没指定单位,大模型把直径写成了半径,或者把毫米当成了米。
这个问题靠肉眼看不出来,所以要在流程里加入尺寸校验。生成后,用代码读取实体边界框,和预期尺寸对比。CadQuery里可以获取实体的BoundingBox:
bbox = result.val().BoundingBox() print("长:", bbox.xlen, "宽:", bbox.ylen, "高:", bbox.zlen)如果边界框尺寸和需求不一致,说明参数或单位有误。调整提示词里的单位约束,比手动改每个数字更高效。
6.3 零件分解不彻底
有时大模型生成一个“巨型函数”,把所有特征都写在一个表达式链里,布尔运算一结束,零件就变成一个整体。这样虽然也能用,但和“可编辑零件分解”的目标相去甚远。
解决办法不是修改代码,而是修改提示词。在交付要求里强制增加“每个零件一个函数”,并把“禁止合并多个零件到单个函数”写进去。如果还是不行,可以给模型一个结构模板,让它按模板填空,效果通常更稳定。
还有一个容易被忽视的情况:模型确实把零件拆成了独立函数,但装配时直接用union把所有实体合成了一个。如果下游需要单独零件,就不能用union,而应该生成一个装配体对象,或者把零件分别导出成独立文件。提示词里要写清楚“装配体保留零件边界”,而不是笼统说“组合在一起”。
提示:生成后检查导出文件的实体数量。如果只有一个实体,说明布尔并集把零件焊死了;如果有多个实体,说明零件边界保留得比较好。
6.4 大模型输出不稳定
大模型天生有随机性。同一个提示词,两次生成结果可能差异巨大。要稳定输出,可以采取几个方法:
- 把temperature调低,减少随机性。
- 在提示词中给出固定结构,比如“先零件清单,再代码,再导出”。
- 生成后做自动校验,不合格就重新生成,或让模型根据报错信息修复。
- 把常用提示词和代码模板沉淀成文件,不让模型每次从零想结构。
记住一点:大模型是助手,不是替代品。它擅长快速出草稿,但最终的结构、正确性、版本管理需要你把关。尤其是机械设计领域,一个尺寸错误可能意味着整个零件报废。AI生成代码之后,必须有人工校验这一关。
7. 从Demo到实际项目:落地建议
7.1 先单零件后装配体
不要一开始就让大模型生成一个几十个零件的复杂装配体。先从单零件开始,跑通“提示词-代码-建模-导出-打开”整个闭环。单零件稳定之后,再逐步增加零件数量和装配关系。
我见过不少失败案例,问题不在大模型,而是自己跳过了单零件验证,直接上复杂装配,最后报错信息根本分不清是几何问题还是代码问题。把范围缩小,才能定位问题。
7.2 把提示词沉淀成模板
项目做久了,提示词会反复使用。我会把角色定义、通用要求、交付格式单独放在一个系统提示词文件里,根据需求再动态插入具体尺寸。这样既减少token,也保证输出结构稳定。
模板的核心是“稳定结构 + 可变参数”。固定句写死:“使用CadQuery”“所有尺寸单位毫米”“零件函数化”“导出STEP/STL”,可变部分是具体零件清单和尺寸。这样模型每次都知道自己扮演什么角色,输出结构不会跑偏。
7.3 用自动校验兜底
批量生成时,不能靠人眼一个个看。要写一个校验脚本,自动检查:
- STEP/STL文件是否生成,且非空。
- 实体边界框尺寸是否在允许范围内。
- 布尔运算是否成功,有没有报错。
- 文件名是否符合命名规则。
校验不通过就写入日志,并触发修复流程。自动校验是批量任务的底线,否则在模型生成和脚本执行之间夹着一个不可控的环节,很难长期维护。
一个比较务实的流程是:先由大模型生成脚本,再用静态检查工具扫一遍语法,然后执行脚本,最后用尺寸校验脚本复核模型。只有全部通过,才进入人工确认。这个流程一开始看起来繁琐,但能救命。
7.4 模型选型与资源规划
到了落地阶段,模型选型会影响整个流程。如果你要处理敏感设计数据,优先本地部署;如果只是快速原型,API足够。本地部署要算显存、内存、推理延迟和量化损失。API方案更省事,但要考虑token费用、网络延迟和数据边界。
无论选哪种,我都不建议把“模型生成的脚本直接用于生产”。先让它生成,再经过静态检查、自动测试、人工确认,然后才进入正式零件库。这跟代码开发里“代码评审”是一个道理。
最后,别追求全自动。“需求进来,模型一生成,零件直接上机床”这种流程在目前阶段风险很大。更务实的做法是:大模型帮你把80%的重复建模工作做完,你负责校验和决策。把单零件跑稳,把模板积累好,后续的收益会很可观。