Search code examples
autodesk-forgeautodesk-viewer

Autodesk.Viewing.Document.load() documentId / urn structure


I am using the Autodesk.Viewing.Document.load() function click. The documentation states that the first parameter is the urn of the file. However if I encode a urn (urn:...) to Base64 (encodeURI) using the js-base64 module click and call

Autodesk.Viewing.Document.load(base64_decoded_urn, onSuccessCallback, onErrorCallback)

I get a 400 response from the server.

But when I call

Autodesk.Viewing.Document.load('urn:' + base64_decoded_urn, onSuccessCallback, onErrorCallback)

The document can be fetched. However, I am actually calling the load function with urn:urn:... because the encoded base64 urn still includes the prefix 'urn:'

Is this behavior desired?


Solution

  • Yes, this is the correct way. For encoding you can rely on urnify method:

    service.urnify = (id) => Buffer.from(id).toString('base64').replace(/=/g, '');

    just like we do in our Simple Viewer tutorial.

    In this case, we're prefixing the urn with urn (refer to viewer.js):

    export function loadModel(viewer, urn) {
        return new Promise(function (resolve, reject) {
            function onDocumentLoadSuccess(doc) {
                resolve(viewer.loadDocumentNode(doc, doc.getRoot().getDefaultGeometry()));
            }
            function onDocumentLoadFailure(code, message, errors) {
                reject({ code, message, errors });
            }
            viewer.setLightPreset(0);
            Autodesk.Viewing.Document.load('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
        });
    }
    

    And the value of the urn passed to loadModel function is base64-encoded, as we can see at '/api/models'endpoint (refer here):

    router.post('/api/models', formidable(), async function (req, res, next) {
        const file = req.files['model-file'];
        if (!file) {
            res.status(400).send('The required field ("model-file") is missing.');
            return;
        }
        try {
            const obj = await uploadObject(file.name, file.path);
            await translateObject(urnify(obj.objectId), req.fields['model-zip-entrypoint']);
            res.json({
                name: obj.objectKey,
                urn: urnify(obj.objectId)
            });
        } catch (err) {
            next(err);
        }
    });