Найти в Дзене

Метод PickObjects для элементов в связанных файлах, и его проблемы

Оглавление

Всем привет! Сегодня ещё одна небольшая статья про выбор элементов в Ревите с помощью 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 используются дважды. Чтобы это проверить, я написал вот такой макрос:

Мы выбираем элементы, проходимся по ним в цикле, а затем записываем в словарь частоту их появления. Запустим макрос на файле, имеющем связи, и выделим некоторые элементы рамкой:

-2

Некоторые элементы были учтены дважды.

Попробуем сделать тоже самое, но выбирать элементы будем последовательно, кликая на них:

-3

Да, список элементов не тот, но суть мы видим: элементы не задублировались

Что делать

Разумеется, мы не можем никак запретить пользователю выбирать внутри PickObjects рамкой. Так что тут варианта 2:

1. Ещё раз подумать, может быть, стоит изменить логику приложения, чтобы пользователь не выбирал конкретные элементы в связи (может, стоит собрать коллектором их все).

2. Учитывать это в коде, и брать элементы только с уникальным Id. Продумывание реализации этого решения я оставлю на ваше усмотрение.

Заключение

Метод несложный, поэтому и статья короткая. Пишите плагины, обращайте внимание на нюансы и обязательно подписывайтесь на мой телеграм-канал о Revit API. До новых встреч!

За помощь в подготовке публикации я благодарю Александра Онучина, который заметил странности в поведении PickObjects и рассказал о них мне.

-4