Название паттерна у материала

Главная Форумы Python Revit Library (API) Название паттерна у материала

Помечено: ,

В этой теме 10 ответов, 4 участника, последнее обновление  Анатолий 11 мес., 3 нед. назад.

Просмотр 11 сообщений - с 1 по 11 (из 11 всего)
  • Автор
    Сообщения
  • #4989 Score: 7

    Legantmar
    Хранитель
    449 pts

    Рубрика обмен опытом. )) Меня спрашивают, я отвечаю, а заодно и другим пригодится.

    Вопрос: как в 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

    В итоге получили, что хотели.

    Теперь несколько слов о том, какие библиотеки нужно подключать.

    1. Мы искали наши параметры, свойства и команды в Revit.DB
      значит подключаем
      clr.AddReference(‘RevitAPI’) # подключаем основную DLL для работы с REVIT API
      from Autodesk.Revit.DB import * # из состава DLL импортируем все из Revit.DB (для простоты, хотя нам нужны были всего 3 директории: Material, FillPatternElement и FillPattern)
    2. По 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.CurrentDBDocument

    mat = UnwrapElement(IN[0])
    patternId = mat.SurfacePatternId
    pattern = doc.GetElement(patternId)
    OUT = pattern.GetFillPattern().Name

    Удачи!

    #6763 Score: 0

    stqwer
    Участник

    Задача у меня несколько аналогичная. Но с наскоку почему-то не решается.

    Для начала вопросы:

    а) почему нельзя было запросить имя у 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. Не понимаю в чём проблема. Помогите, пожалуйста!

    #6765 Score: 0

    Legantmar
    Хранитель
    449 pts

    a) попробуй и узнаешь (но, мне нужно было получить имя заливки, а не элемента)
    б) можно (в моем случае получил бы “Dynamo”)

    далее у тебя идет код оч. похожий на заготовку Александра Попова или Сергея Кривого ))

    я так и не понял, что тебе нужно получить от стен ?

    p.s. иногда NoneType выскакивает потому, что не хватает UnwrapElement

    Создай новую тему и приведи пример “на пальцах”, тогда ответ получишь быстрее и точнее.

    #6874 Score: 0

    Анатолий
    Участник
    14 pts

    Прошу прощения, очень интересно где можно узнать в дот пик что надо использовать именно команду doc.GetElement?

    (“Чтобы получить сам элемент по его Id номеру, воспользуемся командой:pattern = doc.GetElement(patternId) “)

    Почему задаюсь таким вопросом? Пытаюсь из семейства достать существующие типы (особенно их имена), но не могу подобрать подходящую команду..

    С помощью GetFamilySymbolIds() получается достать все id типов семейства, есть там и команда GetFamilyTypeParameterValues(ElementId parameterId), но не могу понять что должно быть в кавычках? Хоть возможно это и не та команда, что мне нужна..

    #6877 Score: 3

    txt
    Модератор
    91 pts

    Покажите ,что подаете на IN[1] ?

    Пытаюсь из семейства достать существующие типы (особенно их имена), но не могу подобрать подходящую команду..



    types=[i for i in IN[0].Types]
    types_name=[i.Name for i in IN[0].Types]
    OUT = types, types_name

    #6878 Score: 0

    Legantmar
    Хранитель
    449 pts

    #6881 Score: 0

    Анатолий
    Участник
    14 pts

    В чем суть? Есть некоторая система нодов, с помощью которых получается сделать копию типоразмера некоторого семейства, но это только типоразмер, элементы семейства еще не созданы (в другой теме обсуждали эти моменты, извините, что и здесь затронул те же вопросы). Все вроде хорошо, но при запуске повторно скрипта элементы типоразмеры больше не дублируются. Подумал, что если смогу все прописать на питоне с помощью ForceChildren, после перезапуска будет создаваться необходимое количество типоразмеров (ни больше, ни меньше, по количеству необходимых типоразмеров перемычек, это потом постараюсь прописать в скрипте).

     

    Огромное спасибо, txt!!!  Как все просто)))

    #6893 Score: 0

    Анатолий
    Участник
    14 pts

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

     

    #6894 Score: 3

    Legantmar
    Хранитель
    449 pts

    Если речь идет про имена материалов разных слоев, то вот так:

     

    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)]

    #6895 Score: 0

    Анатолий
    Участник
    14 pts

    Большое спасибо за проделанный труд, Антон! Очень назидательно! Но немножко не то. Тема та же, перемычки, нужны именно имена структуры стены (“отделка”, “основа”, “структура” и пр.) Может задача непосильная, конечно, пока не могу ни через Lookup ни через RevitApi правильно подставить значения для сравнения. Конечно, скорее всего, из-за нехватки знаний.

    С помощью GetCompoundStructure (и т.д. в моем предыдущем посте) удалось добраться до английских названий структуры, через Object.Type узнаем, что это объект MaterialFunctionAssingment. По идее надо для сравнения или перевести их в объекты другого типа или другим путем сделать такие же объекты. С помощью другого, слишком “заумного” кода (получилось пятикратное повторение почти того же, потому что не смог корректно получить правильный результат, на выходе a,b,c,d,e) добрался до названий структур на русском , но они имеют тип System.String. Пока в поисках и размышлениях, спасибо за помощь!

     

    #6897 Score: 0

    Анатолий
    Участник
    14 pts

    Как всегда, решение очень простое, просто нужно было прописать содержимое списков через ToString и объекты (Finish 1,Substrate, Structure ..) стали System.String, теперь можно сравнивать, только с списками разберусь, не получается пока нормальным дерево списков сохранить с измененными внутренними названиями.

Просмотр 11 сообщений - с 1 по 11 (из 11 всего)

Для ответа в этой теме необходимо авторизоваться.