Найти тему
Хроники Георга

Renga API & Dynamo Core. Часть 1 - понятие документа, пакетные операции экспорта в IFC и вывод чертежей

Оглавление
Дисклеймер: правовая сторона вопроса до конца не ясна, публикую как есть без некоторых частей (см. концовку).

Autodesk Dynamo в общем случае является OpenSource решением со своим Community, разработанный (?) под эгидой Autodesk. Dynamo поставляется как так называемая Core версия (open-source часть) и Core+"Internal" версия (под ряд продуктов Autodesk).

Здесь же ссылки на последующие части

«Renga API & Dynamo Core. Часть 2 - интерфейсы, константы, свойства, чтение свойств; выборка объектов модели и их свойства».

«Renga API & Dynamo Core. Часть 3 - создание новых свойств, присвоение объектам, транзакции».

«Renga API & Dynamo Core. Часть 4 - объекты, уровни, стили отображения и COM-типизация данных».

«Renga API & Dynamo Core. Часть 5 - геометрия объектов, общие выводы»

Примечание: "Internal" - это сугубо моё название, в реальности оно называется как-то по другому.

Пример версии под Civil 3D
Пример версии под Civil 3D
Пример  только-Core версии
Пример только-Core версии

К чему я веду? К возможности подключения Core-версий к иным САПР, не на платформе Autodesk. Собственно говоря, Core-версия ни к какой САПР не привязана, это самостоятельное приложение.

Всё, что нам нужно - это подключить к Dynamo библиотеку, которая будет инициализировать API конкретной САПР. При этом реализация процесса будет состоять из двух важных частей:

  • инициация подключения к САПР из-под Dynamo, в основном, как к COM-объекту (выстраивание логики процесса САПР, пространств модели и пр.);
  • написание отдельных методов, позволяющих получать свойства/создавать что либо в пространстве модели данной САПР.

Как правило, самый *** - это понять как "дружить" Dynamo и процесс САПР с поправкой на то, что Dynamo не воспринимает интерфейсы и некоторые синтаксические конструкции языка типа ref, out и пр. Тут же он не любит, чтобы методы имели значения по умолчанию нестандартных типов (отличных от базовых типов .NET).

Ах да, совсем забыл - Dynamo написан на .NET (C# ), поэтому мы будем говорить только по .NET API. Не уверен насколько у него (Dynamo) налажена интероперабельность с C++ в части пользовательских библиотек (пока не пробовал), но в теории можно будет попробовать все методы писать на C++, а на C# делать лишь "обертку" их заголовков.

1. Загрузка и установка Dynamo Core

Здесь всё просто до безобразия -- качаем скомпилированную Core-версию с данного раздела, распаковываем и по сути сборка Core у нас готова.

Стоит упомянуть разве что про зависимость конкретной версии Dynamo-Core от версии .NET Framework. Так как Renga (к которой я и собираюсь "прикручивать" сборку имеет примеры API на .NET Framework 4.8, то я и качаю Core 2.12 (текущая предпоследняя стабильная). Вообще говоря, 4.8 начался вроде с Core 2.8 ... но тут я следовал принципу "последняя актуальная стабильная",

2. Настройка проекта библиотеки классов

Наш проект мы будем собирать также под .NET Framework 4.8 (как и Dynamo Core). Нигде в API Renga не регламентировано это, к слову.

Логику сборки делаю классической - пустое решение (VS) + библиотека классов на .NET Framework 4.8 и консольное приложение также на .NET Framework 4.8, через которое я запускаю внешнюю программу - DynamoSandbox.exe, куда уже импортирована локальная скомпилированная библиотека классов.

Сложным является вопрос хранения внешних зависимостей. В процессе программирования под Renga используется по-существу, единственная "COM-библиотека" RengaCOMAPI.tlb. В свойствах проекта в VS её нельзя настроить на копирование локально, а проект Dynamo будучи установленным не будет знать где она лежит.

Здесь я вынужденно ввожу первое условие: по абсолютному файловому пути C:\Work\RengaCOMAPI.tlb. должна лежать эта библиотека. К слову, распространять её в составе пакета (онлайн-публикация) я также не имею формального права от Разработчиков программы.

Безусловно, можно распространять пакет нодов под Renga не как стандартный пакет, а как полноценный установщик, который найдет директорию с установленной Renga и положит туда нужные файл, но я так делать во первых не умею, во вторых не буду. Пока что.

3. Подключение к проекту Renga

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

Может быть по крайней мере 3 ситуации:

  1. Программа не запущена вообще
  2. Программа запущена, но не на том проекте/на стартовом виде
  3. Проект уже запущен в одном из процессов программы

Для случая 1 есть пример в справке здесь. Сложней с 2 и 3 - когда надо перехватить запущенный процесс Renga и открыть/перейти к нужному проекту. Процесс обращения к активному процессу Renga описан здесь.

Окей, с API понятно, а как это воплотить в Dynamo? Хах, а вот тут начинается уже интересное. В явном виде передавать интерфейсы (а объекты класса Application, Project, Model и пр. являются именно интерфейсами) в нодах Dynamo не получится. Следовательно, необходимо инициализировать во внутренних методах объекты проекта/модели и обращаться к ним при выполнении соответствующих методов позже.

Я реализовал это в виде класса DynDocument, где расположил объекты интерфейса - приложение и проект.

Примечание: конструкция private DynDocument() { } только лишь для того, чтобы в Dynamo оно не светилось как нод*

Объекты процесса Renga
Объекты процесса Renga

Здесь присутствует структура для Application и IApplication. Первое -- это создание нового процесса Renga (запуск приложения и открытие проекта). Второе - это перебор открытых процессов как IApplication.

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

Это я перехватываю активный процесс с документом и получаю наименование параметров проекта (здания)
Это я перехватываю активный процесс с документом и получаю наименование параметров проекта (здания)
Другой вопрос, что явно открыть конкретный проект среди ряда открытых я не пробовал ... пусть пользователь это сделает сам. В конце концов это не сложно ... чем вот это мучиться с интерфейсом Application.

4. О последовательности выполнения операций. Искусственное направление

Стоит сказать про критическую важность явного задания последовательности выполняемых операций. В силу того, что передавать сущности проекта/модели мы не можем - то наши ноды фактически возвращают void (действие). Для того, чтобы управлять последовательностью выполнения нодов - у меня тип всех изменен с void на int (возвращается "0"). Так я могу управлять очередностью нодов.

5. Пакетные операции на файлах IFC

Рассмотрим вариант пакетной обработки файлов. К примеру, конвертации ряда проектов Renga в IFC. Для этого нам потребуется список файлов и метод API по открытию проекта по файловому пути, экспорту в IFC и закрытию, а также для красоты - настройки экспорта в эти форматы (из коих есть только для ifc -- IIfcExportSettings).

Сколь я не мучился пытаясь передать эти настройки как сущность (com_объект) у меня не вышло - ругалось на "несопоставление типов", поэтому я решил сохранять эти настройки в файле, а потом вызывать их снова из другого метода.

Набор файлов для формирования IFC возьмем простые - из числа примеров поставляемых вместе с программой из директории RengaSoftware\Samples\.

Помня, что Dynamo не умеет работать с пакетной обработкой (ждать завершения части скрипта) даже с искусственно тормозящимся потоком (Thread.Sleep()), я сделаю экспортер в виде большого нода (чтобы в его теле происходило переключение между документами).

Итоговый результат будет примерно такой. Теперь поехали по его разбору
Итоговый результат будет примерно такой. Теперь поехали по его разбору

Первая зеленая группа - это сопоставление трех файлов маппинга параметров (для слоев, типов и значений).

Первая группа параметров
Первая группа параметров

Изюминкой реализации этих параметров является нестандартное задание путям к файлам. Вместо классических "\\" там используется "/" и что прикольно в режиме отладки оно вообще перескакивало через IIfcExportSettings с такими путями и не исполняло процесс!. Возвращалась очень информативная ошибка:

Ошибка)
Ошибка)
Здесь у нас только настройки геометрии - булевы параметры
Здесь у нас только настройки геометрии - булевы параметры
Тут -- настройки файлов
Тут -- настройки файлов

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

Ну и сам "главный" метод
Ну и сам "главный" метод

6. Пакетные операции на чертежах модели

Здесь примерно такая же логика, как в случае с IFC, только если IFC для проекта мог быть один -- то здесь в файле может быть несколько чертежей.

Реализуем скрипты для одного файла и пакетное для нескольких (там, правда, будет иметь место необходимость пред-настройки параметров листов - но оставим это на совести пользователя).

Так будет выглядеть действие для текущего файла.
Так будет выглядеть действие для текущего файла.

В качестве демо файлов также возьмем ранние примеры - какой-то набор листов там есть (нам важно лишь их наличие, а не содержимое).

Содержимое файла
Содержимое файла

Перед тем, как запустить саму процедуру экспорта обратим внимание на понимание чертежей в среде Renga - это не только чертежи (drawings), но и Уровни (Levels), сборки (), разрезы (), фасады () и спецификации. Только чертежи обозначаются как IProject.Drawings, тогда как всё в целом -- как IProject.Drawings2.

В этом случае сведение к типу IDrawingCollection вот так не работает и как их сводить непонятно ....
В этом случае сведение к типу IDrawingCollection вот так не работает и как их сводить непонятно ....
Честно говоря, создание двух методов вместо одного но с перегрузкой операторов выглядит странно ... ну да ладно, не будем это комментировать.
А это результат экспорта ... где элементы модели вставляются как растры! Уфффф
А это результат экспорта ... где элементы модели вставляются как растры! Уфффф
Пакетная операция
Пакетная операция
Вот экспортировались прочие файлы
Вот экспортировались прочие файлы

7. Завершаем первую часть?

Итак, данная статья несет в себе главный посыл:

Работать с API любой САПР через Dynamo Core возможно, если есть API к данной САПР и COM-интерфейс для САПР.

Что мы сделали по отношении к Renga - инициализировали сущности (интерфейсы) процесса, проекта; научились производить пакетные операции над файлами в части формирования IFC и вывода чертежей.

Следующая часть (2) будет посвящена вопросу обращения к свойствам параметров проекта, к свойствам отдельных элементов.

Сам пакет я выкладываю на GitHub (репозиторий здесь). Также публикую набор кода как Dynamo-package под именем "RengaDyn". Ввиду сложности подключения библиотеки "RengaCOMAPI.tlb" к проекту сделайте это сами разместив её по файловому пути

C:\Work\RengaCOMAPI.tlb.

Позже, когда получу разрешение на публикацию её в составе основного кода - выложу и там.

Файл "RengaCOMAPI.tlb" находится в составе этого пакета.

Упоминаемые в статей скрипты (4 шт) также находятся в репозитории на GitHub.

Не пропускайте публикации, подписывайтесь на Telegram-канал с тизерами статей.

#dynamo core #renga #renga api #rengabim #dynamo