9 Nov 2017
Switching Viewables in the Forge Viewer
Here is a quick post to document a feature I just added to my main Forge web site: https://forge-rcdb.autodesk.io. It's about providing a UI to let the user switch between multiple views (or viewable items) contained in a single document. The A360 viewer offers this possibility but it is not part of the viewer API. Look no further I'm bringing that to you at no cost ;)
Listing and switching between viewable items in a Forge document is actually pretty straightforward, you will mainly have to deal with wrapping a nice UI around it to let the user select which item has to be displayed. To see how to include or exclude views from a document before uploading to Forge, take a look at this article: How to Export Multiple 3D Views.
Let's dive into the code (all my examples below are using ES6 and async/await + React for the UI part):
I - Load a document from a translated URN
/////////////////////////////////////////////////////////
// Load a document from URN
//
/////////////////////////////////////////////////////////
static loadDocument (urn) {
return new Promise((resolve, reject) => {
const paramUrn = !urn.startsWith('urn:')
? 'urn:' + urn
: urn
Autodesk.Viewing.Document.load(paramUrn, (doc) => {
resolve (doc)
}, (error) => {
reject (error)
})
})
}
II - Get the list of all viewable items in the loaded document
/////////////////////////////////////////////////////////
// Return viewables
//
/////////////////////////////////////////////////////////
static getViewableItems (doc, roles = ['3d', '2d']) {
const rootItem = doc.getRootItem()
let items = []
const roleArray = roles
? (Array.isArray(roles) ? roles : [roles])
: []
roleArray.forEach((role) => {
items = [ ...items,
...Autodesk.Viewing.Document.getSubItemsWithProperties(
rootItem, { type: 'geometry', role }, true) ]
})
return items
}
III - Load the selected viewable
First we unload the current model, this code assumes we have a model loaded at the time user selects a different item, and simply loads a new one by obtaining its path. I am using viewer.tearDown which ensure memory of the current model is being released. This also supports switching from a 3D model to a 2D one and reciprocally. You can abstract away the React code which is specific to my app here.
/////////////////////////////////////////////////////////
// Load the selected viewable
//
/////////////////////////////////////////////////////////
onItemSelected (item) {
const {activeItem} = this.react.getState()
if (item.guid !== activeItem.guid) {
this.viewer.tearDown()
this.viewer.start()
const path =
this.viewerDocument.getViewablePath(item)
this.viewer.loadModel(path)
this.react.setState({
activeItem: item
})
}
}
That's pretty much all you need to know, the rest of the implementation was purely React and css work to create a nice UI around it. That feature is now available by default for any model with more than one view that you upload to the gallery section of my app: https://forge-rcdb.autodesk.io/gallery
See the code in action below, or refer to the implementation: Viewing.Extension.ViewableSelector.js