如何在Forge聚合视图中获取选中设备的Object ID
多模型聚合场景下Forge Viewer获取选中构件Object ID的问题解决
问题描述
我们使用Forge Aggregate Viewer展示多个BIM模型,点击/双击视图中的设备时会触发缩放,但无法通过代码获取选中设备的Object ID。注:单文件上传时,可在Forge Viewer中正常获取选中设备的Object ID。
曾尝试使用以下代码,但选中设备时未触发:
viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, (args) => { // 逻辑代码 });
现有代码片段
FitToView及选中初始化代码
const Loadedevent = () => { var objval = document.getElementById('<%=hid_objectid.ClientID%>').value; if (objval != '') { var mdlurn = ""; mdlurn = document.getElementById('<%=hid_mdlurn.ClientID%>').value; const models = viewer.getVisibleModels().find(m => m.getData().urn === mdlurn); viewer.fitToView([parseInt(objval)], models); viewer.select([parseInt(objval)], models, Autodesk.Viewing.SelectionType.OVERLAYED); } }
初始选中变更事件代码(无效)
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => { if (args.dbIdArray.length === 1) { viewer.getProperties(args.dbIdArray[0], function (data) { if (FromPage == '') { if (FromSelection == '') { if (Count === 0) { var instanceTree = viewer.model.getData().instanceTree; var parentId = instanceTree.getNodeParentId(args.dbIdArray[0]); viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED); Count = 1; } else { itemobject = args.dbIdArray[0]; Count = 0; } } else { FromSelection = ''; itemobject = args.dbIdArray[0]; } } else { FromPage = ''; itemobject = args.dbIdArray[0]; } }); } });
修改后的事件代码(待修正)
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => { if (!args.selections || args.selections.length <= 0) return; if (args.selections.length == 1 ) { viewer.getProperties(args.selections[0].dbIdArray[0], function (data) { if (FromPage == '') { if (FromSelection == '') { if (Count === 0) { var instanceTree = viewer.model.getData().instanceTree; var parentId = instanceTree.getNodeParentId(args.selections[0].dbIdArray); viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED); Count = 1; } else { const dbIds = args.selections[0].dbIdArray; itemobject = dbIds[0]; Count = 0; } } else { FromSelection = ''; const dbIds = args.selections[0].dbIdArray; itemobject = dbIds[0]; } } else { FromPage = ''; const dbIds = args.selections[0].dbIdArray; itemobject = dbIds[0]; } }); } });
问题分析与修正方案
在多模型聚合场景下,Autodesk.Viewing.SELECTION_CHANGED_EVENT仅针对单个模型的选中事件,无法捕获跨模型的选中变更,必须使用Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT。但该事件的参数结构与单模型事件不同:
args.selections:数组类型,每个元素对应一个选中模型的信息,包含model(模型实例)和dbIdArray(该模型中选中构件的ID数组)- 不能直接使用
args.dbIdArray,这是单模型事件的参数结构
修正后的完整示例代码
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => { // 过滤空选中情况 if (!args.selections || args.selections.length === 0) return; // 遍历所有选中的模型及构件 args.selections.forEach(selection => { const targetModel = selection.model; const selectedDbIds = selection.dbIdArray; if (selectedDbIds.length === 1) { const dbId = selectedDbIds[0]; // 获取构件属性,需传入对应模型指定查询上下文 viewer.getProperties(dbId, (data) => { // 存储选中构件的Object ID itemobject = dbId; // 执行原有业务逻辑 if (FromPage === '') { if (FromSelection === '') { if (Count === 0) { // 使用当前选中模型的instanceTree获取父节点ID const instanceTree = targetModel.getData().instanceTree; const parentId = instanceTree.getNodeParentId(dbId); viewer.select([parentId], targetModel, Autodesk.Viewing.SelectionType.OVERLAYED); Count = 1; } else { Count = 0; } } else { FromSelection = ''; } } else { FromPage = ''; } }, undefined, targetModel); } }); });
关键修正点
- 事件参数处理:使用
args.selections而非args.dbIdArray,每个selection对象包含对应模型的选中信息 - 模型上下文绑定:调用
viewer.getProperties或操作instanceTree时,必须使用当前选中构件所属的模型(selection.model),不能直接用viewer.model(多模型场景下viewer.model指向最后加载的模型) - 空值判断:先判断
args.selections是否存在,避免空指针错误
内容的提问来源于stack exchange,提问作者Sabareeshwari Kannan
相关产品推荐
相关产品推荐

