做 Forgent3D 的第一个决定不是用哪个模型,是 AI 生成的东西到底是什么。
两条路摆在面前。一条是生成网格:你说「一个带把手的杯子」,出来一堆三角面,几秒钟,看起来像那么回事。另一条是让语言模型写 CAD 代码:它写的是一段 Python,描述一个圆柱、挖一个孔、倒一圈圆角,代码跑一遍,几何才出来。
我们选了第二条。不是因为它更酷,是因为第一条做出来的东西没法用在我们想做的事上。
网格的问题不是精度,是它不知道自己是什么
一个网格里的孔不是孔,是一圈排成圆的窄长三角形。你没法问它「这个孔直径多少」,它不知道。你想把孔从 6 mm 改成 6.4 mm 好让 M6 螺丝穿过去,没有「改」这个操作,只能重新生成,而重新生成出来的是另一个杯子,把手的位置都不一样了。
打印机不在乎这些,它只要三角面。但凡过了打印机这一关,CNC 加工、注塑、让 Fusion 或 SolidWorks 打开再改一改、给加工厂报价,没有一样接受网格。更不用说两个版本之间 diff 一下看改了什么。
代码是唯一的真源
所以我们定了一条规矩:每个项目只有一份真源,model.py。它里面有几何、有每个零件的身份、有命名的特征、有默认外观,装配关系也在里面。别的东西,B-rep、网格、缩略图、给查看器用的场景,全是从它算出来的派生品,随时可以删掉重建。
这条规矩的后果是:模型可以放进 git,可以 review,可以 diff,可以在十个月后打开改一个数字然后重建。AI 写错了,你改它的代码,而不是重新抽卡。
改一个数,但别砸掉公式
有一件事我们花了不少力气,就是让用户从界面上改尺寸、但不破坏代码里的意图。AI 写的代码常常长这样:
STOCK = 20
CLEAR = 1.5
PLATE_H = STOCK - 2*CLEAR
plate = Body("plate", geometry=extrude(profile, amount=PLATE_H))用户在面板上把厚度改成 15。最省事的做法是把 PLATE_H 直接写成 15,但这样公式没了,它和 STOCK、CLEAR 脱钩,下次改毛坯厚度板就不跟着动了。另起一张「界面参数表」存 15,又多了一份真源,代码说一个数、面板说另一个数。
我们的做法是改值、保公式:从解释器记下来的表达式反解,15 = STOCK − 2 × 1.5,所以 STOCK 从 20 改成 18,PLATE_H 那一行一个字不动。两个参数共用同一个数、解不出来的,直接报错,不猜。拉伸深度、草图尺寸、一个 helper 的实参,改值走的都是这一条轨道。
代价
代价很明显:语言模型写代码会错,而几何上的错你从代码里看不出来。一个孔的位置写成了 35 而不是 40,代码照样跑,看起来也像那么回事。
所以 agent 不能只写代码,它得自己验证:每改一次就构建一次,量尺寸,看截图,和要求对。这是另一篇的内容。但先说结论:验证这件事,恰恰只有「代码是模型」这条路才做得到,因为能量的是真实几何,而不是一堆三角面。
口号是后来才有的:代码就是模型。先有的是上面那些麻烦。