We talked about some quick filters (ElementQuickFilter) in VB.NET previously. In this article, we will demonstrate some cases about slow filters (ElementSlowFilter).
Slow filters include:
• RoomFilter
• RoomTagFilter
• AreaFilter
• AreaTagFilter
• CurveElementFilter
• ElementLevelFilter
• ElementParameterFilter
• FamilyInstanceFilter
• SpaceFilter
• SpaceTagFilter
• PrimaryDesignOptionMemberFilter
• FamilyStructuralMaterialTypeFilter
• StructuralInstanceUsageFilter
• StructuralMaterialTypeFilter
• StructuralWallUsageFilter
Now let’s look at a specific case, how to create some filters and a final FilteredElementCollector in VB.NET to collect all rooms, areas, spaces and their tags back, and they should be in the primary design option.
To achieve this goal, quite a few different kinds of slow filters seem necessary: RoomFilter, RoomTagFilter, AreaFilter, AreaTagFilter, SpaceFilter, SpaceTagFilter and PrimaryDesignOptionMemberFilter.
Public Shared Function FindRoomsAreasSpacesAndTheirTags(ByVal doc As RvtDocument) As List(Of Autodesk.Revit.DB.Element)
Dim list As New List(Of Autodesk.Revit.DB.Element)()
Dim finalCollector As New Autodesk.Revit.DB.FilteredElementCollector(doc)
Dim filter1 As New Autodesk.Revit.DB.Architecture.RoomFilter()
finalCollector.WherePasses(filter1)
Dim filter2 As New Autodesk.Revit.DB.Architecture.RoomTagFilter()
finalCollector.UnionWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter2))
Dim filter3 As New Autodesk.Revit.DB.AreaFilter()
finalCollector.UnionWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter3))
Dim filter4 As New Autodesk.Revit.DB.AreaTagFilter()
finalCollector.UnionWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter4))
Dim filter5 As New Autodesk.Revit.DB.Mechanical.SpaceFilter()
finalCollector.UnionWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter5))
Dim filter6 As New Autodesk.Revit.DB.Mechanical.SpaceTagFilter()
finalCollector.UnionWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter6))
Dim filter7 As New Autodesk.Revit.DB.PrimaryDesignOptionMemberFilter(False)
finalCollector.IntersectWith((New Autodesk.Revit.DB.FilteredElementCollector(doc)).WherePasses(filter7))
list = finalCollector.ToList()
Return list
End Function
Here is the test code:
Public Shared Sub TestSlowFilters()
Dim elements As List(Of Autodesk.Revit.DB.Element) = ElementFinder.FindRoomsAreasSpacesAndTheirTags(CachedDoc)
MessageBox.Show(String.Format("{0} rooms, areas, spaces and their tags in the PrimaryDesignOption are found in the model.", elements.Count.ToString()))
End Sub
By the way, the above code likely will report zero elements found in some models since those rooms, areas, spaces and their tags may not be in the primary design option at all. So as to exercise the PrimaryDesignOptionMemberFilter, please make sure some elements are really using it.
People may have noticed that all the filters are fully qualified and are from different namespaces such as Autodesk.Revit.DB, Autodesk.Revit.DB.Architecture, and Autodesk.Revit.DB.Mechanical. It is quite inconvenient to sort things like these out one by one. Is there a good way to avoid this?
In fact, all these namespaces and much more have already been imported into the same source like the following:
#Region "Namespaces"
Imports System
Imports System.Text
Imports System.Linq
Imports System.Xml
Imports System.Reflection
Imports System.ComponentModel
Imports System.Collections
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Media.Imaging
Imports System.Windows.Forms
Imports System.IO
Imports Autodesk.Revit.ApplicationServices
Imports Autodesk.Revit.Attributes
Imports Autodesk.Revit.DB
Imports Autodesk.Revit.DB.Events
Imports Autodesk.Revit.DB.Architecture
Imports Autodesk.Revit.DB.Structure
Imports Autodesk.Revit.DB.Mechanical
Imports Autodesk.Revit.DB.Electrical
Imports Autodesk.Revit.DB.Plumbing
Imports Autodesk.Revit.UI
Imports Autodesk.Revit.UI.Selection
Imports Autodesk.Revit.UI.Events
Imports Autodesk.Revit.Collections
Imports Autodesk.Revit.Exceptions
Imports Autodesk.Revit.Utility
Imports RvtApplication = Autodesk.Revit.ApplicationServices.Application
Imports RvtDocument = Autodesk.Revit.DB.Document
#End Region
But we still have to do so due to a weird behavior of the VB.NET IDE and compiler that we have discussed about in more detail in another article.
Revit API & VB.NET – ‘Friend’ Is Not Accessible
Last but not least, the same task can be completed by some other filters, preferably quick filters like the ElementCategoryFilter and/or the ElementClassFilter. And even for the seemingly very special PrimaryDesignOptionMemberFilter, the ElementParameterFilter one can be a replacement, I believe. The alternative (maybe better/quicker) approach will not be demonstrated in detail here, but you can take it as an assignment if you like.
Do not worry about all the different kinds of filters and their arguments, quick or slow, the RevitAddinWizard will help you generate any combinations of the filters and their arguments in VB.NET and C# in a moment.
Recent Comments