熟悉 BIM360 Team 的朋友可能知道他有一个很牛的模型文档版本比较的功能,但如果模型是放在 Google 云盘或是百度云盘上有可能做到吗?
Autodesk Forge 团队先前写了一个从 Google 云盘的转档示例,这个示例会从 Google 云盘里下载模型文档到你的服务器上,在将它上传到 Forge Data Management 服务上进行转档,同时在转档完成后在浏览器上展示结果。
现在让我们修改这个示例让他可以展示两个同项目但不同版号的 Revit 模型(model A 及 model B)。在 Forge Viewer 里,每个 Revit 构件都会对应到一个 dbId,而这个 dbId 也会对应到一个 Reivt 唯一码(Unique GUID),这个唯一码也是 Forge Viewer 的外部编码(Extenal Id),所以只要在 model A 及 model B 里比对两者间有没有不存在的 Extenal Id,以及比对同一个 External Id 的构件属性里有没有被新增、修改及删除的参数,根据这个思路我们可以将没有修改的构件隐藏起来,有异动的构件以绿色(新增的)、红色(删除的)及橘色(有修改的)来上色,就可以在 Forge Viewer 上做出简单的模型比较功能,原代码可以参考这里,示例可造访这里。
示例执行结果如下:
这边是这个比较模型的括展代码:
function VersionChanges(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
VersionChanges.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
VersionChanges.prototype.constructor = VersionChanges;
VersionChanges.prototype.load = function () {
var modelA = this.options.modelA;
var modelB = this.options.modelB;
var removed = {};
var added = {};
var modified = {};
var red = new THREE.Vector4(1, 0, 0, 1);
var green = new THREE.Vector4(0, 0.5, 0, 1);
var orange = new THREE.Vector4(1, 0.6, 0.2, 1);
viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, function () {
listElements(function (listA, listB) {
// make all elements as ghost
viewer.isolate(-1);
viewer.clearThemingColors(modelA);
viewer.clearThemingColors(modelB);
for (var extIdA in listA) {
if (listB[extIdA] != null) continue;
var dbIdA = listA[extIdA].dbId;
removed[extIdA] = dbIdA;
console.log('Removed dbId: ' + dbIdA);
viewer.impl.visibilityManager.show(dbIdA, modelA);
viewer.setThemingColor(dbIdA, red, modelA);
}
for (var extIdB in listB) {
if (listA[extIdB] != null) continue;
var dbIdB = listB[extIdB].dbId
added[extIdB] = dbIdB;
console.log('Added dbId: ' + dbIdB);
viewer.impl.visibilityManager.show(dbIdB, modelB);
viewer.setThemingColor(dbIdB, green, modelB);
}
for (var extId in listA) {
if (typeof listB[extId] === 'undefined') continue; // removed dbId
var dbId = listA[extId].dbId; // should be the same as listB[extId]
var propsA = listA[extId].properties;
var propsB = listB[extId].properties;
for (var i = 0; i < propsA.length; i++) {
if (propsB[i] == null) continue;
if (propsA[i].displayCategory.indexOf('__')==0) continue; // internal properties
if (propsA[i].displayValue != propsB[i].displayValue) {
console.log('Property ' + dbId + ': ' + propsA[i].displayName + ' changed from '
+ propsA[i].displayValue + ' to ' + propsB[i].displayValue);
modified[extId] = dbId;
}
}
if (typeof modified[extId] != 'undefined') {
console.log('Modified dbId: ' + dbId);
// color on both models
//viewer.impl.visibilityManager.show(dbId, modelA);
//viewer.impl.visibilityManager.show(dbId, modelB);
viewer.setThemingColor(dbId, orange, modelA);
viewer.setThemingColor(dbId, orange, modelB);
}
}
});
});
function listElements(callback) {
getAllLeafComponents(modelA, function (modelAdbIds) {
getAllLeafComponents(modelB, function (modelBdbIds) {
// this count will help wait until getProperties end all callbacks
var count = modelAdbIds.length + modelBdbIds.length;
var modelAExtIds = {};
modelAdbIds.forEach(function (modelAdbId) {
modelA.getProperties(modelAdbId, function (modelAProperty) {
modelAExtIds[modelAProperty.externalId] = {'dbId': modelAdbId, 'properties': modelAProperty.properties};
count--;
if (count == 0) callback(modelAExtIds, modelBExtIds);
});
});
var modelBExtIds = {};
modelBdbIds.forEach(function (modelBdbId) {
modelB.getProperties(modelBdbId, function (modelBProperty) {
modelBExtIds[modelBProperty.externalId] = {'dbId': modelBdbId, 'properties': modelBProperty.properties};
count--;
if (count == 0) callback(modelAExtIds, modelBExtIds);
});
});
});
});
}
function getAllLeafComponents(model, callback) {
var components = [];
function getLeafComponentsRec(tree, parentId) {
if (tree.getChildCount(parentId) > 0) {
tree.enumNodeChildren(parentId, function (childId) {
getLeafComponentsRec(tree, childId);
});
}
else
components.push(parentId);
return components;
}
var instanceTree = model.getInstanceTree();
var allLeafComponents = getLeafComponentsRec(instanceTree, instanceTree.nodeAccess.rootId);
callback(allLeafComponents);
}
return true;
};
VersionChanges.prototype.unload = function () {
return true;
};
Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.Forge.Samples.VersionChanges', VersionChanges);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。