Autodesk FORGE Viewer Integration in Native Applications Using Qt

Have you used the Autodesk FORGE Viewer before? If you have, you must be amazed by its ability to render model data in a browser. For those, who do not know about Autodesk FORGE viewer, let us introduce it in brief.
It is a WebGL-based, JavaScript library for 3D and 2D model rendering. 3D and 2D model data may come from applications, such as AutoCAD, Fusion 360, Revit, and many more. Simple!! Right?? And how to use this viewer in a browser? Well, you need access token and URN (Unique resource name) of the file. You can follow this link for the basic application set up.

The Need

Fine. how about viewing these models in the native applications? You may say ok but why? Suppose you have Windows or Android application in which you want to present your product (which is surely a 3D model). Many times, you may think about providing a high definition image of the product, but 3D model really adds a great value for customer experience. So the need is “ you want to render 3D model in a native application”. Next question is how we are going get this feature? Can we do something like this?

  1. Create a native application using C++ and Qt
  2. Insert a webpage containing the Autodesk FORGE Viewer inside it
  3. Set up some interface for communication between a native application and the Autodesk FORGE web application

Ok, these steps sound good. Let’s try this. We will create windows desktop application with Qt. You can follow these Qt installation steps. Now let’s create a Qt project in visual studio. Make sure you add WebEngine, WebEngine Widgets, and Web Channel modules in your project.

Qt Project

In CPP code, use QWebEngineView class which provides a widget that is used to view and edit web documents. In it, we will load the Autodesk FORGE Viewer.
QWebEngineView *view = new QWebEngineView();
QGridLayout* baseLayout = new QGridLayout(this);
baseLayout->addWidget(view, 0, 0);
ui.centralWidget->setLayout(baseLayout);
view->load(QUrl("http://192.168.1.30:8080/basic_viewer.html"));
view->show();
You can design UI like below: In this, you can split the application window in two main widgets i.e left side navigation widget and main widget which will contain the Autodesk FORGE Viewer.

Autodesk FORGE Web App

To initialize Autodesk viewing service use below snippet:

var viewer;
    var options = {
        env: 'AutodeskProduction',
        accessToken: ''
    };
    var documentId = 'urn:'; //model urn
    Autodesk.Viewing.Initializer(options, function onInitialized(){
        Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
    });
After loading document successfully, proceed with viewer initialization:
var viewerDiv = document.getElementById('MyViewerDiv');
    viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv);
    viewer.start(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
Here is how the Autodesk FORGE Viewer with 3D model looks like:

CPP(Qt) And JS(Web Application) Intercommunication

There is a communication mechanism, which works as a bridge between the C++ world to the JavaScript world. It provides a way in which C++ code can call JavaScript functions and vice versa. Not only function calling but also, we can pass the variables from one side to another. These scenarios can be divided into two parts:

Part I

Qt (CPP) app invokes Autodesk FORGE (Js) web app functions:

This is very easy and straightforward way as compared to JavaScript to CPP. In this case, you need to use runJavaScript() function to run JavaScript on a page loaded by QWebEngineView. And pass JavaScript function call as a parameter.
runJavaScript()
Runs the JavaScript code contained in scriptSource. For example,
view->page()->runJavaScript("forgeViewer.SetView('front')");
Here forgeViewer is viewer object, SetView() is a function defined in JavaScript code and ‘front’ is function parameter

Part II

Autodesk FORGE (Js) web app invokes Qt (Cpp) app functions:

In this scenario, we must use QtWebChannel class which enables peer-to-peer communication between a server and a client. In Cpp code, you should have a class which is derived from QObject and it should contain Q_OBJECT macro that declares its own signals and slots.
Let’s say that class name is MyWebChannel which contains a slot as below:
class MyWebChannel: public QObject
{
    Q_OBJECT
public:
    MyWebChannel();
    ~MyWebChannel();

    public slots:
   	 void ActivateUI();             	 
};
[Important Step] Now register an object of this class with QWebChannel object, to get access to the properties, signals and public methods of the object on the remote clients.
QWebChannel* qWebChannel = new QWebChannel();
MyWebChannel* webChannelObj = new MyWebChannel();
qWebChannel->registerObject("mainWindow", webChannelObj);
view->page()->setWebChannel(qWebChannel);
To create an instance of QWebChannel on the client side, we need to add qwebchannel.js file. To communicate with a QWebChannel or WebChannel, a client must use and set up the Javascript API provided by qwebchannel.js. Then instantiate a QWebChannel object and pass it a transport object and a callback function, which will be invoked once the initialization of the channel finishes and published objects become available.
new QWebChannel(qt.webChannelTransport, function (channel) {
	mainWindowObj = channel.objects.mainwindow;	
});
Now we can call CPP functions from Javascript as follows:
mainWindowObj.ActivateUI();

Data passing between Cpp and Js Functions

As I mentioned above, we can pass data in between and this can also be divided into two parts:

Part I

Data passing from CPP to JS
view->page()->runJavaScript("forgeViewer.SetView('back')");
view->page()->runJavaScript("forgeViewer.SetSelectedBodyColor(' "+ colorName +" ',' "+ mSelectedDbId +" ')");
});

Part II

Data passing from JS to CPP
mainWindowObj .ShowModelTreeView(JSON.stringify(treeObj));

Output

In this demo application we have created a native application using Cpp and Qt. Which on startup loads hosted Autodesk FORGE viewer. In the left navigation panel, we get three options like:
  1. The Autodesk FORGE views (You can change view i.e top, bottom, left, right)
  2. Model tree (which shows a listing of model parts, also on selection of particular body, that body gets highlighted in viewer)
  3. Properties of a selected body
Real beauty is that you can do all above options from native application. Isn’t it iteresting?

Leave a comment

Share this Blog Post :

Facebook
X
LinkedIn

Vikrant Kulkarni

Vikrant is a Software Engineer and a Member of Technical Staff in the Marketing Team, contributing to the development and maintenance of technical solutions that support marketing initiatives.