Skip to content

Instantly share code, notes, and snippets.

@leefsmp
Last active February 12, 2016 17:43
Show Gist options
  • Save leefsmp/36b7b737cda36ab8542a to your computer and use it in GitHub Desktop.
Save leefsmp/36b7b737cda36ab8542a to your computer and use it in GitHub Desktop.
ModelLoader View & Data Extension: Allows loading, transformation and unloading of multiple models into the same scene
/////////////////////////////////////////////////////////////////////
// Autodesk.ADN.Viewing.Extension.ModelLoader
// by Philippe Leefsma, Feb 2016
//
/////////////////////////////////////////////////////////////////////
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.ModelLoader = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _panel = null;
///////////////////////////////////////////////////////////////////
// The model API used by this extension
//
///////////////////////////////////////////////////////////////////
var API = {
/////////////////////////////////////////////////////////////////
// Extracts model name (filename) from base64 URN
//
/////////////////////////////////////////////////////////////////
getModelName: function(urn) {
var fileId = decodeURIComponent(escape(window.atob(urn)));
var filename = fileId.split('/')[1];
var splits = filename.split('.');
return filename.substring(0,
filename.length - (splits[splits.length-1].length + 1));
},
/////////////////////////////////////////////////////////////////
// Returns list of models available in the Gallery
//
/////////////////////////////////////////////////////////////////
getGalleryModels: function() {
return new Promise((resolve, reject)=> {
$.get(options.apiUrl + '/models', (models)=> {
resolve(models);
});
});
},
/////////////////////////////////////////////////////////////////
// Returns list of models loaded in the current scene
//
/////////////////////////////////////////////////////////////////
getLoadedModels: function() {
return new Promise((resolve, reject)=> {
resolve(viewer.impl.modelQueue().getModels());
});
},
/////////////////////////////////////////////////////////////////
// Returns Gallery token
//
/////////////////////////////////////////////////////////////////
getToken: function() {
return new Promise((resolve, reject)=> {
$.get(options.apiUrl + '/token', (response)=> {
resolve(response.access_token);
});
});
},
/////////////////////////////////////////////////////////////////
// Returns viewable path from URN (needs matching token)
//
/////////////////////////////////////////////////////////////////
getViewablePath: function(token, urn) {
return new Promise((resolve, reject)=> {
try {
Autodesk.Viewing.Initializer({
accessToken: token
}, ()=> {
Autodesk.Viewing.Document.load(
'urn:' + urn,
(document)=> {
var rootItem = document.getRootItem();
var geometryItems3d = Autodesk.Viewing.Document.
getSubItemsWithProperties(
rootItem, {
'type': 'geometry',
'role': '3d' },
true);
var geometryItems2d = Autodesk.Viewing.Document.
getSubItemsWithProperties(
rootItem, {
'type': 'geometry',
'role': '2d' },
true);
var got2d = (geometryItems2d && geometryItems2d.length > 0);
var got3d = (geometryItems3d && geometryItems3d.length > 0);
if(got2d || got3d) {
var pathCollection = [];
geometryItems2d.forEach((item)=>{
pathCollection.push(document.getViewablePath(item));
});
geometryItems3d.forEach((item)=>{
pathCollection.push(document.getViewablePath(item));
});
return resolve(pathCollection);
}
else {
return reject('no viewable content')
}
},
(err)=> {
console.log('Error loading document... ');
//Autodesk.Viewing.ErrorCode
switch(err){
case 1: //UNKNOWN_FAILURE
console.log('An unknown failure has occurred.');
break;
case 2: //BAD_DATA
console.log('Bad data (corrupted or malformed) ' +
'was encountered.');
break;
case 3: //NETWORK_FAILURE
console.log('A network failure was encountered.');
break;
case 4: //NETWORK_ACCESS_DENIED
console.log('Access was denied to a ' +
'network resource (HTTP 403).');
break;
case 5: //NETWORK_FILE_NOT_FOUND
console.log('A network resource could not ' +
'be found (HTTP 404).');
break;
case 6: //NETWORK_SERVER_ERROR
console.log('A server error was returned when ' +
'accessing a network resource (HTTP 5xx).');
break;
case 7: //NETWORK_UNHANDLED_RESPONSE_CODE
console.log('An unhandled response code was ' +
'returned when accessing a network resource ' +
'(HTTP everything else).');
break;
case 8: //BROWSER_WEBGL_NOT_SUPPORTED
console.log('Browser error: WebGL is not ' +
'supported by the current browser.');
break;
case 9: //BAD_DATA_NO_VIEWABLE_CONTENT
console.log('There is nothing viewable in ' +
'the fetched document.');
break;
case 10: //BROWSER_WEBGL_DISABLED
console.log('Browser error: WebGL is ' +
'supported, but not enabled.');
break;
case 11: //RTC_ERROR
console.log('Collaboration server error');
break;
}
});
});
}
catch(ex){
return reject(ex);
}
});
},
/////////////////////////////////////////////////////////////////
// Loads model into current scene
//
/////////////////////////////////////////////////////////////////
loadModel: function(path, opts) {
return new Promise(async(resolve, reject)=> {
function _onGeometryLoaded(event) {
viewer.removeEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
_onGeometryLoaded);
return resolve(event.model);
}
viewer.addEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
_onGeometryLoaded);
viewer.loadModel(path, opts, ()=> {
},
(errorCode, errorMessage, statusCode, statusText)=> {
viewer.removeEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
_onGeometryLoaded);
return reject({
errorCode: errorCode,
errorMessage: errorMessage,
statusCode: statusCode,
statusText: statusText
});
});
});
},
/////////////////////////////////////////////////////////////////
// Sets model as "current"
//
/////////////////////////////////////////////////////////////////
setCurrentModel: function(model) {
return new Promise((resolve, reject)=> {
viewer.model = model;
var propertyPanel = viewer.getPropertyPanel(true);
propertyPanel.currentModel = model;
model.getObjectTree((instanceTree) =>{
viewer.modelstructure.setModel(instanceTree);
return resolve();
});
});
},
/////////////////////////////////////////////////////////////////
// Fits model to view
//
/////////////////////////////////////////////////////////////////
fitModelToView: function(model) {
return new Promise((resolve, reject)=> {
model.getObjectTree((instanceTree) =>{
viewer.fitToView([instanceTree.rootId]);
});
});
},
/////////////////////////////////////////////////////////////////
// Unloads model from current scene
//
/////////////////////////////////////////////////////////////////
unloadModel: function(model) {
return new Promise(async(resolve, reject)=>{
viewer.impl.unloadModel(model);
viewer.impl.sceneUpdated(true);
return resolve();
});
},
/////////////////////////////////////////////////////////////////
// Applies transform to specific model
//
/////////////////////////////////////////////////////////////////
transformModel: function(model, transform) {
function _transformFragProxy(fragId){
var fragProxy = viewer.impl.getFragmentProxy(
model,
fragId);
fragProxy.getAnimTransform();
fragProxy.position = transform.translation;
fragProxy.scale = transform.scale;
//Not a standard three.js quaternion
fragProxy.quaternion._x = transform.rotation.x;
fragProxy.quaternion._y = transform.rotation.y;
fragProxy.quaternion._z = transform.rotation.z;
fragProxy.quaternion._w = transform.rotation.w;
fragProxy.updateAnimTransform();
}
return new Promise(async(resolve, reject)=>{
var fragCount = model.getFragmentList().
fragments.fragId2dbId.length;
//fragIds range from 0 to fragCount-1
for(var fragId=0; fragId<fragCount; ++fragId){
_transformFragProxy(fragId);
}
return resolve();
});
},
/////////////////////////////////////////////////////////////////
// Hides node (if nodeOff = true completely hides the node)
//
/////////////////////////////////////////////////////////////////
hideNode: function(model, dbIds, nodeOff=false) {
return new Promise((resolve, reject)=> {
dbIds = Array.isArray(dbIds) ? dbIds : [dbIds];
model.getObjectTree((instanceTree)=> {
var vm = new Autodesk.Viewing.Private.VisibilityManager(
viewer.impl,
viewer.model);
dbIds.forEach((dbId)=> {
var node = instanceTree.dbIdToNode[dbId];
vm.hide(node);
vm.setNodeOff(node, nodeOff);
});
return resolve();
});
});
},
/////////////////////////////////////////////////////////////////
// Shows node
//
/////////////////////////////////////////////////////////////////
showNode: function(model, dbIds) {
return new Promise((resolve, reject)=> {
dbIds = Array.isArray(dbIds) ? dbIds : [dbIds];
model.getObjectTree((instanceTree)=> {
var vm = new Autodesk.Viewing.Private.VisibilityManager(
viewer.impl,
viewer.model);
dbIds.forEach((dbId)=> {
var node = instanceTree.dbIdToNode[dbId];
vm.setNodeOff(node, false);
vm.show(node);
});
return resolve();
});
});
}
}
/////////////////////////////////////////////////////////////////
// Extension load callback
//
/////////////////////////////////////////////////////////////////
this.load = function() {
require.config({
//dependencies need to go through transpiling
baseUrl: 'api/extensions/transpile/' +
'Autodesk.ADN.Viewing.Extension.ModelLoader',
paths: {
'modelLoaderCss': 'model-loader.css',
'inspireTreeCss':'inspire-tree.css',
'inspireTree': 'inspire-tree.min'
},
waitSeconds: 0
});
var modules = [
'inspireTree',
'inspireTreeCss',
'modelLoaderCss'
];
// Dynamic dependency loading with RequireJS
require(modules, async(inspireTree)=> {
//set name of original model
viewer.model.name = options.model.name;
var button = createButton(guid(),
'glyphicon glyphicon-list',
'Model Loader', ()=>{
_panel.toggleVisibility();
});
_panel = new ModelLoaderPanel(
viewer.container,
guid(),
button.container,
inspireTree);
var viewerToolbar = viewer.getToolbar(true);
var ctrlGroup = new Autodesk.Viewing.UI.ControlGroup(
'Autodesk.ADN.Viewing.Extension.ModelLoader');
ctrlGroup.addControl(button, {index:1});
viewerToolbar.addControl(ctrlGroup);
console.log('Autodesk.ADN.Viewing.Extension.ModelLoader loaded');
});
return true;
}
/////////////////////////////////////////////////////////////////
// Extension unload callback
//
/////////////////////////////////////////////////////////////////
this.unload = function () {
_panel.setVisible(false);
console.log('Autodesk.ADN.Viewing.Extension.ModelLoader unloaded');
return true;
}
/////////////////////////////////////////////////////////////////
// toolbar button
//
/////////////////////////////////////////////////////////////////
function createButton(id, className, tooltip, handler) {
var button = new Autodesk.Viewing.UI.Button(id);
button.icon.style.fontSize = "24px";
button.icon.className = className;
button.setToolTip(tooltip);
button.onClick = handler;
return button;
}
/////////////////////////////////////////////////////////////////
// Generates random guid to use as DOM id
//
/////////////////////////////////////////////////////////////////
function guid() {
var d = new Date().getTime();
var guid = 'xxxx-xxxx-xxxx-xxxx'.replace(
/[xy]/g,
function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return guid;
}
/////////////////////////////////////////////////////////////////
// The Model Loader Panel
//
/////////////////////////////////////////////////////////////////
var ModelLoaderPanel = function(
parentContainer,
panelId,
btnElement,
InspireTree) {
/////////////////////////////////////////////////////////////////
// Base class constructor
//
/////////////////////////////////////////////////////////////////
Autodesk.Viewing.UI.DockingPanel.call(
this,
parentContainer,
panelId,
'Model Loader',
{shadow: true});
/////////////////////////////////////////////////////////////////
// "Private" ModelLoaderPanel members
//
/////////////////////////////////////////////////////////////////
var _thisPanel = this;
var _isVisible = false;
var _isMinimized = false;
var _loadedModelsTree = null;
var _galleryFilteredNodes = [];
/////////////////////////////////////////////////////////////////
// Initializes the panel
//
/////////////////////////////////////////////////////////////////
async function initialize() {
_thisPanel.content = document.createElement('div');
$(_thisPanel.container).addClass('model-loader');
$(_thisPanel.container).append(generateHtml(panelId));
$('[data-toggle="tooltip"]').tooltip();
reloadTree();
$(`#${panelId}-load-btn`).click(
onLoad);
$(`#${panelId}-load-gallery-btn`).click(
onLoadGallery);
$(`#${panelId}-transform-btn`).click(
onTransform);
$(`#${panelId}-clear-btn`).click(
onClear);
viewer.addEventListener(
Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,
onAggregateSelectionChanged);
// Loads gallery models tree
$('.model-loader .tree-container.gallery').append(
'<div class="model-loader-gallery-tree"></div>'
);
var rootNode = {
type: 'root_node',
text: 'Gallery Models',
children: []
};
var galleryModels = await API.getGalleryModels();
galleryModels.forEach((model)=>{
// filters out .dwg's
var fileId = decodeURIComponent(
escape(window.atob(model.urn)));
if(!fileId.endsWith('.dwg')) {
rootNode.children.push({
type: 'model_node',
text: model.name,
model: model,
children: []
});
}
});
var tree = new InspireTree({
target: '.model-loader-gallery-tree',
data: [rootNode]
});
tree.on('node.dblclick', async(event, node)=> {
if(node.type == 'model_node') {
await loadGalleryNode(node);
reloadTree();
}
});
$(`#${panelId}-search`).on('keyup', (e)=> {
var matches = tree.search(e.target.value);
_galleryFilteredNodes = matches || [];
});
}
/////////////////////////////////////////////////////////////
// Custom html content of the panel
//
/////////////////////////////////////////////////////////////
function generateHtml(id) {
return `
<div class="container">
<button class="btn btn-info btn-load"
id="${id}-load-btn"
data-placement="bottom"
data-toggle="tooltip"
title="Load from URN using provided token">
<span class="glyphicon glyphicon-save btn-span"
aria-hidden="true" style="top:1px;">
</span>
Load
</button>
<input id="${id}-token" type="text"
class="input token"
placeholder=" Token...">
<input id="${id}-urn" type="text"
class="input urn"
placeholder=" Model URN ...">
<hr class="v-spacer">
<div>
<span class="text-span">
Scale:
</span>
<hr class="v-spacer">
<input id="${id}-Sx" type="text"
class="input numeric"
placeholder=" x (1.0)">
<input id="${id}-Sy" type="text"
class="input numeric"
placeholder=" y (1.0)">
<input id="${id}-Sz" type="text"
class="input numeric"
placeholder=" z (1.0)">
<hr class="v-spacer">
<span class="text-span">
Translation:
</span>
<hr class="v-spacer">
<input id="${id}-Tx" type="text"
class="input numeric"
placeholder=" x (0.0)">
<input id="${id}-Ty" type="text"
class="input numeric"
placeholder=" y (0.0)">
<input id="${id}-Tz" type="text"
class="input numeric"
placeholder=" z (0.0)">
</div>
<hr class="v-spacer">
<div>
<span class="text-span">
Rotation (deg):
</span>
<hr class="v-spacer">
<input id="${id}-Rx" type="text"
class="input numeric"
placeholder=" x (0.0)">
<input id="${id}-Ry" type="text"
class="input numeric"
placeholder=" y (0.0)">
<input id="${id}-Rz" type="text"
class="input numeric"
placeholder=" z (0.0)">
<hr class="v-spacer-large">
<button class="btn btn-info btn-transform"
id="${id}-transform-btn"
data-placement="bottom"
data-toggle="tooltip"
title="Transform selected loaded models">
<span class="glyphicon glyphicon-random btn-span"
aria-hidden="true">
</span>
Transform Selection ...
</button>
<button class="btn btn-info btn-clear"
id="${id}-clear-btn"
data-placement="bottom"
data-toggle="tooltip"
title="Clear transform fields">
<span class="glyphicon glyphicon-remove btn-span"
aria-hidden="true">
</span>
Clear
</button>
</div>
<hr class="v-spacer-large">
<input id="${id}-search" type="text"
class="input search"
placeholder=" Search Gallery Models...">
<button class="btn btn-info btn-load-gallery"
id="${id}-load-gallery-btn"
data-placement="bottom"
data-toggle="tooltip"
title="Load filtered gallery models">
<span class="glyphicon glyphicon-import btn-span"
aria-hidden="true">
</span>
Load
</button>
<hr class="v-spacer-large">
<div class="all-trees-container">
<div class="tree-container gallery">
</div>
<hr class="tree-spacer">
<div class="tree-container loaded">
</div>
</div>
</div>`;
}
/////////////////////////////////////////////////////////////////
// Aggregate SelectionChanged handler
//
/////////////////////////////////////////////////////////////////
async function onAggregateSelectionChanged(event) {
if(event.selections && event.selections.length){
var selection = event.selections[0];
var model = selection.model;
await API.setCurrentModel(model);
var nodeId = selection.dbIdArray[0];
setPropertyPanelNode(nodeId);
}
//no components selected -> display properties of root
else {
viewer.model.getObjectTree((instanceTree) =>{
setPropertyPanelNode(instanceTree.rootId);
});
}
}
function setPropertyPanelNode(nodeId) {
viewer.getProperties(nodeId, (result)=>{
if(result.properties) {
var propertyPanel = viewer.getPropertyPanel(true);
propertyPanel.setNodeProperties(nodeId);
propertyPanel.setProperties(result.properties);
}
});
}
/////////////////////////////////////////////////////////////////
// Load button handler
//
/////////////////////////////////////////////////////////////////
async function onLoad(event) {
event.preventDefault();
var urn = $(`#${panelId}-urn`).val();
var token = $(`#${panelId}-token`).val();
if(!urn.length) {
alert('Invalid model URN...');
return;
}
token = (token.length ? token : await API.getToken());
var model = await loadFromURN(token, urn);
model.name = API.getModelName(urn);
reloadTree();
}
/////////////////////////////////////////////////////////////////
// Loads model from URN
//
/////////////////////////////////////////////////////////////////
async function loadFromURN(token, urn) {
var loadOptions = {
placementTransform: buildTransformMatrix()
}
var pathCollection = await API.getViewablePath(
token, urn);
var model = await API.loadModel(
pathCollection[0],
loadOptions);
return model;
}
/////////////////////////////////////////////////////////////////
// Transform button handler
//
/////////////////////////////////////////////////////////////////
function onTransform(event) {
var root = _loadedModelsTree.nodes()[0];
var selectedNodes = [];
root.children.recurseDown((node)=> {
if (node.selected() && node.type == 'model_node') {
selectedNodes.push(node);
}
});
var transform = {
translation: getTranslation(),
rotation: getRotation(),
scale: getScale()
};
selectedNodes.forEach(async(node)=>{
await API.transformModel(
node.model,
transform);
viewer.impl.sceneUpdated(true);
});
}
/////////////////////////////////////////////////////////////////
// Clear Transform button handler
//
/////////////////////////////////////////////////////////////////
function onClear(event) {
$(`#${panelId}-Sx`).val('');
$(`#${panelId}-Sy`).val('');
$(`#${panelId}-Sz`).val('');
$(`#${panelId}-Tx`).val('');
$(`#${panelId}-Ty`).val('');
$(`#${panelId}-Tz`).val('');
$(`#${panelId}-Rx`).val('');
$(`#${panelId}-Ry`).val('');
$(`#${panelId}-Rz`).val('');
}
/////////////////////////////////////////////////////////////////
// Load from gallery button handler
//
/////////////////////////////////////////////////////////////////
async function onLoadGallery(event) {
event.preventDefault();
var promises = [];
_galleryFilteredNodes.forEach((node)=>{
promises.push(loadGalleryNode(node))
});
Promise.all(promises).then(()=> {
reloadTree();
});
}
/////////////////////////////////////////////////////////////////
// Loads a gallery node model
//
/////////////////////////////////////////////////////////////////
async function loadGalleryNode(node) {
// load model from local resource if available
if(node.model.viewablePath &&
node.model.viewablePath.length) {
var loadOptions = {
placementTransform: buildTransformMatrix()
}
var model = await API.loadModel(
node.model.viewablePath[0].path,
loadOptions);
model.name = node.model.name;
}
// load from View & Data server
else {
var token = await API.getToken();
var model = await loadFromURN(
token,
node.model.urn);
model.name = node.model.name;
}
}
/////////////////////////////////////////////////////////////////
// Reloads model tree
//
/////////////////////////////////////////////////////////////////
async function reloadTree() {
$('.model-loader-tree').remove();
$('.model-loader .tree-container.loaded').append(
'<div class="model-loader-tree"></div>'
);
var rootNode = {
type: 'root_node',
text: 'Loaded Models',
children: []
};
var models = await API.getLoadedModels();
models.forEach((model)=>{
rootNode.children.push({
type: 'model_node',
text: `${model.name} [Id: ${model.id}]`,
model: model,
children: []
});
});
var tree = new InspireTree({
target: '.model-loader-tree',
data: [rootNode],
contextMenu: [{
text: 'Set as Current',
handler: (event, node, closer)=> {
closer();
API.setCurrentModel(node.model);
}
},{
text: 'Unload Model',
handler: async(event, node, closer)=> {
closer();
await API.unloadModel(node.model);
reloadTree();
}
}]
});
tree.on('node.dblclick', async(event, node)=> {
if(node.type == 'model_node'){
await API.setCurrentModel(node.model);
await API.fitModelToView(node.model);
}
});
//expand root
tree.nodes()[0].expand();
_loadedModelsTree = tree;
}
/////////////////////////////////////////////////////////////
// Gets input transform
//
/////////////////////////////////////////////////////////////
function getScale() {
var x = parseFloat($(`#${panelId}-Sx`).val());
var y = parseFloat($(`#${panelId}-Sy`).val());
var z = parseFloat($(`#${panelId}-Sz`).val());
x = isNaN(x) ? 1.0 : x;
y = isNaN(y) ? 1.0 : y;
z = isNaN(z) ? 1.0 : z;
return new THREE.Vector3(x, y, z);
}
function getTranslation() {
var x = parseFloat($(`#${panelId}-Tx`).val());
var y = parseFloat($(`#${panelId}-Ty`).val());
var z = parseFloat($(`#${panelId}-Tz`).val());
x = isNaN(x) ? 0.0 : x;
y = isNaN(y) ? 0.0 : y;
z = isNaN(z) ? 0.0 : z;
return new THREE.Vector3(x, y, z);
}
function getRotation() {
var x = parseFloat($(`#${panelId}-Rx`).val());
var y = parseFloat($(`#${panelId}-Ry`).val());
var z = parseFloat($(`#${panelId}-Rz`).val());
x = isNaN(x) ? 0.0 : x;
y = isNaN(y) ? 0.0 : y;
z = isNaN(z) ? 0.0 : z;
var euler = new THREE.Euler(
x * Math.PI/180,
y * Math.PI/180,
z * Math.PI/180,
'XYZ');
var q = new THREE.Quaternion();
q.setFromEuler(euler);
return q;
}
/////////////////////////////////////////////////////////////
// Builds transform matrix
//
/////////////////////////////////////////////////////////////
function buildTransformMatrix() {
var t = getTranslation();
var r = getRotation();
var s = getScale();
var m = new THREE.Matrix4();
m.compose(t, r, s);
return m;
}
/////////////////////////////////////////////////////////////
// setVisible override
//
/////////////////////////////////////////////////////////////
_thisPanel.setVisible = function(show) {
_isVisible = show;
btnElement.classList.toggle('active');
Autodesk.Viewing.UI.DockingPanel.prototype.
setVisible.call(this, show);
}
/////////////////////////////////////////////////////////////
// Toggles panel visibility
//
/////////////////////////////////////////////////////////////
_thisPanel.toggleVisibility = function() {
_panel.setVisible(!_isVisible);
}
/////////////////////////////////////////////////////////////
// initialize override
//
/////////////////////////////////////////////////////////////
_thisPanel.initialize = function() {
this.title = this.createTitleBar(
this.titleLabel ||
this.container.id);
this.closer = this.createCloseButton();
this.container.appendChild(this.title);
this.title.appendChild(this.closer);
this.container.appendChild(this.content);
this.initializeMoveHandlers(this.title);
this.initializeCloseHandler(this.closer);
}
/////////////////////////////////////////////////////////////
// onTitleDoubleClick override
//
/////////////////////////////////////////////////////////////
_thisPanel.onTitleDoubleClick = function (event) {
_isMinimized = !_isMinimized;
if(_isMinimized) {
$(_thisPanel.container).addClass(
'minimized');
}
else {
$(_thisPanel.container).removeClass(
'minimized');
}
}
// Initializes the panel
initialize();
}
/////////////////////////////////////////////////////////////
// Set up JS inheritance
//
/////////////////////////////////////////////////////////////
ModelLoaderPanel.prototype = Object.create(
Autodesk.Viewing.UI.DockingPanel.prototype);
ModelLoaderPanel.prototype.constructor = ModelLoaderPanel;
};
Autodesk.ADN.Viewing.Extension.ModelLoader.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.ModelLoader.prototype.constructor =
Autodesk.ADN.Viewing.Extension.ModelLoader;
Autodesk.Viewing.theExtensionManager.registerExtension(
'Autodesk.ADN.Viewing.Extension.ModelLoader',
Autodesk.ADN.Viewing.Extension.ModelLoader);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment