8 Oct 2017
Get all DbId without enumerating model hierarchy
In most cases, we would need to get all DbId of the model when working with the web application of Forge Viewer. This is because most API methods of manipulating entities require the argument DbId (or array), such as isolate, hide, highlight etc. By the DbId array, we build a map with the the node of model hierarchy, or a kind of unique Id.
One typical way to get all DbId array is to iterate model hierarchy by instanceTree.enumNodeChildren in the event when geometry are all ready (Autodesk.Viewing.GEOMETRY_LOADED_EVENT) The two blogs below tell more. For simple model, this workflow works well, but for a complicated huge model, it will take much time to complete the iteration.
https://forge.autodesk.com/blog/enumerating-leaf-nodes-viewer
Way1: by Forge Viewer API
Actually,the properties of instanceTree provides arrays of DbId and model nodes. They are:
- instanceTree.nodeAccess.dbIdToIndex: contains all dbId, but it is a dictionary that stores the map from DbId to instanceTree.nodeAccess.names array.
- instanceTree.nodeAccess.names: contains the model node index for instanceTree.nodeAccess.strings
- instanceTree.nodeAccess.strings: stores the display name of model node. If there is special suffix, it will need to be got out from instanceTree.nodeAccess.nameSuffixes. e.g. in the snapshot below, [105545] is the suffix.
- instanceTree.nodeAccess.nameSuffixes: stores the suffix strings
So, we can sort out all DbIds from instanceTree.nodeAccess.dbIdToIndex without much effort. Assume we get an DbId, and want to get the display name of corresponding model node, the code snippet can work.
var dbid = 1854;
var it = NOP_VIEWER.model.getData().instanceTree;
var indexinNames = it.nodeAccess.dbIdToIndex[dbid];
var indexinStrings = it.nodeAccess.names[indexinNames];
var nodeMainString = it.nodeAccess.strings[indexinStrings];
var nodeSuffixString = it.nodeAccess.nameSuffixes[indexinStrings];
//final display name of the model node
var nodeFinalName = nodeMainString+nodeSuffixString + ']';
In fact, Forge Viewer API has provided a direct method:
var dbid = 1854;
var it = NOP_VIEWER.model.getData().instanceTree;
//final display name of model node
var nodeFinalName = it.getNodeName(dbid);
If we have known the display name of a model node, we could trim its suffix string, find its index from instanceTree.nodeAccess.strings, get map index from instanceTree.nodeAccess.names, and get out the DbId from instanceTree.nodeAccess.dbIdToIndex.
Way2: by Model Derivative
As well known, to view the model in the browser, we need to ask Model Derivative API of Forge to translate the source file. After the translating, the model hierarchy, DbId, and object properties are all managed in a specific database on Forge cloud. We can just request to get them in the Json format:
1. request to get metadata by https://developer.api.autodesk.com/modelderivative/v2/designdata/:urn/metadata. This call will return a list of model view (metadata) IDs for a design model. The metadata ID enables end users to select an object tree and properties for a specific model view. e.g. the snapshot shows the guid of 3D view of one model.
2. request to get model hierarchy and DbIds by https://developer.api.autodesk.com/modelderivative/v2/designdata/:urn/metadata/:guid, inputingg the guid we got in step 1. As said, after translating, the data is managed in the specific database, but they are not ready in an Json format until the developer requests. So after requesting the first time, the response code is 202, that means Forge accepted the job and will prepare a Json data. We will need to call the same API again to check if the Json data is ready or not. Once the response code is 200, we will see the response by tells the model hierarchy and DbIds.
Next, we can get out all DbIDs from the Json string.