Search code examples
javascriptvue.jsvuejs2autodesk-forgeautodesk-viewer

Coloring model in Forge viewer gives Cannot read properties of undefined (reading 'setThemingColor')


I'm trying to give the provided inventor_sample_file.ipt a different color. I have the below SFC. Some of the code is taken from another SO question.

<template>
    <div class="viewer-container">
        <div id="forge-viewer" />
    </div>
</template>

<script>
export default {
    props: {
        object: {
            type: Object,
            required: true,
        },
    },

    mounted()
    {
        this.initializeViewer();
    },

    data()
    {
        return {
            viewer: null,
            access_token: <some token>, // No, it is not hardcoded
            options: {
                env: 'AutodeskProduction2',
                api: 'streamingV2_EU',  // for models uploaded to EMEA change this option to 'streamingV2_EU'
                getAccessToken: onTokenReady => {
                    let token = this.access_token;
                    let timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
                    onTokenReady(token, timeInSeconds);
                }
            }
        }
    },

    methods: {
        initializeViewer()
        {
            this.$loadScript('https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js')
                .then(() => {
                    Autodesk.Viewing.Initializer(this.options, () => {
                        this.viewer = new Autodesk.Viewing.GuiViewer3D(
                            document.getElementById('forge-viewer'),
                        );

                        let startedCode = this.viewer.start();
                        if( startedCode > 0 )
                        {
                            console.error('Failed to create a Viewer: WebGL not supported.');
                            return;
                        }

                        this.loadModel(<base64 encoded this.object.object_id>);
                    });


                }).catch((error) => {
                    console.warn('Autodesk not loaded', error);
                });
        },

        onDocumentLoadedSuccess(viewer_document)
        {
            let viewerapp = viewer_document.getRoot();
            let default_model = viewerapp.getDefaultGeometry();
            let viewables = viewerapp.search({'type':'geometry'});

            if(viewables.length === 0)
            {
                console.error('Document contains no viewables.');
                return;
            }

            this.viewer.loadDocumentNode(viewer_document, default_model);

            this.viewer.loadExtension('Autodesk.PDF').then( () => {
                this.viewer.loadExtension("Autodesk.Viewing.MarkupsCore")
                this.viewer.loadExtension("Autodesk.Viewing.MarkupsGui")
            });

            console.log(new THREE.Vector4(1, 0, 0, 0.5));
            this.viewer.setThemingColor(4, new THREE.Vector4(1, 0, 0, 0.5), null, true);
        },

        onDocumentLoadedFailure()
        {
            console.error('Failed fetching Forge manifest');
        },

        loadModel(urn)
        {
            const documentId = `urn:${urn}`;
            Autodesk.Viewing.Document.load(
                documentId,
                viewer_document => this.onDocumentLoadedSuccess(viewer_document),
                () => this.onDocumentLoadedFailure
            );
        },
    }
}
</script>

<style scoped>
@import 'https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css';

#forge-viewer {
    width: 100%;
    height: 100%;
    margin: 0;
    background-color: #F0F8FF;
}

.viewer-container {
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
}
</style>

The model is loaded in the viewer but it now gives the following error:

Viewer3D.js:4872 Uncaught TypeError: Cannot read properties of undefined (reading 'setThemingColor')

This error references the following:

Viewer3D.prototype.setThemingColor = function(dbId, color, model, recursive) {
  // use default RenderModel by default
  model = model || this.model;

  model.setThemingColor(dbId, color, recursive); // this line gives the error

  // we changed the scene to apply theming => trigger re-render
  this.impl.invalidate(true);
};

And I'm not surprised as null is given for the model here this.viewer.setThemingColor(4, new THREE.Vector4(1, 0, 0, 0.5), null, true);. Although that shouldn't be a problem if this.model is set but apparently it isn't.

I hope someone can point me in the right direction of how to color the model.

Update

I have added the following as suggested:

this.viewer.loadDocumentNode(viewer_document, default_model).then(model => {    
    console.log('model', model, 'color', new THREE.Vector4(1, 0, 0, 0.5));
    this.viewer.setThemingColor(4, new THREE.Vector4(1, 0, 0, 0.5), model, true);
});

That gives the log as shown below. The error is gone. enter image description here But it still doesn't change the color of the model. enter image description here


Solution

  • From my understanding, It's because you run setThemingColor before loadDocumentNode finish.

    Can you try to put viewer.setThemingColor(...) into the loadDocumentNode()'s callback function ? just to ensure you set the color after the model is fully loaded.

    like this :

    this.viewer.loadDocumentNode(viewer_document, default_model)
    .then(() => {
        //when document node loaded, do...
        this.viewer.setThemingColor(4, new THREE.Vector4(1, 0, 0, 0.5), this.model, true);
    })