Revit 中元素的高级过滤 API
Advanced Filtering of Elements in Revit API
我正在关注此 youtube 视频 (https://www.youtube.com/watch?v=WU_D2qNnuGg&index=7&list=PLc_1PNcpnV5742XyF8z7xyL9OF8XJNYnv) 中显示的示例,该示例说明了 Revit API 中过滤方法优于常规迭代的优势。但是我的代码比迭代方法慢得多:
过滤方法 - 0.16 秒
迭代法 - 0.06 秒
我使用过滤方法的代码是:
import Autodesk.Revit.DB as DB
doc=__revit__.ActiveUIDocument.Document
uidoc=__revit__.ActiveUIDocument
height_param_id=DB.ElementId(DB.BuiltInParameter.WALL_USER_HEIGHT_PARAM)
height_param_prov=DB.ParameterValueProvider(height_param_id)
param_equality=DB.FilterNumericEquals() # equality class
height_value_rule=DB.FilterDoubleRule(height_param_prov,param_equality,10,1e-02)
param_filter=DB.ElementParameterFilter(height_value_rule)
# This program significantly slows down for the next line
walls=DB.FilteredElementCollector(doc)\
.WherePasses(param_filter)\
.ToElementIds()
uidoc.Selection.SetElementIds(walls)
迭代使用了以下代码。
from System.Collections.Generic import List
import Autodesk.Revit.DB as DB
doc=__revit__.ActiveUIDocument.Document
uidoc=__revit__.ActiveUIDocument
sheet_collector=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory\
.OST_Sheets)\
.WhereElementIsNotElementType()\
.ToElements()
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElements()
tallwallsids=[]
for wall in walls:
heightp=wall.LookupParameter('Unconnected Height')
if heightp and heightp.AsDouble()==10:
tallwallsids.append(wall.Id)
uidoc.Selection.SetElementIds(List[DB.ElementId](tallwallsids))
什么迭代方法?
如今,过滤元素收集器通常是检索和迭代 Revit 数据库元素的唯一方法。
过滤元素收集器本身可能很快。
如果你有大量的墙并且你的内存有限,调用ToElementIds
可能会消耗大量资源。
SetElementIds
也可能会费时间。
查看 filtered element collector by pipe system types 上广泛的 Revit API 论坛讨论,了解更多相关信息。
我建议您提供一个 complete minimal reproducible sample case 为每个方法调用配备基准测试代码,以证明性能下降。
如果考虑到这两种方法必须考虑的元素数量,这是有道理的。第一种方法:
walls=DB.FilteredElementCollector(doc)\
.WherePasses(param_filter)\
.ToElementIds()
在此方法中,您要求过滤器考虑模型中的所有元素。这可能有很多元素要通过过滤器。这反对:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElements()
在此方法中,您使用 QUICK 过滤器 OfCategory()
和另一个 WhereElementIsNotElementType()
将选择范围缩小到仅 Wall
个实例。即使您使用一个简单的 for
循环来完成它,这是这里的慢组件,它仍然比通过第一个过滤器传递模型中的所有元素更快。
您可以像这样创建一个过滤器来优化它:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.WherePasses(param_filter)
.ToElements()
这实际上结合了快速类别筛选器、元素类型筛选器和慢速参数筛选器,可能成为整体上更快、更易于阅读的解决方案。
试一试,让我知道这是否有意义。
干杯!
我正在关注此 youtube 视频 (https://www.youtube.com/watch?v=WU_D2qNnuGg&index=7&list=PLc_1PNcpnV5742XyF8z7xyL9OF8XJNYnv) 中显示的示例,该示例说明了 Revit API 中过滤方法优于常规迭代的优势。但是我的代码比迭代方法慢得多:
过滤方法 - 0.16 秒
迭代法 - 0.06 秒
我使用过滤方法的代码是:
import Autodesk.Revit.DB as DB
doc=__revit__.ActiveUIDocument.Document
uidoc=__revit__.ActiveUIDocument
height_param_id=DB.ElementId(DB.BuiltInParameter.WALL_USER_HEIGHT_PARAM)
height_param_prov=DB.ParameterValueProvider(height_param_id)
param_equality=DB.FilterNumericEquals() # equality class
height_value_rule=DB.FilterDoubleRule(height_param_prov,param_equality,10,1e-02)
param_filter=DB.ElementParameterFilter(height_value_rule)
# This program significantly slows down for the next line
walls=DB.FilteredElementCollector(doc)\
.WherePasses(param_filter)\
.ToElementIds()
uidoc.Selection.SetElementIds(walls)
迭代使用了以下代码。
from System.Collections.Generic import List
import Autodesk.Revit.DB as DB
doc=__revit__.ActiveUIDocument.Document
uidoc=__revit__.ActiveUIDocument
sheet_collector=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory\
.OST_Sheets)\
.WhereElementIsNotElementType()\
.ToElements()
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElements()
tallwallsids=[]
for wall in walls:
heightp=wall.LookupParameter('Unconnected Height')
if heightp and heightp.AsDouble()==10:
tallwallsids.append(wall.Id)
uidoc.Selection.SetElementIds(List[DB.ElementId](tallwallsids))
什么迭代方法?
如今,过滤元素收集器通常是检索和迭代 Revit 数据库元素的唯一方法。
过滤元素收集器本身可能很快。
如果你有大量的墙并且你的内存有限,调用ToElementIds
可能会消耗大量资源。
SetElementIds
也可能会费时间。
查看 filtered element collector by pipe system types 上广泛的 Revit API 论坛讨论,了解更多相关信息。
我建议您提供一个 complete minimal reproducible sample case 为每个方法调用配备基准测试代码,以证明性能下降。
如果考虑到这两种方法必须考虑的元素数量,这是有道理的。第一种方法:
walls=DB.FilteredElementCollector(doc)\
.WherePasses(param_filter)\
.ToElementIds()
在此方法中,您要求过滤器考虑模型中的所有元素。这可能有很多元素要通过过滤器。这反对:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElements()
在此方法中,您使用 QUICK 过滤器 OfCategory()
和另一个 WhereElementIsNotElementType()
将选择范围缩小到仅 Wall
个实例。即使您使用一个简单的 for
循环来完成它,这是这里的慢组件,它仍然比通过第一个过滤器传递模型中的所有元素更快。
您可以像这样创建一个过滤器来优化它:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.WherePasses(param_filter)
.ToElements()
这实际上结合了快速类别筛选器、元素类型筛选器和慢速参数筛选器,可能成为整体上更快、更易于阅读的解决方案。
试一试,让我知道这是否有意义。
干杯!