Продолжаем изучать Динамо. В прошлый раз я показал, как создать элементарный скрипт по переносу значения из одного параметра в другой. В том примере мы взяли все трубы и скопировали их имена систем в параметр «Комментарии».
Теперь задачу чуть усложним: будем копировать имена не у всех труб, а только у труб определённой системы. Для этого нам и нужно изучить фильтрацию, а заодно и булеву математику. Не бойтесь, ничего сложного.
Уровень сложности: чуть выше дна.
Время создания: максимум 10 минут.
Версия Ревита и Динамо: 2020.2 и 2.3.0 (работать будет в любой версии).
Алгоритм
Берём все трубы в проекте и получаем у них имена систем. Создаём фильтр в Динамо, чтобы оставить в выборке только трубы указанной нами системы. Копируем имя системы в «Комментарии».
Этот новый скрипт будет двойняшкой предыдущего скрипта, просто я добавлю в него блок фильтрации. Поэтому не буду рассказывать о том, как делаю весь скрипт, читайте в первой статье, здесь же акцент будет только на блоке фильтрации.
Скрипт
Итак, вот мой старый скрипт, оставлю от него первую часть, в которой получаю имена систем с труб. Они видны в ноде GetParameter.
Теперь я хочу отделить из списка элементов только те трубы, у которых имя системы равняется «Т21 1». Пример у нас простой, поэтому в модели есть только одна труба с таким именем системы. Это неважно, потому что будь их сто одна, скрипт был бы точно такой же.
Ноды
Чтобы добавить фильтрацию, нужен нод FilterByBoolMask — Отфильтровать по булевой маске. Булева маска — это список из булевых выражений true и false (тру и фолс). То есть истина/ложь или да/нет.
Маской они называются потому, что этот список из тру/фолс накладывается на список, который нужно отфильтровать. Как маска на лицо.
Если вся эта ерунда с маской пока понятна не до конца, то скоро мы проведём фильтрацию, и станет яснее.
На ноде FilterByBoolMask у нас два входа и два выхода.
List — это список, который мы будем фильтровать, в нашем случае — список с трубами.
Mask — это список-маска, его нужно создать.
Про выходы расскажу чуть позже.
Кроме нода с фильтром нам нужны Код Блок и нод «равно». Код Блок создаю двойным кликом по рабочему пространству, а «равно» возьму в библиотеке, просто напишу «=» в строке поиска и добавлю нод.
В программировании «==» означает проверку равенства двух переменных, а просто «=» означает присвоение значения переменной. То есть выражение a = b значит «записать в переменную a значение переменной b. Если a = 2, b = 3, то результатом a = b будет a равно 3. Грубо говоря, через одинарное «=» мы говорим, чему должна быть равна переменная.
Выражение a == b значит «сравнивать значения переменных a и b, если они равны, то выдать true (истина, действительно равны), если не равны, то выдать false (ложь, значения не равны). Таким образом в программировании сравниваются все величины и результат сравнения — это булевы выражения, либо да, либо нет, true или false.
Создание маски
Чтобы создать маску, возьму список с именами систем, который я уже получил ранее, и сравню каждое значение в списке с тем именем системы, которое мне нужно. В нодах это выглядит так:
То есть я беру нод для поверки равенства, на один вход подаю список с именами систем всех труб, а на второй вход подаю имя той системы, чьи трубы хочу обработать скриптом. В примере это труба с именем системы «Т21 1», этот текст и ввожу в Код Блок.
Если теперь я запущу скрипт, то на выходе из нода «==» получу список булевых выражений:
Посмотрите: скрипт прошёлся по каждому значению в списке с именами систем, сравнил значение с тем, что я задал как эталон, и выдал мне список тру/фолс. Если значение в списке совпало, то выдал тру. Если нет, то фолс. Так как у меня только одна труба с именем системы «Т21 1», то в списке у меня только один тру.
Заметьте, что у списков есть своя нумерация, но начинается она с нуля. Эти номера называют индексами. У меня в списке имён систем значение «Т21 1» расположено в индексе 0. И значение тру также расположено в индексе 0. Это важное соответствие индексов, так как следующим шагом мы будем накладывать эту маску на другой список.
Фильтрация
У нас есть список труб, есть маска. Логично, что из списка труб нам нужно оставить только те, у которых имя системы равно заданному (Т 21 1), то есть в маске стоит значение тру. Для этого нужно подать на нод фильтрации список труб и маску.
Важно! Мы подаём на нод фильтрации не список с именами систем, а список труб. Список с именами систем мы получили, чтобы создать маску через сравнение имён систем с заданным именем (Т21 1).
Что сейчас у нас есть. Есть список из 6 труб. Есть список из имён систем этих труб. Если маска. И вот эту маску я накладываю на список с трубами.
Далее я получаю два списка с элементами на выходах из нода фильтрации. В первом списке «in» у меня элементы, которые получили маску тру. Во втором списке «out» — элементы с маской фолс.
То есть на in я получаю те элементы, который удовлетворяют моим критериям фильтра (имя системы равно «Т21 1»), а на out всё то, что не прошло по критериям. Для этого и нужна маска.
Посмотрите на скриншот выше, элемент в списке, у которого индекс совпадает с индексом тру в маске, уходит в in, остальное — в out.
Если я заменю в Код Блоке имя системы с Т21 1 на Т11 1, то на выходах у меня будут уже другие трубы, так как критерии поменялись. Чтобы заметить разницу, посмотрите на айдишники элементов (зелёные блоки с числами).
Запись значений
Теперь я получил трубы, имя системы которых удовлетворяет моему равенству. Значит, нужно обрабатывать именно эти трубы (в примере это всего одна труба), а всё остальное мне не нужно.
Чтобы сделать это, я возьму элементы с выхода нода фильтрации «in», получу их имена системы и запишу в параметр комментарии.
Эти ноды вам должны быть знакомы по первой статье, ничего нового. Единственная разница, что теперь я обрабатываю те элементы, которые выходят из фильтра. В этом примере это только одна труба.
Можете создать спецификацию в проекте и проверить, что получилось. Гарантирую, что всё сработает. При условии, что вы всё правильно сделали, конечно.
Выводы
- Для фильтрации нам нужен список-маска из значений тру/фолс. Этот список мы как бы накладываем на изначальный список объектов.
- На выходах фильтра мы получаем два списка, в in — те элементы, которые прошли со значением тру, в out — те, что с фолс. Все эти элементы можно и дальше обрабатывать скриптом, всё зависит от задачи.
Визуализировать фильтрацию по маске можно так: представьте, что у вас есть бумажка со списком из 10 позиции и такой же бумажный список-маска к нему. При этом в списке-маске вместо значений true будут прямоугольные прорези. Теперь, если наложить список-маску на исходный список, в прорезях увидим те позиции, которым соответствует true, а скроются те, у которых false. И вот то, что видно, отправится на выход in, а что скрыто — на out.
Другие примеры фильтрации
Всё. Если что-то осталось непонятно, пишите комментарии или задавайте вопросы в Телеграм-чате. Все ссылочки есть ниже.
Чтобы прокачать Ревит-навыки и не пропускать статьи в блоге, подпишитесь на мой Телеграм-канал «Блог Муратова про Revit MEP». Приглашайте коллег и знакомых проектировщиков. Можно обсудить статью и задать вопросы в специальном чате канала.
Отблагодарить автора
Я много времени уделяю блогу. Если хотите отблагодарить меня, то можете сделать небольшой подарок (именно подарок, такой перевод не облагается налогом).
Скачать скрипт из примера можно с Яндекс.Диска.