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

Занимательное Dynamo. Работаем с поверхностями, телами и наборами характеристик

Оглавление

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

К слову, предпосылки для данного шага - это, собственно, появившаяся возможность делать это (формировать тела) программно с обновлением 2021.3. И такая функция почти сразу же была добавлена в функционал Dynamo, но мы её немного улучшим, сделав больше в сторону обхода ошибок и спасения себя от фаталов и необходимости начинать работу заново.

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

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

Итак, о чём мы будем говорить:

1. Создание набора характеристик на поверхности и автоматическое их заполнение;

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

Наш скрипт (по выдавливанию тел и атрибутам) удобно (и логично) разделить на 3 части (скрипта):

  1. Наполнение атрибутами поверхностей;
  2. Выдавливание тел и назначение им условного идентификатора (самая долгая по времени процедура);
  3. Сопоставление идентификатора солида с исходными данными и назначение ему атрибутов от поверхностей (и иным данным);

1. Про исходные данные. Задание начальных условий

Для простоты отладки, возьмем условные поверхности по линейному объекту (поверхности по характерным линиям).

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

2. Насыщение поверхностей атрибутикой

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

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

"Определения произвольной характеристики" - это пользовательские параметры, которые заполняются вручную (или программно при помощи скрипта).

Помимо этого есть её позиционные, классификационные, материальные, проектные, якорные и графические характеристики которые мы не трогаем (и которые я сам никогда не пробовал).

Общая логика назначения атрибутов поверхностям может выглядеть следующим образом: выбираются все поверхности модели, и им назначается заданный набор Характеристик. + по имени поверхности производятся некие логические действия в условном Python скрипте и на выходе мы получаем аффилированные с данной поверхностью атрибуты и их значения
Общая логика назначения атрибутов поверхностям может выглядеть следующим образом: выбираются все поверхности модели, и им назначается заданный набор Характеристик. + по имени поверхности производятся некие логические действия в условном Python скрипте и на выходе мы получаем аффилированные с данной поверхностью атрибуты и их значения

2. Выдавливание тел

2.1 Описание логики скрипта

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

Сперва получаем имена поверхностей и формируем список (он же - по сути, пакетный сценарий "что обрабатывать"):

Формирование заготовки для процесса выдавливания тел
Формирование заготовки для процесса выдавливания тел

Здесь мы сформировали пару списков (верхний - для поверхности "сверху", нижний -- соответственно, "нижней"). Они подают нам 2 поверхности для последующего нода выдавливания тел.

Далее я создаю таблицу ObjectData (это в каком-то смысле аналог Набора характеристик, с более простой логикой, применяемый больше для ГИС, но сейчас он сгодится для фиксации в поле таблицы идентификатора солида):

Создаем вспомогательную таблицу
Создаем вспомогательную таблицу

Тогда общая логика будет выглядеть вот так:

Вид скелета скрипта (выделенный - будущий метод для выдавливания тела)
Вид скелета скрипта (выделенный - будущий метод для выдавливания тела)

2.2 Важные замечания

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

  • операции выдавливания тел между поверхностями не всегда могут завершаться успешно вследствие проблемной триангуляции поверхностей выдавливания - в этом случае нам вернется "ноль" и нумерация объект-идентификатор собьется, поэтому в теле метода мы должны фиксировать только успешные случаи, а проблемные заносить в отдельный список;
  • если обратить внимание на метод Civil 3D API, реализующий этот процесс, мы увидим, что результат выдавливания тела - это набор объектов (вернее, идентификаторов объектов ObjectId), в то время как идентификатор принадлежности у нас один -- здесь в целом можно оставить как есть, но лучшим вариантом будет создать одноранговый список "тело-идентификатор" для гарантированного срабатывания логики Dynamo. Тут же -- возвращать нам нужно не ObjectId а Handle -- подробнее о внутренних идентификаторах см. в этой моей статье, пункт 1.
  • Не исключена вероятность фатальной ошибки при операции выдавливания ... тут можно посоветовать лишь ведение автоматического лога во внешний файл (на каких поверхностях файл крашнулся). Это очень такая ... специфичная и редкая вещь, но лучше застраховать себя от неё заранее.
  • Тут же про "страховку" можно порекомендовать следующий путь: после получения набора солидов смотреть на их Handle (строковое значение) и фиксировать их значения в лог-файл. (даже если он и вылетит, можно будет файл сохранить - в нем будет набор тел, и сохранится лог-файл, по которому мы можем "восстановить" идентификатор солида с исходными поверхностями.

Так как условий много, я реализую это в виде пользовательского нода "BySurfaces" в своей коллекции нодов Civil3D.CustomNodes в группе (классе) "Solids".

К слову, если "посмотреть" на внутренности нода TinSurfaceExtension.CreateSolidsAtSurface из пакета Civil3DToolkit, там тоже встроена логика проверки и главное, отсечения поверхностей с числом граней более 100 000 - то есть они вообще не будут обработаны программно!

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

2.3 Реализация скрипта

Процесс будет выглядеть вот так
Процесс будет выглядеть вот так
А вот результат
А вот результат

Теперь мы можем приступить к третьей части скрипта - внесению в тела наборы характеристик от "родительских" поверхностей, а также "собственные" характеристики свойственные солиду - в частности, объем.

3. Атрибутика солидов от поверхностей

Для дальнейшей работы нам потребуется запомнить 3 параметра: наименование таблицы ObjectData, наименование поля с идентификатором солида и разделитель данных поверхностей в атрибуте-идентификатора.

Фиксируем значения
Фиксируем значения
Далее я инициализирую набор солидов в чертеже по слою и по типу объектов (использую свои фильтры)
Далее я инициализирую набор солидов в чертеже по слою и по типу объектов (использую свои фильтры)
Потом получаю идентификаторы по солидам
Потом получаю идентификаторы по солидам
И получаю поверхности
И получаю поверхности

Теперь необходимо считать свойства атрибутов из наборов характеристик и назначить их телу (в свой, конечно, набор характеристик).

Вот так выглядит набор характеристик для тела
Вот так выглядит набор характеристик для тела
Считывание выглядит вот так (согласен, громоздко)
Считывание выглядит вот так (согласен, громоздко)
Здесь я получаю набор определения характеристик для тел
Здесь я получаю набор определения характеристик для тел
И в рамках Python-скрипта всё группирую в "1 поток"
И в рамках Python-скрипта всё группирую в "1 поток"
Общий вид скрипта
Общий вид скрипта
В результате получается вот так.
В результате получается вот так.

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

На этом всё, несложно, правда? :)

Материалы (условный файл + скрипты выкладываю по ссылке ниже)

https://disk.yandex.ru/d/IWQiYU1WKC504Q

"Готовый" - это с примененными действиями, второй - для ваших экспериментов
"Готовый" - это с примененными действиями, второй - для ваших экспериментов

Скрипты применять в порядке очередности - 1, 2, 3.

В статье используются стандартные ноды Dunamo Core for Civil 3D; Civil3DToolkit 1.30

Также обращаю внимание что версия Civil3D должна быть не ниже 2021.3 (когда появилась опция выдавливания тела по поверхности).

4. Заключение

Итак, в этой статье мы рассмотрели с вами процесс формирования солидов (3D-тел) между поверхностями Civil3D.

Упор мы делали на стабильности работы скрипта (разделение на 3 части) и возможности отката если что-то пойдет не так (см. раздел 2.2).

Предполагается, что описанный процесс можно использовать как шаблон для ваших рабочих операций - сперва поверхности наполняются атрибутами, потом определяется набор пар поверхностей, между которыми надо выдавить тела, затем тела выдавливаются с присвоением временного идентификатора (для понимания между какими поверхностями тело было выдавлено). И в рамках последнего скрипта происходит связывание тела (по его идентификатору) с родительскими поверхностями или иными данными - тут свобода творчества :)

Хочу поблагодарить Александра Панькина за помощь в понимании наборов характеристик - у него отличный YouTube-канал, где он частенько разбирает реализацию отдельных Dynamo-скриптов.

А у меня всё, до новых статей!

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

#dynamo #civil3d #autodesk #solids #surfaces #генплан