Dynamo – Русский – только для чтения
Раздел для программистов и специалистов, использующих Dynamo
отмена
Отображаются результаты для 
Показать  только  | Вместо этого искать 
Вы имели в виду: 

Выбор элементов из разных категорий в Python-е

5 ОТВЕТ 5
РЕШЕНО
Ответить
Сообщение 1 из 6
Grief-rec
2439 просмотров, 5 ответов

Выбор элементов из разных категорий в Python-е

Добрый день!

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

 

Для форума.JPG

 

Заранее, спасибо!

 

5 ОТВЕТ 5
Сообщение 2 из 6
architect.bim
в ответ: Grief-rec

 

Добрый вечер! Не совсем понял, вы работаете через Dynamo или Revit Python Shell. Но в любом случае, вариантов тут может быть несколько. Но как минимум, из самых простых - создать функцию. Тогда можно элементы получать через цикл для списка категорий. Если принципиально, чтобы категория была получена через системное имя, то придется их прописывать вручную. Хотя, если работаете через Dynamo, там можно вообще довольно быстро получать список из нескольких системных категорий.

 

# Создаем функцию
def
 allElements(cat):
    return FilteredElementCollector(doc).OfCategory(cat).WhereElementIsNotElementType().ToElements()

# Создаем или получаем список категорий (не обязательно так, можно подать извне или получить др. способом)    
cats = [BuiltInCategory.OST_Walls,BuiltInCategory.OST_Floors,BuiltInCategory.OST_Rooms]

# Создаем цикл для получения элементов для всех категорий
elems = [allElements(c) for c in cats]

 

 

 


Maxim Stepannikov | Architect, BIM Manager, Instructor
Теги (3)
Сообщение 3 из 6
architect.bim
в ответ: Grief-rec

Другой вариант - создать типизированный список и на его основе фильтр для коллектора.

 

# Список системных категорий
cats = [BuiltInCategory.OST_Walls,BuiltInCategory.OST_Floors,BuiltInCategory.OST_Rooms]
# Преобразование списка в типизированный список
catId = List[BuiltInCategory](cats)
# Создание фильтра по нескольким категориям
catFilt = ElementMulticategoryFilter(catId)
# Применение фильтра к коллектору
elems = FilteredElementCollector(doc).WhereElementIsNotElementType().WherePasses(catFilt).ToElements()

 

 


Maxim Stepannikov | Architect, BIM Manager, Instructor
Теги (3)
Сообщение 4 из 6
architect.bim
в ответ: Grief-rec

Только в последнем случае надо еще и библиотеку System подгрузить, чтобы иметь возможность работать с типизированными списками.

import System
from System.Collections.Generic import *

Maxim Stepannikov | Architect, BIM Manager, Instructor
Теги (3)
Сообщение 5 из 6
Grief-rec
в ответ: architect.bim

Спасибо!

Работаю из Динамо, но пытаюсь постепенно уходить от громоздких конструкций из нодов, создавая один - со скриптом. Следующий шаг - перейти в Visual Studio для создания автономных модулей.

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

Для форума 01.JPG

Чуточку преобразил, ушёл от создания функции (она будет удобна, когда по ходу скрипта нужно будет создать несколько списков. А один раз можно и без неё). Получился такой список элементов, как мне нужен. С ним работать удобнее. Не приходится менять код, который идёт дальше.

Для форума 02.JPG

KElm = [BuiltInCategory.OST_Walls, BuiltInCategory.OST_Doors]
for EL in KElm:
	SElm.extend(FilteredElementCollector(Doc).OfCategory(EL).WhereElementIsNotElementType().ToElements())

Получилось изящнее и меньше строк. Спасибо за подсказку! 

Сообщение 6 из 6
architect.bim
в ответ: Grief-rec

Да, отлично. Ну насчет многоуровневости - да, если нужно плоский, то лучше extend вместо append. Вот пообщался с коллегами, посоветовали одну прикольную штуку - команду exec, которая может выполнять фрагмент кода из строки. Меня смущало, что надо было каждый раз писать BuiltInCategory, с этой командой можно еще короче код сделать. Я пишу одну строку, в которой через запятую указываю OST_Walls,OST_Floors и т.д. Ну а дальше расщепляю и использую exec. =))

elems = []

catNames = 'OST_Walls,OST_Floors,OST_Rooms,OST_Doors'.split(',')

for cn in catNames:
	exec('cat = BuiltInCategory.'+cn)
	elems.extend(FilteredElementCollector(doc).OfCategory(cat).ToElements())

Maxim Stepannikov | Architect, BIM Manager, Instructor
Теги (3)

Не нашли то, что искали? Задайте вопросы в сообществе или поделитесь своими знаниями.

Новая тема  

Autodesk Design & Make Report