22 Mar 2019

Adding custom properties to Property panel

Update:

Viewer 7.37 supports aggregated models, the setProperties method is now setAggregatedProperties. And this code is now part of the Extensions library.

Original post:

This is actually a recurrent topic, first explored at this post, which is not working on newer versions (due CSS breaking changes on v4). It was then revisited as a new toolbar button at this post, which works fine, but isn't replacing the existing Property panel.

So how could we replace the existing Properties panel?

Actually, there is a viewer.setPropertyPanel method that accepts a ViewerPropertyPanel object, which is the built-in panel. So a minimum implementation would just use it and replace the setProperties method. To have a bit more information, let's also replace the setNodeProperties function to capture the dbId. Below is that part of the code.

// *******************************************
// Custom Property Panel
// *******************************************
function CustomPropertyPanel(viewer, options) {
    this.viewer = viewer;
    this.options = options;
    this.nodeId = -1; // dbId of the current element showing properties
    Autodesk.Viewing.Extensions.ViewerPropertyPanel.call(this, this.viewer);
}
CustomPropertyPanel.prototype = Object.create(Autodesk.Viewing.Extensions.ViewerPropertyPanel.prototype);
CustomPropertyPanel.prototype.constructor = CustomPropertyPanel;

CustomPropertyPanel.prototype.setProperties = function (properties, options) {
    Autodesk.Viewing.Extensions.ViewerPropertyPanel.prototype.setProperties.call(this, properties, options);

    // add your custom properties here
    // for example, let's show the dbId and externalId
    var _this = this;
    // dbId is right here as nodeId
    this.addProperty('dbId', this.propertyNodeId, 'Custom Properties');
    // externalId is under all properties, let's get it!
    this.viewer.getProperties(this.propertyNodeId, function (props) {
        _this.addProperty('externalId', props.externalId, 'Custom Properties');
    })
}

CustomPropertyPanel.prototype.setNodeProperties = function (nodeId) {
    Autodesk.Viewing.Extensions.ViewerPropertyPanel.prototype.setNodeProperties.call(this, nodeId);
    this.nodeId = nodeId; // store the dbId for later use
};

Now to make it easy to use, let's wrap it within an extension. This blog post discusses a skeleton for extensions, let's use just the extension piece (not the toolbar or panel). The following extension uses the above panel and wire with the Viewer using .setPropertyPanel. The extension will take care of registering and unregistering the custom property panel.

// *******************************************
// Custom Property Panel Extension
// *******************************************
function CustomPropertyPanelExtension(viewer, options) {
    Autodesk.Viewing.Extension.call(this, viewer, options);

    this.viewer = viewer;
    this.options = options;
    this.panel = null;
}

CustomPropertyPanelExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
CustomPropertyPanelExtension.prototype.constructor = CustomPropertyPanelExtension;

CustomPropertyPanelExtension.prototype.load = function () {
    return true;
};

CustomPropertyPanelExtension.prototype.onToolbarCreated = function () {
    this.panel = new CustomPropertyPanel(this.viewer, this.options);
    var _this = this;
    this.viewer.addEventListener(Autodesk.Viewing.EXTENSION_LOADED_EVENT, function (e) {
        if (e.extensionId !== 'Autodesk.PropertiesManager') return;
        var ext = _this.viewer.getExtension('Autodesk.PropertiesManager');
        ext.setPanel(_this.panel);
    })
};

CustomPropertyPanelExtension.prototype.unload = function () {
    if (this.panel == null) return;
    var ext = this.viewer.getExtension('Autodesk.PropertiesManager');
    this.panel = null;
    ext.setDefaultPanel();
    return true;
};

Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.Sample.CustomPropertyPanelExtension', CustomPropertyPanelExtension);

The last piece is to load the extension. If your application uses the Basic Application tutorial, it would have a line like the following, just add the extension:

viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, { extensions: ['CustomPropertyPanelExtension'] });

 

Related Article