Autodesk Forge:模型比较(BIM 360 功能)
Posted
技术标签:
【中文标题】Autodesk Forge:模型比较(BIM 360 功能)【英文标题】:Autodesk Forge: Model Compare (BIM 360 Feature) 【发布时间】:2017-09-05 16:14:49 【问题描述】:Bim 360 有一个很棒的工具,称为“比较版本”,它允许查看两个 Revit 模型之间的更改。可以在此处找到有关该功能的更多信息:
Compare versions info
Autodesk Forge 中是否有此功能?我找不到它,我确实看到 forge 有一个 BIM 360 API,但我没有看到这个功能可用。
【问题讨论】:
【参考方案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
【讨论】:
以上是关于Autodesk Forge:模型比较(BIM 360 功能)的主要内容,如果未能解决你的问题,请参考以下文章
Autodesk Forge:如何在 BIM 360 Docs 中查找模型的 svf 文件的 URL
广联达的BIMFACE有啥具体的功能?和Autodesk的forge对比如何?