Найти в Дзене

Автоматическая маркировка элементов в Revit API

Оглавление

Ранее я уже немного писал про оформление с помощью API, а именно — о простановке размеров: здесь и здесь. Сегодня же поговорим про автоматическое создание марок, и заодно посмотрим на возможную реализацию некоторых фич плагинов с окнами.

Введение

Вообще, Revit позволяет нам автоматически маркировать элементы командой "Маркировать всё". Но у команды есть минусы: например, нельзя отфильтровать элементы или сдвинуть марки. Попробуем сегодня написать плагин, который будет расставлять марки, сдвигать их на выбранную величину и создавать выноску. Фильтровать элементы я не буду, а буду брать все элементы категории на активном виде. Если вам нужно, то для себя вы можете сделать какую угодно фильтрацию (а здесь ещё раз о фильтрации).

Задача

Создадим приложение, в котором будем выбирать из списка нужную категорию для маркировки. После выбора категории выберем из второго списка подходящую для неё марку, назначим горизонтальное и вертикальное смещение в миллиметрах, а также укажем, хотим ли мы делать выноску, и создадим марку по нажатию кнопки запуска

Окно плагина
Окно плагина

Решение

Одна из неприятных проблем этой задачи: категория не знает о том, к какой категории относятся её марки. То есть стены не знают, что их маркируют Марки стен, и так далее.

Поэтому я покажу вам своё решение этой проблемы, но если вы придумаете более элегантное, обязательно пишите его в комментарии

Примерно тоже самое можно сделать с помощью Dictionary, но я создам отдельный класс, который будет хранить 3 свойства:

  • Имя для пользовательского интерфейса
  • Категория, которую маркируем
  • Марку этой категории
-2

А во ViewModel будем инициализировать список этих объектов так, как нам надо. Для примера я заполню его дверями и окнами:

-3

Дальнейшее заполнение ViewModel я сделаю с помощью библиотеки Community.Toolkit.Mvvm. Если вы ранее не писали оконные приложения на WPF, настоятельно рекомендую ознакомиться с циклом статей про WPF, чтобы понимать, что происходит.

Хотя код по созданию марки будет понятен и без знаний по WPF, так что не спешите закрывать статью.

Итак, заполним нашу ViewModel. У нас будет 2 списка: список CategoryMapper, который я указал выше, для выбора категории; список типов марок для этой категории. Также у нас будет запоминаться выбранный CategoryMapper и выбранный тип марки. И 3 переменных для параметров марки: горизонтальное и вертикальное смещение и строить ли выноску:

-4

Но тут сразу возникает вопрос: а что мы будем отображать во втором списке, если поменяется выбранная категория? Для этого я использую partial метод, создаваемый генератором код в Community.Toolkit.Mvvm:

-5

Этот метод вызывается тогда, когда у нас меняется активный маппер в UI.

На самом деле, можно и вручную также сделать, без генераторов кода, тогда у вас изменится блок set у свойства, что-то типа такого:

public CategoryMapper ActiveMapper
{
get => _activeMapper;

set
{
_activeMapper= value;
OnActiveMapperChanged(value);
OnPropertyChanged();
}
}

Таким образом, у нас каждый раз при смене категории будет меняться предлагаемый список марок.

Осталось только написать команду. Она будет довольно простой, чтобы не усложнять статью:

-6

Какие нюансы тут стоит учесть:
1. Марка по умолчанию ставится с присоединённым концом, по этому в строке 75 я меняю его на свободный.

2. Хотя я назначаю точку положения марки при создании на строке 72, это не особо работает, поэтому я добавляю явное указание на 76 строке.

Вообще, Revit API 2023 предоставляет большой арсенал работы с марками. Что мы можем сделать (ссылка на класс, все методы и свойства внутри):

  1. Добавить к марке элементы (AddReferences), чтобы у одной марки было несколько выносок, или удалить их (RemoveReferences)
  2. Объединить выноски (MergeElbows).
  3. Установить точку присоединения выноски(SetLeaderEnd), точку её излома (SetLeaderElbow) и точку расположения марки (TagHeadPosition).
  4. Повернуть марку (RotationAngle)

В общем, простор для автоматизации маркировки довольно большой. Однажды я даже писал такой плагин:

  • От элемента мы имеем 4 четверти, куда можно сдвинуть марку: вверх влево, вниз влево, вверх вправо, вниз вправо.
  • По очереди в одной транзакции ставим марки в каждое из 4 положений
  • Создаём Outline по марке и ищем число пересекающихся с маркой элементов
  • Переносим марку в положение с наименьшим числом пересечений

Хотя код получился сложный и не всегда рабочий, но марки в разные стороны он раздвигал неплохо. Пробуйте, изучайте тему, может быть, создадите что-то интересное — обязательно делитесь в комментарии результатами.

А это марки, сдвинутые плагином их этой статьи
А это марки, сдвинутые плагином их этой статьи

Ну а у меня на этом всё. Смотрите код из этой в моём репозитории на GitHub, не забывайте подписываться на мой телеграм-канал и до новых встреч!

-8