【问题标题】:Can't use global variable inside tree.enumNodeFragments() delegate不能在 tree.enumNodeFragments() 委托中使用全局变量
【发布时间】:2019-07-29 10:46:07
【问题描述】:

我试图通过 fragId 保存元素的旧材料,但无法执行此操作,因为 tree.enumNodeFragments() 文档或窗口内部不可访问。

    highlight(externalId, color, dict) {
    let viewer = this.viewer;
    var dbId = dict[externalId];


    let myMaterial = this.createMaterial(color);

    // used to rescale and remove the z-fighting
    let scaleRatio = 1.005; // this was determined as optimal through visual inspection

    var tree = NOP_VIEWER.model.getData().instanceTree;

    document.oldMaterials = {};


    tree.enumNodeFragments(dbId,
        function(fragId) {
         document.oldMaterials[fragId] = viewer.model.getFragmentList().getMaterial(fragId);

            viewer.model.getFragmentList().setMaterial(fragId, myMaterial);


            /* important technique if you want to remove z-fighting */
            let fragProxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
            fragProxy.scale = new THREE.Vector3(scaleRatio, scaleRatio, scaleRatio);
            fragProxy.updateAnimTransform();
        },
        true);

    viewer.impl.invalidate(true);
}

【问题讨论】:

    标签: javascript autodesk-forge autodesk-viewer


    【解决方案1】:

    documentwindow 都应该在回调函数的范围内可用,但这不是一个好习惯。尝试在highlight 函数的范围内定义旧材料的映射:

    function highlight(externalId, color, dict) {
        const viewer = this.viewer;
        const dbId = dict[externalId];
        const myMaterial = this.createMaterial(color);
        // used to rescale and remove the z-fighting
        const scaleRatio = 1.005; // this was determined as optimal through visual inspection
        const tree = NOP_VIEWER.model.getData().instanceTree;
        const oldMaterials = {};
    
        tree.enumNodeFragments(dbId, function(fragId) {
            oldMaterials[fragId] = viewer.model.getFragmentList().getMaterial(fragId);
            viewer.model.getFragmentList().setMaterial(fragId, myMaterial);
            /* important technique if you want to remove z-fighting */
            const fragProxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
            fragProxy.scale = new THREE.Vector3(scaleRatio, scaleRatio, scaleRatio);
            fragProxy.updateAnimTransform();
        },
        true);
    
        viewer.impl.invalidate(true);
    }
    

    【讨论】:

    • 我以前有时会尝试这个。调用 tree.enumNodeFragments oldMaterials 后为空。 viewer.model.getFragmentList().getMaterial(fragId) 不为空。
    • 我在 tree.enumNodeFragments 之后调用 console.log(document.oldMaterials) 或 console.log(window.oldMaterials),在控制台中我看到 {}(空字典)。
    • 正如我所提到的,引用全局变量(尤其是document)并不是一个好的做法,并且可能会导致不同的问题。尝试改用本地的oldMaterials const,并确保enumNodeFragments 内部的回调函数实际执行。
    • 如何确保 enumNodeFragments 中的回调函数实际执行?
    • 我的意思是:确认回调函数确实被执行了,比如在里面放一个console.log或者debugger语句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多