Как стать автором
Обновить

Работа с Revit API: устранение рутины при разработке и доставке плагинов

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров206

Каждый bim-специалист сталкивается с необходимостью автоматизации. Многие bim-специалисты приходят к самостоятельному написанию плагинов - модулей для расширения базового функционала ПО. В данной статье рассказано об инструменте, который позволяет исключить рутинные процессы при разработке плагинов для Revit.

Введение

В этой статье будет идти речь о моем инструменте с открытым исходным кодом для работы в ПО Revit: https://github.com/i-savelev/PluginsManager.
Revit - это профессиональное ПО для создания цифровых информационных моделей в строительстве. В силу специфики отрасли, разработкой плагинов для Revit в основном занимаются непрофессиональные программисты. Следствием этого является отсутствие навыков, инструментов и инфраструктуры для разработки - человеку со строительным образованием сложно разбираться с git, совместной разработкой, ci cd, запуском серверов и т.д. Такое могут позволить себе, например, некоторые крупные застройщики, которые имеют в своем составе большие IT подразделения. Но для небольших команд и небольших задач это может быть просто нецелесообразно - слишком много ресурсов будет потрачено на обучение и на внедрение непрофильных инструментов.

Проблема

Плагины для Revit пишутся на языке C# с использованием специальной библиотеки Revit API, которая предоставляется вместе с ПО. Сам плагин представляет из себя сборку dll с библиотекой классов и конфигурационный файл. Все это нужно поместить в определенную папку, чтобы Revit их обнаружил и нарисовал новую панельку с кнопочками. Без инструментов разработки процесс создания плагинов представляет из себя рутину. Опишу основные проблемы на примере наихудшего случая:

  • Как работать совместно? Если в команде разработкой занимаются несколько человек, нужно вручную передавать друг другу части кода или dll файлы для объединения скриптов в один плагин.

  • Как подготовить все для передачи пользователям? Необходимо каждый раз вручную компилировать установщик или, того хуже перекидывать файлы в папку.

  • Как передать обновления и новые файлы пользователям? Необходимо вручную переустанавливать плагин на компьютер каждого пользователя. Особенностью процесса переустановки плагинов для Revit является необходимость перезагрузки программы, что добавляет время ожидания на стороне пользователя. Подробнее про невозможность выгрузки надстроек из Revit можно почитать в статье

  • Как понять, какая версия установлена у пользователя? Следить придется вручную.

Все эти проблемы вроде бы не страшные и не очень сложные, но, напомню, в основном этим приходится заниматься людям без опыта в программировании. Отсюда получается либо много ручной работы, либо неудобные костыли.

Реализация решения

Я решил это вопрос с помощью разработки небольшого инструмента - Plugin Manager. Основная идея позаимствована у инструмента Add-in Manager - популярного инструмента среди bim специалистов, который позволяет с помощью рефлексии запускать команды из .dll файлов и при этом не требует перезапуска Revit. Единственная проблема - данный инструмент имеет чисто "разработческий" интерфейс. Команды в нем имеют названия классов из кода c#, нет никакого разделения и фильтрации. Этот плагин предназначен для тестирования разработчиками и не подходит для использования проектировщиками.

Add-in Manager - популярный плагин для тестирования команд revit api.
Add-in Manager - популярный плагин для тестирования команд revit api.

А идея реализация позаимствована у Jeremy Tammik из его публикации: The Building Coder: Reloading and Debugging External Commands on the Fly.
Если кратко, то реализация с технической стороны выглядит так:

Сначала сборка загружается в виде массива байтов

var assemblyBytes = File.ReadAllBytes(dllFile);
var assembly = Assembly.Load(assemblyBytes);

Далее из этой сборки извлекаются все команды, которые реализуют интерфейс IExternalCommand

IEnumerable<Type> externalCommands = assembly.GetTypes().
	Where(
		type => typeof(IExternalCommand).IsAssignableFrom(type) && !type.IsAbstract
	);

IExternalCommand - это интерфейс Revit API, который должен унаследовать класс, чтобы Revit воспринимал его как выполняемую команду. Сама выполняемая команда должна находится внутри метода Execute, который обязателен для этого интерфейса.

Далее из выбранного типа создается экземпляр команды

IExternalCommand commandInstance = (IExternalCommand)Activator.
    CreateInstance(commandType);

И вызывается стандартный для IExternalCommand метод Execute

Result result = commandInstance.Execute(commandData, ref message, elements);

В окне моего плагина формируется привычная структура с вкладками, иконками, названиями и описанием из команд сборки. Плагин отображает команды из .dll файлов в указанной папке. При этом благодаря File.ReadAllBytes(dllFile) плагин не "занимает" эти файлы, поэтому их можно в любой момент удалить или заменить. Это делает доставку скриптов до пользователей мгновенной и бесшовной - разработчику достаточно загрузить новую сборку в папку на сетевом диске, а пользователю не нужно ничего переустанавливать и перезапускать, достаточно нажать одну кнопку для синхронизации. Т.к. при синхронизации файлы копируются локально, сетевой диск не оказывает влияние на быстродействие.

Plugins Manager
Plugins Manager

Плагин дает возможность гибкой настройки. Для попадания команды в окно необходимо заполнить метаданные (имя, вкладка, описание, изображение). Их можно заполнить двумя способами. В классе программы или в файле настроек config.xml, который располагается рядом с файлами сборок.

Пример полей для настройки прямо в классе:

public static string IS_TAB_NAME => "Название вкладки";
public static string IS_NAME => "Название команды";
public static string IS_IMAGE => "Название проекта.Resources.Название изображения.png";
public static string IS_DESCRIPTION => "Описание";

Пример настройки в файле config.xml

<Commands>
  <Command>
    <CmdCode>Имя проекта.Имя класса</CmdCode>
    <CmdTab>Название вкладки</CmdTab>
    <CmdName>Имя для отображения</CmdName>
    <CmdDescription>Описание команды</CmdDescription>
    <CmdImage>image.png</CmdImage>
  </Command>
</Commands>

Есть возможность вызывать команды из сторонних плагинов, если они не защищены, не имеют зависимостей и, конечно же, их использование не ограничено лицензиями. Для просмотра всех доступных команд в сборках нужно вызвать вспомогательную команду "Показать все команды в папке". Отображаемые имена можно скопировать в файл настроек config.xml в поле CmdCode и вызывать из Plugin Manager.

Также плагин поддерживает настройки для конкретного пользователя. Например, если поменять в файле %appdata%/PluginsManager/config.xml поле <Post>с user на manager, пользователю станут доступны вкладки с решеткой "#" в названии. Таким образом можно "прятать" от пользователей команды, которые находятся в разработке или предназначены для использования только bim специалистами.

Подробнее о том, как настроить панели, описание, отображение картинок, кастомизировать окружение для отдельного пользователя можно прочитать в описании к репозиторию проекта: https://github.com/i-savelev/PluginsManager. Там же есть установочные файлы и исходный код. В папке "sample_dll" находится файл c настроенными под плагин командами. На нем можно протестировать работу.

Таким образом Plugins Manager позволяет:

  • Легко объединять плагины: если разработкой занимается несколько специалистов, каждый может просто загружать свой .dll файл в сетевую папку.

  • Убрать необходимость компилировать установочные .exe или .msi файлы.

  • Избавится от постоянных переустановок. Достаточно закинуть файлик в общую папку

  • Не париться о версиях. Актуальная всегда доступна по нажатию одной кнопки

  • Добавлять команды из сторонних плагинов.

    Все это без потери комфорта для пользователей и без необходимости внедрять хитрые системы автоматизации.

Теги:
Хабы:
0
Комментарии0

Публикации

Ближайшие события