Voltar ao Blog
RevitAPIPythonFilteredElementCollectorAutomação BIM

Coleta de Elementos com FilteredElementCollector — Guia Completo

Paulo Giavoni

Paulo Giavoni

Engenheiro & Especialista BIM

5 janeiro 202610 min read
Coleta de Elementos com FilteredElementCollector — Guia Completo

Introdução aos Coletores de Elementos#

O FilteredElementCollector é a base de qualquer automação no Revit. Toda vez que você precisa trabalhar com elementos — paredes, portas, janelas, vistas — deve primeiro encontrá-los no modelo. O collector é a ferramenta que faz isso.

Analogia prática: Imagine seu modelo Revit como um enorme armazém. O FilteredElementCollector é o sistema de busca automatizado que encontra exatamente o que você precisa, sem ter que procurar manualmente.

Este guia mostra 35+ formas diferentes de filtrar elementos, desde filtros básicos (categoria) até avançados (geometria, parâmetros, posição).

Este é o segundo artigo de uma série de três partes sobre desenvolvimento com Revit API:

  1. Primeiros Passos com Automação BIM
  2. Coleta de Elementos com FilteredElementCollector (este artigo)
  3. Métodos de Seleção de UI

Por Que Usar Collectors em Vez de Seleção Manual?#

Cenário típico sem automação:

  • Abre o Revit
  • Seleciona manualmente 50 paredes
  • Altera um parâmetro em cada uma
  • Repete para cada andar do projeto

Com um collector:

  • Um script encontra automaticamente todas as paredes que atendem critérios precisos
  • Modifica todas em uma única operação
  • Pode ser repetido instantaneamente em outros projetos

Vantagens chave:

  • Precisão — nenhum elemento esquecido
  • Velocidade — segundos em vez de minutos/horas
  • Reutilização — mesmo script para projetos diferentes
  • Documentação — o código documenta exatamente o que foi feito

Bibliotecas e Configuração Necessárias#

Antes de começar, todo script Python no Dynamo que usa Revit API deve começar com estas linhas:

Python
1import clr
2clr.AddReference("RevitAPI")
3from Autodesk.Revit.DB import *
4clr.AddReference('RevitServices')
5from RevitServices.Persistence import DocumentManager
6
7doc = DocumentManager.Instance.CurrentDBDocument

O que este código faz:

  • clr.AddReference — carrega as bibliotecas Revit no Python
  • from Autodesk.Revit.DB import * — importa todas as classes Revit API (Wall, Door, FilteredElementCollector, etc.)
  • DocumentManager — fornece acesso ao arquivo Revit atual
  • doc — a variável que você usará para acessar o modelo

Nota: Copie este bloco no início de cada nó Python Script no Dynamo.


Obtendo Informações do Aplicativo Revit#

Você pode recuperar várias propriedades do aplicativo Revit usando o objeto Application:

Python
1app = doc.Application
2version_info = f"""
3Número da Versão: {app.VersionNumber}
4Nome da Versão: {app.VersionName}
5Build da Versão: {app.VersionBuild}
6Número da Sub Versão: {app.SubVersionNumber}
7Produto: {app.Product}
8Idioma: {app.Language}
9Pasta de Dados do Usuário: {app.CurrentUsersDataFolderPath}
10"""
11print(version_info)

Coletando Categorias do Modelo#

Para começar a trabalhar com elementos Revit, é útil entender as categorias disponíveis:

Python
1from Autodesk.Revit.DB import CategoryType
2
3# Obter todas as categorias
4all_categories = doc.Settings.Categories
5
6# Filtrar por categorias de modelo
7model_categories = [c for c in all_categories if c.CategoryType == CategoryType.Model]
8
9# Imprimir nomes das categorias
10for category in model_categories:
11 print(category.Name)

Tipos de Categoria#

No Revit API, categorias e tipos são identificados por valores enumerados. Veja como trabalhar com eles:

Python
1door_category = Category.GetCategory(doc, BuiltInCategory.OST_Doors)
2sub_categories = door_category.SubCategories
3
4print(f"A categoria 'Portas' tem {sub_categories.Size} subcategorias:")
5for sub_category in sub_categories:
6 print(f"- {sub_category.Name}")

Mudanças no Revit 2022#

O Revit 2022 introduziu identificadores de 64 bits para categorias built-in:

Python
1door_category_type_id = Category.GetBuiltInCategoryTypeId(BuiltInCategory.OST_Doors)
2print(f"O TypeId para a categoria 'Portas' é: {door_category_type_id}")

Filtrar por Classe de Elemento#

Compreender Classes vs Categorias#

Conceito fundamental: No Revit API, "Classe" e "Categoria" são duas coisas diferentes, e a confusão entre elas é o erro mais comum para iniciantes.

  • Classe = O tipo de objeto no código (ex: Wall, Floor, FamilyInstance)
  • Categoria = O grupo funcional que você vê na interface do Revit (ex: "Paredes", "Pisos", "Portas")

Exemplo prático:

  • Uma porta é um FamilyInstance (classe) da categoria "Portas" (BuiltInCategory.OST_Doors)
  • Uma janela é um FamilyInstance (classe) da categoria "Janelas" (BuiltInCategory.OST_Windows)
  • Uma parede é um Wall (classe) da categoria "Paredes" (BuiltInCategory.OST_Walls)

Quando filtrar por classe:

  • Quando você quer todos os elementos daquele tipo de objeto
  • Para operações específicas ao tipo de classe (ex: apenas Wall tem .Flip())

Quando filtrar por categoria:

  • Quando você quer distinguir entre objetos similares (portas vs janelas, ambos FamilyInstance)
  • Para ler parâmetros específicos da categoria

Usando o Atalho OfClass#

A forma mais simples de filtrar por classe é usando o método OfClass:

Python
1# Obter todas as paredes (instâncias + tipos)
2walls = FilteredElementCollector(doc).OfClass(Wall).ToElements()
3
4# Obter apenas os tipos de piso (não as instâncias)
5floor_types = FilteredElementCollector(doc).OfClass(FloorType).ToElements()
6
7# Obter todas as instâncias de família (portas, janelas, mobiliário, etc.)
8family_instances = FilteredElementCollector(doc).OfClass(FamilyInstance).ToElements()

O que significa .ToElements()? O collector não encontra imediatamente todos os elementos — ele os "promete". .ToElements() diz ao collector para efetivamente executar a busca e retornar a lista completa.

Alternativas a .ToElements():

  • .FirstElement() — retorna apenas o primeiro elemento encontrado (mais rápido)
  • .GetElementCount() — conta os elementos sem carregá-los (muito rápido)
  • .ToElementIds() — retorna apenas os Ids em vez dos objetos completos (leve)

Obter todas as instâncias de família

family_instances = FilteredElementCollector(doc).OfClass(FamilyInstance).ToElements()

Text
1### Principais Classes do Revit API
2
3Aqui estão as classes mais comumente usadas para filtragem:
4
5| Classe | Descrição |
6|--------|-----------|
7| `Wall` | Elementos de parede |
8| `Floor` | Elementos de piso |
9| `Ceiling` | Elementos de forro |
10| `FamilyInstance` | Todos os elementos baseados em família |
11| `Level` | Elementos de nível |
12| `Grid` | Linhas de grid |
13| `View3D` | Vistas 3D |
14| `ViewPlan` | Vistas de planta |
15| `ViewSection` | Vistas de corte |
16| `ViewSheet` | Pranchas |
17| `Material` | Materiais |
18| `Family` | Famílias carregadas |
19
20---
21
22## Filtros Rápidos Essenciais
23
24Filtros rápidos são avaliados no nível da memória e são os mais eficientes:
25
26```python
27# Obter apenas tipos de elementos (não instâncias)
28types = FilteredElementCollector(doc).WhereElementIsElementType().ToElements()
29
30# Obter apenas instâncias de elementos (não tipos)
31instances = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
32
33# Obter todos os elementos de uma categoria
34doors = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).ToElements()

Combinando Filtros Rápidos#

Você pode encadear múltiplos filtros para resultados mais precisos:

Python
1# Obter todas as instâncias de portas (não tipos de portas)
2door_instances = FilteredElementCollector(doc) \
3 .OfCategory(BuiltInCategory.OST_Doors) \
4 .WhereElementIsNotElementType() \
5 .ToElements()
6
7# Obter todos os tipos de parede
8wall_types = FilteredElementCollector(doc) \
9 .OfClass(WallType) \
10 .WhereElementIsElementType() \
11 .ToElements()

Filtrar por Valores de Parâmetros#

Uma das funcionalidades mais poderosas é filtrar por valores de parâmetros:

Python
1from Autodesk.Revit.DB import FilteredElementCollector, BuiltInParameter
2from Autodesk.Revit.DB import ParameterValueProvider, FilterStringRule
3from Autodesk.Revit.DB import FilterStringEquals, ElementParameterFilter
4
5# Criar um provedor de valor de parâmetro
6provider = ParameterValueProvider(ElementId(BuiltInParameter.ALL_MODEL_MARK))
7
8# Criar uma regra de filtro (elementos onde Marca é igual a "A1")
9rule = FilterStringRule(provider, FilterStringEquals(), "A1", False)
10
11# Criar e aplicar o filtro
12param_filter = ElementParameterFilter(rule)
13
14elements = FilteredElementCollector(doc) \
15 .OfCategory(BuiltInCategory.OST_Walls) \
16 .WherePasses(param_filter) \
17 .ToElements()

Filtrar por Nível#

Filtrar elementos associados a um nível específico:

Python
1# Primeiro, obter o nível pelo qual você quer filtrar
2levels = FilteredElementCollector(doc).OfClass(Level).ToElements()
3target_level = None
4
5for level in levels:
6 if level.Name == "Nível 1":
7 target_level = level
8 break
9
10if target_level:
11 # Criar um filtro de nível
12 level_filter = ElementLevelFilter(target_level.Id)
13
14 # Obter todos os elementos naquele nível
15 elements_on_level = FilteredElementCollector(doc) \
16 .WherePasses(level_filter) \
17 .ToElements()
18
19 print(f"Encontrados {len(elements_on_level)} elementos no {target_level.Name}")

Elementos dentro de uma BoundingBox#

Encontrar elementos que estão completamente dentro de uma caixa delimitadora definida:

Python
1from Autodesk.Revit.DB import BoundingBoxContainsPointFilter, Outline
2
3# Definir os cantos da caixa delimitadora
4min_point = XYZ(0, 0, 0)
5max_point = XYZ(100, 100, 30) # pés
6
7# Criar um outline a partir dos pontos
8outline = Outline(min_point, max_point)
9
10# Criar o filtro de caixa delimitadora
11bb_filter = BoundingBoxIsInsideFilter(outline)
12
13# Coletar elementos dentro da caixa
14elements_in_box = FilteredElementCollector(doc) \
15 .WherePasses(bb_filter) \
16 .ToElements()
17
18print(f"Encontrados {len(elements_in_box)} elementos dentro da caixa delimitadora")

Elementos Intersectando uma BoundingBox#

Encontrar elementos que intersectam com uma caixa delimitadora:

Python
1from Autodesk.Revit.DB import BoundingBoxIntersectsFilter, Outline
2
3# Definir o volume de busca
4min_point = XYZ(0, 0, 0)
5max_point = XYZ(50, 50, 15)
6
7outline = Outline(min_point, max_point)
8bb_intersect_filter = BoundingBoxIntersectsFilter(outline)
9
10intersecting_elements = FilteredElementCollector(doc) \
11 .WherePasses(bb_intersect_filter) \
12 .ToElements()
13
14print(f"Encontrados {len(intersecting_elements)} elementos intersectando a caixa")

Filtrar Family Symbols (Tipos)#

Obter todos os tipos de uma família específica:

Python
1# Coletar todos os family symbols (tipos)
2family_symbols = FilteredElementCollector(doc) \
3 .OfClass(FamilySymbol) \
4 .ToElements()
5
6# Agrupar por nome de família
7families = {}
8for symbol in family_symbols:
9 family_name = symbol.Family.Name
10 if family_name not in families:
11 families[family_name] = []
12 families[family_name].append(symbol.Name)
13
14# Imprimir resultados
15for family, types in families.items():
16 print(f"\n{family}:")
17 for t in types:
18 print(f" - {t}")

Filtros Lógicos#

Combinar filtros usando operações lógicas:

Python
1from Autodesk.Revit.DB import LogicalAndFilter, LogicalOrFilter
2
3# Criar filtros individuais de categoria
4wall_filter = ElementCategoryFilter(BuiltInCategory.OST_Walls)
5floor_filter = ElementCategoryFilter(BuiltInCategory.OST_Floors)
6door_filter = ElementCategoryFilter(BuiltInCategory.OST_Doors)
7
8# Combinar com lógica OR (paredes OU pisos OU portas)
9or_filter = LogicalOrFilter([wall_filter, floor_filter, door_filter])
10
11# Obter todas as paredes, pisos e portas
12combined_elements = FilteredElementCollector(doc) \
13 .WherePasses(or_filter) \
14 .WhereElementIsNotElementType() \
15 .ToElements()
16
17print(f"Encontrados {len(combined_elements)} paredes, pisos e portas")

Filtro de Exclusão#

Criar um filtro que exclui elementos específicos:

Python
1from Autodesk.Revit.DB import ExclusionFilter
2
3# Obter IDs dos elementos a excluir
4elements_to_exclude = [ElementId(12345), ElementId(67890)]
5
6# Criar filtro de exclusão
7exclusion_filter = ExclusionFilter(elements_to_exclude)
8
9# Coletar todas as paredes exceto as excluídas
10filtered_walls = FilteredElementCollector(doc) \
11 .OfClass(Wall) \
12 .WherePasses(exclusion_filter) \
13 .ToElements()

Filtrar Elementos Visíveis na Vista#

Coletar elementos que são visíveis em uma vista específica:

Python
1# Obter a vista ativa
2active_view = doc.ActiveView
3
4# Coletar elementos visíveis nesta vista
5visible_elements = FilteredElementCollector(doc, active_view.Id) \
6 .WhereElementIsNotElementType() \
7 .ToElements()
8
9print(f"Encontrados {len(visible_elements)} elementos visíveis em {active_view.Name}")

Filtros Rápidos vs Filtros Lentos#

Entender a diferença é crucial para performance:

Filtros Rápidos (Velozes)#

Avaliados no nível do elemento sem abrir dados do elemento:

  • OfClass()
  • OfCategory()
  • WhereElementIsElementType()
  • WhereElementIsNotElementType()

Filtros Lentos (Mais Poderosos)#

Requerem que os dados do elemento sejam abertos:

  • ElementParameterFilter
  • BoundingBoxFilter
  • ElementIntersectsFilter

Boa Prática: Sempre aplique filtros rápidos primeiro, depois filtros lentos:

Python
1# BOM: Filtro rápido primeiro, depois filtro lento
2elements = FilteredElementCollector(doc) \
3 .OfCategory(BuiltInCategory.OST_Walls) \
4 .WhereElementIsNotElementType() \
5 .WherePasses(slow_filter) \
6 .ToElements()
7
8# RUIM: Filtro lento em todo o banco de dados
9elements = FilteredElementCollector(doc) \
10 .WherePasses(slow_filter) \
11 .ToElements()

Filtragem de Elementos Estruturais#

Filtrar elementos estruturais especificamente:

Python
1# Obter pilares estruturais
2structural_columns = FilteredElementCollector(doc) \
3 .OfCategory(BuiltInCategory.OST_StructuralColumns) \
4 .WhereElementIsNotElementType() \
5 .ToElements()
6
7# Obter vigas
8beams = FilteredElementCollector(doc) \
9 .OfCategory(BuiltInCategory.OST_StructuralFraming) \
10 .WhereElementIsNotElementType() \
11 .ToElements()
12
13# Obter fundações
14foundations = FilteredElementCollector(doc) \
15 .OfCategory(BuiltInCategory.OST_StructuralFoundation) \
16 .WhereElementIsNotElementType() \
17 .ToElements()
18
19print(f"Elementos estruturais: {len(structural_columns)} pilares, {len(beams)} vigas, {len(foundations)} fundações")

Labels e Localização#

Trabalhando com labels em diferentes idiomas:

Python
1from Autodesk.Revit.DB import LabelUtils, BuiltInParameter, LanguageType
2
3def get_parameter_labels(language=LanguageType.English):
4 labels = []
5 for param in BuiltInParameter:
6 try:
7 label = LabelUtils.GetLabelFor(param, language)
8 labels.append(f"{param}: {label}")
9 except:
10 pass
11 return labels
12
13english_labels = get_parameter_labels()
14print("Primeiros 5 labels de parâmetros em Inglês:")
15for label in english_labels[:5]:
16 print(label)

Melhores Práticas de Performance#

  1. Use filtros rápidos primeiro — Eles são avaliados antes dos dados do elemento serem carregados

  2. Limite o escopo — Use coletores específicos de vista quando possível:

    Python
    1FilteredElementCollector(doc, view.Id)
  3. Use FirstElement() para resultados únicos:

    Python
    1first_wall = FilteredElementCollector(doc).OfClass(Wall).FirstElement()
  4. Use GetElementCount() para contagem:

    Python
    1wall_count = FilteredElementCollector(doc).OfClass(Wall).GetElementCount()
  5. Evite coletores repetidos — Armazene resultados em cache quando reutilizar:

    Python
    1walls = list(FilteredElementCollector(doc).OfClass(Wall).ToElements())

Próximos Passos#

Continue sua jornada com Revit API no próximo artigo desta série:

Share:

Questions or Feedback?

I'd love to hear your thoughts on this article. Reach out directly and let's start a conversation.

Follow me on LinkedIn for more BIM tips and updates