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

Forge Viewer中getRenderProxy按fragId获取ThreeJS Mesh循环调用异常

Autodesk Forge 批量调用getRenderProxy返回随机Mesh问题解决

问题现象

我尝试通过viewer.impl.getRenderProxy(viewer.model, fragId)函数从Autodesk Forge构件中获取ThreeJS Mesh,但遇到如下问题:若将该函数放入循环逻辑批量获取多个对象的Mesh,最终仅会返回随机的Mesh对象。
为排查问题根源,我使用了同类函数viewer.impl.getFragmentProxy(viewer.model, fragId)进行测试,该函数运行完全正常。

相关测试代码

for(let i = 0, len = nodNamee.length; i < len; i = i+3){
    var instanceTree = viewer.model.getData().instanceTree;
    var fragIds = [];
    instanceTree.enumNodeFragments(nodNamee[i+1], function(fragId){
        fragIds.push(fragId);
    });
    fragIds.forEach(function(fragId) {
        var renderProxy = viewer.impl.getRenderProxy(viewer.model, fragId);
        fragtoMesh.push(renderProxy);
        //var fragmentproxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
        //fragtoProxy.push(fragmentproxy);
    });
}

问题原因

getRenderProxy 是 Forge Viewer 内部为降低内存开销设计的复用型代理对象,所有调用返回的都是同一个全局代理实例的引用,每次调用仅会修改该实例的属性指向当前查询的frag对应的网格数据,不会生成新的独立对象。
你在循环中直接将代理引用存入数组,所有数组元素本质指向同一个代理实例,循环结束后该实例的属性会停留在最后一次查询的frag上,因此会出现返回结果随机、所有元素内容一致的问题。
而getFragmentProxy每次调用会生成独立的片段代理实例,不存在属性覆盖问题,因此循环调用运行正常。

解决方案

  • 如果仅需要临时读取网格的属性,每次调用getRenderProxy后立刻读取目标属性值单独存储,不要存储代理对象本身
  • 如果需要长期持有独立的ThreeJS Mesh实例,可手动从代理中拷贝几何、材质、世界矩阵属性生成新的Mesh,示例如下:
    const renderProxy = viewer.impl.getRenderProxy(viewer.model, fragId);
    // 拷贝属性生成独立Mesh
    const mesh = new THREE.Mesh(renderProxy.geometry, renderProxy.material);
    mesh.matrix.copy(renderProxy.matrixWorld);
    mesh.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale);
    fragtoMesh.push(mesh);
    
  • 优先使用官方推荐的getFragmentProxy操作构件属性,通过其提供的getWorldMatrix()、animTransform等API完成构件变换、属性读取操作,兼容性和稳定性更强。

内容的提问来源于stack exchange,提问作者Ali Ag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:24:04