Просто о BIM
8.63K subscribers
633 photos
101 videos
63 files
713 links
Простым языком об Информационных технологиях в строительстве (BIM)

Автор канала:
Александр Попов @popov_bim

Для общения и связи с авторами: @bimcomments
Download Telegram
#Содержание Просто о BIM @prostobim

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

Часть уже обработал, пробуйте - пишите в комментарии удобно или нет, или что поправить.

#Теория #Практика #Новости #Интриги #ГосТИМ #Стандарты #Классификатор #Подкасты #Деньги #СтроительныеРассказы #IFC #ACC #СуперСистемы #SIGNAL #Образование
#Ссылки #Рейтинги #Autodesk #СтроительствоVSМашиностроение
#Dynamo #Python
👍32🔥1👨‍💻1
#Практика #Dynamo #Python Попробую начать новую рубрику: учимся программировать в Revit с Dynamo

Ставьте лайки если интересно и продолжать настолько практические посты.

Начну с базы.

1. Открываем Revit - ну тут наверно все ясно
2. Открываем Dynamo - на вкладке Управление
3. Вставляем нод Python script - дада остальные ноды вообще непонятно зачем там
4. Вставляем следующий шаблонный код:
#—————Подключение библиотек—————
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
#—————Взятие элементов—————
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
#—————Ссылка на BuiltInCategories: http://www.revitapidocs.com/2018.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm

#—————ВХОДНЫЕ ДАННЫЕ—————
els = UnwrapElement(IN[0])

#—————ОСНОВНАЯ ЧАСТЬ КОДА—————
TransactionManager.Instance.EnsureInTransaction(doc)

TransactionManager.Instance.TransactionTaskDone()
#—————Назначьте вывод переменной OUT—————
OUT = "ok"
👍74🥱10🔥74🏆32❤‍🔥1👏1🗿1
#Практика #Dynamo #Python В чате @bim_help появился вопрос: как получить периметр помещения за вычетом дверных проемов. И недавно я обсуждал с коллегами "как можно считать Плинтуса в отделке если не моделировать?" Решил все таки сесть и покодить.
#—————Подключение библиотек—————
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
#—————Взятие элементов—————
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
doors = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).WhereElementIsNotElementType().ToElements()
#—————Ссылка на BuiltInCategories: http://www.revitapidocs.com/2018.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm

#—————ВХОДНЫЕ ДАННЫЕ—————
els = UnwrapElement(IN[0])

#—————ОСНОВНАЯ ЧАСТЬ КОДА—————
TransactionManager.Instance.EnsureInTransaction(doc)
#-Выбираем только размещенные помещения
roomlist=[]
for room in rooms:
if room.Area > 0:
roomlist.append(room)
#-Проходимся циклом по всем помещениям
for room in roomlist:
id = room.Id
#-Берем периметр у помещения (можно было и LookupParameter("Периметр") но через BuiltIn стабильнее)
P = room.get_Parameter(BuiltInParameter.ROOM_PERIMETER).AsDouble()
#-Проходим циклом по всем дверям и берем только из той же стадии что и Помещения
for door in doors:
phase = doc.GetElement(door.get_Parameter(BuiltInParameter.PHASE_CREATED).AsElementId())
d1 = door.FromRoom[phase]
d2 = door.ToRoom[phase]
#- Бывали ошибки с получением id помещения, потому пока такое нагородил.
try:
id1 = d1.Id
except:
id1=0
try:
id2 = d2.Id
except:
id2=0
if id1 == id or id2 == id:
#-Берем тип и затем ширину двери
W = doc.GetElement(door.GetTypeId()).LookupParameter("Ширина").AsDouble()
#-Вычитаем из Периметра помещения Ширину двери
P = P - W
#-Записываем в параметр Комментарии (можете поменять на другой) полученное в результате обработки значение периметра. Футы переводим в миллиметры домножив на 304.8 и округлив и переводим в текстовый формат, т.к. параметр текстовый. Если сделать параметр с Типом длина, то переводить ни в Миллиметры ни в Текст не нужно.
room.LookupParameter("Комментарии").Set(str(round(P*304.8)))
TransactionManager.Instance.TransactionTaskDone()
#—————Назначьте вывод переменной OUT—————
OUT = "ok"
👍294🏆1
#Практика #Dynamo #Python Продолжу учить тех кто наставил столько лайков данной рубрике. И пройдусь по коду сверху вниз, объясняя что откуда и зачем.

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

Библиотеки - это файлы с расширением dll или py в которых содержатся функции для управления какими-то данными и сервисами. Есть папки дефолтные в которых эти библиотеки ищутся динамой, и если там где-то находятся по имени, то подгружаются. Но если файл библиотеки лежит не в дефолтной папке, то потребуется указать clr’у где еще поискать (потом как-нибудь покажу пример).

import clr

clr - я называю это компилятором, библиотека которая именно тут нужна в динамовском ноде питон, чтобы все остальное работало. Такая местная специфика. Эта библиотека позволяет читать остальные библиотеки.

clr.AddReference('ProtoGeometry')

ProtoGeometry - стандартная библиотека динамо, для работы с геометрией динамо.

from Autodesk.DesignScript.Geometry import *

Из библиотеки ProtoGeometry заходим в группу классов (Пространство имен называется - Namespaces) Autodesk - DesignScript - Geometry и добавляем оттуда все классы, чтобы можно было ими ниже по коду пользоваться. звездочка - * - означает всё.

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

Далее аналогично подгружаем библиотеку RevitAPI - это главная библиотека где все основные методы для работы с элементами в ревите. Если не все то большинство методов с revitapidocs.com находятся в этой библиотеке. Тут взятие свойств, создание элементов, копирования и перемещения и прочее.

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

и завершаем сегодняшний обзор RevitServices и сервисами которые мы оттуда подгружаем - это сервис транзакций и документ менеджера для получения объекта открытого документа.

Про транзакции отдельно напишу.
👍47🔥10🥱52
#Практика #Dynamo #Python Продолжаем разбор кода

doc = DocumentManager.Instance.CurrentDBDocument

в переменную doc записываем текущий открытый документ.

Переменной может быть любой текст не взятый в кавычки, в том числе и на кириллице (но так не делают обычно). Т.е. названия переменных вы придумываете сами - можете d = написать, можете document2 =. Но есть забронированные системные операторы и переменные, типа: and, or, if, else и прочие, которые нельзя брать.

Не рекомендуется также переменные называть как классы в различных библиотеках - Wall, List, Document (иначе ниже по коду эти классы вам могут понадобиться, а уже переменной перезаписаны и вы не будете понимать что случилось). Синтаксис кстати учитывается, т.е. wall занимайте смело.

Для получения открытого документа использум подключенный класс сервиса DocumentManager и используем атрибут из него Instance и затем из полученного результата атрибут - CurrentDBDocument.

Откуда я знаю какие брать атрибуты? я что знаю их наизусть? где посмотреть?

Я обычно копирую подобные команды из предыдущих скриптов, а ищу новые в гугле, просто вводя: Revit Dynamo Python Move element
Revit Dynamo Python Get Type of element

И обычно все методы и атрибуты можно для библиотеки RevitAPI посмотреть на revitapidocs.com

Но для RevitServices и класса DocumentManager там нет описаний методов и атрибутов. Но быстрым поиском в гугле я и такое могу найти, если хочется покопаться и понять весь функционал: https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitServices/Persistence/DocumentManager.cs

Несколько раз уже писал слова атрибуты и методы - они отличаются тем, что атрибуты вызываются без круглых скобок, а методы со скобками после названия команды. Методы могут требовать подачи значений на вход в скобках. Атрибуты кстати тоже, но в квадратных скобках. На самом деле в них разницы не много, в какое-то время аутодеск даже хотел всё на методы перевести, но потом эту идею остановил.

Но идеологически атрибуты нужны для взятия системных свойств у классов, получения состояния экземпляров классов, а методы для выполнения действий - создания, перемещения, удаления и прочего.

В C# документ берется без RevitServices напрямую из Application.ActiveUIDocument.Document, полагаю что в динамо так нельзя, потому подругому делается.
🔥13🥱4👍2
#Практика #Dynamo #Python Продолжаем разбор скрипта

rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()

В переменную rooms записываем все элементы, найденные через FilteredElementCollector из текущего открытого файла, записанного выше в переменную doc. Для получения через коллектор элементов надо указать Категорию через формат OST_Category, указать что только Экземпляры надо брать
WhereElementIsNotElementType()

или Типы
WhereElementIsElementType()

и переводим результат в список элементов.
ToElements()

doors = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).WhereElementIsNotElementType().ToElements()

Аналогично получаем все двери.
els = UnwrapElement(IN[0])

этот метод из шаблона, чисто динамовский, берет на заданную переменную (в данном случае els) значение поданное в Python Script на IN[0] и при этом это значение превращает в ревитовский формат из динамовского функцией
UnwrapElement()

Такая специфика динамо, что все элементы, которые протекли по проводам, надо переводить (разворачивать) в ревитовские элементы, чтобы применять к ним ревитовские
методы.
TransactionManager.Instance.EnsureInTransaction(doc)

Открытие транзакции. Что такое Транзакция? Если совсем просто - это действие в ревите которое можно откатить Ctrl+Z. Т.е. вы объявляете об открытии транзакции, затем накапливаете различные действия внутри транзакции своим кодом, а потом завершаете транзакцию, закрываете ее и применяете.
TransactionManager.Instance.TransactionTaskDone() 

Если транзакция завершилась успешно, то все изменения применяются, если не успешно, то отменилась или выдала ошибку с вопросом "че делать?".

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

Можете заметить что если вы даже внутри цикла начнете открывать транзакции, то через Ctrl+Z вы потом каждый элемент цикла отдельно не сможете отменить в ревите, т.к. сам процесс динамо также имеет транзакцию на общий свой запуск. Это стандартная защита программ от выполнения зацикливания, чтобы просто ошибку выдать или закрыть ее и не увести компьютер в зависание и переполнение памяти.
OUT = "ok"

Это тоже специфика нода динамо, есть выходные значения, они подаются на OUT в самом ноде. Если через запятую выведете несколько значений, то они выведутся списком.
🔥13🥱43👍2❤‍🔥1