Название паттерна у материала
Главная › Форумы › Python › Revit Library (API) › Название паттерна у материала
- В этой теме 10 ответов, 4 участника, последнее обновление 7 лет, 2 месяца назад сделано Анатолий.
-
АвторСообщения
-
Рубрика обмен опытом. )) Меня спрашивают, я отвечаю, а заодно и другим пригодится.
Вопрос: как в Dynamo получить имя паттерна из материала? (в примере ниже, у материала “Dynamo” имя назначенного паттерна “Бетон”)
Далее мои рассуждения.
Первое, создадим схему нодов:
Второе, обязательное, это развернем материал mat = UnwrapElement(IN[0])
Раз речь идет о материале, то неплохо было бы заглянуть в REVIT API, а конкретно следующий путь: RevitAPI / Autodesk.Revit.DB / Material
Я для этого использую бесплатный JetBrains dotPeekНе потнятно, что есть у материала, но нам нужен паттерн. А со словом паттерн только 2 параметра и скорее всего нам нужен SurfacePatternId.
Как следует из названия речь идет не о самом элементе, а о его номере Id в базе проекта.
patternId = mat.SurfacePatternId # это Id паттерна, а не сам паттерн
Чтобы получить сам элемент по его Id номеру, воспользуемся командой:
pattern = doc.GetElement(patternId)
Посмотрим, что мы получили в итоге OUT = pattern
И как видим получили некий FillPatternElementОпять лезем в Revit.DB и ищем FillPatternElement
И скорее всего нам понадобится команда GetFillPattern()
OUT = pattern.GetFillPattern()
Получили FillPattern, опять ищем в Revit.DB
Смотрим большой список разных параметров и свойств и понимаем, что нам скорее всего нужно Name
OUT = pattern.GetFillPattern().Name
В итоге получили, что хотели.
Теперь несколько слов о том, какие библиотеки нужно подключать.
- Мы искали наши параметры, свойства и команды в Revit.DB
значит подключаем
clr.AddReference(‘RevitAPI’) # подключаем основную DLL для работы с REVIT API
from Autodesk.Revit.DB import * # из состава DLL импортируем все из Revit.DB (для простоты, хотя нам нужны были всего 3 директории: Material, FillPatternElement и FillPattern) - По ID номеру элемента мы получали из документа (из его базы) сам элемент, через команду doc.GetElement(), поэтому подключаем DocumentManager следующим кодом:
clr.AddReference(“RevitServices”) # импорт DLL RevitServices
from RevitServices.Persistence import DocumentManager # импорт DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument # doc – текущая база данных документа
Итоговый скрипт выглядит следующим образом:
import clr
clr.AddReference(‘RevitAPI’)
from Autodesk.Revit.DB import *clr.AddReference(“RevitServices”)
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocumentmat = UnwrapElement(IN[0])
patternId = mat.SurfacePatternId
pattern = doc.GetElement(patternId)
OUT = pattern.GetFillPattern().NameУдачи!
АнонимНеактивированныйЗадача у меня несколько аналогичная. Но с наскоку почему-то не решается.
Для начала вопросы:
а) почему нельзя было запросить имя у pattern? Не знаю почему в JetBrains dotPeek такое свойство у FillPatternElement отсутствует. Но, если посмотреть Revit API Help, то у класса FillPatternElement есть свойство Name, унаследованное от класса Element, от которого оно произошло.
б) а можно запросить Name у Material? (я понимаю, что это не для Вашей задачи, но в целом – можно или нет?)
К чему задал вопрос “б”. У меня ситуация следующая. Есть функция, в которую входит параметр (не имя, а сам параметр элемента). Задача функции, в зависимости от типа записи значения, выдать нужное. ValueString имеет приоритет. Но в случае с ElementID хотелось бы выводить также имя элемента, на который указывает этот ID. Однако попытка обратиться к Name, приводит к ошибке “AttributeError:Name”:
def GetSHPValue(paramet):
doc = DocumentManager.Instance.CurrentDBDocument
value = None
try:
tempValue = paramet.AsValueString()
except:
tempValue = None
pass
if tempValue == None:
if paramet.StorageType == StorageType.String:
value = paramet.AsString()
elif paramet.StorageType == StorageType.Integer:
value = paramet.AsInteger()
elif paramet.StorageType == StorageType.Double:
value = paramet.AsDouble()
elif paramet.StorageType == StorageType.ElementId:
id = paramet.AsElementId()
if doc.GetElement(id) != None:
elem = doc.GetElement(id)
id = str(id)+”| |”+elem.GetType().Name
value = id
return value
else:
if paramet.StorageType == StorageType.ElementId:
id = paramet.AsElementId()
if doc.GetElement(id) != None: #про вот эту строчку будет отдельный вопрос ниже
elem = doc.GetElement(id)
id = str(id)+”| |”+elem.GetType().Name+”| |”+elem.Name #вот здесь идёт ошибка относительно elem.Name
tempValue = tempValue +”| |”+id
return tempValueТеперь вопрос про “if doc.GetElement(id) != None:”. Здесь столкнулся со следующим: если Id отрицательный (т.е. ссылается на что-то встроенное в Ревите – категорию и т.п.), то GetElement не работает и выдаёт ошибку “NoneType”. А я хотел бы выводить информацию аналогичную и по категориям и т.п. Как получать доступ к встроенным элементам? (чтобы считать их имя и какие-нибудь ещё свойства).
На вход у меня приходили простые стены. Бралось множество их параметров и передавались в данную функцию. Ошибка именно в ней. При этом среди положительных Id у меня шли материалы, уровни, стадии, типы стен. Исходя из Revit API Help у них у всех есть свойство Name. Не понимаю в чём проблема. Помогите, пожалуйста!
a) попробуй и узнаешь (но, мне нужно было получить имя заливки, а не элемента)
б) можно (в моем случае получил бы “Dynamo”)далее у тебя идет код оч. похожий на заготовку Александра Попова или Сергея Кривого ))
я так и не понял, что тебе нужно получить от стен ?
p.s. иногда NoneType выскакивает потому, что не хватает UnwrapElement
Создай новую тему и приведи пример “на пальцах”, тогда ответ получишь быстрее и точнее.
Прошу прощения, очень интересно где можно узнать в дот пик что надо использовать именно команду doc.GetElement?
(“Чтобы получить сам элемент по его Id номеру, воспользуемся командой:pattern = doc.GetElement(patternId) “)
Почему задаюсь таким вопросом? Пытаюсь из семейства достать существующие типы (особенно их имена), но не могу подобрать подходящую команду..
С помощью GetFamilySymbolIds() получается достать все id типов семейства, есть там и команда GetFamilyTypeParameterValues(ElementId parameterId), но не могу понять что должно быть в кавычках? Хоть возможно это и не та команда, что мне нужна..
В чем суть? Есть некоторая система нодов, с помощью которых получается сделать копию типоразмера некоторого семейства, но это только типоразмер, элементы семейства еще не созданы (в другой теме обсуждали эти моменты, извините, что и здесь затронул те же вопросы). Все вроде хорошо, но при запуске повторно скрипта элементы типоразмеры больше не дублируются. Подумал, что если смогу все прописать на питоне с помощью ForceChildren, после перезапуска будет создаваться необходимое количество типоразмеров (ни больше, ни меньше, по количеству необходимых типоразмеров перемычек, это потом постараюсь прописать в скрипте).
Огромное спасибо, txt!!! Как все просто)))
А посложнее задачу можно решить? Можно как-то добраться до имени структуры стены? Необходимо для того чтобы провести сравнение и создать новые списки с переменными данными, с которыми возможно будет работать дальше.
Если речь идет про имена материалов разных слоев, то вот так:
import clr clr.AddReference('RevitAPI') from Autodesk.Revit.DB import * clr.AddReference("RevitServices") import RevitServices from RevitServices.Persistence import DocumentManager doc = DocumentManager.Instance.CurrentDBDocument str = UnwrapElement(IN[0]).WallType.GetCompoundStructure() num = str.LayerCount layersName = [] for i in range(num): layersName.append(doc.GetElement(str.GetMaterialId(i)).Name) OUT = layersName
Код можно немного сократить (но не забыть про подключаемые библиотеки)
str = UnwrapElement(IN[0]).WallType.GetCompoundStructure()
OUT = [doc.GetElement(str.GetMaterialId(i)).Name for i in range(str.LayerCount)]Большое спасибо за проделанный труд, Антон! Очень назидательно! Но немножко не то. Тема та же, перемычки, нужны именно имена структуры стены (“отделка”, “основа”, “структура” и пр.) Может задача непосильная, конечно, пока не могу ни через Lookup ни через RevitApi правильно подставить значения для сравнения. Конечно, скорее всего, из-за нехватки знаний.
С помощью GetCompoundStructure (и т.д. в моем предыдущем посте) удалось добраться до английских названий структуры, через Object.Type узнаем, что это объект MaterialFunctionAssingment. По идее надо для сравнения или перевести их в объекты другого типа или другим путем сделать такие же объекты. С помощью другого, слишком “заумного” кода (получилось пятикратное повторение почти того же, потому что не смог корректно получить правильный результат, на выходе a,b,c,d,e) добрался до названий структур на русском , но они имеют тип System.String. Пока в поисках и размышлениях, спасибо за помощь!
Как всегда, решение очень простое, просто нужно было прописать содержимое списков через ToString и объекты (Finish 1,Substrate, Structure ..) стали System.String, теперь можно сравнивать, только с списками разберусь, не получается пока нормальным дерево списков сохранить с измененными внутренними названиями.
- Мы искали наши параметры, свойства и команды в Revit.DB
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.