На сайте
добавлена для скачивания объектная модель Autodesk Inventor!
Работа с примитивами. Доступ к
базе данных чертежа
Любой создаваемый в Автокаде чертеж состоит из примитивов,
геометрическое описание которых хранится в специальном формате (формате Автокада)
в файле чертежа (расширение .dwg). Для оперирования примитивами необходимо в
программе на Автолиспе сначала найти имя примитива в базе данных Автокада. Попробуем
извлечь это имя из ГБД при помощи Автолиспа.
Получение информации о примитивах
Нарисуйте отрезок. (команда line).
Для того, чтобы указать на примитив, используются различные способы. В частности,
можно указать последний нарисованный элемент.
Взятие имени последнего созданного примитива: (entlast)
Имя примитива необходимо сохранить в переменной с помощью оператора присваивания
setq. Введите в командной строке:
Тем самым мы присвоили переменной ENAME имя последнего
примитива (в данном случае отрезка). Имена примитивов в Автокаде - шестнадцатеричные
величины; имя примитива может быть, например, таким: 60000А14.
Используя это имя, вы можете при помощи функции ENTGET
получить доступ к данным, связанным с примитивом:
Доступ
к данным: (entget имя)
Данные о примитиве выдаются списком, поэтому должны быть записаны в переменную,
которую потом можно анализировать:
(setq EDATA (ENTGET
ENAME))
В результате выполнения команды вы получите сообщение, содержащее в своей
структуре всю информацию о примитиве. Начиная от его имени и заканчивая слоем
и цветом:
Не все примитивы столь легко читаемы.
Если цвет или тип линии не указываются, значит они соответствуют типам линии
и цвету для заданного слоя.
DXF-коды
Список состоит из кодов формата DXF (Drawing exchange Format - формат обмена
рисунками). Каждый подсписок имеет две части. Первая - код DXF, вторая - данные.
Целое число 0, например, представляет собой код типа примитива. Код 8 говорит
о том, что следующее за ним число - номер слоя. Код 10 - начальная точка примитива,
код 11 - конечная и т.п. Отметим, что набор кодов DXF различен для примитивов
разных типов. Однако сами коды относятся ко всем примитивам - имя примитива,
например, всегда хранится в подсписке с кодом DXF -1.
Представим полученный список EDATA в структурированном
виде:
( (-1 . <Имя примитива:
60000020>)
(0 . "LINE") - Тип примитива
(8 . "0") - Слой
(101.02.00.0) - Начальная точка
(11 6.0 6.0 0.0) ) - Конечная точка
Пользуясь кодами DXF, можно извлечь из списка EDATA
любую информацию о примитиве.
Создать свой список для описание примитива в DXF-формате можно
при помощи оператора (cons код значение)
; получится список
вида
(код . значение)
Наборы примитивов
Из Автолиспа также можно работать с наборами примитивов: предоставлять пользователю
возможность заносить примитивы в набор и затем их модифицировать. Набор формируется
функцией ssget:
(ssget
режим точка1 точка2 <фильтр>)
Необязательный аргумент режим - строка, которая указывает способ выбора примитива.
Возможны следующие значения режима:
Режим:
"Р" выбирается текущий набор;
"L" выбирается последний сформированный
на чертеже примитив;
"W" < точка1 >
<точка2> - выбираются примитивы, попавшие в рамку с углами в <
точке1 > и <точке2>;
"С" <точка1> <точка2>
- выбираются примитивы, пересекаемые рамкой. Кроме этих возможны еще две конструкции:
Точка:
(ssget<
точка >) - Здесь выбираются примитивы, проходящие
через < точку >.
Фильтры:
(ssget "х" < фильтр >) - Здесь
<фильтр> - список, элементами которого являются одна или несколько
точечных пар. Каждая точечная пара строится по следующей форме: (< код >.< значение >) - Здесь <код>
- одно из принятых чисел, показывающих, по какому признаку выбираются примитивы,
например;
0 - примитивы одного типа;
2 - примитивы, входящие в один блок (INSERT) ;
6 - по типу линии;
7 - по гарнитуре шрифта;
8 - по имени слоя;
62 - по цвету и др. < значение > - значение признака.
; Выбирает по одному
объекты чертежа:
(ssget)
; Выбирает текущий набор:
(ssget "P")
;Выбирает последний примитив:
(ssget "L")
;Выбирает примитив, проходящий через точку (2,2):
(ssget '(2 2))
;или:
(ssget'(list 2 2))
;Выбирает примитивы в рамке от (0,0) до (5,5):
(ssget "Р" '(0 0) '(5 5))
;Вернет набор, включающий все примитивы, находящиеся на слое, именованном как
"SLI":
(ssget "X" '((8 . "SLI")))
;вернет набор, состоящий из всех линий красного цвета (1 - номер красного цвета):
(ssget "X" '((0. "LINE") (62 .1)))
После того, как Вы определили необходимый Вам набор примитивов, можно использовать
его во всех функциях модифицирования чертежа - Copy,
move, erase, etc...
Например: Выполнение последовательности функций
(setq sdel (ssget
"X" '((6 . "CENTER"))))
(command "ERASE" sdel) ; приведет к стиранию всех примитивов, изображенных
осевыми линиями.
Работа с наборами/списками примитивов
(sslength
список_сформированный_ssget) - определение длины списка
В результате мы извлекаем имя примитива из списка, и оно уже может обрабатываться
оператором entget для извлечения данных.
Пример:
; Выводим на экран
подряд все типы примитивов из списка aa
(setq i 0)
(while (< i (sslength aa))
; данные о примитиве
(setq aa0 (entget(ssname aa i)))
(setq aa0 (assoc 0 aa0))
(print (nth 1 aa0))
(setq i(+ i 1))
)
Из Автолиспа можно непосредственно модифицировать данные о существующих примитивах.
Однако для добавления нового примитива необходимо использовать команды отрисовки
или редактирования Автокада. Это ограничение связано с желанием защитить ГБД
от неграмотного программиста: неправильно пользуясь командами Автокада, вы не
сможете испортить саму ГБД - самое большее, что вы испортите, это свой чертеж.
Программное изменение примитивов
Для модификации геометрических характеристик примитива надо уметь находить в
DXF-списке данных примитива (наша переменная EDATA)
подсписки, в которых хранится нужная информация. Выбор и изменение различных
данных, относящихся к примитиву, осуществляются по коду DXF (это всегда целое
число) с помощью функций ASSOC и SUBST:
Возвращает копию исходного списка с заменой всех найденных подсписков, идентичных
старомуэлементу, на новыйэлемент.
Если вхождений не обнаружено, SUBST возвращает копию
старого списка (не nil!):
В приведенном выше примере мы фактически сказали Автолиспу: "Возврати
мне подсписок с DXF-кодом 0. Автолисп просмотрел DXF-список примитива, нашел
подсписок с кодом 0 и возвратил его. Разумеется, целиком. Полученный по коду
подсписок все еще содержит DXF-код, который необходимо убрать: первый элемент
списка, уже "отработал" свое и больше не понадобится. Для этой цели
лучше всего использовать функцию CDR:
Команда: (cdr (assoc
О EDATA))
Автолисп возвращает: "line"
Извлекая из DXF-списков нужную информацию, можно программно обрабатывать ее
и затем, внеся изменения в DXF-список примитива при помощи функции SUBST,
модифицировать ГБД при помощи функции ENTMOD:
(entmod
список)
Эта функция преобразует список в формат, возвращаемый функцией ENTGET,
и обновляет информацию в ГБД. Следует иметь в виду, что функция ENTMOD
не всесильна. Во-первых, нельзя изменить тип примитива (если вы хотите сделать
это, вам остаётся только удалить его с помощью функции ENTDEL
и создать новый примитив с помощью функции COMMAND).
Во-вторых, все объекты, на которые ссылается список данных, должны быть известны
Автокаду к тому моменту, когда вызывается функция ENTMOD
(гарнитура шрифта, типы линий, имена форм и блоков и пр.). Исключением из этого
правила является слой - если определённого в списке слоя нет, будет создан новый.
Целые значения автоматически преобразуются в значения с плавающей точкой
Когда обновляется не основной примитив, а "подпримитив" (вершина полилинии
или атрибут блока), изображение на экране не обновляется (это невыгодно) - для
обновления изображения следует использовать функцию ENTUPD: