“智慧仓储数字孪生”这几个字听起来很高大上,但当它真正落到日常执行层面时,很多人第一反应是“先买个三维引擎”或者“找外包建模团队”。我之前接过一个仓储可视化原型项目,任务很直接:把一整套货架、AGV、分拣台搬进三维场景,并能跟着业务参数做同步变化。最初我试过纯手工在 Blender 里摆模型,但换一个仓库布局就得重摆一次,效率低到让人怀疑人生。后来我把 Antigravity 和 Blender MCP 接在一起,用自然语言驱动编程化建模,一套场景几分钟就能生成出来。这篇文章是这套方案的上篇,重点讲链路搭建、仓库场景建模逻辑和第一次跑通实战,不吹底层原理,只讲我实际用过之后觉得该做的事。
如果你正准备做仓储或者物流相关的数字孪生 Demo,又不想被重型游戏引擎绑架,这篇文章应该对你有用。我会把环境配置、数据模型、对象组织、AI 对话建模这几个环节全部拆开,踩过的坑也一并说出来。
1. 先别急着建模,搞懂 Antigravity + Blender MCP 这条链路的价值边界
1.1 “智慧仓储数字孪生”一开始最容易被带偏的地方
先聊聊数字孪生的“度”。很多需求方一提数字孪生,就想要实时反向控制、设备同步、物理引擎仿真、大屏指挥中心,什么都往里塞。但对大多数内部仓储项目来说,第一步真正要解决的其实是“能不能把布局和状态在三维空间里看清楚、算清楚”。也就是说,先把静态的货架、通道、设备位置表达准确,再把库位占用、AGV 当前位置、出入库任务这些业务数据挂到三维对象上,就已经完成了 60% 的价值。
Antigravity + Blender MCP 这套组合,正好适合这个阶段。Antigravity 是一个以 AI 编程为核心的 IDE,能读写工程代码、执行命令、和外部 MCP 服务器通信;Blender MCP 则是把 Blender 的 Python API 包成一堆可供 AI 调用的工具。于是你可以告诉 AI:“按这张表格生成仓库货架布局”,AI 会调用 MCP 工具在 Blender 里创建对象、设置材质、摆坐标,甚至帮你做一段简单的 AGV 路径动画。
需要注意,这套链路不是工业级仪控系统,它不保证毫秒级数据同步,也不会直接去驱动 PLC。它适合做方案评审、业务推演、演示汇报,以及给后续 Web 端孪生提供模型资产。把这些先说清楚,后面用起来心态会很稳。
1.2 为什么我不用传统 Blender 脚本而用 Antigravity 驱动
传统 Blender 脚本建模完全可以实现,比如我在老项目里就写过一堆函数去生成货架和传送带。麻烦在于:每次需求一变,脚本就得改,改完还要手动在编辑器里运行、看效果、再改参数,循环往复。而 Antigravity 作为 AI 原生 IDE,能把“理解需求 -> 生成代码 -> 远程执行 -> 反馈结果”揉成一条链。你只需描述想要的布局,剩下的代码由大模型生成并经由 MCP 发到 Blender 执行。
另一个原因是可复现性。用 MCP 跑出来的操作会落到 Python 命令上,命令可以保存成脚本文件,换一台机器重新执行便能得到相同场景。这个特点对于数字孪生特别重要,因为仓储建模本质上就是“用数据生成三维场景”,数据进,场景出,不许靠人手感。
1.3 这套链路能做什么、不能做什么
能做的:
- 参数化货架、库区、通道、设备的自动搭建。
- 从 JSON、CSV、Excel 导出数据生成布局。
- 快速创建 AGV 行驶路径和简单动画。
- 通过 Blender 的 Eevee / Cycles 渲染出效果图。
- 生成 glTF / FBX 等格式,供 Web 端集成。
不能做的:
- 实时接入 PLC 控制系统。
- 高精度物理仿真(比如碰撞检测、堆垛机力学模拟)。
- 多用户同时在线操作同一个场景(Blender 本身不是多人编辑器)。
- 自动保证业务逻辑正确性,AI 生成的脚本仍然需要复核。
把这些边界摆在台面上,后面所有操作都围绕“数据可视化 + 流程演示”展开。这样既不会因为过度承诺翻车,也能让项目快速出成果。
2. 搭环境的一次性清单:三分钟拼出能跑的通路
2.1 需要准备的四个组件及各自角色
整体链路涉及四个角色:
| 组件 | 角色 | 说明 |
|---|---|---|
| Antigravity | AI 客户端 / MCP Client | 负责接收自然语言指令、调用模型生成代码、连接外部 MCP 服务 |
| Blender MCP Server | 协议中转 | 把 MCP 工具调用翻译成 Blender 可执行的 Python 命令 |
| Blender MCP 插件 | Blender 侧服务端 | 运行在 Blender 进程内部,接收命令并操作场景 |
| Blender | 3D 场景承载 | 最终呈现货架、AGV、路径等三维对象 |
Antigravity 负责大脑部分,Blender MCP 插件相当于手脚。MCP 协议在这里扮演“标准插座”的角色,让 AI 工具之间不再各自为政,而是用统一方式调用能力。
安装方面没有需要付费的组件。Blender 用 4.0 以上版本就行,Blender MCP 项目在社区里能找到,通常是一个 zip 插件加一个命令行服务端。Antigravity 直接下载官方安装包即可。
2.2 MCP 服务器的接入配置
MCP 服务有两种常见接入方式:一种是命令行类型,IDE 本地启动一个子进程,通过 stdio 通信;另一种是 HTTP 类型,IDE 通过网络端口连接远程服务。Blender 和 IDE 本身在同一台机器上时,TCP 端口方式最稳定。
我建议的配置路径是:
- 在 Blender 里安装 Blender MCP 插件,安装后在插件面板会看到“Start MCP Server”按钮,点击后 Blender 进入监听状态,常见默认监听端口是 9876,具体以你使用的实现版本为准。
- 在 Antigravity 的 MCP 管理界面添加服务器,填入服务名称和地址。若服务端走的是 HTTP,一个典型的配置会包含
url字段。 - 如果使用命令行方式,MCP 配置会类似:
{ "mcpServers": { "blender-mcp": { "command": "blender-mcp" } } }这里的关键是command指向可执行命令。如果服务端是用 Python 安装的,则需确保命令行环境和 IDE 启动环境一致,否则会出现“IDE 找不到 blender-mcp 命令”的报错。
2.3 用一次空对象创建验证连通性
环境配好以后,别急着生成复杂场景。先做一个最小连通测试:在聊天对话里要求“创建一个名为 TestEmpty 的空对象,放在坐标 (0, 0, 1) 处”。正常情况下 Antigravity 会生成类似这样的 Python 代码,并通过 MCP 执行:
import bpy bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 1)) bpy.context.object.name = "TestEmpty"执行完后 Blender 场景里应该能看到一个带坐标轴的空对象。看到这个结果,说明 Antigravity 到 MCP、再到 Blender 的链路已经通了。如果失败,优先排查三个地方:插件是否监听、端口是否一致、Antigravity 的 MCP 配置里地址是否拼写错误。
3. 把仓库“拆件”:数字孪生场景的数据与对象层次
3.1 从 CAD 平面图到数据化布局的思路
做仓库数字孪生并不需要把 CAD 图纸原样搬进 Blender,那样成本高且不利于参数化调整。正确思路是把平面图抽象成数据:哪里是库区、哪里是通道、货架尺寸多少、AGV 走哪条路。一张 40 米乘 30 米的仓库平面图,抽象后可能就是一张 JSON。
{ "warehouse": { "name": "模拟仓库X", "width": 40, "depth": 30, "aisle_width": 3.2 }, "zones": [ { "id": "storage", "label": "存储区", "x": 0, "y": 0, "w": 28, "d": 30 }, { "id": "sorting", "label": "分拣区", "x": 28, "y": 0, "w": 6, "d": 30 }, { "id": "loading", "label": "月台区", "x": 34, "y": 0, "w": 6, "d": 30 } ], "racks": [ { "id": "R-01", "zone": "storage", "x": 2, "y": 3, "col": 8, "level": 4 } ], "agvs": [ { "id": "AGV-01", "current_node": "N1", "target_node": "N8" } ] }数据化布局带来的好处是:换一个仓库,只需要改 JSON,不必手动移动三维对象。Antigravity 拿到 JSON 后,能快速生成对应建模脚本,这比“让建模师按图重建”快一个数量级。
3.2 三层对象结构:物理层、逻辑层、数据层
我习惯把整个场景拆成三个层次,这个分层方式在数字孪生项目里非常重要。
物理层是真正看得见的模型,包括地面、墙体、货架、托盘、AGV、月台门等。材质、尺寸、比例都在这一层处理。逻辑层用来表达物体之间的归属和关系,比如某个货架属于哪个库区、某条路径属于哪台 AGV,Blender 里可以用集合和父子关系表达。数据层是附加在对象上的业务属性,比如货架的库位号、当前存储状态、AGV 的电量、任务编号。
在 Blender 里给对象挂数据,可以用自定义属性。例如给货架对象添加“库位状态”字段:
obj = bpy.data.objects["ST_RACK_A01_03"] obj["bin_status"] = "occupied" obj["sku"] = "SKU-0001"之后只要业务数据更新,脚本遍历这些对象并修改属性即可。三层分开的好处是便于追溯:别人接手项目时,看到物理模型知道长什么样,看到逻辑集合知道归属关系,看到自定义属性知道业务状态从哪来。
3.3 命名规范:让 AI 后续操作不至于找错对象
AI 建模最大的隐患之一是对象命名混乱。Blender 默认会把新生成的立方体命名为 Cube、Cube.001、Cube.002,多生成几批后,AI 再通过名称去操作对象时基本等于瞎猜。
我在项目里定的规则是“前缀 + 区域 + 类目 + 序号”。例如:
ST_RACK_A01_03:存储区 A01 货架第 03 列AG_ROUTE_P01:AGV 行驶路径 01CON_SORT_BELT_01:分拣区输送带 01
所有对象命名都由脚本统一控制,不允许使用 Blender 默认名。在 MCP 对话里,明确告诉 AI:“创建对象后必须重命名,前缀以 ST_ 开头”。这个细节看似简单,却能避免后续 90% 的“找不到对象”问题。
4. 第一次实战:通过自然语言驱动 Blender 生成仓库数字孪生
4.1 场景准备:清场和单位设定
跑正式布局前,先给场景做初始化。我通常用一条指令让 AI 执行:
import bpy # 清空场景中所有对象 bpy.ops.object.select_all(action='SELECT') bpy.ops.object.delete() # 清理无用的 mesh 数据块 for mesh in list(bpy.data.meshes): if mesh.users == 0: bpy.data.meshes.remove(mesh) # 单位设置为米,场景尺寸按实际仓库设置 bpy.context.scene.unit_settings.system = 'METRIC' bpy.context.scene.unit_settings.scale_length = 1.0仓库长 40 米、宽 30 米,直接按真实尺寸建模。为什么坚持真实尺寸?因为后续要导给 Web 端做数字孪生,尺寸不对会导致路径动画、碰撞检测全部失真。用真实尺寸建出来的模型,每一块地板、每一个货架都是可测量的,而不是徒有其表的“示意图”。
4.2 让 AI 按货位布局批量搭建货架
货架生成是整个场景里最机械的部分,也是最适合交给 AI 的部分。我会把需求写成一段比较自然的描述:
“在存储区创建 4 排货架,每排 8 列,每列 4 层,排间距 2.5 米,列间距 1.6 米,货架尺寸为长 1.2 米、深 0.8 米,层高 0.9 米。用 ST_RACK_ 前缀命名所有对象。”
Antigravity 会生成类似这样的 Python 并通过 MCP 执行:
import bpy def add_rack(origin): bpy.ops.mesh.primitive_cube_add(size=1, location=(origin[0], origin[1], origin[2])) obj = bpy.context.object obj.scale = (0.6, 0.4, 0.9) obj.name = f"ST_RACK_{origin[0]:.0f}_{origin[1]:.0f}" for row in range(4): for col in range(8): x = 2 + col * 1.6 y = 5 + row * 2.5 add_rack((x, y, 0.45))实际项目里货架不会是一根立方体,还会有立柱、层板、托盘位。我在第一次跑通时只让 AI 生成占位体,先把布局密度、通道宽度验证出来。确认整体比例合适后,再把简单立方体替换成高模。
这一步的心法是:先占位,后细化。不要一上来就让 AI 生成精细货架模型,否则几十个高模加上几百个零部件,Antigravity 对话过程会变得很卡,而且一旦坐标错了,调整成本会指数级上升。
4.3 注入“智慧”要素:AGV 路径与动画
静态货架只是仓储场景的基础,真正让它“智慧”起来的是 AGV 路径规划可视化。我先创建一条路径曲线,再让 AI 把一台简易 AGV 绑定到路径上。
创建路径的脚本大致如下:
bpy.ops.curve.primitive_curve_path_add() path_obj = bpy.context.object path_obj.name = "AG_ROUTE_P01" # 后续可通过 path_obj.data.splines 编辑路径点给 AGV 加跟随路径约束:
bpy.ops.object.select_all(action='DESELECT') agv = bpy.data.objects.get("AGV_01") if agv: bpy.context.view_layer.objects.active = agv bpy.ops.object.constraint_add(type='FOLLOW_PATH') agv.constraints["Follow Path"].target = bpy.data.objects["AG_ROUTE_P01"] agv.constraints["Follow Path"].use_fixed_location = TrueBlender 的 Follow Path 约束会把 AGV 按住路径移动,再通过调整路径曲线上的点控制走向。此时只要在 Antigravity 对话里说“把 AGV-01 的速度调到每秒 1.2 米”,AI 就能修改动画或路径的求值参数,生成对应效果。
坦白讲,这种动画不是真正意义上的路径规划算法调度,它只是把预设路线可视化。但对于仓储方案评审来说,已经能把动线逻辑看得非常直观。真正的动态调度,可以在下篇接数据层之后再做。
4.4 检查渲染输出与场景导出
场景生成后,我习惯先截一张顶视图确认布局。用 Blender 的视图截图功能或者直接让 MCP 工具抓取当前视口,都能快速看到结果。常见的问题是货架间距是否按预期、通道是否过窄、AGV 路径有没有穿墙。
确认没有问题后,导出 glTF 格式给 Web 端使用:
bpy.ops.export_scene.gltf(filepath="/tmp/warehouse_demo.glb", export_format='GLB')导出前记得检查是否勾选了“应用修改器”和“包括自定义属性”。数字孪生场景里,自定义属性承载业务状态,不带属性导出的模型等于丢了一半数据。
5. 跑通后我再回来看这些坑:MCP 工作流中的真实体验
5.1 MCP 工具“做得到”和“做不到”要分开看
Blender MCP 通常会给 AI 暴露一批工具,比如创建对象、设置材质、运行 Python、获取场景信息等。但不少资料会把这件事说得过强,好像 AI 已经能精准控制 Blender 的每个按钮。实际体验是:MCP 工具层只负责“调用接口”,复杂的建模能力仍要靠 Python 代码实现。AI 生成 Python 时,对 Blender API 的掌握程度不代表它能理解三维空间。
我在对话里会明确告诉 AI:“优先使用 Python 方式创建所有对象,不要依赖菜单操作。”这一条经验能让连通率大幅提升。
5.2 坐标系与 Blender 单位精度问题
Blender 默认坐标是 X 向右、Y 向里、Z 向上,但很多仓储平面图习惯用 X、Y 表示长宽,Z 忽略不计。如果直接把平面图上的 X、Y 映射到 Blender 的 X、Y,Z 设为 0,大概率会出现地面不在水平面的错觉,因为 Blender 的默认地面是 Z=0。
此外还有单位比例问题。Blender 默认单位是米,但有些 CAD 图纸是毫米,导入时如果不除以 1000,一个货架会变成几百米高。我的经验是,所有数据在进入 Blender 前统一成米制,并且由脚本一次性换算,不要依赖 AI 猜。
5.3 对象爆炸:AI 生成代码时的“命名混乱”
AI 生成的批量建模脚本,如果没规定命名规则,Blender 会自动创建 Cube.032、Sphere.014 之类的名称。对象一多,后续“删除所有货架”“统计货架数量”这类指令就没法准确执行。
解决方式是每次建模指令里强制加上命名要求,并在脚本结尾打印对象清单:
for obj in bpy.context.scene.objects: print(obj.name)看到完整清单,再继续下一个指令,逻辑就清晰很多。如果已经发生命名混乱,我一般让 AI 写一段插件,按对象类型和位置重新批量命名,而不是手动一个个改。
5.4 提示词技巧:把目标说成参数,而不是形容词
第一次用 Antigravity 驱动 Blender 时,我的指令是“货架摆得整齐点”。AI 很努力,但“整齐”这种词没法转换成坐标,结果它生成了随机偏置,效果很难看。后来我把所有“形容词”换成“参数”:货架尺寸、间距、行数、列数、起始坐标,一个参数一个值。
好的指令是:
“在坐标 (0, 5) 处放置第一列货架,沿 X 方向复制 8 列,列间距 1.6 米,沿 Y 方向复制 4 排,排间距 2.5 米。”
坏的指令是:
“把仓库放满货架,看起来科学一点。”
模型不是设计师,它需要的是精确参数,不是审美倾向。这个经验无论用在 Antigravity 还是其他 AI 编程工具里都一样。
6. 数据接入与下一步的方向
当前这套场景里,货架、AGV、路径都是“看起来存在”的静态对象。真正要让数字孪生“活”起来,下一步需要把业务数据接进来。我在项目里一般分两步走。
第一步,建立对象 ID 与业务 ID 的映射。比如货架对象名ST_RACK_A01_03,对应后台 WMS 库位A-01-03。这个映射可以直接写在 CSV 里,脚本启动时读一次,然后把库位占用状态写入 Blender 自定义属性。
第二步,定时刷新状态。外部系统每 5 秒推送一次库存状态,脚本对比最新数据和对象属性,变化的部分通过修改模型颜色、位置或文字标签体现。这个过程不需要人工编辑 Blender 界面,而是有一个独立的同步脚本在后台运行。
我目前正在把一个 AGV 的任务列表接入这套场景,让 AGV 对象根据任务数据沿路径移动,而不是只做循环动画。等到下篇写出来时,核心就是“实时数据如何驱动 Blender 场景变化”,包括数据协议、同步脚本结构以及异常处理。
对我个人来说,Antigravity + Blender MCP 最大的价值不是省掉了敲代码的手工活,而是把“说需求”到“出三维场景”的距离压缩到几分钟。只要把仓库数据结构和命名规则定好,之后每次换布局、换参数,都只是重新说一句话的事。