ISelectionFilter Example

ISelectionFilter allows you to limit what is allowed to be selected when you use Selection methods.

This might improve user experience by allowing selection of the correct elements for the script. You can define any logic you want for allowing selection.

Simple ISelectionFilter

ISelectionFilter is an Interface. So it means that it is like a blueprint you could use for creating your own class with special functionality.

If you going to check documentation you will notice that ISelectionFilter Interface has 2 methods and it mentions that both needs to be overridden.


Here is a simple example on how to create ISelectionFilter for Wall category.

from Autodesk.Revit.UI.Selection import ISelectionFilter

class CustomFilter(ISelectionFilter):

    def AllowElement(self, element):
        if element.Category.BuiltInCategory == BuiltInCategory.OST_Walls:
            return True

💡Element argument refers to a placeholder for element. You can use it for creating logical rules that will be applied to all elements in the model to ensure if they can be selected or not

💡If you make any errors inside Interface class you won't see any error messages, it will just return False and disallow selection. So make sure you catch and display your errors with try/except during development. That's very important.

How to use custom ISelectionFilter

Here is how to use this custom filter we created above it for PickObject

from Autodesk.Revit.UI.Selection import ObjectType

my_filter       = CustomFilter() # Class you created based on ISelectionFilter
ref_picked_elem = uidoc.Selection.PickObject(ObjectType.Element, my_filter)
picked_elem     = doc.GetElement(ref_picked_elem)


Reusable Example

You can also make reusable class for Classes and Categories like this:

from Autodesk.Revit.UI.Selection import ISelectionFilter

class ISelectionFilter_Classes(ISelectionFilter):
    def __init__(self, allowed_types):
        """ ISelectionFilter made to filter with types
        :param allowed_types: list of allowed Types"""
        self.allowed_types = allowed_types

    def AllowElement(self, element):
        if type(element) in self.allowed_types:
            return True


class ISelectionFilter_Categories(ISelectionFilter):
    def __init__(self, allowed_categories):
        """ ISelectionFilter made to filter with categories
        :param allowed_types: list of allowed Categories"""
        self.allowed_categories = allowed_categories

    def AllowElement(self, element):
        if element.Category.BuiltInCategory in self.allowed_categories:
            return True

You will notice that I added an __init__ to provide a list of allowed types or categories so it can be a reusable class.

Here is an example on how you could use them across all your scripts:

#1️⃣ ISelectionFilter - Classes
filter_types    = ISelectionFilter_Classes([Room, RoomTag])
selected_elements_ = selection.PickObjects(ObjectType.Element, 
                                           filter_types)


#2️⃣ ISelectionFilter - Categories
filter_cats       = ISelectionFilter_Categories([BuiltInCategory.OST_Walls])
selected_elements = selection.PickObjects(ObjectType.Element, 
                                          filter_cats)

💡As you can see you will provide a list of allowed types/categories and it works.

⌨️ Happy Coding!
Erik Frits