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

14/05/2015

Еще раз о списке элементов инженерной системы

Я уже писал о том, как можно получить список элементов инженерной системы, а также об улучшении алгоритма.

Однако, как оказалось, на реальном проекте с множеством систем и сотней тысяч элементов, данный поиск занимает ну очень много времени, так как фильтрация по значению параметра, относится к классу, так называемых медленных фильтров или низко производительных.

После этого стал искать другой способ как это можно сделать быстрее.

В процессе поиска я открыл DotPeek чтобы изнутри взглянуть на методы класса MEPSystem. Из интересного я обнаружил защищенный метод getElementsInNetwork(), который по названию звучит как «то что нужно»

 

Первой мыслью было с помощью рефлексии вызвать этот метод. Однако, воспользовавшись функцией поиска использования метода в том же DotPeek, мы видим, что этот метод используется в методе MechanicalSystem.DuctNetwork() и PipingSystem.PipingNetwok(), который являются публичными.

 

Таким образом, все оказалось довольно просто. Нужно было искать не в базовом классе, в наследуемых. Правда непонятно, для чего нельзя было создать один метод типа MEPSystem.SystemNetwork(). Видимо это связано с электрикой, так как там структура данных совсем другая.

Ну а пока же нам просто нужно вызывать нужный метод для трубопроводов или механизмов в отдельности.

Еще раз проверим на тестовом примере из первой статьи:

 

Выполним такой код:

Код - C#: [Выделить]
  1.                     
  2.             filteredElementCollector = new FilteredElementCollector(doc);
  3.             systems =
  4.                 filteredElementCollector
  5.                     .OfClass(typeof (MechanicalSystem))
  6.                     .ToElements();
  7.  
  8.             sb = new StringBuilder();
  9.  
  10.             foreach (MechanicalSystem system in systems)
  11.             {              
  12.                 sb.AppendLine(string.Format("{0}: {1} Type: {2}; Количество элементов: {3}",
  13.                     system.Id,
  14.                     system.Name,
  15.                     system.GetType().Name,
  16.                     system.DuctNetwork.OfType<Element>().Count()));
  17.  
  18.                 foreach (Element element in system.DuctNetwork)
  19.                 {
  20.                     sb.AppendLine(string.Format("    {0}: {1} Тип: {2}",
  21.                     element.Id,
  22.                     element.Name,
  23.                     element.GetType().Name));
  24.                 }
  25.  
  26.             }
  27.  
  28.             TaskDialog.Show("Systems", sb.ToString());

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

 

Автор: Виктор Чекалин

Обсуждение: http://adn-cis.org/forum/index.php?topic=2704

Опубликовано 14.05.2015