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

使用Autodesk Viewer AggregatedView类加载多模型时遇404错误的问题咨询及使用示例需求

Fixing 404 Error with Autodesk Viewer's AggregatedView & Complete Usage Example

Let's break down what's going wrong with your code first, then walk through a complete, working example of using AggregatedView to load multiple models and interact with each of them.

Why You're Getting the 404 Error

Your main issue is asynchronous execution timing:

  • Autodesk.Viewing.Document.load runs asynchronously, but you're calling view.setNodes(bubbleNodes) immediately after starting all the load requests. At that point, bubbleNodes is still empty (or only partially populated), so the viewer tries to load invalid/non-existent nodes and throws a 404.
  • Additionally, double-check that each entry in your docs array is a valid, base64-encoded URN (without surrounding <> brackets) and that your getForgeToken function returns a token with viewables:read access to all those documents.

Complete Working AggregatedView Example

Here's a revised version of your code that handles asynchronous loading properly, plus extra functionality to switch between models and access their properties:

let aggregatedView;
const bubbleNodes = [];

async function loadModels(docs) {
    const options = {
        env: 'AutodeskProduction',
        getAccessToken: getForgeToken
    };

    // Wait for Viewer initialization to finish
    await new Promise((resolve) => {
        Autodesk.Viewing.Initializer(options, resolve);
    });

    const htmlDiv = document.getElementById('forgeViewer');
    aggregatedView = new Autodesk.Viewing.AggregatedView();
    
    // Initialize the AggregatedView instance
    await aggregatedView.init(htmlDiv, options);

    // Wrap each document load in a Promise to handle async flow
    const loadPromises = docs.map(docUrn => {
        return new Promise((resolve, reject) => {
            Autodesk.Viewing.Document.load(docUrn, (doc) => {
                const geometryNodes = doc.getRoot().search({ type: 'geometry' });
                if (geometryNodes.length > 0) {
                    bubbleNodes.push(geometryNodes[0]);
                    resolve();
                } else {
                    reject(new Error(`No geometry found in document: ${docUrn}`));
                }
            }, (errorCode, errorMsg) => {
                reject(new Error(`Failed to load document ${docUrn}: ${errorMsg} (Code: ${errorCode})`));
            });
        });
    });

    // Wait for all documents to load before setting nodes
    try {
        await Promise.all(loadPromises);
        await aggregatedView.setNodes(bubbleNodes);
        console.log('All models loaded successfully!');
        
        // Example: Switch to the second model (index 1)
        switchToModel(1);
    } catch (err) {
        console.error('Error loading models:', err);
    }
}

// Helper to programmatically switch between loaded models
function switchToModel(nodeIndex) {
    if (nodeIndex >= 0 && nodeIndex < bubbleNodes.length) {
        aggregatedView.selectModel(bubbleNodes[nodeIndex]);
        console.log(`Switched to model: ${bubbleNodes[nodeIndex].data.name}`);
    } else {
        console.error('Invalid model index');
    }
}

// Example: Get properties of a selected part from the active model
async function getSelectedPartProperties() {
    const selection = aggregatedView.getSelection();
    if (selection.length === 0) {
        console.log('No part selected');
        return;
    }

    const dbId = selection[0].dbId;
    const activeModel = selection[0].model;

    await new Promise((resolve, reject) => {
        activeModel.getProperties(dbId, (props) => {
            console.log('Part Properties:', props);
            resolve(props);
        }, (err) => {
            reject(err);
        });
    });
}

// Replace this with your actual token retrieval logic
function getForgeToken(callback) {
    // Example token fetch (replace with your endpoint)
    fetch('/api/forge/token')
        .then(res => res.json())
        .then(data => {
            callback(data.access_token, data.expires_in);
        })
        .catch(err => console.error('Failed to get token:', err));
}

Key Improvements & Notes

  • Async/Await for Reliable Flow: We use Promise.all to wait for all document loads to complete before calling setNodes, ensuring bubbleNodes is fully populated with valid geometry nodes.
  • Robust Error Handling: Added try/catch blocks and rejection logic for failed loads, so you can pinpoint exactly which model is causing issues.
  • Model Switching: The switchToModel function lets you toggle between loaded models programmatically, or you can use the viewer's built-in model switcher in the toolbar.
  • Property Access: The getSelectedPartProperties function demonstrates how to retrieve attributes of a selected part from the currently active model.
  • Token Validation: Ensure your getForgeToken returns a token with viewables:read scope for every document in your docs array.

内容的提问来源于stack exchange,提问作者nacho richart ribes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:03:16