- •Основы сапр
- •Лекция 1 Пути повышения качества и производительности проектирования на основе использования эвм
- •Правила оформления блок – схем алгоритмов
- •Лекция 2 сапр как объект проектирования
- •Состав и структура сапр
- •Лекция 4
- •3D – моделирование в машиностроении
- •AutoCad – единая платформа для проектирования
- •Как сейчас устроен AutoCad?
- •Как сегодня работают в среде AutoCad?
- •Инженерная графика
- •Трехмерное моделирование
- •Визуализация проектных решений
- •Лекция 6 Трехмерные построения
- •Координаты в трехмерном пространстве
- •Уровень и высота
- •Системы координат
- •Настройка вида
- •Трехмерные полилинии
- •Лекция 8 Тонирование
- •Лекция 9 Области
- •Лекция 10 Разрезы и сечения
- •Редактирование тел
- •Лекция 12 Создание приложений для программных пакетов
- •Visual lisp
- •Переменные языка AutoLisp
- •Переменные языка AutoLisp определенные пользователем
- •Лекция 13 Типы данных языка AutoLisp
- •Обзор функций языка AutoLisp
- •Математические функции
- •Лекция 14 Использование функции get для ввода данных.
- •Условное ветвление программ
- •Организация циклов
- •Вызов команд Автокада из программы на языке AutoLisp
- •Лекция 15 Вывод данных в командную строку
- •Файловый ввод - вывод
- •Определение функции
- •Лекция 16 Доступ к примитивам и средствам Автокада
- •Лекция 17 Требования, предъявляемые к техническому обеспечению
- •Режимы работы технических средств сапр
Лекция 16 Доступ к примитивам и средствам Автокада
Главной особенностью языка AutoLisp является то, что он позволяет осуществлять доступ к графической базе данных (ГБД) п.AutoCAD, т.е. его возможности можно использовать для работы с геометрическими примитивами чертежа.
Как вы уже знаете, любой создаваемый в Автокаде чертеж состоит из примитивов, геометрическое описание которых хранится в специальном формате (формате Автокада) в файле чертежа (расширение .dwg). При загрузке чертежа Автокад заполняет графическую базу данных: записывает системные настройки, создает список объектов и вносит в ГБД геометрическое описание этих объектов, присваивая каждому примитиву уникальное имя. Итак, в сеансе редактирования каждый примитив (отрезок, дуга, окружность и т.п.) имеет свое имя по которому его распознает сам Автокад. Эти имена меняются от одного сеанса редактирования к другому и поэтому нет смысла их запоминать. Однако можно в программе на AutoLISP сначала найти имя примитива в базе данных Автокада, с тем чтобы впоследствии непосредственно манипулировать геометрическими характеристиками примитива. Например, чтобы извлечь из ГБД имя последнего (last) построенного примитива (допустим отрезка прямой) в командной строки запишем: (setq ename (entlast))
Автокад возвращает например <Entity name: 60000A14>.
Тем самым мы присвоили переменной ename имя последнего объявленного примитива - точки, отрезка прямой, дуги, текста и т.д.. Напомним еще раз, что имена примитивов изменяются от сеанса к сеансу, и вы наверняка увидите на экране другое имя. Имена примитивов в Автокаде – шестнадцатеричные величины и может быть например таким: 60000А14. Используя это имя, можно при помощи функции ENTGET получить доступ к данным, связанным с примитивом: (setq edata (entget ename))
Если это отрезок прямой то переменной edata будет присвоено значение:
((-1 . <Entity name 60000A14>) (0 . “LINE”) (8 . “LAYER1”) (10 16.22 84.25 0.0) (11 8.11 0.18 0.0) (210 0.0 0.0 1.0))
Имя примитива - это тип данных языка AutoLisp, и если функции ENTGET требуется имя примитива, то бесполезно указывать шестнадцатеричное число 60000А14 - надо передать значение переменной ename, в которой это имя хранится.
В языке AutoLisp, описание примитивов, представляют собой список, состоящий, в свою очередь, из подсписков, в которых сгруппированы по функциональному назначению все данные о примитиве, как геометрические, так и общие: слой, цвет и т.п. Подсписки отличаются по специальным кодам формата DXF (Drawing eXchange Format - формат обмена рисунками), позволяющим определить, какой тип данных хранится в подсписке. Каждый подсписок имеет две части. Первая часть - код DXF, вторая - данные. Например для примитива “LINE” коды DXF -1 . - имя примитива, 0 . - тип примитива, 8 . - имя слоя, 10 - начальная точка примитива, 11 - конечная точка, 210 - направление выдавливания.
Следует обратить внимание что подсписки с кодами DXF -1 . , 0 . , 8 . , (структура кода : цифра-пробел-точка) являются списками типа “точечная пара”, которые нельзя получить функцией LIST. Такие списки необходимо получать с помощью функции QUOTE, например: (setq sp_t ‘(8 . “LAYER_ALL”))
Представим переменную список edata в виде таблицы:
Код DXF |
Данные |
Характеристика
|
-1. |
60000А14 |
Имя примитива |
0. |
“LINE” |
Тип примитива |
8. |
“LAYER1” |
Имя слоя которому принадлежит примитив |
10 |
16.22 84.25 0.0 |
Начальная точка отрезка |
11 |
8.11 0.18 0.0 |
Конечная точка отрезка |
210 |
0.0 0.0 1.0 |
Направление выдавливания (служебный код) |
Следовательно, пользуясь кодами DXF, можно извлечь из сложного списка edata любую информацию о примитиве. Такой доступ к рисунку более сложен, но предоставляет широкие возможности. Теперь можно программно изменять практически все свойства примитивов. Поэтому при работе со списками данных о примитивах важно знать кодировку кодов DXF. Значения DXF кодов основных примитивов даны в Приложении С.
Имена примитивов можно определять указанием точки принадлежащей примитиву, с помощью функции:
(entsel строка-подсказка)
Выбирается примитив, при этом выбор должен быть сделан указанием на примитив. Возвращается список, первый элемент которого - имя выбранного примитива, а второй - координаты точки в которой он был указан. Строка-подсказка используется для запроса примитива. Если она не указана, то выдается стандартный запрос "Select object:" (Выберите объект).
Например, для ранее определенного отрезка прямой функция ENTSEL
(setq ent1 (entsel))
присваивает переменной ent1 значение списка
( <Entity name 60000A14> ( 11 14.0 5.28 0.0))
где первый элемент списка - имя примитива <Entity name 60000A14>, а второй - (11 14.0 5.28 0.0) – код DXF и координаты точки лежащей на выбранном отрезке в которой он был указан. Присвоить имя примитива переменной ename, можно с помощью следуюшей конструкции:
(setq ename (car ent1))
Примитивы можно удалять из чертежа функцией ENTDEL:
(entdel ename)
В данном случае переменная ename - имя примитива. Этот способ позволяет удалять из ГБД также невидимые примитивы, что невозможно обычным выбором объектов (нельзя выбрать объект если он находится в отключенном слое). Следует отметить одну интересную особенность: функция ENTDEL вызванная повторно с тем же именем примитива, восстановит его в ГБД. Для получения DXF характеристик примитивов можно использовать конструкцию: (setq ent_p (entget (car (entsel))
Если в ответ на запрос функции entsel "Select object:" будет указан примитив то переменной ent_p будет присвоено значение сложного списка (типа edata).
Для модификации геометрических характеристик примитива непосредственно в ГБД надо уметь находить в DXF-списке данных примитива (например переменная EDATA) подсписки, в которых хранится нужная информация. Выбор и изменение различных данных, относящихся к примитиву, осуществляются по коду DXF (это всегда целое число) с помощью функций ASSOC и SUBST.
(assoc элемент_списка сложный_список)
Извлекает из сложного_списка элемент списка по ключу элемент_ списка. Если элемент_списка не найден ASSOC возвращает nil. С ее помощью можно извлечь, например, из списка edata
((-1 . <Entity name 60000A14>) (0 . “LINE”) (8 . “LAYER1”) (10 16.22 84.25 0.0) (11 8.11 0.18 0.0) (210 0.0 0.0 1.0)) список содержащий координаты начальной точки (код 10):
(setq edata_start (assoc 10 edata))
Переменная edata_start определяет подсписок (10 16.22 84.25 0.0).
В приведенном выше примере мы фактически сказали AutoLISP: "Возврати подсписок с DXF-кодом 10". Автолисп просмотрел DXF-список примитива, нашел подсписок с кодом 10 и возвратил его. Разумеется целиком. Полученный по коду подсписок edata_start, все еще содержит DXF-код 10, который можно убрать. Для этой цели лучше всего использовать функцию CDR:
(setq pp1 (cdr edata_start))
Переменная pp1 определяет список (16.22 84.25 0.0).
С помощью этой функции можно присвоить переменной имя слоя в котором находится примитив, например:
(setq lay (cdr (assoc 8 edata)))
Переменной lay присваивается символьное значение LAYER1
(subst новый элемент старый элемент список)
Возвращает копию исходного списка с заменой всех найденных подсписков, идентичных старому элементу, на новый элемент. Например, присвоим переменной p_start значение подсписка списка edata, содержащего координаты начальной точки отрезка прямой
так (setq p_start (assoc 10 edata))
или так (setq p_start (nth 3 edata))
Учитываем, что нумерация элементов списка начинается со значения 0. Тогдa: если
(setq edata_new (substr (list 10 22.4 35.16 0) p_start edata))
то переменная edata_new определит новый список
((-1. <Entity name 60000A14>) (0. “LINE”) (8. “LAYER1”) (10 22.4 35.16 0)
(11 8.11 0.18 0.0) (210 0.0 0.0 1.0)).
Если вхождений не обнаружено, SUBST возвращает копию старого списка.
Извлекая из DXF-списков нужную информацию, можно программно обрабатывать ее и затем, внеся изменения в DXF-список примитива при помощи функции SUBST, модифицировать ГБД при помощи функции ENTMOD:
(entmod список)
Эта функция (где переменная список - сложный список типа edata) обновляет информацию в ГБД. Следует иметь в виду, что функция ENTMOD не всесильна.
Как уже говорилось, имена примитивов действительны лишь в текущем сеансе редак-тирования. Но в AutoLISP есть средство - метки, позволяющее узнавать примитивы из других сеансов. Метки - это просто номера примитивов в ГБД: они присваиваются автоматически в процессе создания примитивов, если были включены командой п. AutoCAD HANDLES. С ними можно работать из AutoLISP с помощью функции HANDENT:
(handent метка)
Возвращает имя примитива, который указывается строковым параметром метка. После того как получено имя примитива, оно может быть использовано для дальнейшей работы. Например если характеристика примитива опреде-лена сложным списком, в котором код DXF 5 . определяет метку примитива
((-1 . <Entity name 60000A14>) (0 . “LINE”) (8 . “LAYER_ALL”) (5 . “5А”) (16.22 84.25 0.0) (11 8.11 0.18 0.0) (210 0.0 0.0 1.0))
то функция
(setq ename (handent “5A”))
присвоит переменной ename значение <Entity name 60000A14>.