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

Forge Viewer添加自定义模型片段后位置异常问题咨询

问题

我通过以下代码在Forge Viewer中添加包含多个网格的自定义模型:

let cameras = camerasJSON.cameras[0];
let sceneBuilder = await viewer.loadExtension('Autodesk.Viewing.SceneBuilder');
let modelBuilder = await sceneBuilder.addNewModel({
    modelNameOverride: 'Cameras',
    conserveMemory: false
})
cameras.forEach(camera => {
    const sphereGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 8, 8));
    const sphereMaterial = new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) });
    let p = [+camera[2]/1000, +camera[3]/1000, +camera[4]/1000]
    const sphereTransform = new THREE.Matrix4().compose(
        new THREE.Vector3(...p),
        new THREE.Quaternion(0,0,0,1),
        new THREE.Vector3(1, 1, 1)
    );
        
    let mesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
    mesh.matrix = sphereTransform
    mesh.dbId = camera[0].split('_')[1];    
    modelBuilder.addMesh(mesh);
})

随后用以下代码获取点击片段的位置:

event.selections[0].model.getInstanceTree().enumNodeFragments(event.selections[0].dbIdArray[0], function (frag) {       
    let fragProxy = viewer.impl.getFragmentProxy(viewer.model, frag);
    let matrix = new THREE.Matrix4();       
    fragProxy.getWorldMatrix(matrix);       
    let position = new THREE.Vector3().setFromMatrixPosition(matrix);
    console.log(position);
});

实际获取的位置(及变换矩阵)与初始设置不匹配。创建的绿色球体显示位置正确,但获取到的片段位置完全不符,即使相对位置也不对(模型已炸开以便观察)。移除全局偏移无效果,主模型不存在此问题。不确定是位置获取方式错误,还是片段在添加时位置被篡改。

原因与解决方法

  • 错误点1:获取片段代理时用错模型对象
    你在获取fragProxy时使用了viewer.model,但自定义模型是通过SceneBuilder添加的独立模型实例,正确的模型对象应该是选中事件返回的event.selections[0].model。

  • 错误点2:直接赋值mesh.matrix的方式易导致矩阵不同步
    Forge的SceneBuilder更推荐通过设置mesh.position、mesh.quaternion、mesh.scale来定义变换,再手动更新矩阵,避免内部矩阵状态不同步。

修正后的获取位置代码

const selectedModel = event.selections[0].model;
selectedModel.getInstanceTree().enumNodeFragments(event.selections[0].dbIdArray[0], function (frag) {       
    let fragProxy = viewer.impl.getFragmentProxy(selectedModel, frag);
    let matrix = new THREE.Matrix4();       
    fragProxy.getWorldMatrix(matrix);       
    let position = new THREE.Vector3().setFromMatrixPosition(matrix);
    console.log(position);
});

优化后的自定义模型添加代码

cameras.forEach(camera => {
    const sphereGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 8, 8));
    const sphereMaterial = new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) });
    let p = [+camera[2]/1000, +camera[3]/1000, +camera[4]/1000]
        
    let mesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
    // 直接设置位置、旋转、缩放
    mesh.position.set(...p);
    mesh.quaternion.set(0, 0, 0, 1);
    mesh.scale.set(1, 1, 1);
    // 手动更新矩阵确保状态同步
    mesh.updateMatrix();
    mesh.dbId = camera[0].split('_')[1];    
    modelBuilder.addMesh(mesh);
})

内容的提问来源于stack exchange,提问作者Roma M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:25:05