Покажу, как с помощью Динамо можно создать фильтры вида, настроить их и добавить к виду. Буду показывать на примере актуального Ревита 2025, но общая логика будет одинаковой для всех версий, которые существуют на момент создания статьи.
Буду показывать на примере одного вида и одного фильтра. В качестве вида возьму 3Д-вид, он будет открыт у меня в Ревите, поэтому я просто получу активный вид нодами. Если нужно добавить фильтр к нескольким видам, то нужно создать список видов и обрабатывать их. Как получать элементы из модели, можете почитать в отдельной статье. Как фильтровать элементы, читайте в другой базовой статье.
Получаем активный вид
Получили активный документ, дальше получаем активный вид. Активный вид — это тот вид, что открыт у вас в Ревите в данный момент, эта вкладка будет жирным шрифтом в интерфейсе.
Разматываем ноды для фильтра
Для добавления фильтра к виду есть нод View.AddFilter. У него всего два входа, на первый подаём вид, на второй — какой-то parameterFilter. И вот сюда надо подать настройки фильтра. Делает это другим нодом — ParameterFilterElement.ByRules. В этот нод надо подать уже три входных данных, вот тут уже и начинается разматывание нодов.
Первый вход name — это имя нашего фильтра. Его будем указывать вручную, но так как имя фильтра должно быть уникальным, то будет полезно проверить, а уникально ли имя нашего фильтра. Можете сделать это так: взять все фильтры, которые есть в проекте, получить их имена и проверить, содержит ли список то имя, что вы хотите добавить. Если содержит, то вернуть ошибку, если нет, то работаем дальше.
Второй вход categories — ждёт список категорий, к которым будет применяться фильтр.
Третий вход rules — это критерии для фильтрации.
По сути этот нод заменяет нам окно создания фильтра в интерфейсе Ревита, где мы точно также задаём имя фильтра, категории и критерии. Это и называется фильтром по правилам в отличии от фильтра выбора, где мы обрабатываем заранее выбранный перечень элементов. Об этом тоже есть отдельная статья.
В нашем примере именем фильтра сделаю просто код блок с текстом. Список категорий можете создать любым удобным вам образом. Поскольку вы, скорее всего, хотите применять фильтр ко всем элементам на виде, то можно получить все элементы на активном виде, дальше взять их категории и оставить уникальные значения.
Способ быстрый и удобный, но есть одно но: если у вас на виде каким-то образом скрыты категории, которые тоже нужно добавить в фильтры, то их в фильтре не появится. Ситуация вроде как маловероятная, но всё же возможная, поэтому учитывайте данный нюанс. Если готовы именно так получать список категорий, то вот цепочка нодов, чтобы это сделать:
В принципе, конечно, надёжнее будет создать список категорий по внутренним именам категорий. Тут нам нужен текстовый список внутренних имён категорий и нод Category.ByName. Покажу на примере пары категорий, как это будет выглядеть:
Внутренние имена — это то, как категории называются внутри Ревита независимо от языка Ревита. В русском интерфейсе трубы будут в категории «Трубы», в англоязычном — «Pipes», но внутреннее имя для этой категории — OST_PipeCurves. Оно универсальное и не зависит от локализации. Поэтому использовать такие имена надёжнее всего. Вот список таких категорий:
"OST_PlaceHolderPipes",
"OST_PipeInsulations",
"OST_PipeAccessory",
"OST_FlexPipeCurves",
"OST_PipeFitting",
"OST_PipeCurves",
"OST_PlaceHolderDucts",
"OST_DuctLinings",
"OST_DuctInsulations",
"OST_FlexDuctCurves",
"OST_DuctAccessory",
"OST_DuctTerminal",
"OST_DuctFitting",
"OST_DuctCurves",
"OST_MechanicalEquipment",
"OST_PlumbingFixtures",
"OST_Sprinklers",
"OST_PlumbingEquipment",
"OST_MechanicalControlDevices"
Теперь переходим к входу rules. Для этого нам нужен ещё один нод — FilterRule.ByRuleType.
У него тоже три входа. На первый type нужно подать оператор для критерия фильтра. Просто написать текстом нельзя, поэтому тут тоже нужен ещё один нод — Select Rule Type. В нём выберу Equals, то есть «равно». Про операторы в фильтрах тоже есть статья. Вы можете выбрать любой подходящий для вас оператор.
Второй вход value — сюда пишем значение для сравнения, это просто текстовое поле. Напишу текст в кодблоке.
Третий вход parameter ждёт от нас параметр для фильтра. И тут нельзя просто написать имя параметра текстом, нужно подавать специальный элемент — Parameter. Поскольку у всех элементов, которые планируем обрабатывать, должен быть один и тот же параметр, то можно сделать вот что: берём все элементы и по имени параметра получаем этот самый параметр нодом Parameter.ParameterByName, а потом оставляем только первый элемент списка.
При таком получении параметра главное, чтобы не наткнутся на элемент, у которого такого параметра нет. Иначе получим «ноль» вместо параметра и ошибку в скрипте. На скриншоте ниже такой пример, тут в элементы на активном виде попадают трубопроводные системы (не элементы, а система на элементах), а у них нет параметра «ИмяСистемы».
Возможно, в версиях до 2025 такая операция выдаст ошибку, а не игнор, я не проверял.
Собственно, нод FilterRule.ByRuleType и вся цепочка нодов для него по сути заменяют область, где мы задаём критерии для фильтра в интерфейсе Ревита. Если к фильтру нужно добавить несколько критериев, то создаёте отдельно каждый критерий, объединяете в список и добавляете в rules:
Если вы создаёте фильтр на несколько критериев, то вам становится важна обработка этих критериев в формате логического перемножения И или логической суммы ИЛИ. Через Динамо это поменять нельзя, ну или я не нашёл, а по умолчанию Динамо создаёт фильтр с логической суммой, что не всегда нужно.
Чтобы это исправить, я обратился к Сергею Нефёдову, автору блога про Ревит АПИ и работу в Си Шарпе под Ревит. Он написал код для Питона, с помощью которого можно переключать режим «ИЛИ» на «И».
Вам нужно создать Python Script и подать на его вход имя вашего фильтра, просто текст. Вот этот код, вставьте его в Питон-скрипт:
import clr
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager as TM
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
# Get the current Revit document
doc = DocumentManager.Instance.CurrentDBDocument
TM.Instance.EnsureInTransaction(doc) # Открытие транзакции
# Get an existing ParameterFilterElement by name (replace with your filter's name)
filter_name = IN[0]
collector = FilteredElementCollector(doc).OfClass(ParameterFilterElement)
parameter_filter = None
for f in collector:
if f.Name == filter_name:
parameter_filter = f
break
if parameter_filter:
# Switch between AND (all rules must pass) and OR (any rule must pass)
if parameter_filter.GetElementFilter() is LogicalOrFilter:
# Change from AND to OR
#parameter_filter.SetElementFilter(LogicalOrFilter(parameter_filter.GetElementFilter().GetFilters()))
pass
else:
# Change from OR to AND
parameter_filter.SetElementFilter(LogicalAndFilter(parameter_filter.GetElementFilter().GetFilters()))
else:
pass
TM.Instance.TransactionTaskDone() # Закрытие транзакции
OUT = parameter_filter
Если тема автоматизации и Си Шарп вам интересны, то вот вам ссылка на Телеграм-канал Сергея.
Собираю все эти ноды, запускаю скрипт. Динамо создаёт фильтр и добавляет его к указанному виду. Это хорошо, но мало: нужно настроить либо видимость, либо переопределить графику элементов, которые попали под действие фильтра. Иначе фильтр бесполезен.
Чтобы фильтр поработал, нужно добавить ещё два нода: View.SetFilterOverrides и OverrideGraphicSettings.ByProperties. Первый задаёт переопределения фильтра на виде, а второй задаёт настройки графического переопределения. Если проще, то первый нод управляет галочкой видимости и настройками графики, а второй — задаёт настройки графики.
На нод View.SetFilterOverrides нужно подать вид, к которому добавили фильтр и его настройки. Это уже есть, просто соединяем лапшу. Последний вход hide отвечает за галочку «Видимость» фильтра. Если нужно скрыть элементы, то подайте сюда False
из нода Boolen.
На вход overrides нужно подать настройки переопределения графики. За это отвечаем большущий нод OverrideGraphicSettings.ByProperties. Если вам нужно просто скрывать элементы, то нужно этот нод подключить и ничего с ним больше не делать. А если хотите перекрашивать элементы, то нужно задать настройки этого перекрашивания. Сделал вот такую инструкцию для вас, думаю, разберётесь сам, что к чему, просто сравните то, что есть в настройках переопределения графики фильтра и в этом ноде.
Чтобы задавать цвета, нужны ноды с цветом, например Color Palette или Color.ByARGB. На второй нод надо подавать числа от 0 до 255, альфа — это прозрачность, а остальное — код цвета по RGB, то есть красный, зелёный и синий каналы.
Чтобы задать образец заливки, берите нод Fill Patterns, это выпадающий список с заливками из проекта. Аналогично с образцами линий, нод Line Patterns. Вес линии задаётся обычным целым числом. Прозрачность и уровень детализации можно изменить в видимости/графике, но не в фильтрах, поэтому их опускаем. Полутона — булево выражение, подавайте туда тру или фолз.
В общем-то, вот и всё. Такая комбинация нодов решает нашу задачу: фильтр добавляется к виду, видимость или графика меняется. Поэтому и написал про «разматывать» ноды, ведь пришлось каждый раз добавлять всё новые и новые ноды, чтобы собрать всю конструкцию. Вот так она выглядит для создания фильтра: