Antigravity+Blender MCP:智慧仓储数字孪生三维建模实战

📅 发布时间:2026/10/14 12:31:45
Antigravity+Blender MCP:智慧仓储数字孪生三维建模实战
“智慧仓储数字孪生”这几个字听起来很高大上但当它真正落到日常执行层面时很多人第一反应是“先买个三维引擎”或者“找外包建模团队”。我之前接过一个仓储可视化原型项目任务很直接把一整套货架、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 需要准备的四个组件及各自角色整体链路涉及四个角色组件角色说明AntigravityAI 客户端 / MCP Client负责接收自然语言指令、调用模型生成代码、连接外部 MCP 服务Blender MCP Server协议中转把 MCP 工具调用翻译成 Blender 可执行的 Python 命令Blender MCP 插件Blender 侧服务端运行在 Blender 进程内部接收命令并操作场景Blender3D 场景承载最终呈现货架、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(typePLAIN_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、月台门等。材质、尺寸、比例都在这一层处理。逻辑层用来表达物体之间的归属和关系比如某个货架属于哪个库区、某条路径属于哪台 AGVBlender 里可以用集合和父子关系表达。数据层是附加在对象上的业务属性比如货架的库位号、当前存储状态、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_P01AGV 行驶路径 01CON_SORT_BELT_01分拣区输送带 01所有对象命名都由脚本统一控制不允许使用 Blender 默认名。在 MCP 对话里明确告诉 AI“创建对象后必须重命名前缀以 ST_ 开头”。这个细节看似简单却能避免后续 90% 的“找不到对象”问题。4. 第一次实战通过自然语言驱动 Blender 生成仓库数字孪生4.1 场景准备清场和单位设定跑正式布局前先给场景做初始化。我通常用一条指令让 AI 执行import bpy # 清空场景中所有对象 bpy.ops.object.select_all(actionSELECT) 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(size1, location(origin[0], origin[1], origin[2])) obj bpy.context.object obj.scale (0.6, 0.4, 0.9) obj.name fST_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(actionDESELECT) agv bpy.data.objects.get(AGV_01) if agv: bpy.context.view_layer.objects.active agv bpy.ops.object.constraint_add(typeFOLLOW_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_formatGLB)导出前记得检查是否勾选了“应用修改器”和“包括自定义属性”。数字孪生场景里自定义属性承载业务状态不带属性导出的模型等于丢了一半数据。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、YZ 设为 0大概率会出现地面不在水平面的错觉因为 Blender 的默认地面是 Z0。此外还有单位比例问题。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 最大的价值不是省掉了敲代码的手工活而是把“说需求”到“出三维场景”的距离压缩到几分钟。只要把仓库数据结构和命名规则定好之后每次换布局、换参数都只是重新说一句话的事。