You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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);
        }
    });
});

关键修正点

  1. 事件参数处理:使用args.selections而非args.dbIdArray,每个selection对象包含对应模型的选中信息
  2. 模型上下文绑定:调用viewer.getProperties或操作instanceTree时,必须使用当前选中构件所属的模型(selection.model),不能直接用viewer.model(多模型场景下viewer.model指向最后加载的模型)
  3. 空值判断:先判断args.selections是否存在,避免空指针错误

内容的提问来源于stack exchange,提问作者Sabareeshwari Kannan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:10:48