mariappan .gameo
mariappan .gameo

Reputation: 341

What is the proper way to create a custom toolbar extension in Nuxt.JS for autodesk forge viewer?

I have a basic viewer application in nuxt.js. I wanted to customize the toolbar and display an additional button.I have followed several resources and previous answers but still not clear how to handle those in nuxt.

I followed this tutorial - https://learnforge.autodesk.io/#/viewer/extensions/skeleton

Note : Even if it's possible to create a toolbar button without extension,that would help me.Because what all I need is a custom toolbar button and I would handle events with js over there.

I have two stage of problems, initially

The toolbar extension is working properly sometimes but sometimes I'm getting Autodesk is not defined error.How to handle this in nuxt.js? I tried setting like this,

//eslintrtc

{ "globals": { "Autodesk": true } }

But this is not working in all cases.

2.After adding the buttons,I wish to handle the button click event in the vue component(ie.in the index.vue file) or access the index.vue component's data inside the extension.js file.

What is the proper way to achieve this?I have tried few but those don't work,

I'll leave a simplified code here,can someone help me correct this in such a way it works as a nuxt app?

//index.vue

<template>
    <div id="forgeViewer"></div>
</template>
<script>
import AlarmTable from "../components/AlarmTable.vue"
import MyAwesomeExtension from './extensions/myawesomeextension.js';

export default {
  components: {
    AlarmTable
  },
  data(){
    return{
      isActive:false,
      viewer:null
    }
  },
  mounted(){
      let ref = this;
      this.initAutodesk(app,ref);
  },
  methods:{
    initAutodesk(app,ref){
    var htmlDiv = document.getElementById('forgeViewer');
    const viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);

//can I register extension something like this outside and use the toolbar button 
    // Autodesk.Viewing.theExtensionManager.registerExtension('MyAwesomeExtension', MyAwesomeExtension);  

//document.getElementById('MyAwesomeExtensionButton') undefined

    this.viewer = viewer;
    var closable = null;
    var options = {
        env: 'AutodeskProduction',
        api: 'derivativeV2',  // for models uploaded to EMEA change this option to 'derivativeV2_EU'
        getAccessToken: function(onTokenReady) {
          var token = 'my access token';
          var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
          onTokenReady(token, timeInSeconds);
        }
      };

    Autodesk.Viewing.Initializer(options, function() {
      var startedCode = viewer.start();
      if (startedCode > 0) {
        console.error('Failed to create a Viewer: WebGL not supported.');
        return;
      }
      console.log('Initialization complete, loading a model next...');
    });
    var documentId = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZmFjaWxpb25ld2NsaWVudGJ1Y2tldC9yYWNfYWR2YW5jZWRfc2FtcGxlX3Byb2plY3QucnZ0';
    Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, this.onDocumentLoadFailure);
    function onDocumentLoadSuccess(viewerDocument) {
        var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
        viewer.loadDocumentNode(viewerDocument, defaultModel);
        viewer.addEventListener( Autodesk.Viewing.SELECTION_CHANGED_EVENT, event=>{
          console.log(event.dbIdArray.length);

          })
    }
  },

  onDocumentLoadFailure() {
      console.error('Failed fetching Forge manifest');
    }
  }
}
</script>

<style>
body {
    margin: 0;
  }
  #forgeViewer {
    width: 100%;
    height: 100%;
    margin: 0;
    background-color: #F0F8FF;
  }
.myAwesomeExtensionIcon {
    background-image: url(/img/myAwesomeIcon.png);
    background-size: 24px;
    background-repeat: no-repeat;
    background-position: center;
}

</style>

//myawesomeextension.js

// Content for 'my-awesome-extension.js'
export default class MyAwesomeExtension extends Autodesk.Viewing.Extension {
    constructor(viewer, options) {
        super(viewer, options);
        this._group = null;
        this._button = null;
    }

    load() {
        console.log('MyAwesomeExtensions has been loaded');
        return true;
    }

    unload() {
        // Clean our UI elements if we added any
        if (this._group) {
            this._group.removeControl(this._button);
            if (this._group.getNumberOfControls() === 0) {
                this.viewer.toolbar.removeControl(this._group);
            }
        }
        console.log('MyAwesomeExtensions has been unloaded');
        return true;
    }

    onToolbarCreated() {
        // Create a new toolbar group if it doesn't exist
        this._group = this.viewer.toolbar.getControl('allMyAwesomeExtensionsToolbar');
        if (!this._group) {
            this._group = new Autodesk.Viewing.UI.ControlGroup('allMyAwesomeExtensionsToolbar');
            this.viewer.toolbar.addControl(this._group);
        }

        // Add a new button to the toolbar group
        this._button = new Autodesk.Viewing.UI.Button('myAwesomeExtensionButton');
        this._button.onClick = (ev) => {
            // Execute an action here
        };
        this._button.setToolTip('My Awesome Extension');
        this._button.addClass('myAwesomeExtensionIcon');
        this._group.addControl(this._button);
    }
}

Upvotes: 0

Views: 522

Answers (2)

Andrei Pavlov
Andrei Pavlov

Reputation: 35

  1. Place registerExtension method inside myawesomeextension.js as exported function:
    export default function() {
      Autodesk.Viewing.theExtensionManager.registerExtension(
        "MyAwesomeExtension",
        MyAwesomeExtension
      );
    }
  1. Import myawesomeextension.js in index.vue:
<script>
    import myawesomeextension from './extensions/myawesomeextension';
  1. Register extension before loading viewer (example with local svf files):
  mounted() {
    myawesomeextension();
    this.loadViewer();
  },
  methods: {
    loadViewer() {
      let config3d = {
        extensions: ["MyAwesomeExtension"]
      };
      this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
        this.$refs.forgeViewer,
        config3d
      );
      Autodesk.Viewing.Initializer(this.options, () => {
        this.viewer.initialize();
        this.viewer.start(this.project.svfUrl, this.options);
      });
    },

Upvotes: 0

Bryan Huang
Bryan Huang

Reputation: 5342

I tried to add from static folder - but we can't access component inside it Tried to import the class - autodesk is undefined error

This is to be expected as the Autodesk namespace is not initialized (as Viewer libraries/scripts are yet to be loaded) when the imported module is evaluated in build/run time (and hence the undefined error) ...

Use dynamic import to defer the evaluation ... try something like:

async initAutodesk(app,ref){
//...
const MyAwesomeExtension = await import('./extensions/myawesomeextension.js').then(mod=>mod.default)
Autodesk.Viewing.theExtensionManager.registerExtension('MyAwesomeExtension', MyAwesomeExtension);
viewer.loadExtension...

Upvotes: 1

Related Questions