Automation12 мая 20261332 слов

Dynamo и Python: пять сценариев, которые экономят часы

Пять рабочих сценариев с кодом: заполнение параметров из таблицы, проверки по своим правилам, нумерация, выгрузки и сверка. Замеры до и после, типовые поломки.

Dynamo и Python: пять сценариев, которые экономят часы

Нумерация квартир в семнадцатиэтажном доме занимала у инженера почти полный рабочий день: 612 помещений, порядок обхода по часовой стрелке, отдельная логика для секций. Скрипт делает это за 40 секунд. Писали его шесть часов, окупился он на втором доме.

Собрал пять сценариев, которые за последние два года экономили больше всего времени. Каждый с куском кода и с замером: сколько занимало руками, сколько занимает сейчас.

Оговорка сразу: это не универсальные решения, а рабочие заготовки. Под ваши параметры и правила их придётся править, но каркас останется.

Зачем внутри графа Python

Узлами удобно тянуть данные и смотреть промежуточный результат. Как только начинается ветвление, циклы и условия, граф превращается в паутину из полусотни узлов, которую невозможно читать.

Один узел Python Script заменяет эти пятьдесят и работает быстрее: данные не гоняются между узлами, всё считается в одном месте.

Практическое деление у нас такое. Узлами достаём элементы и передаём на вход, внутри питона вся логика, наружу отдаём результат. Граф остаётся из трёх-четырёх блоков и понятен любому, кто его откроет.

Сценарий 1. Заполнить параметры из таблицы

Самая частая задача. Пришла таблица от смежника или от заказчика, в ней марки и характеристики оборудования, надо перенести это в модель.

Руками: 2-4 часа на сотню позиций, плюс опечатки. Скриптом: минута на любой объём.

# IN[0] - элементы, IN[1] - словарь {марка: {параметр: значение}}
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
elementy, tablica = UnwrapElement(IN[0]), IN[1]

TransactionManager.Instance.EnsureInTransaction(doc)
zapisano, propuscheno = 0, []
for e in elementy:
    marka = e.LookupParameter("ADSK_Марка")
    klyuch = marka.AsString().strip() if marka and marka.AsString() else None
    if klyuch not in tablica:
        propuscheno.append(klyuch)
        continue
    for imya, znachenie in tablica[klyuch].items():
        p = e.LookupParameter(imya)
        if p and not p.IsReadOnly:
            p.Set(str(znachenie))
            zapisano += 1
TransactionManager.Instance.TransactionTaskDone()

OUT = zapisano, sorted(set(propuscheno))

Ключевая деталь в последней строке. Скрипт возвращает не только счётчик записей, но и список того, что не совпало. Без этого вы никогда не узнаете, что двенадцать позиций из таблицы не нашли себе элемент в модели.

Второй нюанс это strip(). Пробел в конце строки невидим глазом и рушит сравнение. На реальных таблицах из Excel он встречается постоянно.

Сценарий 2. Проверка модели по своим правилам

Готовые проверки закрывают общие случаи. Требования вашей организации они не знают: что марка обязательна для всех дверей, что помещение без имени публиковать нельзя, что высота установки розеток задана параметром.

Такая проверка пишется на полстраницы и гоняется перед каждой публикацией модели.

# Возвращает список нарушений: элемент, правило, значение
narusheniya = []
for e in UnwrapElement(IN[0]):
    marka = e.LookupParameter("ADSK_Марка")
    if not marka or not (marka.AsString() or "").strip():
        narusheniya.append([e.Id.IntegerValue, "марка пустая", ""])
    vysota = e.LookupParameter("Высота установки")
    if vysota and vysota.AsDouble() <= 0:
        narusheniya.append([e.Id.IntegerValue, "высота не задана", 0])
OUT = narusheniya

Замер по одному из проектов: ручная выборочная проверка перед выдачей занимала у ведущего 3-4 часа и ловила примерно половину проблем. Скрипт проходит модель за полторы минуты и находит всё, что описано правилами.

Дальше список нарушений уходит в CSV или подсвечивается в модели. Второй вариант нагляднее: инженер видит красным свои элементы и правит их сам, без письма от координатора.

Какие правила вообще стоит проверять, зависит от того, что у вас в модели сейчас творится. Отправная точка это чек-лист аудита.

Сценарий 3. Нумерация по маршруту

Помещения, квартиры, стояки, оси. Задача, где ручная работа особенно обидна: полдня кликов, а любое изменение планировки обнуляет результат.

Логика скрипта простая. Берём центры помещений, группируем по уровням, внутри уровня сортируем по углу относительно центра секции, дальше присваиваем номера по формату.

import math
tochki = [(e, e.Location.Point) for e in UnwrapElement(IN[0])]
cx = sum(p.X for _, p in tochki) / len(tochki)
cy = sum(p.Y for _, p in tochki) / len(tochki)
po_uglu = sorted(tochki, key=lambda t: math.atan2(t[1].Y - cy, t[1].X - cx))

Замер: 612 помещений вручную это около шести часов с перепроверкой. Скриптом 40 секунд, и перезапуск после правки планировки стоит ещё 40 секунд.

Важная оговорка. Автоматическая нумерация хороша, пока правило нумерации выражается формулой. Как только появляются исключения вида «а вот эти три квартиры считаем отдельно, так исторически сложилось», скрипт превращается в лоскутное одеяло. Такие исключения лучше оставлять на ручную доводку.

Сценарий 4. Выгрузка ведомости под свой шаблон

Экспорт спецификации из Revit даёт таблицу, которая почти никогда не совпадает с формой заказчика. Дальше инженер полчаса двигает колонки в Excel, и так каждую неделю.

Скрипт собирает данные сразу в нужном виде: те колонки, в том порядке, с теми единицами и с подсчётом итогов.

stroki = []
for e in UnwrapElement(IN[0]):
    t = doc.GetElement(e.GetTypeId())
    stroki.append([
        e.LookupParameter("ADSK_Марка").AsString(),
        t.LookupParameter("Наименование").AsString() if t else "",
        round(e.LookupParameter("Объём").AsDouble() * 0.0283168, 3),  # футы³ в м³
        e.LevelId and doc.GetElement(e.LevelId).Name,
    ])
OUT = sorted(stroki, key=lambda s: (s[3] or "", s[0] or ""))

Обратите внимание на пересчёт объёма. Revit внутри хранит длины в футах, а объёмы в кубических футах, независимо от того, что показано на экране. Забытый коэффициент это классическая ошибка, из-за которой в ведомость уезжают цифры, отличающиеся в 35 раз.

Замер: сбор ведомости объёмов бетона по этажам занимал 40-50 минут ручной работы в Excel. Сейчас три минуты, из которых две уходят на открытие модели.

Сценарий 5. Сверка модели с внешней таблицей

Задача возникает перед выдачей и перед закупкой. Есть модель, есть спецификация от смежника или список оборудования от поставщика. Вопрос один: где расхождения.

Скрипт читает таблицу, читает модель и выдаёт три списка: есть в модели и нет в таблице, есть в таблице и нет в модели, совпадает по марке, но расходится по количеству.

Замер по инженерному разделу среднего объекта: ручная сверка двух списков по 300 позиций занимала около четырёх часов, причём у двух человек результаты не совпадали. Скрипт даёт ответ за две минуты и всегда одинаковый.

Здесь важнее не скорость, а повторяемость. Такую сверку можно гонять каждую неделю, а вручную её делают один раз перед сдачей, когда исправлять уже поздно.

Сколько это экономит за год

СценарийБылоСталоЧастотаЭкономия в год
Заполнение параметров из таблицы3 часа1 минута2 раза в месяцоколо 70 часов
Проверка перед публикацией3,5 часа2 минутыеженедельнодо 160 часов
Нумерация помещений6 часов1 минута4 раза в год на объект24 часа
Ведомость по своей форме45 минут3 минутыеженедельно35 часов
Сверка с внешней таблицей4 часа2 минутыежемесячно45 часов

Числа с наших проектов, у вас будут другие. Правило для оценки: считайте не разовую экономию, а годовую. Операция на десять минут, повторяемая ежедневно пятью людьми, стоит дороже, чем разовая четырёхчасовая.

Что ломается чаще всего

Забытая транзакция. Симптом: скрипт отработал без ошибок, а в модели ничего не изменилось. Любая запись в документ идёт внутри транзакции, чтения это не касается.

Питон не тот. Симптом: рабочий скрипт после обновления Revit выдаёт ошибку импорта. В новых версиях по умолчанию стоит CPython3, старые скрипты писались под IronPython2. Движок переключается в правом верхнем углу окна редактора.

Футы. Симптом: цифры в ведомости отличаются в 3,28 или в 35 раз. Внутренние единицы Revit не совпадают с тем, что показано на экране.

None в списке. Симптом: скрипт падает на середине, часть модели уже изменена. У элемента не оказалось параметра, и обращение к нему уронило цикл. Лечится проверкой перед каждым обращением.

Скрипт съел всю память. Симптом: Revit висит десять минут на модели, где раньше работал за секунды. Обычно внутрь цикла попал запрос к базе, который надо было сделать один раз снаружи.

Как отдать это команде

Файл графа, разосланный по почте, живёт неделю. Дальше у каждого своя копия с правками.

Рабочих варианта два. Скрипт кладут в Dynamo Player: пользователь видит поля ввода и кнопку запуска, а граф не трогает. Либо логика переезжает в кнопку pyRevit на ленте. Что выбрать и когда это окупается, разобрано в сравнении плагина и Dynamo.

В обоих случаях нужен хозяин библиотеки: человек, который ведёт список скриптов, версии и отвечает на вопросы. Без него набор превращается в свалку за полгода.

Где скрипты не помогут

Они не чинят исходные данные. Заполнение параметров из таблицы работает, пока марки в модели и в таблице записаны одинаково. Три варианта написания одной марки уронят любой сценарий, и разбираться придётся руками.

Они не заменяют инженера. Скрипт проставит номера, посчитает объёмы и найдёт пустые поля. Правильно ли подобрано сечение, он не скажет.

Они плохо переживают исключения. Правило с пятью оговорками дешевле выполнить руками, чем описывать кодом и потом поддерживать.

И они не окупаются на разовой работе. Прежде чем садиться за скрипт, посчитайте частоту: меньше 20 часов ручной работы в год, автоматизировать не стоит, если только цена ошибки не высока сама по себе.

Короткие ответы

Нужно ли уметь программировать? Для первых сценариев достаточно уверенного чтения кода и готовности разбираться. Сложное лучше отдать разработчику.

Где смотреть методы API? В официальной документации Revit API и в примерах сообщества. Ещё полезен просмотрщик свойств, он показывает, как параметр называется на самом деле.

Скрипт может испортить модель? Да, запись в документ необратима без отмены. Первые запуски делают на копии файла, это правило без исключений.

Работает ли это в связанных моделях? Читать можно, писать нет. Правки делаются в исходном файле раздела.

Сколько стоит такой скрипт на заказ? Простой сценарий из тех, что выше, это 1-3 дня работы. Точнее считается после разбора вашей модели и параметров.

С чего начать

Выпишите операции, которые команда делает руками каждую неделю, и рядом поставьте минуты. Первая же строка сверху списка и есть ваш первый скрипт.

Начинать лучше с чтения: проверка или выгрузка ничего не портит, а пользу приносит сразу.

Мы пишем такие сценарии под конкретные модели и упаковываем их так, чтобы пользоваться мог весь отдел. Примеры на странице Dynamo-скриптов и в кейсах. Опишите свою рутину через контакты, оценим за день.

Нужен похожий BIM/AI процесс?

Напишите в Telegram или на email — разберём задачу и предложим архитектуру решения.

Telegram Оставить заявку