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

Занимательное Dynamo. Транзакции к содержимому чертежа. Операции с текстом и немного прикладной геометрии.

Оглавление

Введение: в данной статье продолжим серию по работе с Dynamo for Civil 3D и посвятим её теме работы с текстом (объекты типа MText и Text) по той причине, что стандартных нодов по работе с ними довольно мало, а получение отдельных свойств возможно лишь через транзакции к базе данных чертежа.

Снова та же картинка (Оригинал: https://avatars.mds.yandex.net/get-zen_doc/198359/pub_5b031feb83090562e4b1650f_5b0e832057906a66d8e239bb/scale_1200)
Снова та же картинка (Оригинал: https://avatars.mds.yandex.net/get-zen_doc/198359/pub_5b031feb83090562e4b1650f_5b0e832057906a66d8e239bb/scale_1200)

1. Где встречаются операции по работе с текстом?

Сперва давайте представим ряд ситуаций, где может понадобится работать с текстом как с отдельными примитивами (все эти ситуации мы рассмотрим в данной статье)

  • редактирование топоосновы с большим числом примитивов AutoCAD (текст, отрезки, штриховки);
  • простановка текстовых меток/обозначений (в особенности, на листах);
  • корректировка положения меток относительно объектов Civil 3D

По существу первые 2, это основные ситуации; остальное уже отдельные варианты. В остальном желательно использовать определения атрибута блока (для точечных объектов), либо вовсе запихивать текст в атрибутику (наборы характеристик/object data).

Пример текстовых обозначений
Пример текстовых обозначений

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

2. Выборка содержимого

Выбрать содержимое можно по разному - от прямого Select Objects до более универсального - All objects On Layer/Of Type. В случае с топоосновами, которые имеют жесткое именование слоев удобен первый случай:

Три типа выбора объектов
Три типа выбора объектов

Каждый из вариантов требует в идеале дополнительной проверки на формат данных (принадлежность слою, типу объекта)

Вариант проверки на тип объекта
Вариант проверки на тип объекта

3. Получение значения текста и формирование нового списка

А вот тут начинается уже интересное. Базовых нодов для чтения текста не предусмотрено (есть только для создания и получения некоторых геометрических параметров).

Для получения содержимого текста необходимо обращаться к базе данных чертежа при помощи транзакции.

Выглядит всё примерно так
Выглядит всё примерно так

Суть заключается в том, что в состав "шаблона для Python Script" вставляется конструкция следующего вида:

item_handle = <<InputItem>>.Handle
item_id = db.GetObjectId(False,Handle(int(item_handle, 16)),0);
_item = t.GetObject(item_id,OpenMode.ForRead)

И уже далее в зависимости от типа "_item" получают его свойства, в нашем случае - содержимое текста получается методом TextString.

Вариант изменения написания текста
Вариант изменения написания текста

4. Процедура обновления содержимого текста

По существу, процесс мало отличается от запроса значений текста - только теперь добавляется процесс завершения транзакции t.Commit() и изменение варианта чтения БД чертежа с чтения на запись OpenMode.ForWrite:

Процедура присвоения тексту новых значений
Процедура присвоения тексту новых значений

5. Изменение поворота текста для красивой ориентации на ВЭ

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

В качестве объекта, относительно которого будет задаваться вращение будем использовать трассы, тем более что она зачастую и используется как объект для вывода листов при помощи стандартного функционала Civil 3D:

Где это встречается
Где это встречается

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

Первым действием мы "обнулим" повороты для всего текста - сделав значение "0". Затем, для каждого из объектов текста мы найдем значение точки пересечения перпендикуляра, опущенного из точки текста на трассу и выявим наименьшее расстояние - значит этот текст принадлежит данной трассе, после чего вычислим угол поворота текста и запишем в список необходимый гол поворота. И после того, как мы пройдемся по всем объектам текста - в рамка одной транзакции запишем изменения в чертеж.

5.1 Обнуление всего текста

Выглядеть это будет примерно так
Выглядеть это будет примерно так

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

5.2 Текущая точка местоположения текста

Базовые ноды получения геометрии объекта здесь не подойдут - для получения геометрии объектов текста придется снова делать транзакцию, причем для Text нужно получать элемент "Position", а для MText - "Location". Возвращаемое значение имеет тип Point 3D, от которого мы получаем координаты и сводим к X,Y:

Процесс получения текущей координаты текста
Процесс получения текущей координаты текста

5.3 Получение угла поворота текста относительно ближайшей трассы

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

В качестве метода определения положения текста относительно трассы будем использовать метод API: StationOffsetAcceptOutOfRange, который позволяет продолжать выполнение кода, если точка лежит за пределами трассы

Здесь у нас такая конструкция
Здесь у нас такая конструкция
Начало скрипта и вспомогательные функции
Начало скрипта и вспомогательные функции

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

Окончание скрипта
Окончание скрипта

6. Итоги и заключение

Попробую показать результат применения скрипта. Вот так было "до":

Что было до
Что было до
Как стало после
Как стало после

Для устранения наложения текста можно внести в тело метода GetCoordsOfText доп. опцию проверки, есть ли наложение с каким-либо занесенным в список точек текстом:

Вот такого типа
Вот такого типа

А сам метод, который сдвинет текст на верные координаты вписать в структура скрипта вот так:

Дополнение
Дополнение

Хотя честно сказать. хоть счетчик показывает выполнение действий для всех "пересекающихся сущностей", но реально изменяется только ~ 25%. Почему так, я пока не разобрался ... это будет тогда следующая статья - на тему устранения наложений объектов друг на друга.

Вдобавок, надо похоже вносить исключение на величину угла поворота текста - так как работает это всё тоже не однозначно.

Сама текущая версия скрипта доступа по ссылке с названием "Roads_RotateTextOnViewport2.dyn".

#autodesk #civil 3d #dynamo #text #mtext #text intersection #ironpython #мтекст #текст autocad

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