Добрый день! Вопрос. Используя windowsInProject =FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).WhereElementIsNotElementType().ToElements() , мы получаем все окна в проекте. Если применить фильтр к ним, например по стадии filtr = windowsInProject.Where(lambda x: x.LookupParameter("Стадия возведения").AsValueString()=="Проект"), на выходе получим элементы в виде Autodesk.Revit.DB.FamilyInstance. Прошу подсказать как их возможно перевести в читабельность?
И еще один вопрос: возможно ли получить Autodesk.Revit.DB.ElementId, если имеем только Id типа(элемента) представленного в формате System.Int64?
PS. На второй вопрос ответ нашел. Нужно входящие элементы анврапнуть и присвоить им команду UnwrapElement(i).GetTypeId().
Запишу, чтобы не забыть. import clr
clr.AddReference("RevitNodes")
import Revit
family=IN[0] # на вход подаем семейство
familyName=family.Name
types = family.Types #получение всех типов семейства без подключения каких-либо библиотек
types = Revit.Elements.Family.ByName(familyName).Types #получение всех типов семейства (по имени семейства) с библиотеками import clr/clr.AddReference("RevitNodes")/import Revit
elements = []
for type in types:
elem = Revit.Elements.FamilyInstance.ByFamilyType(type) #получение всех экземпляров данного семейства (с теми же подключаемыми библиотеками)
elements.append(elem)
OUT = elements
Добрый день!
По сути скрипт написал. Но выяснились особенности марок. По крайней мере марок труб: невозможно получить типоразмер элемента (FamilyInstance.Type), равно как нельзя назначить типоразмер элементу марки (нодом FamilyInstance.SetType). Хотя для других категорий они работают.
Вместо FamilyInstance.Type пришлось применить костыль из 2-х Element.GetParameterValueByName, подав на вход “Тип” и “Имя типа” (для получения имени типоразмера). А вот с назначением типоразмера пока ничего не выходит.
Посоветуйте что-нибудь…
Задача стояла чуть шире.. см. код ниже)) Но твое видео навело на интересную мысль: просто найти все параметры а потом сделать пересечение данных множеств и получить множество параметров которые принадлежат всей коллекции. Хорошо бы теперь все это оформить с помощью хотя бы SlowFilter, а не перебора нерасторопным питоном в лоб))
Уровни слишком специфичный параметр что бы по на его основе фильтровать.. тем >, что для разных семейств он представлен по разному: стены – зависимость снизу и сверху, familySymbol – уровень плюс смещение, и.т.д
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
clr.AddReference("System.Core")
from System.Collections.Generic import List
import System
clr.ImportExtensions(System.Linq)
""" Function region """
def set_of_string(set_string):
name = ' '
for i in set_string:
name += ' ' + str(i)
return name
""" Main region """
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document
collector = FilteredElementCollector(doc)
collector.WhereElementIsNotElementType() # only Instances pass the collector
list_of_categories = [
ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns),
ElementCategoryFilter(BuiltInCategory.OST_Walls),
# ElementCategoryFilter(BuiltInCategory.OST_Floors)
]
logical_filter = LogicalOrFilter(list_of_categories)
collector.WherePasses(logical_filter)
parameter_sets = []
trigger = 0
for element in collector:
try:
parameter_set = set()
for parameter in element.Parameters:
parameter_set.add(parameter.Id)
parameter_sets.append(parameter_set)
print('ok! ' + set_of_string(parameter_set))
except:
print('Error...')
continue
a = set.intersection(*parameter_sets)
print(len(a))
for id in a:
print(id.Value.ToString())
Столкнулась с проблемой при работе скрипта. Пытаюсь расставить элементы (осветительные приборы) с размещением на грани в центре какого-либо помещения на потолке (в моем случае на перекрытие). Я определяю необходимую мне surfase из всего списка поверхностей перекрытия. Точку размещения определяю как центр помещения (пока рассматриваю помещения прямоугольной формы).
При работе в обычном файле без связанных файлов все работает отлично, а как только перехожу в большой проект со связанными файлами, где перекрытия лежат в связи, ревит выдает ошибку и закрывается:
Элементы я получаю из линкового файла через Element.GetFromLinkedFile. Возникает вопрос возможно ли в принципе подобное действие?
Или же все действия по выбору и определению поверхности перекрытия нужно делать внутри этого же питон скрипта в котором осуществляется размещение элементов. Чтобы ревит понимал, что поверхность берется из линкового файла. Если так то тогда как можно определить внутри питона surfase перекрытия? face.append(i.Faces) не работает. AttributeError: ‘Floor’ object has no attribute ‘Faces’
К сожалению, Динамо не обладает особой гибкостью. Стены – это встроенные семейства. И получив такую ошибку я понял, что скорее всего нод не может найти это системное семейство. Через 10 секунд поисков я нашел нод WallType.ByName – работает со стенами. Также есть FloorType.ByName…
Вывод – универсального решения нет (что странно).
С выбором типов любого элемента нет проблем через АПИ (Питон)
П.С.
Почекал лукапом проекты. Действительно, типы семейств хранятся в разных типах объектов.
Все обычные семейства это объект класса “FamilySymbol”
У встроенных семейств свои классы для хранения типов.
WallType, FloorType, CableTrayType и т.п.
Динамо-нод FamilyType.ByName вытягивает только “FamilySymbol”. Метод АПИ GetTypeID – универсален и может получать доступ к любым объектам, описывающим типы.
Так… проверил в Динамо.
familyInstance.Symbol – как ни странно, но получаем не FamilySymbol, а стринг str. – Может быть, это особенность Питона?
У стринга конечно же нету атрибута .Name
Метод извлечения типа через документ работает.
typeId = i.GetTypeId()
type = doc.GetElement(typeId)
Есть макрос для заполнения полей спецификации для revit 2015, но в 2016 он не работает. После поисков причины, выяснилось, что изменились методы get и set, но разобраться сам не могу, прошу помощи.
часть макроса
foreach (Element e in DuctCurves)
{
ElementType e_type = doc.GetElement( e.GetTypeId() ) as ElementType;//Получить экземпляр семейства
m_duct = e_type.get_Parameter(BuiltInParameter.WINDOW_TYPE_ID).AsString();//Получить значение параметра типа семейства “Маркировка типоразмера”
o_duct = e_type.get_Parameter(BuiltInParameter.ALL_MODEL_DESCRIPTION).AsString();//Получить значение параметра типа семейства “Описание”
ds_name = e.get_Parameter(BuiltInParameter.RBS_SYSTEM_NAME_PARAM).AsString();//Получить значение “Имя системы”
err_name = e.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString();
Parameter is_round = e.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);
if (is_round!=null)
{
t_duct = “диаметр мм-“;
}
else
{
t_duct = “сечение мм-“;
}
duct_size = e.get_Parameter(BuiltInParameter.RBS_CALCULATED_SIZE).AsString();//Получить значение параметра типа экземпляра “Размер”
dlina = e.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble();//Получить значение параметра типа экземпляра “Длина”
dlina = UnitUtils.ConvertFromInternalUnits(dlina, DisplayUnitType.DUT_METERS);
e.get_Parameter(“SPКол-во”).Set(dlina);//Установить значение общего параметра экземпляра “Кол-во”
e.get_Parameter(“SPЕдиница измерения”).Set(“м.”);//Установить значение общего параметра экземпляра “Единица измерения”
e.get_Parameter(“SPИмяСистемы”).Set(ds_name);
e.get_Parameter(“SPПодгруппаРаздела”).Set(“2.Воздуховоды”);
ss_name = e.get_Parameter(BuiltInParameter.RBS_DUCT_PIPE_SYSTEM_ABBREVIATION_PARAM).AsString();//Получить значение “Сокращение системы”
switch (ss_name) {
case “В”:
e.get_Parameter(“SPРазделСпецификации”).Set(“Вентиляция. “+ds_name);
break;
case “П”:
e.get_Parameter(“SPРазделСпецификации”).Set(“Вентиляция. “+ds_name);
break;
case “Р”:
e.get_Parameter(“SPРазделСпецификации”).Set(“Вентиляция. “+ds_name);
break;
default:
for point in points:
newobj = doc.Create.NewFamilyInstance(point.ToXyz(),elemTypeSymbol,lvl,StructuralType.NonStructural)
elementlist.append(newobj.ToDSType(False))
TransactionManager.Instance.TransactionTaskDone()
import clr
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
#IN[0] - выбранное в Ревите семейство
#IN[1] Название нужного параметра (строка)
pars_fam_editor=doc.EditFamily(doc.GetElement(UnwrapElement(IN[0]).GetTypeId()).Family).FamilyManager.Parameters
get_formula=[i.Formula for i in pars_fam_editor if i.Definition.Name==IN[1]]
OUT=get_formula