【问题标题】:Autodesk Forge: Model Compare (BIM 360 Feature)Autodesk Forge:模型比较(BIM 360 功能)
【发布时间】:2017-09-05 16:14:49
【问题描述】:

Bim 360 有一个很棒的工具,称为“比较版本”,它允许查看两个 Revit 模型之间的更改。可以在此处找到有关该功能的更多信息:

Compare versions info

Autodesk Forge 中是否有此功能?我找不到它,我确实看到 forge 有一个 BIM 360 API,但我没有看到这个功能可用。

【问题讨论】:

    标签: autodesk-forge autodesk-viewer autodesk-model-derivative autodesk-data-management autodesk-bim360


    【解决方案1】:

    不,至少现在是这样。会很好,不是吗?也许在未来......

    【讨论】:

      【解决方案2】:

      您可以使用ForgeAuthor sdk 执行此操作。

      ForgeAuthor 是一个基于 .net 框架 4.5 的 .net 库,它提供了一种很好的面向对象的方式来操作 Audesk Forge Svf 模型,就像操作 XML 或 JSON 一样简单。

      ForgeAuthor 可以读取 Autodesk Forge SVF 模型,比较差异,并生成差异模型。

      #region setup materials
      
                      var matUnmodified = new Material
                      {
                          Color = Vector3D.FromColor(0xffffff), //Darker: Vector3D.FromColor(0x101010)
                          Transparent = 0.95,
                          Reflectivity = 0
                      };
      
                      var matAdd = new Material
                      {
                          Color = Vector3D.FromColor(Color.GreenYellow)
                      };
      
                      var matDelete = new Material
                      {
                          Color = Vector3D.FromColor(Color.Red)
                      };
      
                      var matModifiedBefore = new Material
                      {
                          Color = Vector3D.FromColor(Color.Orange),
                          Transparent = 0.5
                      };
      
                      var matModifiedAfter = new Material
                      {
                          Color = Vector3D.FromColor(Color.Aqua),
                      };
      
                      #endregion
      
                      var baseModelPath = txtBaseModel.Text;
                      var incrModelPath = txtIncrementModel.Text;
                      var diffModelPath = txtDiffModel.Text;
      
                      var svfbase = baseModelPath.EndsWith(@"zip")
                          ? SvfDocument.LoadFromZipFile(baseModelPath)
                          : SvfDocument.LoadFromSvfFile(baseModelPath);
      
                      var svfincr = incrModelPath.EndsWith(@"zip")
                          ? SvfDocument.LoadFromZipFile(incrModelPath)
                          : SvfDocument.LoadFromSvfFile(incrModelPath);
      
                      var compareResult = CompareModel(svfbase, svfincr);
      
                      var svfdiff = new SvfDocument();
                      svfdiff.Model.Name = @"Diff Model";
                      svfdiff.Metadata = svfbase.Metadata;
      
                      var nodeUnmodified = svfdiff.Model.Children.CreateNode();
                      nodeUnmodified.Name = @"Unmodified";
      
                      var nodeAdded = svfdiff.Model.Children.CreateNode();
                      nodeAdded.Name = @"Added";
      
                      var nodeDeleted = svfdiff.Model.Children.CreateNode();
                      nodeDeleted.Name = @"Deleted";
      
                      var nodeModifiedBefore = svfdiff.Model.Children.CreateNode();
                      nodeModifiedBefore.Name = @"Modified Before";
      
                      var nodeModifiedAfter = svfdiff.Model.Children.CreateNode();
                      nodeModifiedAfter.Name = @"Modified After";
      
                      svfbase.EnumerateNodes(node =>
                      {
                          if (node.Children?.Count == 0 &&
                              node.Fragments?.Count > 0 &&
                              string.IsNullOrEmpty(node.ExternalId) == false)
                          {
                              if (compareResult.Unmodified.Remove(node.ExternalId))
                              {
                                  ImportNodeWithPath(nodeUnmodified, node, svfbase.Model, matUnmodified);
                              }
                              else if (compareResult.Deleted.Remove(node.ExternalId))
                              {
                                  ImportNodeWithPath(nodeDeleted, node, svfbase.Model, matDelete);
                              }
                              else if (compareResult.Modified.Contains(node.ExternalId))
                              {
                                  var targetNode =
                                      ImportNodeWithPath(nodeModifiedBefore, node, svfbase.Model, matModifiedBefore);
                                  targetNode.ExternalId += @"_Before";
                              }
                          }
                      }, svfbase.Model);
      
                      svfincr.EnumerateNodes(node =>
                      {
                          if (node.Children?.Count == 0 &&
                              node.Fragments?.Count > 0 &&
                              string.IsNullOrEmpty(node.ExternalId) == false)
                          {
                              if (compareResult.Added.Remove(node.ExternalId))
                              {
                                  ImportNodeWithPath(nodeAdded, node, svfincr.Model, matAdd);
                              }
                              else if (compareResult.Modified.Remove(node.ExternalId))
                              {
                                  ImportNodeWithPath(nodeModifiedAfter, node, svfincr.Model, matModifiedAfter);
                              }
                          }
                      }, svfincr.Model);
      
                      svfdiff.SaveToFolder(diffModelPath, true);
                      svfdiff.Dispose();
      
                      svfbase.Dispose();
                      svfincr.Dispose();
      
      
      
      private (HashSet<string> Unmodified, HashSet<string> Added, HashSet<string> Deleted, HashSet<string> Modified)
              CompareModel(SvfDocument svfbase, SvfDocument svfincr)
          {
              var baseNodes = new Dictionary<string, SvfNode>();
              svfbase.EnumerateNodes(node =>
              {
                  if (node.Children?.Count == 0
                      && node.Fragments?.Count > 0
                      && string.IsNullOrEmpty(node.ExternalId) == false)
                  {
                      baseNodes[node.ExternalId] = node;
                  }
              }, svfbase.Model);
      
              var elementsAdded = new HashSet<string>();
              var elementsUnmodified = new HashSet<string>();
              var elementsModified = new HashSet<string>();
              var elementsDeleted = new HashSet<string>();
      
              svfincr.EnumerateNodes(node =>
              {
                  if (node.Children?.Count == 0
                      && node.Fragments?.Count > 0
                      && string.IsNullOrEmpty(node.ExternalId) == false)
                  {
                      if (baseNodes.TryGetValue(node.ExternalId, out SvfNode baseNode))
                      {
                          if (baseNode.Fragments.Equals(node.Fragments))
                          {
                              elementsUnmodified.Add(node.ExternalId); //unmdified
                          }
                          else
                          {
                              elementsModified.Add(node.ExternalId); //modified
                          }
      
                          baseNodes.Remove(node.ExternalId);
                      }
                      else
                      {
                          elementsAdded.Add(node.ExternalId); //added
                      }
                  }
              }, svfincr.Model);
      
              foreach (var p in baseNodes.Keys)
              {
                  elementsDeleted.Add(p); //deleted
              }
              baseNodes.Clear();
      
              return (elementsUnmodified, elementsAdded, elementsDeleted, elementsModified);
          }
      
          private SvfNode ImportNodeWithPath(SvfNode targetNodeRoot, SvfNode sourceNode, SvfNode sourceNodeRoot, Material material)
          {
              var targetNode = sourceNode.Parent == sourceNodeRoot
                  ? targetNodeRoot
                  : ImportNodeWithPath(targetNodeRoot, sourceNode.Parent, sourceNodeRoot, material);
              var resultNode = targetNode.Children.FirstOrDefault(x => x.Name == sourceNode.Name);
              if (resultNode == null)
              {
                  resultNode = targetNode.Children.ImportNode(sourceNode, null, false);
                  foreach (var fragment in resultNode.Fragments)
                  {
                      fragment.Material = material;
                  }
              }
              return resultNode;
          }
      

      snapshot

      【讨论】:

        猜你喜欢
        • 2021-12-09
        • 2018-05-29
        • 2020-06-24
        • 2020-05-06
        • 2021-02-17
        • 2021-01-27
        • 2019-12-18
        • 2020-10-05
        • 2021-11-27
        相关资源
        最近更新 更多