Найти в Дзене

pyRevit. Как работать со связями через Revit API

Скажу честно — раньше я думал, что работать с элементами в связанных моделях в Revit скриптом это как пытаться гладить кота через стекло: и вроде рядом, и вроде видно, но тронуть нельзя. Спойлер: можно. Главное — знать подход. Когда ты подключаешь связанный файл в Revit, он как бы и здесь, но как бы и не здесь. Это отдельный Document, а все элементы внутри — чужие. Поэтому простая конструкция типа: doc = __revit__.ActiveUIDocument.Document walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).ToElements() ...не покажет тебе ничего из связанного файла. Потому что doc — это твоя текущая модель. Все связи в Revit — это RevitLinkInstance. Чтобы добраться до чужих элементов, сначала надо найти сами инстансы связи: from Autodesk.Revit.DB import RevitLinkInstance link_instances = FilteredElementCollector(doc).OfClass(RevitLinkInstance).ToElements() А дальше магия: for link in link_instances: linked_doc = link.GetLinkDocument() # вот он, чужой doc — с ним и работаем Тепе
Оглавление

Жду вас в моем ТГ

pyRevit | BIM. Илья Нистратов

🔄 Работа с элементами в связанных файлах: Revit и немного магии pyRevit

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

🧠 В чём прикол Revit-связей?

Когда ты подключаешь связанный файл в Revit, он как бы и здесь, но как бы и не здесь. Это отдельный Document, а все элементы внутри — чужие. Поэтому простая конструкция типа:

doc = __revit__.ActiveUIDocument.Document

walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).ToElements()

...не покажет тебе ничего из связанного файла. Потому что doc — это твоя текущая модель.

🚪 Заходим через RevitLinkInstance

Все связи в Revit — это RevitLinkInstance. Чтобы добраться до чужих элементов, сначала надо найти сами инстансы связи:

from Autodesk.Revit.DB import RevitLinkInstance

link_instances = FilteredElementCollector(doc).OfClass(RevitLinkInstance).ToElements()

А дальше магия:

for link in link_instances:

linked_doc = link.GetLinkDocument() # вот он, чужой doc — с ним и работаем

Теперь ты можешь делать FilteredElementCollector(linked_doc) — и собирать хоть стены, хоть виды, хоть кошек, если они в модели.

🚪 Пример: ищем все двери в выбранных связях

from Autodesk.Revit.DB import BuiltInCategory

for link in selects_link:
linked_doc = link.GetLinkDocument()
if linked_doc:
doors = FilteredElementCollector(linked_doc)\
.OfCategory(BuiltInCategory.OST_Doors)\
.WhereElementIsNotElementType()\
.ToElements()
for door in doors:
print(door.Name)

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

⚠️ Важное

  • Ты не можешь изменять элементы в связанных документах.
  • Только читать. Проверять. Анализировать.

⚠️ Что может пойти не так

  • Связь не загружена — linked_doc будет None

🛠 Маленький лайфхак

  1. Если хочешь собрать всё в одну таблицу (например, список всех воздуховодов из всех моделей) — используй print_table из моего другого гайда, он тебе пригодится.
  2. Подготовь себе форму для выбора документа из связанных моделей.

🧙 Удобная форма взаимодействия с doc связей

Revit может показывать в проекте связи, которые на самом деле не загружены (файл не найден, путь потерян, и т.д.). Такие связи дадут None, и при попытке получить элементы всё упадёт.

Поэтому перед подачей в список фильтруем их.... а давайте вообще сделаем форму которая будет:

  • Считывать у документа связи
  • Проверять на доступность
  • Выдавать форму выбора с нормальными именами
  • Возвращаться документ выбранных связей
-2

Код тут

📌 Выводы

Работа с связками — это как работа с соседями: уважай границы, но знай, как постучаться. Через RevitLinkInstance, немного кода и SelectFromList можно сделать настоящую автоматизацию, не открывая десять моделей подряд.