
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:
- Primeiros Passos com Automação BIM
- Coleta de Elementos com FilteredElementCollector (este artigo)
- 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:
1import clr2clr.AddReference("RevitAPI")3from Autodesk.Revit.DB import *4clr.AddReference('RevitServices')5from RevitServices.Persistence import DocumentManager6
7doc = DocumentManager.Instance.CurrentDBDocumentO que este código faz:
clr.AddReference— carrega as bibliotecas Revit no Pythonfrom Autodesk.Revit.DB import *— importa todas as classes Revit API (Wall, Door, FilteredElementCollector, etc.)DocumentManager— fornece acesso ao arquivo Revit atualdoc— 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:
1app = doc.Application2version_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:
1from Autodesk.Revit.DB import CategoryType2
3# Obter todas as categorias4all_categories = doc.Settings.Categories5
6# Filtrar por categorias de modelo7model_categories = [c for c in all_categories if c.CategoryType == CategoryType.Model]8
9# Imprimir nomes das categorias10for 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:
1door_category = Category.GetCategory(doc, BuiltInCategory.OST_Doors)2sub_categories = door_category.SubCategories3
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:
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
Walltem.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:
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()
1### Principais Classes do Revit API2
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 Essenciais23
24Filtros rápidos são avaliados no nível da memória e são os mais eficientes:25
26```python27# 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 categoria34doors = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).ToElements()Combinando Filtros Rápidos#
Você pode encadear múltiplos filtros para resultados mais precisos:
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 parede8wall_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:
1from Autodesk.Revit.DB import FilteredElementCollector, BuiltInParameter2from Autodesk.Revit.DB import ParameterValueProvider, FilterStringRule3from Autodesk.Revit.DB import FilterStringEquals, ElementParameterFilter4
5# Criar um provedor de valor de parâmetro6provider = 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 filtro12param_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:
1# Primeiro, obter o nível pelo qual você quer filtrar2levels = FilteredElementCollector(doc).OfClass(Level).ToElements()3target_level = None4
5for level in levels:6 if level.Name == "Nível 1":7 target_level = level8 break9
10if target_level:11 # Criar um filtro de nível12 level_filter = ElementLevelFilter(target_level.Id)13 14 # Obter todos os elementos naquele nível15 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:
1from Autodesk.Revit.DB import BoundingBoxContainsPointFilter, Outline2
3# Definir os cantos da caixa delimitadora4min_point = XYZ(0, 0, 0)5max_point = XYZ(100, 100, 30) # pés6
7# Criar um outline a partir dos pontos8outline = Outline(min_point, max_point)9
10# Criar o filtro de caixa delimitadora11bb_filter = BoundingBoxIsInsideFilter(outline)12
13# Coletar elementos dentro da caixa14elements_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:
1from Autodesk.Revit.DB import BoundingBoxIntersectsFilter, Outline2
3# Definir o volume de busca4min_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:
1# Coletar todos os family symbols (tipos)2family_symbols = FilteredElementCollector(doc) \3 .OfClass(FamilySymbol) \4 .ToElements()5
6# Agrupar por nome de família7families = {}8for symbol in family_symbols:9 family_name = symbol.Family.Name10 if family_name not in families:11 families[family_name] = []12 families[family_name].append(symbol.Name)13
14# Imprimir resultados15for 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:
1from Autodesk.Revit.DB import LogicalAndFilter, LogicalOrFilter2
3# Criar filtros individuais de categoria4wall_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 portas12combined_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:
1from Autodesk.Revit.DB import ExclusionFilter2
3# Obter IDs dos elementos a excluir4elements_to_exclude = [ElementId(12345), ElementId(67890)]5
6# Criar filtro de exclusão7exclusion_filter = ExclusionFilter(elements_to_exclude)8
9# Coletar todas as paredes exceto as excluídas10filtered_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:
1# Obter a vista ativa2active_view = doc.ActiveView3
4# Coletar elementos visíveis nesta vista5visible_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:
ElementParameterFilterBoundingBoxFilterElementIntersectsFilter
Boa Prática: Sempre aplique filtros rápidos primeiro, depois filtros lentos:
1# BOM: Filtro rápido primeiro, depois filtro lento2elements = 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 dados9elements = FilteredElementCollector(doc) \10 .WherePasses(slow_filter) \11 .ToElements()Filtragem de Elementos Estruturais#
Filtrar elementos estruturais especificamente:
1# Obter pilares estruturais2structural_columns = FilteredElementCollector(doc) \3 .OfCategory(BuiltInCategory.OST_StructuralColumns) \4 .WhereElementIsNotElementType() \5 .ToElements()6
7# Obter vigas8beams = FilteredElementCollector(doc) \9 .OfCategory(BuiltInCategory.OST_StructuralFraming) \10 .WhereElementIsNotElementType() \11 .ToElements()12
13# Obter fundações14foundations = 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:
1from Autodesk.Revit.DB import LabelUtils, BuiltInParameter, LanguageType2
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 pass11 return labels12
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#
-
Use filtros rápidos primeiro — Eles são avaliados antes dos dados do elemento serem carregados
-
Limite o escopo — Use coletores específicos de vista quando possível:
Python1FilteredElementCollector(doc, view.Id) -
Use
FirstElement()para resultados únicos:Python1first_wall = FilteredElementCollector(doc).OfClass(Wall).FirstElement() -
Use
GetElementCount()para contagem:Python1wall_count = FilteredElementCollector(doc).OfClass(Wall).GetElementCount() -
Evite coletores repetidos — Armazene resultados em cache quando reutilizar:
Python1walls = list(FilteredElementCollector(doc).OfClass(Wall).ToElements())
Próximos Passos#
Continue sua jornada com Revit API no próximo artigo desta série:
- Anterior: Primeiros Passos com Automação BIM
- Próximo: Métodos de Seleção de UI
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
