Работа с объектами AutoCADИсточник: intuit intuit
Получение информации об объектахЛюбой объект базы данных AutoCAD является сущностью (entity ) и имеет имя сущности. По имени сущности можно получить справку об объекте из любого места процедуры. Программным путем можно получать или устанавливать набор параметров заданного объекта базы данных. Функция ENTLAST возвращает имя сущности. Функция ENTGETвозвращает описание сущности в том виде, в каком она хранится в базе данных. Задание 5.1 Постройте прямую и выведите на экран ее имя сущности Command: (command "_line" "0,0,0" "50,0" "") _line Specify first point: 0,0,0 Specify next point or [Undo]: 50,0 Specify next point or [Undo]: Command: nil Command: (entlast) <Entity name: 7ef92198> А теперь сделайте запрос на получение последней сущности: Command: (setq myline (entget (entlast))) В ответ получите возвращаемое значение: ((-1 . <Entity name: 7ef92198>) (0 . "LINE") (330 . <Entity name: 7ef90cf8>) (5. "163") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 0.0 0.0 0.0) (11 50.0 0.0 0.0) (210 0.0 0.0 1.0)) Функция возвращает большой список, состоящий из 12 вложенных списков. К каждому из вложенных списков можно обращаться как к группе, индексированной по первому элементу. Это код группы объекта. Имя сущности входит в группу с кодом -1. Тип сущности ("LINE") входит в группу с кодом 0. Однако смысл кодов может меняться в зависимости от типа объекта. В таблице приведены некоторые коды групп стандартных объектовAutoCAD :
Полный список кодов можно найти в справочной системе Visual LISP по команде Help - Visual LISP Help Topics - Content - DXF Reference - Entities Section - Common Group Codes for Entities . Информацию о начерченном нами отрезке можно просмотреть и в среде AutoLISP . Для этого нужно при выделенном отрезке открыть диалоговое окноInspect по команде View - Browse drawing database - Browse Selection . В контекстном меню строки LINE выбрать команду LINE . Появится диалоговое окно Acad Line с информацией (рис. 5.1): Рис. 5.1. Получение информации об объекте в среде AutoLISP Выбор и изменение различных данных сущностей выполняются функциями ASSOC и SUBST . Функция ASSOC возвращает список, найденный по коду группы. Ее параметрами являются код группы и имя большого списка. Например, если в качестве первого параметра выбрать 10 (ASSOC 10 MyLine ), то функция ASSOC возвратит значение кода и начальную точку отрезка. Функция SUBST заменяет в списке все вхождения некоторого значения другим значением. Она содержит три параметра: Первый параметр - чем заменять; Второй параметр - что заменять; Третий параметр - в каком списке выполнить замены. Сам чертеж можно модифицировать с помощью функции ENTMOD , передав ей в качестве параметра обновленный список базы данных чертежа. Задание 5.2 Построить отрезок (0,0 50,0). Изменить координаты начальной точки на (50,50). Command: _line Specify first point: 0,0,0↵ Specify next point or [Undo]: 50,0↵ Проверьте координаты конечной точки: Command: id↵ Specify point: X = 50.0000 Y = 0.0000 Z = 0.0000 Command: *Cancel* Присвойте переменной myline значение списка параметров отрезка: Command: (setq myline (entget (entlast))) ↵ ((-1 . <Entity name: 7ef921a8>) (0 . "LINE") (330 . <Entity name: 7ef90cf8>) (5 . "165") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 0.0 0.0 0.0) (11 50.0 0.0 0.0) (210 0.0 0.0 1.0)) Присвойте переменной startpt значение координат начальной точки: Command: (setq startpt (assoc 10 myline)) ↵ (10 0.0 0.0 0.0) Присвойте переменной new_startpt новое значение координат начальной точки: Command: (setq new_startpt '(10 50.0 50.0 0.0)) ↵ (10 50.0 50.0 0.0) Замените в списке параметров координаты начальной точки новым значением: Command: (setq myline (subst new_startpt startpt myline)) ↵ ((-1 . <Entity name: 7ef921a8>) (0 . "LINE") (330 . <Entity name: 7ef90cf8>) (5 . "165") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 50.0 50.0 0.0) (11 50.0 0.0 0.0) (210 0.0 0.0 1.0)) Измените сам отрезок: Command: (entmod myline) ↵ ((-1 . <Entity name: 7ef921a8>) (0 . "LINE") (330 . <Entity name: 7ef90cf8>) (5 . "165") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 50.0 50.0 0.0) (11 50.0 0.0 0.0) (210 0.0 0.0 1.0)) В результате этих действий горизонтальный отрезок станет вертикальным.
Создание набора выделенных объектовС помощью функции SSGET (Selection Set Get - получение набора выделения) можно создать набор выделения. Именно эта функция выводит знакомое приглашение Select objects . Наиболее часто с наборами объектов используются следующие функции:
Пример Построим две окружности и четыре отрезка. Затем присвоим переменной mysset выделенный набор: Command: (setq mysset (ssget)) ↵ Select objects: Specify opposite corner: 6 found Select objects:↵ <Selection set: d> Проверим количество объектов в наборе mysset : Command: (sslength mysset) ↵ 6 Извлечем имя сущности нулевого элемента набора mysset : Command: (SSNAME MYSSET 0) ↵ <Entity name: 7ef921d8> Получим данные об этом объекте Command: (entget (ssname mysset 0)) ↵ ((-1 . <Entity name: 7ef921d8>) (0 . "LINE") (330 . <Entity name: 7ef90cf8>) (5 . "16B") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 -30.0 0.0 0.0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0)) Command: Задание 5.3 Построение объектов разного типа. Распечатка типов Постройте на экране отрезок, окружность, полилинию, прямоугольник и текст. В новом файле AutoLISP наберите следующий код: (defun c:listsset (/ mysset counter) (setq mysset (ssget)) (setq counter 0) (while (< counter (sslength mysset)) (terpri) (princ (cdr (assoc 0 (entget (ssname mysset counter))))) (setq counter (+ counter 1)) ) (princ) ) Сохраните файл как Mysset.lsp в \AutoCAD2007\Support . Загрузите его. В командной строке введите команду listsset . В ответ на приглашение выделите все объекты чертежа. Программа выведет следующий текст: Command: listsset↵ Select objects: all↵ 5 found Select objects:↵ MTEXT LWPOLYLINE LWPOLYLINE LINE CIRCLE Процедура работает следующим образом. В первой строке объявляется функция и две переменных: mysset и counter . Во второй строке переменной mysset присваивается набор выделенных пользователем объектов по запросу функции SSGET . В третьей строке счетчик counter устанавливается в нуль. В четвертой строке начинается цикл WHILE . Вначале функция SSLENGTH определяет количество элементов в наборе mysset . Затем задается условие выполнения цикла: показания счетчика должны быть меньше количества элементов в наборе. Другими словами, должны быть обработаны все объекты набора. В пятой строке стоит функция TERPRI - перевод строки. В шестой строке описаны пять операторов, работа которых выводит содержимое списка на экран. Вначале функция SSNAME определяет имя объекта с номером COUNTER в наборе mysset . Затем с помощью функции ENTGET процедура получает список данных на объект. Далее функция ASSOC извлекает из списка имя объекта из группы с кодом 0. В результате имеется точечная пара, где первым элементом является код группы, а вторым элементом является имя объекта. Функция CDR возвращает лишь нужное нам имя объекта, пропуская первый элемент списка. Функция PRINC выводит результат на экран. В седьмой строке значение счетчика увеличивается на 1. Цикл повторяется для следующего объекта. В восьмой строке цикл WHILE закрывается. В девятой строке стоит оператор корректного завершения процедуры. Скобка в десятой строке ограничивает тело функции. Ввод данных пользователемВ интерактивном режиме часто требуется предоставить пользователю возможность ввести какие-либо данные. Связь процедуры с пользователем в AutoLISP осуществляет ряд функций с префиксом GET . Основные из этих функций приведены в таблице.
Часто нужно приостановить выполнение процедуры, чтобы ввести значения или указать точку на объекте. Для этого в тело процедуры можно включить функцию PAUSE . Например, в команде (command "circle" pause "30") сделана пауза. Пользователь должен указать координаты центра, а затем программа создаст окружность с радиусом 30. Задание 5.4 Получение данных от пользователя Обратите внимание на функцию ENTSEL . Она представляет собой упрощенный вариант функции SSGET . Функция используется для выделения пользователем одного объекта. Она возвращает имя сущности и точечную пару, содержащую координаты указанной точки. Следовательно, после использования функции ENTSEL с помощью функции CAR можно получить имя сущности для функции ENTGET . В процедуре Вы встретитесь с параметром Т функции GETSTRING . Если он не равен nil , то при вводе данных допускаются пробелы. Таким образом, с помощью этого аргумента пользователь может вводить текстовые константы, состоящие из нескольких слов. Без него AutoLISP интерпретировал бы пробел как нажатие клавиши ENTER .
Процедура работает следующим образом.
Задание 5.5 Копирование свойств объекта В приведенной ниже программе заданному объекту присваивается тот же слой, что и другому объекту. Выполняется копирование свойств объекта. Методика, примененная здесь для копирования слоев объектов, может быть применена для изменения любых других свойств объектов AutoCAD . ;;; Копирование слоя выделенного объекта ;;; и присвоение слоя другим объектам (defun c:matchlayer (/ src_object mysset counter cur_ent_layer) ;; приглашение пользователю (princ "\n***Выделите исходный объект***") (if (setq src_object (car (entsel))) ; выделить объект (progn ; считывание слоя ; выбранного объекта (setq src_layer (assoc 8 (entget src_object))) ;; приглашение пользователю (princ "\n***Выделите объекты для копирования слоя***") ;; выделение нескольких объектов ;; с помощью функции ssget (if (setq mysset (ssget)) ; анализ выделенных объектов (progn ; если объекты выделены, выполнить следующее (setq counter 0) (while (< counter (sslength mysset)) (setq cur_ent (entget (ssname mysset counter))) (setq ent_layer (assoc 8 cur_ent)) (entmod (subst src_layer ent_layer cur_ent)) (setq counter (+ counter 1)) ) ;_ конец WHILE ) ;_ конец PROGN (princ "\nНи одного объекта не выделено") ) ;_ конец if ) ;_ завершение функции PROGN для выделения объектов ;; сообщение пользователю, если не выделен исходный объект (princ "\nВы не выделили исходный объект") ) ;_ конец оператора IF (princ) ) ;_ конец функции c:matchlayer В этой процедуре вначале определяется имя выделенного объекта с помощью функции (CAR (ENTSEL)) . Затем функция ENTGET выбирает сам объект по его имени и передает как параметр функции ASSOC . Эта функция выбирает слой объекта в группе с кодом 8 и формирует точечную пару код-имя слоя. Функция SETQ присваивает значение точечной пары переменной src_layer . На следующем шаге процедура получает от пользователя набор выделенных объектов с помощью функции SSGET . Этот набор присваивается переменной mysset . Далее в цикле идет перебор объектов набора. Для каждого из объектов функции выполняют одинаковые действия:
Выделение объекта источника происходит в теле оператора IF . Если объект не выделен, то блок "если ложно" выводит сообщение об ошибке: "Вы не выделили исходный объект". Аналогично для набора выводится сообщение: "Ни одного объекта не выделено". Задание 5.6 Отладка процедуры.
В процедуре применена новая функция проверки на равенство EQUAL . Она применяется для сравнения списков. Функции доступа и функции модификацииРассмотрим на простом примере, как свойства объектов AutoCAD экспортируются в AutoLISP . Пусть требуется получить координаты начальной точки отрезка. ;;; Эта функция создает отрезок с помощью функции COMMAND и возвращает nil (defun make-aline() (command "_line" "5,5" "15,5" "") ) Загрузите функцию. Для запуска последующих функций нужно набирать их выражения в окне Console средыVisual LISP . Для получения координат начальной точки выполните следующие действия:
Если требуется получить одновременно несколько свойств объекта, то нужно несколько раз повторить всю последовательность операций. Чтобы не писать один и тот же код многократно, можно создать простуюфункцию-интерфейс. В этой функции нужно объединить все выполненные выше операции для получения информации из любой группы свойств объекта, а не только из группы с кодом 10. Пример: ;;; Возвращает любую группу, значение кода которой ;;; содержится в списке свойств объекта ;;; Параметрами функции являются имя сущности и код группы (defun Get-A-Group-Code (EntityName GroupCode) (cdr (assoc GroupCode (entget EntityName))) ) Определяемая функция является функцией с аргументом. Параметры, стоящие в скобках, - это формальные параметры. Вместо них могут быть подставлены фактические параметры. Проверьте, например, работу этой функции, используя определенную ранее переменную LineEntity : (Get-A-Group-Code LineEntity 10)↵ (5.0 5.0 0.0) Можно специализировать этот интерфейс, определив специально функцию, извлекающую данные только из группы с кодом 10. Для такой функции понадобится лишь один параметр - имя сущности. Код группы будет включен в вызов функции: ((defun Get-A-Group-10-Code (anEntityName) (Get-A-Group-10-Code anEntityName 10) ) Проверьте работу этой функции, используя определенную ранее переменную LineEntity : (Get-A-Group-Code LineEntity)↵ (5.0 5.0 0.0) Изменить свойства объекта можно с помощью функций CONS, SUBST, ENTMOD . Функция CONS создает новый список, добавляя в него первый элемент. Ее используют, если хотят присвоить группе с определенным кодом значения заданного списка. Ведите, например, в окне Console такой код: (setq NewStartPoint (cons 10 (0 0 0)))↵ Среда AutoLISP возвратит следующее: (10 0 0 0) Используя переменные NewStartPoin и LinePropertyList , можно подставить вновь созданный список в группу с кодом 10. Это делается с помощью функции SUBST : (Setq AcadLinePropertyList (subst NewStartPoin (assoc 10 AcadLinePropertyList))) Чтобы внести выполненные в списках изменения в реальный объект AutoCAD , можно воспользоваться функцией ENTMOD : (entmod LinePropertyList)↵ Создадим функцию-интерфейс, которая модифицирует группу с любым кодом для произвольного объекта: (defun put-group-code-value (Entityname Groupcode Value / PropertyList) (setq PropertyList (entget Entityname)) (setq PropertyList (subst (cons GroupCode Value) (assoc GroupCode PropertyList) PropertyList );_ завершение subst );_ завершение setq (entmod PropertyList) );_ завершение put-group-code-value В данной функции применены все выполнявшиеся ранее действия. Рассмотрим работу этой функции. В первой и второй строках определяется функция put-group-code-value с тремя аргументами. В качестве первого выступает имя сущностиEntityname , код группы Groupcode и новое значение группы с этим кодом Value . Здесь же определена локальная переменная PropertyList , предназначенная для хранения списка свойств объекта. В третьей строке переменной PropertyList присваивается список свойств объекта, получаемый с помощью функции ENTGET . В строке 4 описан процесс присвоения новых значений указанной группе списка. В строках 5-8 выполняется подстановка новой группы, созданной функцией (cons GroupCode Value) , на место текущих значений группы в списке свойств PropertyList . В строке 11 база данных чертежа модифицируется с помощью функции ENTMOD . Эта функция позволяет существенно упростить модификацию любой группы списка свойств. Теперь с помощью функции put-group-code-valueможно модифицировать группу с кодом 10 для нашего отрезка. Введите и загрузите функцию. Проверьте ее работу, введя в Visual LISP следующий код: (put-group-code-value LineEntity 10 '(5 5 0))↵ Функция изменит координаты начальной точки отрезка. По этому принципу можно определить отдельную функцию, которая модифицирует группу с кодом 10 или с любым другим кодом. (defun put-group-10-code (Entityname Value) (put-a-group-code-value Entityname 10 Value) Введите и загрузите эту функцию. Затем в окне CONSOLE введите следующий код, чтобы изменить координаты начальной точки отрезка на 15, -5,0. (put-group-10-code LineEntity '(15 -5 0)) В окне AutoCAD убедитесь, что начальная точка отрезка изменилась.
Разработка приложений на языке LISPНесколько выполняемых совместно и связанных между собой LISP -программ можно объединить в один проект. Каждый такой проект может работать в исходных текстах или в компилированных файлах с расширением FAS . Компиляция проекта в единый FAS -файл дает преимущества по скорости загрузки и выполнения. Новый проект создается по команде Project - New Project . После введения имени проекта открывается диалоговое окно Project Properties с двумя вкладками (рис.5.2).
Рис. 5.2. Диалоговые окна Project properties Проекты открываются по команде Project - Open Project . Окно проекта содержит перечень файлов и панель инструментов с командами, аналогичными командам в меню (рис.5.3). Файлы открываются двойным щелчком на их имени. Загрузить весь проект можно, щелкнув по кнопке Load Project FAS . Можно работать также с каждым файлом в отдельности. Рис. 5.3. Открытие файлов LSP из окна проекта Другой вид приложений - VLX -приложения, в состав которых могут входить не только LSP -файлы, но и DSL-файлы диалоговых окон, FAS -файлы и текстовые TXT -файлы. Все включаемые компоненты собираются в единый файл приложения с расширением VLX . Для создания нового VLX -приложения нужно вызвать мастера по команде File - Make Application - New Application Wizard (рис.5.4). Выбор режима, определяющего тип приложения, возможен из двух вариантов: SIMPLE или EXPERT . Простое приложение может состоять только из LSP и FAS -файлов. В сложном приложении могут присутствовать также DSL, PRJ и TXT -файлы. Рис. 5.4. Вызов мастера создания VLX-файлов Загрузить файл можно по команде File - Load File , либо с консоли с помощью функции Load , либо в сеансе AutoCAD . Помимо примитивов, в рисунке всегда присутствует неграфическая информация: описания блоков, таблицы слоев, видовых экранов, типов линий, размерных стиле и пр. Все они хранятся в базе данных примерно в таком же виде, как примитивы. Для доступа к табличным объектам в языке AutoLISP используют функции: tblnext, tblobjname, tblsearch . В качестве названий таблиц в этих функциях могут фигурировать только следующие текстовые строки:
Рассмотрим на примерах схему использования этих функций. (setq listlay1 (tblnext "LAYER" T)) - возвращает список с данными первого слоя рисунка, например, такого типа: ((0 . "Layer") (2 . "0") (70 . 0) (62 . 7) (6 . "Continuous")). Это список точечных пар. DXF -коды означают:
Для примитивов подобный список возвращает функция entget . (setq listlay2 (tblnext "LAYER")) - возвращает список с данными второго слоя рисунка, например, такого типа: ((0 . "Layer") (2 . "Inner") (70 . 4) (62 . 4) (6 . "Dashed")). Если запустить функцию (setq lay2name (tblobjname "Layer" "Inner")) , то она возвратит <Entity name:14ab234> . Теперь с помощью функцииentget можно получить тот же список, что и для listlay2 в предыдущем примере. С помощью этих функций можно проанализировать наличие в чертеже таких элементов, как описания блоков, пользовательские системы координат, текстовые стили. Свойствами, аналогичными таблицам, обладают словари. Существуют словари стилей мультилиний, групп, таблиц, растровых изображений, вкладок листов. Пользовательские приложения могут создавать в чертеже свои словари. Операции над словарями и их элементами осуществляют функции: dictadd, dictnext, dictremove, dictrename, dictsearch, namedobjdict . Здесь нет операции модификации записи. Поэтому при необходимости нужно вначале удалить старую запись. Затем добавить в словарь новую. Файлы AutoLISP можно загрузить либо непосредственно в AutoCAD , либо в среде Visual LISP . Все файлы процедур должны иметь расширение .LSP. Однако для безопасности и ускорения работы процедуры AutoLISP можно компилировать в файлы проекта с расширением .PRJ или .VLX . Программа сначала загружает одноименные файлы с расширением .VLX . Если такого файла нет, то программа ищет файл .PRJ . Если и его нет, то загружается файл .LSP . Однако, если файл LSP более новый, чем другие, то он загрузится в первую очередь. Загpузить файл "Circle.LSP " в AutoCAD можно следующими способами:
Если файл находится в каталоге, не включенном в список маршрутов поддержки, то необходимо задать полный маршрут файла: (load "c:/Programm Files/AutoCAD 2007/Support/Circle") или (load "c:\\Programm Files\\AutoCAD 2007\\Support\\Circle") Обычно все процедуры AutoLISP сохраняют в одном каталоге. Этому каталогу создают маршрут доступа к файлам поддержки по команде Tools - Options - Files - Support File Search Path - Add - Browse . Программа AutoCAD автоматически загружает четыре файла AutoLISP . Первые два - системные ACAD2010.LSP и ACADDOC2010.LSP . Два других файла предназначены для пользователей: ACAD.LSP и ACADDOC.LSP . Пользователи могут загружать в эти файлы любое количество процедур. При открытии нескольких чертежей можно по-разному организовывать процедуры AutoLISP в зависимости от того, применяются ли они ко всем чертежам или к чертежу, открытому первым. Файл ACAD.LSP загружается только для первого чертежа. Файл ACADDOC.LSP загружается при открытии каждого чертежа. Порядок загрузки файлов:
Файлы AutoLISP , загруженные для одного конкретного чертежа со своими переменными, не будут доступны в остальных чертежах. Для совместного использования функций в нескольких чертежах вместо команды (load "circle" ) нужно применить команду (vl-load-all "circle" ). Действие функций файла будет распространяться не только на все открытые чертежи, но и на все чертежи, которые будут открыты в данном сеансе. Упражнение Создайте приветствие на экране. Загрузите в файл C:\Programm Files\AutoCAD2010 \Support\acad.lsp такую процедуру: (defun c:tex (/) (command "-view" "_top" "_vscurrent" "_2dwireframe" "_regen") (entmake (list '(0 . "TEXT") '(8 . "0") '(100 . "AcDbText") '(10 0.0 0.0 0.0) '(40 . 2.5) '(1 . "Hello") '(7 . "Standard") ) ) (command "_zoom" "_e") ) (c:tex) Проанализируйте каждую группу списка свойств текстового примитива.
Ключевые терминыСущность объекта (entity ) - список параметров объекта в базе данных. Имя сущности (entity name) - параметр сущности с кодом DXF , равным -1. Набор объектов - совокупность объектов, выделенных по команде ssget (Selection Set Get - получение набора выделения). Файлы инициализации - четыре файла AutoLISP , автоматически загружаемые в AutoCAD . Для пользователей предназначены два файла: ACAD.LSP иACADDOC.LSP . Проект - несколько выполняемых совместно и связанных между собой LISP -программ.
Краткие итогиЛюбой объект AutoCAD описывается в базе данных программы списком своих параметров. С помощью функций доступа и модификации возможно редактирование этих параметров и изменение объекта. |