Basic Application
The ViewingApplication
object helps managing the Viewer instance and abstracts some of the Viewer’s boilerplate code.
This tutorial has the same objective as Basic Viewer’s tutorial, but it uses the ViewingApplication
class.
Before You Begin
Follow the Before You Begin section in Basic Viewer Step-by-Step Tutorial.
Step 1: Prepare your HTML
Use the HTML below to:
- Fetch JSON manifest from Forge using
viewerApp.loadDocument()
. - Identify the 3D and 2D viewables contained in JSON manifest using
viewerApp.bubble.search()
. - Select the first viewable and and load it using
viewerApp.selectItem()
.
This approach keeps a reference to viewerApp
instead of viewer
. Developers can still access the Viewer instance through viewerApp.getCurrentViewer()
,
but will have to call it after the Viewer instance has been created. See more information below.
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<!-- The Viewer CSS -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/2.*/style.min.css" type="text/css">
<!-- Developer CSS -->
<style>
body {
margin: 0;
}
#MyViewerDiv {
width: 100%;
height: 100%;
margin: 0;
background-color: #F0F8FF;
}
</style>
</head>
<body>
<!-- The Viewer will be instantiated here -->
<div id="MyViewerDiv"></div>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/2.*/three.min.js"></script>
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/2.*/viewer3D.min.js"></script>
<!-- Developer JS -->
<script>
var viewerApp;
var options = {
env: 'AutodeskProduction',
getAccessToken: function(onGetAccessToken) {
//
// TODO: Replace static access token string below with call to fetch new token from your backend
// Both values are provided by Forge's Authentication (OAuth) API.
//
// Example Forge's Authentication (OAuth) API return value:
// {
// "access_token": "<YOUR_APPLICATION_TOKEN>",
// "token_type": "Bearer",
// "expires_in": 86400
// }
//
var accessToken = '<YOUR_APPLICATION_TOKEN>';
var expireTimeSeconds = 60 * 30;
onGetAccessToken(accessToken, expireTimeSeconds);
}
};
var documentId = 'urn:<YOUR_URN_ID>';
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D);
viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
function onDocumentLoadSuccess(doc) {
// We could still make use of Document.getSubItemsWithProperties()
// However, when using a ViewingApplication, we have access to the **bubble** attribute,
// which references the root node of a graph that wraps each object from the Manifest JSON.
var viewables = viewerApp.bubble.search({'type':'geometry'});
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
viewerApp.selectItem(viewables[0].data, onItemLoadSuccess, onItemLoadFail);
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
function onItemLoadSuccess(viewer, item) {
console.log('onItemLoadSuccess()!');
console.log(viewer);
console.log(item);
// Congratulations! The viewer is now ready to be used.
console.log('Viewers are equal: ' + (viewer === viewerApp.getCurrentViewer()));
}
function onItemLoadFail(errorCode) {
console.error('onItemLoadFail() - errorCode:' + errorCode);
}
</script>
</body>
Refer to the Basic Viewer tutorial for a note on Error Codes.
Step 2: Customization
Before the above code can be used, two strings need to be updated with a valid access token and the seed URN.
accessToken: '<YOUR_APPLICATION_TOKEN>'
var documentId = 'urn:<YOUR_URN_ID>';
Important: The value assigned to variable documentId
must be prefixed with string urn:
.
The callback function onDocumentLoadSuccess()
gets invoked after the Viewer successfully fetches the manifest JSON from Forge.
It then inspects the manifest using viewerApp.bubble.search()
and validates that there is at least one viewable, either 2D or 3D, available to initialize the 3D canvas.
Developers can choose which of the available viewables will get loaded into the Viewer. Furthermore, developers are encouraged to build a UI to navigate through the available viewables.
If no viewables are found, an error message will get pushed to the console.
Check the Field Guide for more information on the benefits of using a ViewingApplication
.
Step 2: Change model in Viewer
Changing the Viewer’s model requires fewer steps compared to how it is done in the Basic Viewer tutorial.
Adding the UI and callback, however, is still the same.
Start by adding a <button>
right after MyViewerDiv
.
<div id="MyViewerDiv"></div>
<button id="MyNextButton" onClick="loadNextModel()">Next!</button>
Add button style:
<style>
#MyNextButton {
position: absolute;
top: 5px;
left: 5px;
z-index: 1;
font-size: 40px;
cursor: pointer;
}
</style>
Add two global variables declarations right after var viewerApp
:
var viewerApp;
var viewables;
var indexViewable;
In the function onDocumentLoadSuccess()
, promote the viewables
variable from local to global scope by removing var
.
Also, initialize indexViewable
to 0
.
And finally, define the new button’s onClick
callback function loadNextModel()
:
function loadNextModel() {
// Next viewable index. Loop back to 0 when overflown.
indexViewable = (indexViewable + 1) % viewables.length;
viewerApp.selectItem(viewables[indexViewable].data, onItemLoadSuccess, onItemLoadFail);
}
Try it out!
Notice that using viewerApp.selectItem()
removes the need to manually call viewer.tearDown()
and viewer.setUp()
.
The reference to Autodesk.Viewing.Document
object has been replaced with viewerApp.bubble
, which provides enhanced functionality by wrapping plain JSON objects in typed objects. Refer to the JavaScript Library section for details.
Viewer version
The example code provided here is fetching the latest Viewer version available. We recommend that before your application is published to your customers, a specific version of the Viewer’s codebase gets requested.
More information on API Basics, section Getting the Code.