Сообщество программистов Autodesk в СНГ

ADN Club => Revit API => Тема начата: Пашин Евгений от 07-12-2015, 09:26:23

Название: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 09:26:23
Доброе утро!

Подскажите, пожалуйста, как определить количество экземпляров семейства по его имени или ID в проекте? Хотя бы алгоритм.

Цель: перебрать все экземпляры (и их параметры) семейств и сформировать на базе этой информации отчеты.

P.S.: Пробовал перебрать все FamilyInstance, но затруднения вызвало то, что не все экземпляры определяются.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Антон Останин от 07-12-2015, 10:13:55
Евгений,
 var famInstances = new FilteredElementCollector(doc).OfClass(typeof (FamilyInstance)).ToList();
вот так не все экземпляры возвращает?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:15:30
Сейчас опробую )


К сожалению, тоже самое!!!

Крыши как не видел, так и не видит.

Попробую видео быстренько сварганить...
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 10:21:29
Евгений, через FilteredElementEollector в любом случае.
Код - C# [Выбрать]
  1.                         var collector = new FilteredElementCollector(ActiveUIDocument.Document);
  2.                        
  3.                         ElementId familyId = new ElementId(12345);
  4.                        
  5.                         var instances =
  6.                                 collector
  7.                                 .OfClass(typeof(FamilyInstance))
  8.                                 .OfType<FamilyInstance>()
  9.                                 .Where(fi=>fi.Symbol.Family.Id == familyId);
  10.                        
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 10:23:09
Крыши как не видел, так и не видит.
Крыши это системное семейство. Для них другой алгоритм.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Антон Останин от 07-12-2015, 10:24:28
Крыши это случайно не класс RoofBase?
Тогда их нужно иначе искать.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 10:25:02
Каждое системное семейство в API представлено своим классом. В общем виде не получится извлечь. Для крыш будет так:
Код - C# [Выбрать]
  1.                         var collector = new FilteredElementCollector(ActiveUIDocument.Document);
  2.                                                                
  3.                         var roofs =
  4.                                 collector
  5.                                 .OfClass(typeof(RoofBase))
  6.                                 .WhereElementIsNotElementType();
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:25:42
Крыши это системное семейство. Для них другой алгоритм.

Так, а вот на этом месте можно поподробнее?

Дело в том, что я вижу практически все экземпляры семейств, могу даже категории семейств определять, но вот именно крышу не вижу в списке. А какие еще семейства я не могу увидеть?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:26:32
Каждое системное семейство в API представлено своим классом. В общем виде не получится извлечь. Для крыш будет так:
Код - C# [Выбрать]
  1.                         var collector = new FilteredElementCollector(ActiveUIDocument.Document);
  2.                                                                
  3.                         var roofs =
  4.                                 collector
  5.                                 .OfClass(typeof(RoofBase))
  6.                                 .WhereElementIsNotElementType();

Попробую... один момент.


Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:33:18
Великолепно!

А есть еще какие-то семейства, определяемые таким же образом?

Похоже стен тоже нет.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 10:37:44
А есть еще какие-то семейства
Все системные семейства - стены, перекрытия, крыши, воздуховоды, трубы, кабельные лотки... Возможно еще что то упустил. Для каждого из таких семейств есть свой класс в API
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:42:50
Все системные семейства - стены, перекрытия, крыши, воздуховоды, трубы, кабельные лотки... Возможно еще что то упустил. Для каждого из таких семейств есть свой класс в API

Да уж ))) Так и есть! Ответ, в принципе получен. Спасибо, Виктор!

Для определения экземпляров стен это выглядит так:

Код - C# [Выбрать]
  1.                         var collector = new FilteredElementCollector(ActiveUIDocument.Document);
  2.                                                                
  3.                         var roofs =
  4.                                 collector
  5.                                 .OfClass(typeof(Wall))
  6.                                 .WhereElementIsNotElementType();

А есть где-нибудь перечень всех системных семейств и названия их классов?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:47:49
Возможно еще что то упустил

Если только перила )))
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 10:50:13
А есть где-нибудь перечень всех системных семейств и названия их классов?
Списка такого вроде нет. Первое что пришло в голову - вот так:
Код - C# [Выбрать]
  1.         var systemFamilies =
  2.                 collector
  3.                 .WhereElementIsNotElementType()
  4.                 .Where(e=>!doc.GetElement(e.GetTypeId()) is FamilySymbol)
  5.                 .Select(e=>typeof(e))
  6.                 .Distinct()
  7.                 .ToList();
Т.е. берем все элементы, смотрим, чтобы их тип не являлся объектом класса FamilySymbol, т.е. системным.
Код не проверял. Здесь будет только список тех системных классов, экземпляры которых присутствуют в документе.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 10:51:42
Попробую... один момент!
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 11:06:17
Не могу врубиться, что такое «e»?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 11:07:52
Мне сначала нужно сделать выборку элементов и для каждого элемента выполнить этот код?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 11:10:30
Не могу врубиться, что такое «e»?
Лямбда-выражения (https://msdn.microsoft.com/ru-ru/library/bb397675.aspx).
В данном случае это объект класса Element, так как collector возвращает список объектов класса Element
Мне сначала нужно сделать выборку элементов и для каждого элемента выполнить этот код?
Нет, выполнить как есть
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 11:15:59
Правильно ли я понимаю, что сначала нужна эта строка:

Код - vb.net [Выбрать]
  1. Dim collector As FilteredElementCollector = New FilteredElementCollector(Doc.Document).OfClass(GetType(Element))
  2.  

А затем:

Код - vb.net [Выбрать]
  1.             For Each el As Element In collector
  2.  
  3.                 ' Здесь Ваш код, который я пока переписать на VB не могу )))
  4.  
  5.             Next
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 07-12-2015, 11:21:46
Правильно ли я понимаю, что сначала нужна эта строка:

Код - vb.net: [Выделить]
Dim collector As FilteredElementCollector = New FilteredElementCollector(Doc.Document).OfClass(GetType(Element))
 
Нет. Она просто лишняя. New FilteredElementCollector(Doc.Document) и так уже возвратит коллекцию Element.

' Здесь Ваш код, который я пока переписать на VB не могу )))
Гуглитть по словам Linq VB.NET :) записать это вроде можно на vb.net
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 07-12-2015, 11:40:14
Гуглитть по словам Linq VB.NET  записать это вроде можно на vb.net

Задача на засыпку?  :)

Я первый раз имею дело с LINQ!

А есть какое-нибудь решение, только проще ? )))

Не получается пока.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Андрей Фазлеев от 08-12-2015, 12:22:26
С Linq-запросами очень рекомендую разобраться,
в документации есть пример использования.
Незаменимый инструмент для работы со списками.

По вопросу темы - можно сначала получить все элементы, являющиеся объектами модели

описано здесь: http://adn-cis.org/izvlechenie-vsex-elementov-modeli.html

а затем перебирать их по типу элемента
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 08-12-2015, 12:36:30
Этим и займусь )
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 09-12-2015, 11:10:16
Усложню задачу, нужно узнать сколько экземпляров каждого типа семейства , количество типов не ограниченно.
То есть допустим есть список значения какого нибудь параметра семейства:
ширина=[300, 300,500,500,1000,100,100,100]
тут видно что есть экземпляры с одинаковым типом, единственное что я придумал это сортировка по одинаковым значениям , но проблема в том что таких параметров десятки
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 09-12-2015, 11:45:58
Усложню задачу, нужно узнать сколько экземпляров каждого типа семейства , количество типов не ограниченно.
То есть допустим есть список значения какого нибудь параметра семейства:
ширина=[300, 300,500,500,1000,100,100,100]
тут видно что есть экземпляры с одинаковым типом, единственное что я придумал это сортировка по одинаковым значениям , но проблема в том что таких параметров десятки

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

А сортировку вести по списку, взятому из FamilySymbolSet! Там этот список уже готов, просто считай количество )
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 09-12-2015, 11:57:50
Усложню задачу, нужно узнать сколько экземпляров каждого типа семейства
Очевидно, что нужно узнать тип каждого экземпляра, и посчитать количество в разрезе типов.
Поможет LINQ и группировка:
Код - C# [Выбрать]
  1.                         var collector = new FilteredElementCollector(ActiveUIDocument.Document);
  2.                          
  3.             var instances =
  4.                 collector
  5.                 .OfClass(typeof(FamilyInstance))
  6.                 .OfType<FamilyInstance>()
  7.                 .GroupBy(fi=>fi.GetTypeId())
  8.                 .Select(g=> new {ElementTypeElementTypeId = g.Key, ElementType = doc.GetElement(g.Key) as ElementType, Instances = g.ToList()})
  9.                 .ToList();
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 09-12-2015, 12:11:21
Если это так, то можно у данного семейства проверить список FamilySymbolSet, если справочник не обманывает )))
в 2016 эта коллекция удаленна ((
Autodesk.Revit.DB.FamilySymbolSet

Правильно ли я Вас понимаю, что речь идет об одном и том же семействе, просто у семейства имеются множество (список) типоразмеров с разными значениями свойств?
не только разные значения но и разные типы семейства , тоесть значения могут совпадать абсолютно все но это другой тип.
Очевидно, что нужно узнать тип каждого экземпляра, и посчитать количество в разрезе типов.
ну да в принципе , так и иду :
detail = collector2.OfClass(FamilyInstance).ToElements()
detail2 = collector2.OfType(FamilyInstance).ToElements()
Поможет LINQ и группировка:
спасибо , будем гуглить тогда и разбираться :) думал что есть в самом API что то чтобы не изобретать велосипед.......
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 09-12-2015, 12:54:30
detail = collector2.OfClass(FamilyInstance).ToElements()
detail2 = collector2.OfType(FamilyInstance).ToElements()
в коде между detail и detail2 разницы нет:)

думал что есть в самом API что то
Так вроде и нет велосипеда:) Используется API в чистом виде без всяких велосипедов для удовлетворения ваших нужд. Для этого API и нужно. Какой вы метод ожидали в API? GetAllFamilySymbolsWithInstances?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 09-12-2015, 15:52:01
detail = collector2.OfClass(FamilyInstance).ToElements()
detail2 = collector2.OfType(FamilySymbol).ToElements()
а так ? :)
Так вроде и нет велосипеда:)
ну я увидел LINQ и у меня сразу возник перед глазами такой хороший циклокрос ) я так понимаю это множественный критерий сортировки, тогда в  Python нужно еще почитать как это реализуется
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 09-12-2015, 15:58:20
detail = collector2.OfClass(FamilyInstance).ToElements()
detail2 = collector2.OfType(FamilySymbol).ToElements()
а так ?
А так вижу, что напрямую collector2.OfType(FamilySymbol) лучше не применять. В этом случае фильтрация идет не средствами Revit, а выбираются абсолютно все элементы и после этого с помощью LINQ идет фильтрация.
Ну и собственно не очень понятно что хотели этим добиться.

ну я увидел LINQ и у меня сразу возник перед глазами такой хороший циклокрос ) я так понимаю это множественный критерий сортировки, тогда в  Python нужно еще почитать как это реализуется
LINQ это не велосипед, а инструмент, которым как и любым другим надо правильно уметь пользоваться.

Без LINQ -  выбираете все элементы, затем в цикле перебираете все элементы, для каждого элемента получаете его тип и в какой нибудь словарик помещаете количество экземпляров каждого типа.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 09-12-2015, 16:03:29
я не говорю что это велосипед , я просто изначально даже не знал про это , поэтому и подумал что это нечто сложное
А так вижу, что напрямую collector2.OfType(FamilySymbol) лучше не применять.
не спорю , это пока что мысли
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 09-12-2015, 16:09:40
поэтому и подумал что это нечто сложное
В целом идея такова. Метода, который бы выдал нам количество экземпляров конкретного типа - нет. Но есть все, для того чтобы это посчитать.
Варианта 2.
1) Либо мы сначала берем все экземпляры, который нам нужны, затем группируем их по типу. Как группируем - с помощью LINQ или циклами - не важно.
2) Если у нас есть список типов, для которых мы хотим посчитать количество экземпляров, то с помощью FilteredElementCollector в цикле выбираем все экземпляры заданного типа и соответственно берем их количество.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Пашин Евгений от 10-12-2015, 06:32:25
В целом идея такова. Метода, который бы выдал нам количество экземпляров конкретного типа - нет. Но есть все, для того чтобы это посчитать.
Варианта 2.
1) Либо мы сначала берем все экземпляры, который нам нужны, затем группируем их по типу. Как группируем - с помощью LINQ или циклами - не важно.
2) Если у нас есть список типов, для которых мы хотим посчитать количество экземпляров, то с помощью FilteredElementCollector в цикле выбираем все экземпляры заданного типа и соответственно берем их количество.

Изначально так и думал делать.
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 10-12-2015, 17:37:03
проблема в том что список не постоянный , туда может залетать "сам" любой тип семейства.

Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 11-12-2015, 09:38:49
проблема в том что список не постоянный , туда может залетать "сам" любой тип семейства.
Тогда вариант 1
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 11-12-2015, 10:50:53
отсортировал используя
p=Parameter
p=windows.LookupParameter("номер типа")
    if (p == None):
        continue
a=p.GetType
далее в цикле заношу все значения типов в список и этот список сортирую методами Python и получаю список количества типов данного семейства из:
ElementCategoryFilter
правильно я понял ?
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 11-12-2015, 10:58:22
теперь проблема другого порядка !
есть список типов каждого экземпляра [2, 3, 4, 5, 5, 5, 2, 2, 2, 1, 1, 2, 2]
всего 13 экземпляров и 5 типов
значения параметров типа:
например ширина=[4.79002624671916, 3.937007874015748, 5.905511811023622, 2.2965879265091864, 5.905511811023622]
например высота=  [3.838582677165354, 3.838582677165354, 3.838582677165354, 3.838582677165354, 3.838582677165354]
как связать количество экземпляров типа с параметрами каждого типа , ведь в данный момент 2 тип есть и в начале и в конце списка , если их отсортировать то не факт что первые значения параметров будут соответствовать 2 типу
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: Виктор Чекалин от 11-12-2015, 11:29:09
как связать количество экземпляров типа с параметрами каждого типа
Я абсолютно не понял зачем их связывать. Одинаковые типы имеют одинаковые параметры. Соответственно тот тип 2, который есть в начале, будет иметь те же самые параметры, что и типы 2 в самом конце. Потому что это один и тот же объект (тип)
Название: Re: Как подсчитать количество экземпляров семейства в проекте?
Отправлено: miko от 11-12-2015, 11:33:57
вы правы , пока писал понял как решить проблему, нужно просто для списка типов каждого экземпляра [2, 3, 4, 5, 5, 5, 2, 2, 2, 1, 1, 2, 2]
 написать алгоритм перебора данного списка с помощью for и def . Вопрос решен :)