Всем привет! Сегодня ещё одна небольшая статья про выбор элементов в Ревите с помощью API.
Итак, мы хотим выбрать несколько элементов в связанном файле. Мы можем легко это сделать вот таким образом:
var references = uidoc.Selection.PickObjects(ObjectType.LinkedElement);
Теперь элементы можно выбирать рамкой, можно по одному, как пожелаете. Не забудьте в конце нажать "Готово" на панели под панелью инструментов Ревита. Но что с этим делать дальше?
Метод PickObjects возвращает нам список объектов класса Reference. Если мы, как обычно, попробуем просто получить элемент с помощью GetElement, то у нас, скорее всего, ничего не выйдет: во-первых, на каком документе получать (надо на связанном), во-вторых, у каждой Reference будет одинаковый ElementId, равный Id экземпляра связи.
Поэтому, чтобы получить элемент, нам нужно сделать 2 действия:
1. Получить связанный документ, выбрав RevitLinkInstance, подав в GetElement значение из свойства ElementId. Затем мы получим документ через GetLinkDocument
2. Чтобы получить элемент в связанном документе, нам надо сделать так:
linkDoc.GetElement(reference.LinkedElementId);
Теперь с элементом можно проводить нужные манипуляции.
Проблемы с выбором связанных элементов рамкой
А теперь самое интересное. При выборе элементов рамкой (не тыкая в каждый, а забирая целиком), мы получаем дублирование некоторых элементов. Некоторые Id используются дважды. Чтобы это проверить, я написал вот такой макрос:
Мы выбираем элементы, проходимся по ним в цикле, а затем записываем в словарь частоту их появления. Запустим макрос на файле, имеющем связи, и выделим некоторые элементы рамкой:
Некоторые элементы были учтены дважды.
Попробуем сделать тоже самое, но выбирать элементы будем последовательно, кликая на них:
Да, список элементов не тот, но суть мы видим: элементы не задублировались
Что делать
Разумеется, мы не можем никак запретить пользователю выбирать внутри PickObjects рамкой. Так что тут варианта 2:
1. Ещё раз подумать, может быть, стоит изменить логику приложения, чтобы пользователь не выбирал конкретные элементы в связи (может, стоит собрать коллектором их все).
2. Учитывать это в коде, и брать элементы только с уникальным Id. Продумывание реализации этого решения я оставлю на ваше усмотрение.
Заключение
Метод несложный, поэтому и статья короткая. Пишите плагины, обращайте внимание на нюансы и обязательно подписывайтесь на мой телеграм-канал о Revit API. До новых встреч!
За помощь в подготовке публикации я благодарю Александра Онучина, который заметил странности в поведении PickObjects и рассказал о них мне.