Найти в Дзене
Хроники Георга

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

Оглавление

Итааааааааак, занавес - начинаем! [погружение в геометрию объектов Renga]

Да, ура, наконец-то мы дошли до этого момента.

Начало серии смотри по ссылкам ниже:

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

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

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

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

1. Основы представления геометрии объекта в Renga

Начнем с небольшой вводной - любой объект в 3D вне зависимости от своего типа содержит свой набор геометрии. Где-то это простые формы, где-то простые с вырезами, где-то мульти-фигура ... где-то же просто поверхности (surface)/мэши (mesh). Вся геометрия в конечно счете сводится до "сеток" - grid.

Итак, класс (интерфейс), который отвечает за получение геометрии объектов - это IDataExporter (наследник IProject). У него есть 2 сына метода - GetObjects3D() и GetGrids(), которые выгружают геометрию 2х типов - ExportedObject3D (группа mesh для каждого объекта + объектные свойства) и IGridMaterial (под-объектами имеющими 1 структуру и 1 материал).

Согласно справке:

The difference between the methods is that IExportedObject3D provide represent the geometry aggregated per object, whereas IGridWithMaterial items aggregate the geometry by grid type and material.

1.1 IExportedObject3D

В силу того, что методов у IExportedObject3DCollection лишь 2 - это получение отдельного объекта и подсчет количества вхождений, я не буду делать для него отдельного нода, а сразу получу список объектов, входящих в него.

Каждый отдельный объект списка (IExportedObject3D) представляет собой контейнер со свойствами + содержит метод для получения Mesh'а. Свойства я также оформлю словарем, а получение Mesh'а - методом, возвращающим структуру IMesh. Заметим, что Mesh возвращается не какой-то коллекцией, а по индексу из "набора Mesh-структур в объекте", поэтому в методе для получения IMesh я верну тоже набор.

Стоит отметить что IExportedObject3D неприводим к IModelObject. Между ними однако есть связь - это свойство ModelObjectId, благодаря которому в выборку объектов можно включать отсортированные раннее объекты модели.

Интерфейс IMesh похож на IExportedObject3D - набор свойств и метод для возврата сетки (IGrid).

Вот только связи между IGridMaterial и уже полученной IGrid нет, то есть получив из IExportedObject3D -> Mesh -> IGrid сопоставить этот IGrid с материалом (цветом) я уже никак не смогу ...

Среди свойств Mesh есть так называемый MeshType, который содержит один из идентификаторов Mesh types.

А когда я увидел количество идентификаторов для GridTypes мне стало плохо ...
А когда я увидел количество идентификаторов для GridTypes мне стало плохо ...

1.2 Grids

Теперь мы приблизились и к Grid'ам.

Напомню, что интерфейс IDataExporter возвращал нам IGridWithMaterialCollection. С него то и начнем. Эта структура сродни IExportedObject3DCollection. Содержит набор отдельных интерфейсов IGridWithMaterial, которые в свою очередь содержат 2 свойства - объект IGrid и Material (IGridMaterial).

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

Здесь я немного в замешательстве, почему метод "раскрытия" цвета лежит именно в этом локальном методе.

Углубляться в материалы (IMaterial, IMaterialLayer, IMaterialManager, IMaterialLayerCollection) я не буду.

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

1.3 IGrid

Ну всё. Дальше пошла хардкорная 3D геометрия. Рекомендую запастись крепкими напитками. 🚀🚀🚀

A grid is a subset of a mesh corresponding to a particular face of an exported object. This interface provides access to grid vertices and their normals and texture coordinates.

Структура IGrid состоит из граней (Trinagles), образованных точками (Vertex), нормалями (FloatVector3D) и "texture coordinate" - что это такое я не совсем понял.

1.3.1 Triangles

Из структуры IGrid получаем набор отдельных Triangle, каждая из которых содержит 3 вершины (Vertex), представленных индексами. По этим индексам я запрашиваю координаты и отдаю разные вещи - и эти индексы, и точки Renga, а потом в обратную генерирую геометрию Dynamo.

Тут надо освежить у читателя представление про геометрию Dynamo. Базовый тип геометрии - точка (Point), грань (Face) недекларируемая - одна из составных Mesh. Для генерации Mesh'а Dynamo из Mesh'a Renga нам потребуется сперва получить всю триангуляцию для объекта, а затем на её базе сгенерировать Mesh как набор индексов точек и связанных с ними граней по методике этой статьи.

Я, конечно, буду возвращать из набора GetTriangles сразу нужные структуры вот так:

Получение описания mesh
Получение описания mesh
Это результат - вынос в 3d только стен. Похоже, правда?
Это результат - вынос в 3d только стен. Похоже, правда?

2. Сложности и ограничения

О чём стоит сказать?

Я пытаюсь выносить в среду Dynamo геометрию Renga, так как к ней есть больше методов по работе с геометрией, + сущности Dynamo будут одинаковы для любых САПР - что позволит применять к ним одинаковые подходы обработки.

В случае с Renga для формирования вида геометрии у нас есть 2 варианта, оба настраиваемых. Выше я показал реализацию выбора объектов сцены (IExportedObject3D), отобранные по типу ObjectTypes.

Для случая GetGrids() и варианта представления объектов как IGridWithMaterial у нас также есть возможность контролировать категории объектов, попадающих в фильтр. Вернее даже не так, обращаться к типу IGrid можно на обоих сценариях!

Grid.GetInfo - GridTypes
Grid.GetInfo - GridTypes

То есть для экспорта геометрии с материалами/цветом мы можем "забыть" про выборку по объектам и в целом про интерфейс IExportedObject3D, и работать только с IGrid, что мы и попробуем рассмотреть далее.

3. IGrid и GridTypes

Оооооооо, как надоело это забивать(((((
Оооооооо, как надоело это забивать(((((

Итак, GridTypes позволит нам фильтровать отдельные IGrid. Кроме того, если бы мы выбрали путь работы только с IExportObject3D каждый отдельный GridTypes позволил бы нам сохранить уникальный материал/цвет для каждого объекта.

Я реализовал это вот так
Я реализовал это вот так

При реализации столкнулся с багом ... что GridTypes в свойстве IGrid хранятся как Int32 а не как Enum ... а так как в GridTypes нумерация не сквозная, то сравгивать число с числом нельзя .. некорректно.

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

Так конечно костыльно .. но я тогда воспользуюсь сперва ограничением по IExportObject3D, а потом уже применю ограничитель к тем типам что остались.

Ну вот,  другая картинка
Ну вот, другая картинка
Общий вид на эксперименты с геометрией
Общий вид на эксперименты с геометрией

4. Выводы по статье

Итак, в данной статье мы познакомились с представление геометрии объектов в среде Renga.

Каждый объект в конечном итоге сводится к набору IGrid с ассоциированной каждой IGrid каким-то материалов. Выборку объектов сцены, попадающих под выгрузку можно настроить 2 способами - фильтрацией объектов сцены по id-объектов (IModelObject и там же ILevelObject), и по значению GridType. Однако на текущий момент корректная фильтрация по GridType невозможна в силу ошибки интерйеса IGrid где запись о типе хранится как число, а не как Enumertor (да и сами GridType по правде говоря смотрелись бы логичными как GUID, а не числа).

Mesh построенный в Dynamo на основе Renga-mesh выглядит корректным и его можно передавать. Протестированный пакет Dynamo- MeshToolkit нормально экспортирует только STL, но у него есть 2 недостатка:

STL в среде FreeCAD
STL в среде FreeCAD
  • ошибки экспорта в OBJ, DAE, PLY;
  • невозможность передать цвет/материал;

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

Видимо, придется писать библиотеку для экспорта хотя бы простых форм в графические форматы.

Ах да. ещё одна проблема, которая самая важная - экспорт в графические форматы будет без учета координат модели, что нам критически важно для сборки модели в общих координатах.

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

Также надеюсь, что разработчики сделают возможным читать у IGuid идентификатор IMesh, куда он относится - чтобы не мучиться со сравнением двух огромных структур IExportedObject3DCollection и IGridWithMaterialCollection (притом дублирующих друг друга) чтобы узнать цвет или материал объекта.

Ну что могу сказать, на это наверное пока всё со статьями про Renga API ... остались неописанными разделы про стили (Styles), частично трогал но нужно больше про IMaterial, IEnity, IUI, про выбор объектов, профили ... эээ. в общем много еще чего можно было бы написать - но увы, надо переключаться на другие рабочие задачи.

Искренне ваш

https://pbs.twimg.com/media/ExyBHd6VEAEWXR0.jpg
https://pbs.twimg.com/media/ExyBHd6VEAEWXR0.jpg

P.S. Напоминаю, что весь исходный код лежит в публичном GitHub-репозитории здесь. Все скрипты, упоминаемые в статье также лежат там в этой папке.

Сам пакет доступен среди менеджера пакетов в Dynamo по прямому поиску:

Текущая версия 1.0.4 - по окончании статьи
Текущая версия 1.0.4 - по окончании статьи

Для работы пакета необходимо разместить библиотеку из Renga SDK по нужному пути на диске С - см. описание на github.

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

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