Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
METHOD / Основы САПР / Лекц_Основы_САПР.doc
Скачиваний:
2353
Добавлен:
05.03.2016
Размер:
2.06 Mб
Скачать

Лекция 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>.

Соседние файлы в папке Основы САПР