如何在 Forge 查看器中显示 2 个不同的标签集作为标记

How can I show 2 different label sets as markup in the forge viewer

我正在尝试根据示例标记代码在 Forge 查看器中显示一些标签。我的代码适用于一个数据集,但当我添加另一个数据集时,我得到:“BuildingData.js:113 Uncaught TypeError: this.frags[("dbId" + dbId)] 不可迭代”。这 2 个数据集是对 BuildingData class 的扩展,它们只是创建一个按钮并调用 super.init()。我不明白为什么当我激活第二个标签集时它会失败。

我使用的是查看器的 v7。

class BuildingData extends Autodesk.Viewing.Extension {
    constructor(viewer, options) {
        super(viewer, options);
    }

    init(){
        //Callback to update labels
        const updateLabelsCallback = () => {
            if(this.button.getState() === 0) {
                this.updateLabels();
            }
        };

        //Events when to update the labels
        OnEvent(this.viewer, Autodesk.Viewing.CAMERA_CHANGE_EVENT, updateLabelsCallback);
        OnEvent(this.viewer, Autodesk.Viewing.ISOLATE_EVENT, updateLabelsCallback);
        OnEvent(this.viewer, Autodesk.Viewing.HIDE_EVENT, updateLabelsCallback);
        OnEvent(this.viewer, Autodesk.Viewing.SHOW_EVENT, updateLabelsCallback);       
        
        //Add the button to the data bar
        this.button.onClick = (ev) => {           
            this.enabled = !this.enabled;
            this.button.setState(this.enabled ? 0 : 1);
            this.showLabels();
        };
        
        this.viewer.dataBar.getControl("dataGrp").addControl(this.button);
    }

    cleanup(){
        //remove button from data bar
        this.viewer.dataBar.getControl("dataGroup").removeControl(this.button);

        //remove labels
        let labels = FindAll(`#${this.viewer.clientContainer.id} div.adsk-viewing-viewer label.data.${this.dataClass}`);
        for(let label of labels) label.remove();
    }

    showLabels() {
        let viewerContainer = Find(`#${this.viewer.clientContainer.id} div.adsk-viewing-viewer`);

        //remove old labels
        let labels = FindAll(`#${this.viewer.clientContainer.id} div.adsk-viewing-viewer label.data.${this.dataClass}`);
        for(let label of labels) label.remove();
        
        //show new labels?
        if(!this.enabled) return;

        //check if the model tree is available
        let tree = this.viewer.model.getInstanceTree();
        if(tree === undefined){
            console.log("Model tree is not loaded yet"); 
            return;
        }

        //select sessor & fit to view
        const onClick = (e) => {
            this.viewer.select(e.currentTarget.dataset.dbId);
            this.viewer.utilities.fitToView();
        };

        this.frags = [];
        for(let i = 0; i < this.labels.length; i++){
            const label = this.labels[i];
            this.frags["dbId" + label.dbId] = [];

            // create the label for the dbId
            let lbl = document.createElement("label");
            lbl.classList.add("data");
            lbl.classList.add("update");
            lbl.classList.add(this.dataClass);
            lbl.dataset.dbId = label.dbId;
            lbl.style.cssText = `display: ${this.viewer.isNodeVisible(label.dbId) ? "block" : "none"}`;
            
            //add click event
            OnEvent(lbl, "click", onClick);
            
            let span = document.createElement("span");
            lbl.appendChild(span);
            span.innerText = label.name;       
            
            viewerContainer.appendChild(lbl);
            
            //Collect fragment ids of dbId
            tree.enumNodeFragments(label.dbId, (fragId) => {
                this.frags["dbId" + label.dbId].push(fragId);
                this.updateLabels();
            });
        }
    }

    updateLabels() {
        for(const label of FindAll(`#${this.viewer.clientContainer.id} div.adsk-viewing-viewer .update`)){
            const dbId = label.dataset.dbId;
            
            //get center of the dbId based on the bounding box of the fragments
            const pos = this.viewer.worldToClient(this.getBoundingBox(dbId).center());

            //position label in the center of the box
            label.style.cssText = `left: ${Math.floor(pos.x - label.offsetWidth / 2)}px`;
            label.style.cssText +=`top: ${Math.floor(pos.y - label.offsetHeight / 2)}px`;
            label.style.cssText +=`display: ${this.viewer.isNodeVisible(dbId) ? "block" : "none"})`;
        }
    }

    getBoundingBox(dbId) {
        var fragList = this.viewer.model.getFragmentList();
        const nodebBox = new THREE.Box3()
        
        //get bounding box for each fragment
        for(const fragId of this.frags["dbId" + dbId]){ //<----- ERROR is here
            const fragBBox = new THREE.Box3();
            fragList.getWorldBounds(fragId, fragBBox);
            nodebBox.union(fragBBox);
        }

        return nodebBox
    }
}

我找到了解决方案,我试图更新查看器中的所有标签(两个数据集的),而不仅仅是与活动数据集对应的标签。更改 updateLabels() 中的 1 行修复了它:

const label of FindAll(`#${this.viewer.clientContainer.id} div.adsk-viewing-viewer .data.${this.dataClass}`