2

实作简易的模型版本比较的截图

熟悉 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);

英文原文:https://forge.autodesk.com/bl...


康益昇
748 声望103 粉丝