EN
RuBIM.tech
RuBIM.tech
14 subscribers
goals
0 of 100 paid subscribers
Как только наберется более 100 подписчиков, я пойму что эта тематика интересна и появится стимул публиковать больше статей.

Знакомство с Revit API, Методы получения элементов. часть 2

Ранее мы познакомились с конструктором класса FilteredElementCollector, подробно останавливаться на нём не будет, это тема отдельной статьи, а рассмотрим следующий вариант, когда пользователь выбрал элементы и нам надо с ними уже провзаимодействовать.
Для это нам понадобится обратится к классу Selection к его методу GetElementIds
Selection - это класс представляющий собой объект, который позволяет взаимодействовать с выбранными элементами в пользовательском интерфейсе Revit. Он предоставляет информацию о том, какие элементы выбраны пользователем, и позволяет выполнять различные операции с этими выбранными элементами.
GetElementIds() - метод для получения ElementId выбранных элементов в виде списка.
Класс находится в пространстве имен Autodesk.Revit.UI, то необходимо вначале обратиться к ActiveUIDocument, а после к Selection 
строчка кода для получения списка ElementId будет выглядеть следующим образом:
Но так лучше не писать, во первых это долго читать, во вторых если еще раз ниже по коду придется обращается к ActiveUIDocument, то и писать тоже долго.
Так гораздо лучше. Что мы тут видим? А видим то что имя uidoc ссылается на объект ActiveUIDocument, можно также сказать что переменная uidoc содержит в себе объект ActiveUIDocument.
"=" - это оператор присвоения, то есть имени(переменой)  uidoc присвоено значение в виде объекта ActiveUIDocument, заметьте что a=5, это не означает что переменная с именем "а" равно значению пяти, а означает то, что через имя "а" можно получить объект с типом данных int имеющее значение пять, проще говоря а это объект типа целое число значение которого 5
Имя - это идентификатор объекта, модуля, класса, функции, переменной, ссылки
Для нубов кратко: все объекты программы хранятся в оперативной памяти, память в свою очередь разбита на ячейки в которых они хранятся. Считайте что имя - это код который нужен что бы открыть постамат и забрать свою посылку(объект).
Выполним код в RPS, попробуем получить список и узнать сколько элементов в списке.
С первыми двумя строками  разобрались, давайте дальше.
Через встроенную функцию - len()языка python, передав ей объект lst_elementIds, получили объект, на который будет ссылать имя count_elements_in_lst_elementIds("переменной с именем count_elements_in_lst_elementIds присвоили значение в виде объекта с типом данных int, значение которому присвоила функция, вернув нам результат своей работы в виде объекта имеющем значения, которое она вычислила")
Если для вашей версии версии Revit не удалось установить  RevitPythonShell, то вот код для Dynamo.
Рассмотрим этот данный код, видим что для решение аналогичной задачи необходимо импортировать дополнительные модули и добавить ссылки на определённые библиотеки(RevitAPI.dll, RevitServices.dll), а так же иначе получаем доступ к ActiveUIDocument.
Модуль - это файл, который содержит программный код, который можно использовать в других программах. Модули помогают организовать и структурировать код, разбивая его на более мелкие и независимые части. Это один из фундаментальных механизмов модульности и повторного использования кода в больших программных проектах.
DLL
(Dynamic Link Library)
- это файл библиотеки, который и содержит
необходимые классы и методы.
Импортирование и добавление ссылки на библиотеки .NET в IronPython
происходит через модуль clr (Common Language Runtime)
Добавить добавляет на .NET сборку с именем "RevitAPIUI" можно
воспользовавшись методом AddReference из модуля clr.
Продолжим писать код далее, получим элементы для дальнейшего взаимодействия с ними.
Чтобы не перебирать весть список в цикле for можно было бы воспользоваться срезом lst_elementIds[:5], но так бы мы получили только шесть первых элементов списка(отсчёт с нуля, поэтому 5 указывает на шестой элемент в списке). В примере используется условие выхода из цикла когда index счётчика будет больше 5, enumerate() организовал индексацию
Итак получили элементы с Pipe всё понятно, этот класс указывает что пользователь выделил, трубы, обратите внимание на наследование классов  
Видно что Element является основным, а MEPCurve родительским, и он родитель также не только труб, но и воздуховодов, лотков, коробов.
FamilyInstance - это класс загружаемых семейств, посмотрите для кого он является родительским.
Теперь отфильтруем, отдельно будем работать с трубами, отдельно с их соединительными деталями.
Объявили счётчик другим образом, создали функции для обработки труб и соединительных деталей, функция for_fittings просто объявления.
Встроенной функцией 
isinstance() определили принадлежность элемента к классу.
Для того что бы дальше отфильтровать элементы принадлежащие классу FamilyInstance необходимо определить их категории. 
FamilyInstance наследник Element, и унаследовал свойства элемента, обратимся к свойству Category и воспользуемся методом GetHashCode()
element_category_code = element.Category.GetHashCode()
element_category_code примет целочисленное значение, пошли смотреть в RevitLookUp какое это число для категории "Соединительные детали трубопроводов"
Логика основного кода проста, заключается в переборе списка и фильтрации, но список получаем от пользователя, если он ничего не выбрал, то список будет пустой и циклом перебирать нечего будет.
Необходимо уведомить пользователя, о том что он не выбрал элементы.
Это можно реализовать реализовать с помощью метода Show из TaskDialog
Также по завершению работы скрипта покажем пользователь сообщение.
Прежде чем приступить к реализации функции get_pipe_title_and_length, давайте вначале разберемся какими способами можно получить параметр у элемента.
Использовать метод LookupParameter, который позволяет получить параметр по его имени, его лучше использовать для пользовательских параметров, для встроенных параметров нужно использовать метод get_Parameter в который нужно передать BuiltInParameter.
Типы параметров:
1. Встроенный параметр
2. Общий параметр
3. Параметр проекта
4. Параметр семейства
5. Глобальный параметр
Почему не рекомендую использовать LookupParameter для всех параметров:
1. Встроенные параметры изменяют своё имя в зависимости от языка Revit.
Метод вернёт вам вместо параметра None.
2. У одного и того же элемента может быть несколько параметров с одинаковыми наименованиями. Создание общего параметра "Уровень" в элементе, параметра проекта с таким же именем и даже создание аналогичного параметра внутри семейства не представляет никаких проблем. Всем этим параметрам можно назначить разные типы данных и единицы измерения.
Метод вернёт первый найден в коллекции Parameters по указанному имени
Типы данных параметров.
1. Действительное число (float) AsDouble()
2. ElementId AsElementId()
3. Целое число (int)  AsInteger()
4. Строка (strAsString()
5. Строковое представление значения параметра (str)  AsValueString()
Свойство параметра  StorageType позволяет узнать какой тип данных хранит параметр, а свойство  IsReadOnly - доступность на изменения.
Revit Lookup - незаменимый инструмент, воспользуемся им что бы узнать необходимые встроенные имена параметров. 
Посмотрим на функции которые вызывает основной код
посмотрим на весь код
и проверим его работу
В следующей попробуем заставить пользователя выбрать элементы.

Subscription levels

Читатель

$ 5,4 per month
Считаешь что контент полезен, подпишись и поддержи автора и сможешь читать больше статей.

Продвинутый читатель

$ 16 per month
С этим уровнем подписки уже можно будет читать полный цикл статей про разработку инструментов.

Нетерпеливый читатель

$ 32 per month
С этим уровнем вы раньше всех сможете читать ещё неопубликованные статьи для других подписчиков, а также будет доступен исходный код из статей.
...

Пытливый читатель

$ 54 per month
С этим уровнем сможете вступить в закрытый телеграмм чат.
Go up