如何加载 Forge Viewer 的扩展(无需 viewerApp)
2019-07-10
1288
我正在尝试为一个 Web 应用程序开发 Forge Autodesk 查看器, 本教程 。我在尝试加载 扩展 时遇到问题,实际上它们从未加载到查看器上。
我已经开发了本教程的查看器,扩展工作正常。
我的查看器和本教程的查看器之间的主要区别在于,本教程中使用了
viewerApp
,而我必须直接使用
GUIViewer3D
(用于聚合多个模型)。
我已经尝试以不同的顺序加载查看器和扩展,但也没有改变工作方式。我认为扩展的代码是正确的,因为它在教程中有效,但我不确定如何将它链接到我的查看器。
加载查看器的代码:
Autodesk.Viewing.Initializer(options, function onInitialized() {
// Initialisation du Viewer
var viewerDiv = document.getElementById('MyViewerDiv');
var config = {
extensions: ['DockingPanelExtension']
};
viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv, config);
viewer.initialize();
});
索引的代码
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<!-- The Viewer CSS -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/style.min.css"
type="text/css">
<!-- Developer CSS -->
<link rel="stylesheet" href="/static/style.css" type="text/css">
<!-- Common packages: jQuery, Bootstrap, jsTree -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/jstree.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/themes/default/style.min.css" />
</head>
<body>
<!-- Fixed navbar by Bootstrap: https://getbootstrap.com/examples/navbar-fixed-top/ -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<ul class="nav navbar-nav left">
<li>
<a href="http://developer.autodesk.com" target="_blank">
<img alt="IM-Pact" src="static/img/IMPact.png"
height="20">
</a>
</li>
<li>
<button type="button" class="btn btn-default navbar-btn" onClick="callNew()">Add next model</button>
</li>
</ul>
</div>
</nav>
<!-- End of navbar -->
<div class="container-fluid fill">
<div class="row fill">
<div class="col-sm-4 fill">
<div class="panel panel-default fill">
<div class="panel-heading" data-toggle="tooltip">
Buckets & Objects
<span id="refreshBuckets" class="glyphicon glyphicon-refresh" style="cursor: pointer"></span>
<button class="btn btn-xs btn-info" style="float: right" id="showFormCreateBucket"
data-toggle="modal" data-target="#createBucketModal">
<span class="glyphicon glyphicon-folder-close"></span> New bucket
</button>
</div>
<div id="appBuckets">
tree here
</div>
</div>
</div>
<div class="col-sm-8 fill">
<div id="MyViewerDiv"></div>
</div>
</div>
</div>
<form id="uploadFile" method='post' enctype="multipart/form-data">
<input id="hiddenUploadField" type="file" name="theFile" style="visibility:hidden" />
</form>
<!-- Modal Create Bucket -->
<div class="modal fade" id="createBucketModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cancel">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Create new bucket</h4>
</div>
<div class="modal-body">
<input type="text" id="newBucketKey" class="form-control"> For demonstration purposes, objects
(files) are
NOT automatically translated. After you upload, right click on
the object and select "Translate". Bucket keys must be of the form [-_.a-z0-9]{3,128}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="createNewBucket">Go ahead, create the
bucket</button>
</div>
</div>
</div>
</div>
<!-- <button id="MyNextButton" onClick="callNext()">Next!</button> -->
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.min.js?v=v6.6"></script>
<!-- Developer JS -->
<script src="static/js/docLoad.js"></script>
<script src="static/js/modelLoad.js"></script>
<script src="static/js/extensions/dockingpannelextension.js"></script>
<script src="static/js/viewer.js"></script>
<script src="static/js/tree.js"></script>
</body>
扩展的代码
// *******************************************
// Model Summary Extension
// *******************************************
var propsToList = [];
function addToList(item) {
if (propsToList.includes(item)) {
var index = propsToList.indexOf(item);
propsToList.splice(index, 1);
} else {
propsToList.push(item)
}
console.log(propsToList)
}
function ModelSummaryExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
this.panel = null; // create the panel variable
}
ModelSummaryExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
ModelSummaryExtension.prototype.constructor = ModelSummaryExtension;
ModelSummaryExtension.prototype.load = function () {
if (this.viewer.toolbar) {
// Toolbar is already available, create the UI
this.createUI();
} else {
// Toolbar hasn't been created yet, wait until we get notification of its creation
this.onToolbarCreatedBinded = this.onToolbarCreated.bind(this);
this.viewer.addEventListener(Autodesk.Viewing.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
}
return true;
};
ModelSummaryExtension.prototype.onToolbarCreated = function () {
this.viewer.removeEventListener(Autodesk.Viewing.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
this.onToolbarCreatedBinded = null;
this.createUI();
};
ModelSummaryExtension.prototype.createUI = function () {
var _this = this;
// prepare to execute the button action
var modelSummaryToolbarButton = new Autodesk.Viewing.UI.Button('runModelSummaryCode');
modelSummaryToolbarButton.onClick = function (e) {
// check if the panel is created or not
if (_this.panel == null) {
_this.panel = new ModelSummaryPanel(_this.viewer, _this.viewer.container, 'modelSummaryPanel', 'Model Summary');
}
// show/hide docking panel
_this.panel.setVisible(!_this.panel.isVisible());
// if panel is NOT visible, exit the function
if (!_this.panel.isVisible()) return;
// ok, it's visible, let's get the summary!
// first, the Viewer contains all elements on the model, including
// categories (e.g. families or part definition), so we need to enumerate
// the leaf nodes, meaning actual instances of the model. The following
// getAllLeafComponents function is defined at the bottom
_this.getAllLeafComponents(function (dbIds) {
// now for leaf components, let's get some properties
// and count occurrences of each value.
// get only the properties we need for the leaf dbIds
_this.viewer.model.getBulkProperties(dbIds, propsToList, function (dbIdsProps) {
// iterate through the elements we found
dbIdsProps.forEach(function (item) {
// and iterate through each property
item.properties.forEach(function (itemProp) {
// now use the propsToList to store the count as a subarray
if (propsToList[itemProp.displayName] === undefined)
propsToList[itemProp.displayName] = {};
// now start counting: if first time finding it, set as 1, else +1
if (propsToList[itemProp.displayName][itemProp.displayValue] === undefined)
propsToList[itemProp.displayName][itemProp.displayValue] = 1;
else
propsToList[itemProp.displayName][itemProp.displayValue] += 1;
});
});
// now ready to show!
// the Viewer PropertyPanel has the .addProperty that receives the name, value
// and category, that simple! So just iterate through the list and add them
propsToList.forEach(function (propName) {
if (propsToList[propName] === undefined) return;
Object.keys(propsToList[propName]).forEach(function (propValue) {
_this.panel.addProperty(
/*name*/
propValue,
/*value*/
propsToList[propName][propValue],
/*category*/
propName);
});
});
})
})
};
// modelSummaryToolbarButton CSS class should be defined on your .css file
// you may include icons, below is a sample class:
modelSummaryToolbarButton.addClass('modelSummaryToolbarButton');
modelSummaryToolbarButton.setToolTip('Model Summary');
// SubToolbar
this.subToolbar = (this.viewer.toolbar.getControl("MyAppToolbar") ?
this.viewer.toolbar.getControl("MyAppToolbar") :
new Autodesk.Viewing.UI.ControlGroup('MyAppToolbar'));
this.subToolbar.addControl(modelSummaryToolbarButton);
this.viewer.toolbar.addControl(this.subToolbar);
};
ModelSummaryExtension.prototype.unload = function () {
this.viewer.toolbar.removeControl(this.subToolbar);
return true;
};
ModelSummaryExtension.prototype.getAllLeafComponents = function (callback) {
var cbCount = 0; // count pending callbacks
var components = []; // store the results
var tree; // the instance tree
function getLeafComponentsRec(parent) {
cbCount++;
if (tree.getChildCount(parent) != 0) {
tree.enumNodeChildren(parent, function (children) {
getLeafComponentsRec(children);
}, false);
} else {
components.push(parent);
}
if (--cbCount == 0) callback(components);
}
this.viewer.getObjectTree(function (objectTree) {
tree = objectTree;
var allLeafComponents = getLeafComponentsRec(tree.getRootId());
});
};
// *******************************************
// Model Summary Panel
// *******************************************
function ModelSummaryPanel(viewer, container, id, title, options) {
this.viewer = viewer;
Autodesk.Viewing.UI.PropertyPanel.call(this, container, id, title, options);
}
ModelSummaryPanel.prototype = Object.create(Autodesk.Viewing.UI.PropertyPanel.prototype);
ModelSummaryPanel.prototype.constructor = ModelSummaryPanel;
Autodesk.Viewing.theExtensionManager.registerExtension('ModelSummaryExtension', ModelSummaryExtension);
提前致谢!
1个回答
在扩展 JavaScript 文件中,您正在使用名称
ModelSummaryExtension
注册扩展,但在查看器初始化代码中,您正在使用
extensions: ['DockingPanelExtension']
传递配置对象。这可能是扩展未加载的原因。请尝试使用以下配置初始化
GuiViewer3D
类:
let config = {
extensions: ['ModelSummaryExtension']
};
编辑(扩展命名已修复):
初始化
GuiViewer3D
时,调用其
start()
方法,而不是
initialize()
。它将在内部调用
initialize()
(用于初始化内部结构、事件处理程序等)、
setUp();
(用于根据您的配置对象配置查看器),最后如果向函数传递了 URN 或文件路径参数,它将调用
loadModel()
。
Petr Broz
2019-07-10