12 Sep 2017

Property based selection / isolation

All models shown in the Viewer tend to have lots of metadata and properties for each object. Some of them serve the purpose of organising them into groups (Group1, Group2, etc) and can be really useful to quickly narrow down the selection or isolate only members of a specific group.

This is something that is quite easy to achieve using the Viewer's Javascript API, and it provides a completely generic solution, so you'll be able to filter on any properties of the object.

In the above example (see pic), we were isolating all objects which had the "Type Name" set to "08 FOUNDATION WALL 12" CMU"

To achieve this you have to create a function that will handle the event when the user clicks a property value in the Property Palette. Inside there we can use the Viewer's search() functionality to find objects with the same property value.
a) if the property.attributeName is unique in the model for this property then we are pretty much set, otherwise we still need to filter down the objects - see getSubset() below
b) in order to speed up the selection as shown by Augusto, I place the property value in quotation marks: "<property value>" 

Once we have our functions, we can assign our click handler to Autodesk.Viewing.UI.PropertyPanel.prototype.onPropertyClick

    // ...
    oViewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv);
    Autodesk.Viewing.UI.PropertyPanel.prototype.onPropertyClick = onPropertyClick
    // ...
}

function getSubset(dbIds, name, value, callback) {
    console.log("getSubset, dbIds.length before = " + dbIds.length)
    oViewer.model.getBulkProperties(dbIds, {
        propFilter: [name],
        ignoreHidden: true
    }, function(data) {
        var newDbIds = []
        for (var key in data) {
            var item = data[key]
            if (item.properties[0].displayValue === value) {
                newDbIds.push(item.dbId)
            }
        }

        console.log("getSubset, dbIds.length after = " + newDbIds.length)

        callback(newDbIds)

    }, function(error) {})
}

function onPropertyClick(property, event) {
    console.log(property.name + " = " + property.value)
    oViewer.search('"' + property.value + '"', function(dbIds) {
        console.log(dbIds.length);
        getSubset(dbIds, property.name, property.value, function(dbIds) {
            oViewer.isolate(dbIds)
        })
    }, function(error) {}, [property.attributeName])
}

 

Related Article