By Philippe Leefsma (@F3lipek)
The latest release of the viewer available at https://autodeskviewer.com/viewers/2.5/viewer3D.min.js is unfortunately introducing a breaking change in the way you have to access the model structure. The migration is rather straightforward but any code you have in your application relying on viewer.getObjectTree is likely to be broken.
Here is a simple snippet that illustrates how to iterate the direct children of the root node:1 var instanceTree = viewer.model.getData().instanceTree; 2 3 var rootId = this.rootId = instanceTree.getRootId(); 4 var rootName = instanceTree.getNodeName(rootId); 5 var childCount = 0; 6 7 instanceTree.enumNodeChildren(rootId, function(childId) { 8 9 var childName = instanceTree.getNodeName(childId); 10 11 console.log(childName); 12 13 childCount++; 14 });For a more elaborated sample, take a look at the implementation of my ModelStructure Extension. It implements two methods: "buildModelTree" that returns the model tree as object using a recursive function and "executeTaskOnModelTree" that returns an array of Promises which run a task on each node component. Using that function, you could for example get all components which contain a property named 'Material', it will then return the list of all matches in an array when all promises have resolved:
1 /////////////////////////////////////////////////////////////////// 2 // A demo task 3 // 4 /////////////////////////////////////////////////////////////////// 5 function hasPropertyTask(model, dbId, propName, matches) { 6 7 return new Promise(function(resolve, reject){ 8 9 model.getProperties(dbId, function(result) { 10 11 if(result.properties) { 12 13 for (var i = 0; i < result.properties.length; ++i) { 14 15 var prop = result.properties[i]; 16 17 //check if we have a match 18 if (prop.displayName == propName) { 19 20 var match = { 21 dbId: dbId 22 } 23 24 match[propName] = prop.displayValue; 25 26 matches.push(match); 27 } 28 } 29 } 30 31 return resolve(); 32 33 }, function() { 34 35 return reject(); 36 }); 37 }); 38 }Use it has follow:
1 var matches = []; 2 3 // Creates a thunk for our task 4 // We look for all components which have a 5 // property named 'Material' and returns a list 6 // of matches containing dbId and the prop value 7 var taskThunk = function(model, dbId) { 8 9 return hasPropertyTask( 10 model, dbId, 'Material', matches); 11 } 12 13 var taskResults = executeTaskOnModelTree( 14 viewer.model, taskThunk); 15 16 Promise.all(taskResults).then(function(){ 17 18 console.log('Found ' + matches.length + ' matches'); 19 console.log(matches); 20 });Here is the full implementation of the extension:
calling var instanceTree = model.getData().instanceTree;
returns instanceTree as undefined. strange?
(is there any better documentation than https://developer.autodesk.com/api/viewerapi/? I'm struggling to find it useful... like what is returned by getData()? all the source says is return this.myData which seems like it could be anything. Is it defined somewhere?)
Posted by: Ken | 04/28/2016 at 09:32 AM
Maybe this is because the file is a DWFx When I select things in the viewer I get a lot of information about them but when I look at the model browser, it appears empty.
Posted by: Ken | 04/28/2016 at 09:38 AM
Most likely you are not waiting for the following events to fire when you load your model so the instanceTree has not been loaded yet:
Autodesk.Viewing.GEOMETRY_LOADED_EVENT
Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT
Take a look at this post:
http://adndevblog.typepad.com/cloud_and_mobile/2015/08/asynchronous-viewer-events-notification.html
There is no better documentation, I think that blog and the forum should address most of the topics. You can also post your questions on the forum if you are stuck, we will address them: http://forums.autodesk.com/t5/cloud-services/ct-p/94
You can simply do console.log(model.getData()) to see what is returned by this method and ultimately looking at the source code: https://autodeskviewer.com/viewers/2.5/viewer3D.js
Posted by: Philippe Leefsma | 04/28/2016 at 05:20 PM