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
相关产品推荐
相关产品推荐

