Метод Intersect в плагине C# под Ревит не создает пересечение коллекций. Подскажите, почему?
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > Метод Intersect в плагине C# под Ревит не создает пересечение коллекций. Подскажите, почему?

Метод Intersect в плагине C# под Ревит не создает пересечение коллекций. Подскажите, почему?

Ответ
Поиск в этой теме
Непрочитано 05.09.2023, 10:39 #1
Метод Intersect в плагине C# под Ревит не создает пересечение коллекций. Подскажите, почему?
AlexV
 
Инженер
 
С-Пб
Регистрация: 02.10.2008
Сообщений: 3,696

В "selects" - текущий выбор юзера. В "rebarAlls" - коллекция объектов модели, отфильтрованная по определенным параметрам. Обе коллекции содержат элементы, проверил по id - пересекающиеся элементы есть. Отчего жеж итоговое rebars.count у меня всегда получается ноль? : )


Код:
[Выделить все]
UIDocument uidoc = cmdData.Application.ActiveUIDocument;
IList<Element> selects = uidoc.Selection.GetElementIds().Select(x => doc.GetElement(x)).ToList();
IList<Element> rebarAlls = GetRebarElements(doc);
string str1="";
foreach (Element element in selects)
 {
  ElementId id = element.Id;
str1 = str1 + id.ToString() + "\n";
}
str1 = str1 + "\n" + "\n";
foreach (Element element in rebarAlls)
{
ElementId id = element.Id;
str1 = str1 + id.ToString() + "\n";
}
rebars = selects.Intersect(rebarAlls).ToList();
TaskDialog.Show("RebarSketch", str1);

***
List<Element> GetRebarElements(Autodesk.Revit.DB.Document doc)
 {
  List<Element> rebars = new List<Element>();
  FilteredElementCollector colRebar = new FilteredElementCollector(doc).OfClass(typeof(Rebar)).WhereElementIsNotElementType();
  rebars.AddRange(colRebar.ToElements().Where(x => x.LookupParameter("ЭскизВкл").AsInteger() == 1).ToList());

  FilteredElementCollector colRebarC = new FilteredElementCollector(doc).OfClass(typeof(RebarContainer)).WhereElementIsNotElementType();
  rebars.AddRange(colRebarC.ToElements().Where(x => x.LookupParameter("ЭскизВкл").AsInteger() == 1).ToList());

  FilteredElementCollector sc = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructConnections).WhereElementIsNotElementType();
  rebars.AddRange(sc.ToElements().Where(x => x.LookupParameter("Форма") != null));

  return rebars;
  }
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
Просмотров: 1616
 
Непрочитано 05.09.2023, 11:39
#2
trir


 
Регистрация: 18.12.2010
Сообщений: 5,114


Цитата:
проверил по id - пересекающиеся элементы есть
возможно потому что это разные объекты

Цитата:
Находит пересечение множеств, представленных двумя последовательностями, используя для сравнения значений компаратор проверки на равенство по умолчанию.
trir вне форума  
 
Автор темы   Непрочитано 05.09.2023, 12:00
#3
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,696


Цитата:
Сообщение от trir Посмотреть сообщение
возможно потому что это разные объекты
Но как они могут быть разными, если element.Id одинаковые?
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Непрочитано 05.09.2023, 12:20
1 | #4
trir


 
Регистрация: 18.12.2010
Сообщений: 5,114


разные транзакции - разные element, это ведь просто обёртки
trir вне форума  
 
Автор темы   Непрочитано 05.09.2023, 13:15
#5
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,696


Цитата:
Сообщение от trir Посмотреть сообщение
разные транзакции - разные element, это ведь просто обёртки
А, понятно.. блин, то есть Intersect ом их так просто не поженить.. : D
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Непрочитано 05.09.2023, 13:39
#6
trir


 
Регистрация: 18.12.2010
Сообщений: 5,114


можно получить список Id как int и работать с ними
trir вне форума  
 
Автор темы   Непрочитано 05.09.2023, 15:05
#7
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,696


Цитата:
Сообщение от trir Посмотреть сообщение
можно получить список Id как int и работать с ними
Вот так сделал, вроде работает..

Код:
[Выделить все]
using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ME.Functions
{
    public class ElementEqualityComparer : IEqualityComparer<Element>
    {
        public bool Equals(Element x, Element y)
        {
            if (ReferenceEquals(x, y))
                return true;
            if (x is null || y is null)
                return false;
            return x.Id == y.Id;
        }

        public int GetHashCode(Element obj)
        {
            return obj.Id.GetHashCode(); 
        }
    }
}
...

rebars = rebarAlls.Intersect(selects, new ElementEqualityComparer()).ToList()

Offtop: спасибо 2м форумам и одному жпт-чат-боту : D
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Непрочитано 05.09.2023, 15:58
#8
iliorik


 
Регистрация: 03.10.2009
Сообщений: 735


Как я понял твой макрос должен выдать id элементов армирования, которые находятся в выбранном элементе.
Видимо Rebar не совсем элементы. ElementIntersectsElementFilter тоже тут не сработает
Посмотри решение по ссылке - https://www.revitapidocs.com/2017.1/...c02c2769d7.htm
Без преобразования в GeometryObject и Curve мне кажктся не обойтись
Еще можно через rebar_element.Local as LocalPoint попробовать. Но там тоже поколдовать придётся
__________________
Черточки и точки на плоскости - лишь посредник между идеей проекта и его физическим воплощением

Последний раз редактировалось iliorik, 05.09.2023 в 16:00. Причина: уточнил задачу
iliorik вне форума  
 
Автор темы   Непрочитано 05.09.2023, 18:38
#9
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,696


Цитата:
Сообщение от iliorik Посмотреть сообщение
Как я понял твой макрос должен выдать id элементов армирования, которые находятся в выбранном элементе.
Видимо Rebar не совсем элементы. ElementIntersectsElementFilter тоже тут не сработает
Посмотри решение по ссылке - https://www.revitapidocs.com/2017.1/...c02c2769d7.htm
Без преобразования в GeometryObject и Curve мне кажктся не обойтись
Еще можно через rebar_element.Local as LocalPoint попробовать. Но там тоже поколдовать придётся
Offtop: "Мопед " макрос не совсем мой. Я только объявление часть кода переписываю.
"id элементов армирования, которые находятся в выбранном элементе" - не, id элементов армирования само по себе мне не нужно - эти строчки я прилепил, что б сравнить id объектов, которые попадают в две разные коллекции (одна - собирается из находящихся в модели элементов категорий несущая арматура и соединения несущих конструкций по фильтрам, другая - выбор юзера). Я думал, что раз id одинаковые, то и объекты тоже. Оказалось, нет.

Мне объяснили, что
Цитата:
"Intersect для корректной работы требуется чтобы в типе были переопределены методы Equals, GetHashCode. Класс Element этого не делает. Значит, нужно создать класс реализующий IEqualityComparer<Element> и передать его в метод Intersect."
Вобщем, класс я такой сочинил, и все вроде заработало, как хотелось.
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Непрочитано 06.09.2023, 11:55
#10
iliorik


 
Регистрация: 03.10.2009
Сообщений: 735


Цитата:
Сообщение от AlexV Посмотреть сообщение
Мне объяснили, что
Цитата:
"Intersect для корректной работы требуется чтобы в типе были переопределены методы Equals, GetHashCode. Класс Element этого не делает. Значит, нужно создать класс реализующий IEqualityComparer<Element> и передать его в метод Intersect."
Вобщем, класс я такой сочинил, и все вроде заработало, как хотелось.
Хорошее решение.
__________________
Черточки и точки на плоскости - лишь посредник между идеей проекта и его физическим воплощением
iliorik вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > Метод Intersect в плагине C# под Ревит не создает пересечение коллекций. Подскажите, почему?



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему так непопулярен Ревит? Написатель Revit 1497 26.11.2014 09:59
Подскажите литературу по определение КПУ Mr_Churs Поиск литературы, чертежей, моделей и прочих материалов 2 20.11.2013 15:39
Подскажите плиз, ести ли программка которая из выбранного элемента чертежа создает новый файл? vkoap Программирование 13 05.06.2013 18:51
Подскажите метод надежной идентификации примитива в чертежа между разными сессиями swkx Программирование 7 06.02.2013 10:40
Подскажите пожалуйста почему не работает этот лисп-код выборки строк из таблиц? lexluther LISP 1 02.09.2009 21:43