工程模型进入浏览器后,最容易被低估的不是材质或相机,而是“这个三角形到底属于哪个工程对象”。
在普通展示页里,给每个 Mesh 一个 UUID 似乎就能完成点击选择。但一旦接入结构树、属性、设备台账、告警、进度、问题单和模型版本,运行时 UUID 很快会失效:重新转换会变,合批后一个 Mesh 对应多个构件,LOD 切换会替换几何,实例化又让多个对象共享同一份网格。
稳定对象身份必须独立于渲染对象存在。
四种 ID 不要混为一谈
1. 源系统对象 ID
它来自 IFC、Revit、机械装配或企业资产系统。buildingSMART 的 IFC 4.3 文档规定,具有语义意义并继承自 IfcRoot 的对象使用 IFC-GUID 标识;该标识在对象生命周期内应保持不变,以便合并、版本化和从外部引用。
这类 ID 最接近业务语义,但仍要记录来源系统和模型版本。不同项目、不同导出链路或错误复制的数据不能只凭一串字符盲目合并。
2. 转换缓存对象 ID
源模型第一次转换时,应为可查询对象生成稳定的内部键,并保存:来源、源 ID、版本、结构父子关系、属性索引和几何片段列表。
内部键的价值在于屏蔽不同格式的差异。IFC 有 GlobalId,STEP 装配、JT、CATIA 或 DWG 又可能采用完全不同的实例和引用方式,但查看器需要一套统一查询接口。
3. 渲染索引
GPU 更适合处理紧凑整数,而不是长字符串。渲染阶段通常把当前工作集映射成 objectIndex、instanceIndex、批次内 offset 或拾取颜色。
这些值只在特定缓存版本、批次或帧内有效。它们必须能反查稳定对象 ID,却不能被业务系统长期保存。否则模型重新切块或调整 LOD 后,昨天的“对象 3721”可能已经指向另一个构件。
4. 业务实体 ID
设备台账、工单、告警和施工任务通常有自己的主键。业务数据不要直接写进几何缓存,而应通过关联表连接稳定对象 ID。一个设备可以对应多个构件,一个构件也可能关联多个时间区间或业务记录。
这样模型更新、业务数据更新和渲染优化可以独立演进。
合批不是丢掉身份的理由
减少 Draw Call 时,常见误区是把大量构件合成一个 Mesh 后只保留合并对象。正确做法是在批次内部维护范围或实例到对象的映射:拾取获得 primitive/instance 后,先得到紧凑渲染索引,再回到稳定对象 ID,最后查询结构、属性和业务数据。
Khronos glTF 2.0 允许在节点的 extras 中保存应用自定义数据,这适合携带轻量查询键;但完整属性和版本关系通常应放在独立索引中。extras 是承载方式,不是工程语义模型。
版本更新必须产生映射结果
“重新导入并覆盖旧模型”会让所有外部引用变成猜测。每次模型更新至少应输出四类结果:保持不变、新增、删除、疑似拆分或合并。
优先使用源系统稳定 ID;ID 不可靠时,再结合装配路径、类型、名称、空间位置和几何签名做候选匹配,并把低置信度项交给人工确认。不要默默按数组下标关联。
一条可落地的数据链路
源模型负责提供工程语义;转换层生成统一对象身份、结构属性和几何片段;查看缓存保存稳定映射;GPU 只消费紧凑工作集索引;业务系统通过关联表连接设备、任务、告警和工单。
这条链路建立后,结构树选择、视图高亮、属性查询、隐藏、测量、协同标注和业务联动才会指向同一个对象。
我们做 ModelView 时,把源格式转换、查看缓存、WebGPU 运行时和工程对象身份分层处理,目标就是在分块、LOD、合批和按需加载后仍保留结构树、属性和业务集成能力。
说明一下,我是 ModelView 的开发者。Windows 标准版可以直接下载,用自己的 BIM、机械 CAD 或工业装配模型测试;企业内网、在线平台和业务系统对接可在现有引擎上继续开发:
参考资料:
- buildingSMART IFC 4.3 Object Attributes:ifc43-docs.standards.buildingsmart.org/IFC/RELEASE…
- buildingSMART IfcGloballyUniqueId:ifc43-docs.standards.buildingsmart.org/IFC/RELEASE…
- Khronos glTF 2.0 Specification:registry.khronos.org/glTF/specs/…