Введение
Я часто видел плагины, которые позволяют провернуть массовое добавление связей, на той же вкладке pyRevit есть такой или у BimStep. Но все они предлагают просто указать сразу несколько .rvt файлов, то есть не подходили для работы с ревит сервером. Думаю, что большинство используют именно RS для хранения моделей.
Получается «спасибо, дура», самого важного-то и не добавили. Сделаем сами:
План
Что мне надо:
- Спросить у пользователя что за объект
- Спросить какие конкретно модели он хочет
- Конвертировать путь из текста в modelpath
- Передать классу который добавляет связь
- Настроить способ размещения (по общим или внутренее начало)
- Обработать ошибки
Начало
1- используется для указания кодировки файла скрипта.
2 - название скрипта или его заголовок.
3 - автора скрипта.
4 - это строка, содержащая документацию или описание скрипта.
9 - импорт необходимых классов и функций из модуля Autodesk.Revit.DB, которые понадобятся для работы со связями в Revit.
13 -импортируем модули pyrevit.script и pyrevit.coreutils, которые предоставляют удобные функции и инструменты для написания сценариев в PyRevit.
14 - импорт функции из сторонего файла который описан в этой статье
15 - импортируем модуль datetime, который позволяет работать с датой и временем.
16 - импортируем модуль os, который предоставляет функции для работы с операционной системой, такие как работа с файловой системой.
17-18 - Эти строки создают объект вывода, который используется для вывода информации из скрипта.
script.get_output().close_others(all_open_outputs=True) закрывает все открытые выводы, чтобы избежать возможных конфликтов.
21 - получаем имя пользователя, который в данный момент использует Revit, и сохраняет его в переменной user.
22 - получаем активный документ Revit и сохраняет его в переменной doc, чтобы можно было обращаться к нему в коде.
21 - Эта строка использует FilteredElementCollector для получения всех экземпляров связей Revit из активного документа doc и сохраняет их в переменной links.
О добавление связей
Есть у нас метод Create класса RevitLinkType который создаст связь в моделе (не разместит, а создат)
Ему нужен:
- doc - документ модели в которую добавляем связь
- modelPath - по своей сути адрес модели которую надо добавить
- RevitLinkOption - настройки размещения связи
с первым и третьим все понятно
Но что там с modelpath - конструктора для него нет и как же тогда его получить. Покопав немного нахожу:
DB.ModelPathUtils.ConvertUserVisiblePathToModelPath
Данный метод возьмет адрес модели в виде строки, а отдаст уже заветный ModelPath
Значит, нам надо подготовить список состоящий из адресов до каждой модели, каждого объекта.
О том как я это реализовал читай в этой статье:
Добавления связей
Опишем функцию add_link
Функция будет вызываться для каждой ссылки и в качестве аргумента получать ее же.
29 - Создаем экземпляр таймера
30 - Получаем имя модели используя метод basename от ссылки на модель и просто пока храним ее, еще пригодится
31 - Конвертим нашу текстовую ссылку в экземпляр класса ModelPath
32 - Создаем экземпляр класса RevitLinkOptions используя первую перегрузку
33,34 - Вызываем 2 варианта размещения связи, они нам потребуются для аргумента ImportPlacement метода Create класса RevitLinkInstance
Данный класс и метод нужны для размещения экземпляров связи.
39 - Создание типаразмера связи (с этим не должно быть никаких ошибок, на всякий случай тоже поместил в try except)
40 - Попытка разместить экземпляр связи по общим координатам
41 - завершаем подсчет времени
42 - вывод информации о том что связь размещена, её имя, id и время которое на это потребовалось
46, 47 - в случае если попытка размещения экземпляра выдало ошибку проверяем, что она связана с отсутствием общей площадки
49 - размещаем связь используй внутреннее начало
50 - завершаем подсчет времени
51 - вывод информации о том что связь размещена, её имя, id и время которое на это потребовалось
56 - если ошибка не была связана с размещением выводим информацию о связи и ошибки
Еще одна функция
Задача данной функции проверить добавлена ли связь с таким же именем в модель.
Отдаем ей имя модели которую пытаемся добавить, она проходится по каждой из имеющихся связей в модели и сравнивает их имена.
Если совпали - вернеет True
MAIN
65 - Эта строка вызывает функцию select_file() из модуля sup, которая открывает диалоговое окно выбора объектов и моделей и возвращает список выбранных ссылок на модели.
66 - проверяем, были ли выбраны связи пользователем. Если список sel_links не пустой начинаем магию
67-68 - выводим принт и разделить (горизонтальная полоска)
69 - создаем объект таймера, который будет использоваться для измерения времени выполнения операций.
70 - обновляем прогресс-бар вывода с нулевым значением прогресса и общим количеством связей для добавления, о нем читаем тут:
71-72 - открываем транзацикцию и стартуем.
73 - происходит итерация по выбранным связям. Переменная i - это индекс текущей связи в списке, а l - сама связь.
74 - получаем имя файла (связи) из полного пути к файлу.
75 - проверяем, не пытается ли пользователь добавить модель в саму себя
79 - вызываем функцию is_there_link(), которая проверяет существует ли уже связь с таким же именем в проекте.
83 - завернув в try except вызываем функцию add_link(l) c аргментов в виде самой ссылки на модель
84 - реагируем на то поймали ли какую-то ошибку
89 - обновляем прогресс-бар
90 - закрываем транзакцию
92 - подсчитываем сколько времени это все заняло
94-94 - печатаем разделитель и время
Таким образом, этот фрагмент кода отвечает за добавление выбранных пользователем связей в проект Revit, с выводом информации о ходе выполнения операции и времени, затраченном на нее.
РЕЗУЛЬТАТ
Результатом работы программы станет вот такое окно и размещенные связи.
Кстати первое: эти вот id кликабельны и при нажатие они выделят связь
Кстати второе: для добавления через этот скрипт не нужно открывать какой-то подходящий вид
P.S.
Несмотря на малое количество строк и низкую сложность, скрипт считаю чисто мастхевом.
P.S.S
Сейчас этот мини скрипт был 100 раз переписан и обзавелся интерфейсом.