I was following example shown in this youtube video (https://www.youtube.com/watch?v=WU_D2qNnuGg&index=7&list=PLc_1PNcpnV5742XyF8z7xyL9OF8XJNYnv) which illustrates superiority of filtering methods in Revit API over usual iteration. But my code is significantly slower than the the iteration method :
filter method-0.16 secs
iteration method-0.06 secs
My code using filter method is :
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)
For iteration following code was used.
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))
This makes sense if you consider the amount of elements that the two methods have to consider. First method:
walls=DB.FilteredElementCollector(doc)\
.WherePasses(param_filter)\
.ToElementIds()
In this method you are asking the filter to consider ALL elements in the model. That's potentially a lot of elements to pass through the filter. That's opposed to:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElements()
In this method you use the QUICK filter OfCategory()
and another WhereElementIsNotElementType()
to narrow down the selection to only Wall
instances. Even though you follow that through with a simple for
loop which is the slow component here, its still FASTER than passing ALL elements in the model through the first filter.
You can optimize it by creating a filter like so:
walls=DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.WherePasses(param_filter)
.ToElements()
This would actually combine the quick category filter, element type filter, and slow parameter filter to potentially be an overall faster and easier to read solution.
Give it a go, and let me know if this makes sense.
Cheers!