Странное поведение методов UnionWith, IntersectWith в FilterElementCollector

Автор Тема: Странное поведение методов UnionWith, IntersectWith в FilterElementCollector  (Прочитано 1783 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн А.BalmАвтор темы

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Добрый день!
  Столкнулся со странным поведением при вызове методов UnionWith, IntersectWith в классе FilterElementCollector.
Когда параллельно создаются 2 или более коллектора, которые фильтруются через .WhereElementIsElementType() или .WhereElementNotIsElementType() вызов метода UnionWith() или IntersectWith(), такое ощущение, что инвертирует фильтр .WhereElement(Is, IsNot)ElementType() на противоположный:


Фрагмент кода для теста:
Код - C# [Выбрать]
  1. var fecWalls = new FilteredElementCollector(doc)
  2.     .WhereElementIsElementType()
  3.     .OfCategory(BuiltInCategory.OST_Walls);
  4. PrintCollector(fecWalls, "Walls");
  5.  
  6. var fecColumns = new FilteredElementCollector(doc)
  7.     .WhereElementIsElementType()
  8.     .OfCategory(BuiltInCategory.OST_StructuralColumns);
  9. PrintCollector(fecColumns, "Columns");
  10.  
  11. fecWalls.UnionWith(fecColumns);
  12. PrintCollector(fecWalls, "Result");

функция PrintCollector группирует по имени элементы в коллекторе и выводит их количество в каждой группе, а так же выводит Id типа элемента ([element].GetTypeId()) для первого элемента в группе, что бы проверить является ли найденный элемент типом или экземпляром, если типом, то Id = -1


Вывод PrintCollector: видно, что fecWalls и fecColumn содержат типы элементов, Result - уже экземпляры.
--* EVENTS *--
   Collector Walls has 4 elements:
      Name: Витраж 1 - 1 item, Id: -1
      Name: APMV_НС 200 (B25 W4 F150) - 1 item, Id: -1
      Name: APMV_Пилон 250 (Бетон B25) - 1 item, Id: -1
      Name: APMV_Пилон 200 (Бетон B25) - 1 item, Id: -1
   Collector Columns has 2 elements:
      Name: C120.30-8 (B25 W4 F150) - 1 item, Id: -1
      Name: C120.35-8 (B25 W4 F150) - 1 item, Id: -1
   Collector Result has 679 elements:
      Name: APMV_НС 200 (B25 W4 F150) - 116 items, Id: 612036
      Name: APMV_Пилон 250 (Бетон B25) - 39 items, Id: 2408247
      Name: APMV_Пилон 200 (Бетон B25) - 51 items, Id: 2408249
      Name: C120.30-8 (B25 W4 F150) - 473 items, Id: 2516913



Код - C# [Выбрать]
  1. var fecWalls = new FilteredElementCollector(doc)
  2.     .WhereElementIsNotElementType()
  3.     .OfCategory(BuiltInCategory.OST_Walls);
  4. PrintCollector(fecWalls, "Walls");
  5.  
  6. var fecColumns = new FilteredElementCollector(doc)
  7.    .WhereElementIsNotElementType()
  8.     .OfCategory(BuiltInCategory.OST_StructuralColumns);
  9. PrintCollector(fecColumns, "Columns");
  10.  
  11. fecWalls.UnionWith(fecColumns);
  12. PrintCollector(fecWalls, "Result");


--* EVENTS *--
   Collector Walls has 206 elements:
      Name: APMV_НС 200 (B25 W4 F150) - 116 items, Id: 612036
      Name: APMV_Пилон 250 (Бетон B25) - 39 items, Id: 2408247
      Name: APMV_Пилон 200 (Бетон B25) - 51 items, Id: 2408249
   Collector Columns has 473 elements:
      Name: C120.30-8 (B25 W4 F150) - 473 items, Id: 2516913
   Collector Result has 6 elements:
      Name: Витраж 1 - 1 item, Id: -1
      Name: APMV_НС 200 (B25 W4 F150) - 1 item, Id: -1
      Name: APMV_Пилон 250 (Бетон B25) - 1 item, Id: -1
      Name: APMV_Пилон 200 (Бетон B25) - 1 item, Id: -1
      Name: C120.30-8 (B25 W4 F150) - 1 item, Id: -1
      Name: C120.35-8 (B25 W4 F150) - 1 item, Id: -1


Кто то еще с этим сталкивался? Я как то неправильно понимаю суть FilterElementCollector? Или так и должно быть?
« Последнее редактирование: 21-01-2020, 17:00:25 от А.Balm »

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
И в чём же странность?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А.Balm,
Напоминаю про правильное форматирование кода на форуме!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн А.BalmАвтор темы

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Странность в том что объединяя 2 коллектора с элементами, я ожидаю получить все элементы из 2-х объединяемых, а вместо этого получаю типы этих(?) элементов.

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Или так и должно быть?

Неа, видимо баг.

Вообще, рекомендую использовать LogicalAndFilter и LogicalOrFilter. Хотя для задачи, описываемой выше вполне подойдет ElementMulticategoryFilter

Оффлайн А.BalmАвтор темы

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Спасибо, так и правда намного лучше и быстрее работает.
Один только не смог фильтр создать по материалам из которых состоит семейство. Идея возникла следующая: отнаследоваться от ElementFilter или одного из его наследников и создать свой ElementMaterialFilter. Только не понятно как это реализовать (какие методы реализовывать и как). Есть ли какие то примеры или советы на эту тему?

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
отнаследоваться от ElementFilter или одного из его наследников и создать свой ElementMaterialFilter

О наследовании классов из Revit API забудь. Revit API - тонкая прослойка между управляемым кодом Addin-а и native самого Revit-а.

Вариантов 2 - первый - отфильтровать по максимум исходные элементы, а дальше перебором. Второй - создать ведомость материалов или взять готовую. Спецификация - это вид, по ней можно создать FilteredElementCollector с помощью конструктора, принимающего id вида:
Код - C# [Выбрать]
  1. public FilteredElementCollector(
  2.         Document document,
  3.         ElementId viewId
  4. )

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