Revit API。从主要模型元素所在的链接模型中获取一个房间
Revit API. Get a room from the linked model in which the main model element is located
我有一个非常简单但同时具有挑战性的 Revit 问题 Api。
有一个主要的 Revit-MEP 模型和一个链接的建筑模型。我想知道我的 MEP 元素属于哪个房间。为此,我尝试了两种方法:
- 对link模型使用
ElementIntersectsFilter
(Jeremy博客上有一篇文章)——当link旋转或移位时它不起作用。
- 导入实体几何体并转换实体,然后使用
ElementIntersectsSolidFilter
– 它有效,但要花费大量时间。例如,我的主模型有大约 35000 个元素和 Linked 1100 个房间。 95% 的时间用于传球 ElementIntersectsSolidFilter
。对于一个房间平均 30 秒,这意味着系统挂起 9 小时!
过滤 MainModel 中的所有目标元素(~35000 个元素)
ICollection<ElementId> fec = new FilteredElementCollector(doc)
.WhereElementIsNotElementType()
.WherePasses(new ElementMulticategoryFilter(bic))
.ToElementIds()
.ToList();
从 link 获取所有房间并检索实体(~1100 元素)
IEnumerable<Room> rooms = new FilteredElementCollector(link.GetLinkDocument())
.WhereElementIsNotElementType()
.OfCategory(BuiltInCategory.OST_Rooms)
.Cast<Room>();
RoomInfo 包含有关 Room
的可靠信息和其他附加信息
rlf – 完成所有检索工作
IEnumerable<RoomInfo> ifs = rlf.GetItemInfos(rooms).Cast<RoomInfo>();
一种获取实体和对目标元素集合的引用的方法。
Return 所有元素都与实体相交并将它们从目标集合 (~35000) 中移除,因此集合在每次迭代中都在下降。
Public ICollection<ElementId> GetIntersectedElements(Solid solid, ref ICollection<ElementId> eIds)
{
if (!eIds.Any())
{
log.Info($"Input collection is empty. Task done.");
return new List<ElementId>();
}
var solidFilter = new ElementIntersectsSolidFilter(solid);
var fec = new FilteredElementCollector(doc, eIds)
// This filter eat time
.WherePasses(solidFilter)
.ToElementIds();
if (fec.Any())
{
eIds = new FilteredElementCollector(doc, eIds)
.Excluding(fec)
.ToElementIds();
}
return fec;
}
对于如何在合理的时间内完成此操作的任何想法,我将不胜感激
你可以更简单有效地解决这个问题。您需要弄清楚模型主 MEP 模型和链接的建筑模型之间的转换。接下来确定您的家庭实例或 MEP 元素或其他任何东西的位置 P。将 P 从 MEP 模型转换为链接的建筑模型。在建筑模型中,找出哪个房间或 space 包含转换点。
Revit API 论坛中最近的一个话题处理了一个不同的主题,但说明了几乎所有需要的原则:How to calculate the column finish area of room。
我有一个非常简单但同时具有挑战性的 Revit 问题 Api。 有一个主要的 Revit-MEP 模型和一个链接的建筑模型。我想知道我的 MEP 元素属于哪个房间。为此,我尝试了两种方法:
- 对link模型使用
ElementIntersectsFilter
(Jeremy博客上有一篇文章)——当link旋转或移位时它不起作用。 - 导入实体几何体并转换实体,然后使用
ElementIntersectsSolidFilter
– 它有效,但要花费大量时间。例如,我的主模型有大约 35000 个元素和 Linked 1100 个房间。 95% 的时间用于传球ElementIntersectsSolidFilter
。对于一个房间平均 30 秒,这意味着系统挂起 9 小时!
过滤 MainModel 中的所有目标元素(~35000 个元素)
ICollection<ElementId> fec = new FilteredElementCollector(doc)
.WhereElementIsNotElementType()
.WherePasses(new ElementMulticategoryFilter(bic))
.ToElementIds()
.ToList();
从 link 获取所有房间并检索实体(~1100 元素)
IEnumerable<Room> rooms = new FilteredElementCollector(link.GetLinkDocument())
.WhereElementIsNotElementType()
.OfCategory(BuiltInCategory.OST_Rooms)
.Cast<Room>();
RoomInfo 包含有关 Room
的可靠信息和其他附加信息rlf – 完成所有检索工作
IEnumerable<RoomInfo> ifs = rlf.GetItemInfos(rooms).Cast<RoomInfo>();
一种获取实体和对目标元素集合的引用的方法。 Return 所有元素都与实体相交并将它们从目标集合 (~35000) 中移除,因此集合在每次迭代中都在下降。
Public ICollection<ElementId> GetIntersectedElements(Solid solid, ref ICollection<ElementId> eIds)
{
if (!eIds.Any())
{
log.Info($"Input collection is empty. Task done.");
return new List<ElementId>();
}
var solidFilter = new ElementIntersectsSolidFilter(solid);
var fec = new FilteredElementCollector(doc, eIds)
// This filter eat time
.WherePasses(solidFilter)
.ToElementIds();
if (fec.Any())
{
eIds = new FilteredElementCollector(doc, eIds)
.Excluding(fec)
.ToElementIds();
}
return fec;
}
对于如何在合理的时间内完成此操作的任何想法,我将不胜感激
你可以更简单有效地解决这个问题。您需要弄清楚模型主 MEP 模型和链接的建筑模型之间的转换。接下来确定您的家庭实例或 MEP 元素或其他任何东西的位置 P。将 P 从 MEP 模型转换为链接的建筑模型。在建筑模型中,找出哪个房间或 space 包含转换点。
Revit API 论坛中最近的一个话题处理了一个不同的主题,但说明了几乎所有需要的原则:How to calculate the column finish area of room。