昨天和一位Revit二次开发人员讨论了关于如何访问链接文件(Linked File)的问题。因为之前没有涉及过,所以写了简单的测试代码验证,现分享如下:
1. Revit 2012 中提供 TransmissionData 类访问链接文件的路径和状态
通过 TransmissionData 可以很方便地访问(读/写)当前文档中链接文档的路径和加载状态属性;
但是我没有找到通过 TransmissionData 类访问链接文件内部元素的方法。希望能有朋友能指点,先谢了!
2. Autodesk.Revit.ApplicationServices.Application.Documents 属性返回当前 Revit 打开的所有文档对象
包括手工打开的和加载的链接文档;
判断是否是链接文档的方式是通过判断其 ActiveView 是否为 NULL。这个条件也可以用来判断如下特殊情况:
当前有一个打开的文档和一个链接的文档虽然处在不同的目录下,但是有相同的文件名。
-- 当前打开了文档 [目录#1]\1.rvt
---- [目录#1]\1.rvt 链接了文档 [目录#1]\1-1.rvt
-- 当前打开了文档 [目录#2]\1-1.rvt
另外在 Revit 2012 中测试还发现:同一份文档无法同时打开和链接。
有了 ActiveView 的判断和 上面这个 Revit 约束,我们在访问链接文档及其元素的时候就可以避免二义性了。
有了链接文档的 Document 对象,就可以访问其包含的元素等文档内部数据了。
3. 通过 FilteredELementCollector 获取当前文档中所有链接文档及其包含元素
一个包含链接文档的文档,可以通过元素过滤器来获取所有的链接文档其对应链接文档包含的元素在当前文档中的实例。
代码如下:
private void ListLinkedElements(Application app) { foreach (Document doc in app.Documents) { if (doc.ActiveView != null) // ActiveView 为 null 说明是链接文档 { // 获取所有链接文档 FilteredElementCollector collector = new FilteredElementCollector(doc); IList<Element> rvtLinkedDocuments = collector.OfCategory(BuiltInCategory.OST_RvtLinks).OfClass(typeof(RevitLinkType)).ToElements(); Debug.Print(string.Format("there're {0} Revit Linked Documents in document {1}", rvtLinkedDocuments.Count, doc)); // 获取所有链接元素 collector = new FilteredElementCollector(doc); IList<Element> rvtLinkedInstances = collector.OfCategory(BuiltInCategory.OST_RvtLinks).OfClass(typeof(Instance)).ToElements(); Debug.Print(string.Format("there're {0} Revit Linked Documents in document {1}", rvtLinkedInstances.Count, doc)); } else // ActiveView 有效说明是打开文档(注意可能不止一个打开文档) { FilteredElementCollector collector = new FilteredElementCollector(doc); IList<Element> rooms = collector.OfCategory(BuiltInCategory.OST_Rooms).ToElements(); Debug.Print(string.Format("there're {0} rooms in document {1}", rooms.Count, doc)); } } }其中获取到的链接实例元素的名称是有格式的:[链接文件名] : [自然数编号] (Not Shared)
比方说链接文件1.rvt 中的一个房间,在被链接文档中的元素名称为:1.rvt : 1 (Not Shared)。所以想判断链接实例属于哪个链接文档时,可以通过从元素名称中提取链接文档名称来实现。