Autocad entities что это
Приведенные выше функции AutoLISP дают пользователю возможность работы только с файлами последовательного доступа. Указателем позиции в файле, с которой далее будет происходить чтение (запись), является переменная, в которой хранится дескриптор этого файла. Механизм работы с файлами виден на следующем примере.
Пример использования функций работы с файлами
Первое выражение - (setq ff (open "c: \\test.txt" "w")) - создает переменную ff , в которую заносится дескриптор файла c:\test.txt , открываемого для записи (в первом аргументе функции open обратная косая черта удваивается). Затем выражение ( write-line "первая строка" ff ) заносит в открытый файл первую запись (текст "Первая строка" из 13 символов) и символы с кодами 13 и 10, которые в файлах последовательного доступа разделяют записи.
В операционной системе UNIX признаком конца записи является один символ с кодом 10.
После этого указатель файла показывает на начало второй записи, куда поочередно - с помощью двукратного применения функции write-char - заносятся символы с кодами 65 (буква "А") и 67 ("С"). Затем в продолжение второй записи файла с помощью функции write-line заносится текст "вторая строка" (13 символов) и добавляются символы с кодами 13 и 10, означающие конец второй записи файла. Вслед за этим файл с дескриптором ff закрывается функцией close .
Вторая часть листинга начинается функцией открытия того же файла, но уже в режиме чтения. Затем с помощью двукратного применения функций read-char читаются два первых символа первой записи, которые запоминаются в переменных s1 и s2 . После этого в переменную strl читается остаток первой записи. Далее в переменную str2 читается вторая запись файла. Третья операция чтения с помощью функции read-line приносит nil , поскольку в файле c:\test.txt третьей записи нет. По окончании выполнения рассмотренной программы переменная ff очищается (в ней хранился дескриптор файла). Другие переменные получат такие значения:
Функции доступа к примитивам
Рисунок в системе AutoCAD имеет организацию, аналогичную организации базы данных, в которой элементы (графические примитивы и неграфические объекты) имеют списковую структуру . Каждый примитив имеет свой тип. Перечислим все эти типы примитивов в алфавитном порядке: 3DFACE, 3DSOLID, ACAD_PROXY_ENTITY, ARC, ARCALIGNEDTEXT, ATTDEF, ATTRIB, BODY, CIRCLE, DIMENSION, ELLIPSE, HATCH , IMAGE, INSERT, LEADER , LINE, LWPOLYLINE, MLINE, MTEXT, OLEFRAME, OLE2FRAME, POINT, POLYLINE , RAY, REGION, RTEXT, SEQEND, SHAPE, SOLID, SPLINE , TEXT, TOLERANCE, TRACE, VERTEX , VIEWPORT , WIPEOUT, XLINE . Как правило, наименование типа совпадает с английским именем команды системы AutoCAD , которая создает графический объект.
Функции, рассматриваемые в данном разделе, работают с примитивами рисунка, обращаясь непосредственно к их внутренней структуре. AutoLISP имеет средства выбора графических объектов, как по их порядковому номеру, так и по определенным признакам (цвету, слою и т. п.).
Функция entlast извлекает последний неудаленный основной примитив рисунка:
Функция возвращает nil , если в рисунке нет неудаленных примитивов (например, когда вы только что создали новый рисунок); иначе возвращается имя последнего основного примитива в следующем виде:
Полученное имя следует сохранить в переменной, например:
Функция entnext позволяет перейти в рисунке к следующему примитиву (подпримитиву):
В качестве единственного аргумента функции entnext может выступать ранее полученное имя примитива текущего рисунка. Если функция вызывается без аргумента, то она возвращает имя первого неудаленного примитива в базе рисунка. При наличии аргумента функция возвращает имя следующего примитива, либо nil , если база графических объектов рисунка исчерпана.
- (setq el (entnext)) - возвращает имя первого неудаленного примитива;
- (setq e2 (entnext е2)) - возвращает имя примитива, следующего за e1 ;
- (setq еЗ (entnext еЗ)) - возвращает имя примитива, следующего за e2 .
Функция entlast возвращает имя последнего основного примитива. Это означает, что если последним созданным графическим объектом рисунка является сложный объект (например, полилиния типа POLYLINE ), то вслед за ним в базе рисунка следуют подпримитивы, т. е. вершины (имя примитива - VERTEX ), а завершается перечисление подпримитивов полилинии примитивом SEQEND .
Пример (в предположении, что объект типа POLYLINE является последним основным примитивом):
- (setq eela (entlast)) - возвращает имя основного примитива последней полилинии ;
- (setq v1 (entnext eela)) - возвращает имя примитива, являющегося первой вершиной полилинии ;
- (setq v2 (entnext v1)) - возвращает имя примитива, являющегося второй вершиной полилинии .
В легкой полилинии (примитиве типа LWPOLYLINE ) нет подпримитивов и информация обо всех вершинах может быть извлечена из основного примитива.
Функция entsel предлагает пользователю указать один объект, выдавая соответствующий запрос:
Здесь аргумент - любая строка текста. Функция возвращает список, состоящий из двух элементов: имени выбранного примитива и точки, которой пользователь указал объект (такая точка, как правило, оказывается вне самого примитива, поскольку точность указания мышью зависит от величины прицела). Можно указать объект вводом с клавиатуры ключевого слова Last - тогда в возвращаемом списке координаты точки будут нулевыми.
Имя указанного пользователем объекта может быть извлечено из такого списка, например, с помощью функции car .
Функция entdel позволяет удалять неудаленные основные примитивы и восстанавливать примитивы, ранее удаленные в данном сеансе редактирования:
Функция возвращает имя удаляемого (восстанавливаемого) примитива. Следует иметь в виду, что при операции сохранения рисунка все примитивы, помеченные как удаленные, из рисунка стираются и уже больше не могут быть восстановлены.
Функция entget является основным инструментом извлечения информации о примитиве, т. к. получает список с его характеристиками:
Здесь аргумент - это имя примитива для получения его данных, аргумент - это список с именами приложений, с помощью которых к примитиву привязаны расширенные данные (о расширенных данных см. ниже).
Предположим, в рисунке первым объектом является отрезок (тип примитива - LINE ). Тогда выражение (setq le (entget (entnext) ) ) должно вернуть примерно такой список:
В этом списке элементами являются точечные пары и списки, причем и в тех, и в других первыми элементами- выступают целые числа, называемые DXF -кодами. Под соответствующим кодом в точечных парах и списках находятся данные определенного типа:
- код -1 указывает имя примитива (),
- код 0 - тип примитива (" LINE "),
- код 5 - метку (внутренний номер примитива в рисунке),
- код 410 - имя вкладки пространства модели или листа,
- код 8 - имя слоя ("0"),
- код 10 - координаты начальной точки (201.536 140.622 0.0),
- код 11 - координаты конечной точки (285.148 96.5053 0.0),
- код 210- направление вектора нормали к плоскости, в которой описан примитив. Остальные коды, не имеющие принципиального значения, здесь не рассматриваются. С помощью функции assoc можно из списка с характеристиками объекта извлечь нужную точечную пару, а затем, применив функцию cdr , получить данные необходимого DXF -кода.
Продолжим пример с отрезком:
- (cdr (assoc 0 le)) - возвращает " LINE " (тип примитива);
- (cdr (assoc 8 le)) - возвращает "0" (имя слоя);
- (cdr (assoc 10 le)) - возвращает (201.536 140.622 0.0);
- (cdr (assoc 11 le)) - возвращает (285.148 96.5053 0.0).
Кроме того, по коду 62 можно было бы извлечь номер цвета примитива, по коду 6 - имя типа линии, по коду 48 - собственный масштаб типа линии, по коду 311 - вес линии (умноженный на 100). В рассмотренном выше списке le точечных пар с такими DXF -кодами нет, поэтому для них действуют значения по умолчанию: BYLAYER (ПОСЛОЮ) или 1.
Рассмотрим, какой примерный список можно было бы получить для окружности (объекта типа CIRCLE ):
Для окружности DXF -коды -l, 0, 410, 8, 210 имеют тот же смысл, что и для всех примитивов (в том числе и для примитива типа " LINE "). Под кодом 40 находится радиус окружности, а точечная пара с DXF -кодом 10 хранит в себе данные о центре.
Поэтому для рассматриваемой окружности:
- (cdr (assoc 40 le)) - возвращает 27.8941 (радиус);
- (cdr (assoc 10 le) ) - возвращает (387.691 142.198 0.0).
Сравнивая справочную информацию, выдаваемую командой LIST , и список, получаемый с помощью функции entget , можно получить геометрический смысл DXF -кодов для примитивов других типов.
Если построить в программе список, описывающий примитив (кроме точечной пары с флагом -1), то можно создать в рисунке такой примитив с помощью следующих функций:
- (entmake ) - создает новый примитив по списку, структура которого аналогична структуре списка, возвращаемого функцией entget ; функция entmake не может создать примитив типа VIEWPORT ; возвращаемое значение - аргумент или nil , если создание объекта невозможно;
- (entmakex ) - создает новый примитив или неграфический объект по списку, аналогично функции entmake ; возвращаемое значение - имя нового примитива или nil , если создание объекта невозможно.
Функция entmod похожа на функцию entmake , но получает в качестве аргумента список, который содержит точечную пару с DXF -кодом -1 (т. е. имя существующего в рисунке примитива) и модифицирует примитив в соответствии с новым списком (в списке могут изменяться любые данные, кроме имени примитива, типа примитива и метки):
Функция entmod изменяет примитив в базе рисунка и возвращает аргумент при успешном завершении или nil - при невозможности выполнить изменение. Для перерисовки примитива на экране следует воспользоваться функцией entupd :
Здесь аргумент - это имя примитива в том виде, в котором оно выводится, например, функцией entlast .
Другие функции доступа к примитивам:
- (handent ) - возвращает имя примитива или неграфического объекта по его метке; аргумент - это текстовая строка с шестнадцатеричной меткой в том виде, в каком она возвращается функцией entget ;
- (nentsel [запрос] ) - запрашивает объект и для простого примитива возвращает такой же список из имени примитива и точки указания, как и функция entsel . Если указанный пользователем примитив является трехмерной полилинией ( POLYLINE ), то первым элементом возвращаемого списка будет имя подпримитива начальной вершины ( VERTEX ) участка, на котором указывалась полилиния. Если указанный пользователем объект является вхождением блока ( INSERT ), то возвращается список из двух или четырех элементов. Если аргумент запроса не задан, то в качестве подсказки выводится запрос: Select object :
- (nentselp [запрос] []) - аналогична функции nentsel , но если указанным примитивом является вхождение блока ( INSERT ), то возвращает список, в котором третьим элементом является матрица преобразования размером не 4х3, а 4х4 (см. ниже); если задан аргумент , то запрос не выдается и аргумент выступает в качестве точки указания.
Функция nentsel работает с блоками (точнее, с примитивами типа INSERT ) следующим образом. В случае, если пользователь указал атрибут блока, то функция возвращает список из двух элементов: первым является имя объекта-атрибута, а вторым - точка указания атрибута. В случае, если пользователь указал не атрибут, а объект, принадлежащий вхождению блока, то возвращается список из четырех элементов:
- первым является имя примитива, с помощью которого был указан блок,
- вторым - точка указания,
- третьим - матрица размером 4х3 для преобразования точек из системы координат объекта (СКО) в МСК,
- четвертым - список с именем блока, содержащим указанный примитив (если примитив входит в блок, который вложен в другой блок. то список содержит все имена вкладываемых блоков, начиная от самого внутреннего и кончая самым внешним).
Матрица размером 4х3, которая выдается в качестве третьего элемента возвращаемого функцией nentsel значения, имеет вид: ((m00 m01 m02) (m10 m11 m12) (m20 m21 m22) (m30 m31 m32)) . Тогда преобразование точек из СКО в МСК идет по системе уравнений:
Здесь (X Y Z) - координаты точки до преобразования, (X' Y' Z') - координаты точки после преобразования.
Функция nentselp работает аналогично функции nentsel , но в случае, если пользователь указал объект, принадлежащий вхождению блока, то тоже возвращается список из четырех элементов, но третьим элементом является матрица размером 4х4, которая служит для преобразования точек из системы координат объекта (СКО) в МСК. Матрица имеет вид: ((n00 n01 n02 n03) (n10 n11 n12 n13) (n20 n21 n22 n23) (0.0 0.0 0.0 1.0)) . Преобразование точек из СКО в МСК идет по такой системе уравнений:
Это очередная статья из цикла, посвященного разработке плагинов для AutoCAD. Речь в ней будет идти о базовых операциях со слоями в документе.
1. Общая информация
Слои могут сильно упростить жизнь не только инженеру, создающему чертеж, но и программисту. Например, все расположенные на одном слое элементы можно при необходимости очень быстро скрыть, а затем вновь отобразить на рабочей области.
В рамках этой статьи нам потребуются некоторые базовые сведения, которые в основном можно почерпнуть отсюда (зеркало)
1.1. Слой номер ноль
Любой документ AutoCAD всегда содержит в себе как минимум один слой — нулевой (с именем «0»), который невозможно удалить. Этот слой часто оказывается очень полезным — например, при удалении других слоев.
1.2. Текущий слой
Один из слоев документа обязательно должен являться текущим (current). На него помещаются все добавляемые на чертеж объекты (по крайней мере примитивные — с блоками дела обстоят несколько сложнее).
1.3. Свойства слоев
- включен ("on");
- заморожен ("freeze");
- заблокирован ("lock").
Флаг "включен" отвечает за видимость слоя. Если этот флаг сброшен, то все элементы, расположенные на слое, перестают отображаться на чертеже.
Флаг "заморожен" также отвечает за видимость слоя. По своему действию он аналогичен флагу «включен». Как указано в документации, это свойство позволяет повысить производительность на очень больших чертежах.
Флаг "заблокирован" отвечает за возможность редактирования слоя. Если этот флаг установлен, то все элементы, расположенные на слое, становятся недоступными для любых изменений (перемещение, удаление и т. п.). Кроме того, на заблокированный слой нельзя добавлять новые элементы.
Свойствами слоев можно управлять из AutoCAD. На расположенном ниже рисунке ядовито-зеленым выделена панель «Слои» (Layers), а фиолетовым выделен выпадающий список слоев, в левой части которого находятся переключатели свойств (лампочка, солнышко, открытый замок — «on», «freeze» и «lock» соответственно).
На эти переключатели действительно стоит обратить внимание: при написании плагина не всегда всё получается с первого раза, и порой приходится применять «ручное управление».
Некоторые сайты утверждают, что на этой картинке изображены не зеленый и фиолетовый цвета, а лайм и гелиотроп.
…
Наверное, я — собака.
1.4. Управление слоями
Самые простые действия со слоями были рассмотрены в предыдущем пункте. Для более сложных операций (например, создание или удаление слоя) нужно воспользоваться панелью «Свойства слоев» (Layer Properties), которая вызывается командой LAYER или щелчком по соответствующей иконке на панели «Слои» (обозначена оранжевым на рисунке в предыдущем подразделе). Вот как выглядит эта панель:
Особый интерес представляет выделенная рамкой секция кнопок. Первая кнопка в ней создает новый слой, третья — удаляет существующий, если это возможно.
- нулевой слой;
- текущий слой;
- слой, содержащий хотя бы один объект;
- слой, на который имеется ссылка в определении блока.
На самом деле список запрещенных к удалению слоев несколько длиннее:
К сожалению, автору данного поста не приходилось сталкиваться ни с Defpoints, ни с Xref-dependent layers, поэтому проработку этих элементарных вопросов оставим читателям в качестве несложного домашнего задания. ^__^
На этом с теорией все, можно приступать к практике.
2. Написание плагина
2.1. Создание нового проекта плагина
2.2. Добавление ссылок на необходимые библиотеки
2.3. Добавление нового слоя
Все присутствующие в документе слои хранятся в списке слоев. Для добавления на чертеж нового слоя достаточно добавить новый элемент в этот список.
Однако несмотря на простоту операции, кода получается довольно много.
После загрузки плагина и выполнения команды «TestCommand» на чертеже должен появиться новый слой:
В приведенном выше коде использовались две важные конструкции, которые часто встречаются при работе с объектами чертежа:
Документация Autocad говорит, что запросы на изменение объектов или на доступ к AutoCAD могут выполняться в любом контексте и от любого количества приложений. Чтобы предотвратить конфликты с другими запросами, программист должен сам обеспечить блокировку документа перед его изменением. Невыполнение этого требования в некоторых случаях приводит к возникновению ошибки при изменении базы данных документа.
После выполнения всех необходимых изменений в базе данных её следует разблокировать, используя метод Dispose() объекта DocumentLock . Также можно использовать блок using с объявлением в нём объекта DocumentLock — в этом случае при выходе из блока база данных разблокируется автоматически. (источник, зеркало)
По моему опыту, использование конструкции using гораздо удобнее, так как сводит к нулю вероятность забыть вызвать метод Dispose() .
В документации (зеркало) указано, что при работе с объектами, такими как отрезки, окружности и полилинии, или с таблицей идентификаторов и ее записями необходимо открывать объект для чтения или записи.
Попытки игнорировать это требование ни к чему хорошему не приведут — могут возникнуть весьма неприятные (в том числе с точки зрения отладки) ошибки.
- начало новой транзакции;
- открытие объекта на чтение или запись;
- если объект создается впервые (его еще нет в документе) — добавление его в базу данных документа;
- фиксация транзакции;
- завершение транзакции.
Как и в случае с DocumentLock , необходимо или вызывать метод Dispose() после окончания работы с транзакцией, или использовать конструкцию using .
Теперь, когда мы разобрались с блокировкой документа и транзакциями, можно перейти к разбору остальной части кода.
Во-первых, мы подключаем необходимые пространства имен:
Во-вторых, мы блокируем документ и начинаем транзакцию:
В-третьих, мы получаем ссылку на таблицу слоев документа:
Метод GetObject() принимает на вход два параметра: Id объекта, который необходимо открыть, и уровень доступа. Узнать Id таблицы слоев документа можно с помощью свойства LayerTableId базы данных этого документа. Поскольку нам необходимо изменить таблицу слоев (добавить в нее новый слой), мы используем уровень доступа «запись» ( OpenMode.ForWrite ). Наконец, метод GetObject() возвращает значение типа «объект» ( object ), которое необходимо явно привести к нужному нам типу ( LayerTable ).
В-четвертых, мы создаем новый слой:
Слой (а точнее, соответствующая ему запись в таблице слоев документа) имеет тип LayerTableRecord . Его конструктор не принимает никаких значений, поэтому всю инициализацию приходится проводить уже после создания.
В этом примере мы изменили только имя нового слоя, однако при необходимости можно задать и другие параметры, например видимость (свойство IsOff ) или доступность для редактирования (свойство IsLocked ).
В-пятых, мы заносим новый слой в таблицу слоев документа:
Таблица слоев — это класс, для которого реализован интерфейс IEnumerable . Для добавления нового элемента используется метод Add() .
В-шестых, мы добавляем новый слой в БД документа:
Поскольку до начала транзакции этого слоя не существовало, мы должны явно указать, что его необходимо добавить в БД документа. Если этого не сделать, запись добавлена не будет.
Важная деталь: функция AddNewlyCreatedDBObject должна вызываться не до, а после добавления слоя в таблицу слоев документа. Если попытаться поменять эти операции местами, то слой не будет добавлен. Стройного логического объяснения этому у меня нет; буду рад, если знающие люди поделятся разгадкой в комментариях.
В-седьмых, мы фиксируем транзакцию:
Если какие-либо элементы, открытые во время транзакции с помощью метода GetObject() , были изменены, то для сохранения этих изменений в БД документа необходимо зафиксировать транзакцию, вызвав метод Commit() . В противном случае никакие изменения сохранены не будут, и документ останется в состоянии, которое существовало на момент начала транзакции.
Наконец, мы заканчиваем транзакцию и снимаем блокировку документа:
Вот он, важный плюс использования конструкции using ! Без нее очень легко забыть вызвать метод Dispose() , тем более что сделать это нужно дважды — для фиксации транзакции и для разблокировки документа. А при использовании конструкции using метод Dispose() вызывается автоматически.
2.4. Установка текущего слоя
Получить текущий слой документа и установить новый можно с помощью свойства Clayer базы данных документа.
2.5. Изменение свойств и переименование слоя
Для изменения свойств слоя нужно открыть соответствующую запись в таблице слоев.
Перед операцией со слоем нелишним будет убедиться в его существовании с помощью метода Has() таблицы слоев документа.
Если мы загрузим плагин, выполним команду «TestCommand», а затем — команду «NewCommand», то увидим, что созданный нами слой стал скрытым, заблокированным и сменил имя. Теперь никто его не найдет.
2.6. Удаление слоя
Удаление слоя происходит во многом аналогично изменению. Для соответствующей записи в таблице слоев вызывается метод Erase() следующим образом:
- нулевой слой;
- текущий слой;
- слой, содержащий хотя бы один объект;
- слой, на который имеется ссылка в определении блока.
Если необходимо удалить слой, на котором присутствуют какие-либо объекты, то перед удалением слоя необходимо удалить все эти объекты или же перенести их на другой слой.
А в блоге Kean Walmsley есть шаблон для поиска всех размещенных на слое объектов. На базе этого примера можно написать функцию, удаляющую со слоя все объекты.
В любом случае, перед удалением слоя не лишним будет убедиться в корректности операции, а само удаление обрамить конструкцией try . catch .
В этом коде нам уже знакомо все, кроме метода Purge() . Принцип его действия описан в документации: он анализирует коллекцию объектов и на выходе оставляет в ней только те объекты, на которые никто не ссылается.
В рассмотренном примере метод Purge() вызывается для коллекции, в которой находится только один объект — удаляемый слой. Если на этот слой никто не ссылается, то после вызова метода Purge() он останется в коллекции, и тогда можно приступать к удалению. Если же вызов метода Purge() вернет пустую коллекцию, то на удаляемый слой имеются ссылки — вероятно, это размещенные на нем объекты.
Если мы загрузим плагин и выполним команду «TestCommand», а затем — команду «NewCommand», то увидим, что созданный нами слой удалится с чертежа.
2.7. Запрет затемнения заблокированных слоев
В завершение хотелось бы рассказать еще об одном параметре, связанном со слоями.
По умолчанию заблокированные слои в AutoCAD отображаются затемненными. Максимально возможное затемнение составляет 90% (как у прямоугольника на рисунке ниже).
Для изменения степени затемнения служит переменная LAYLOCKFADECTL. Ее значение устанавливается соответствующим ползунком на панели управления слоями (обведен на рисунке зеленым цветом).
Для изменения значения переменной LAYLOCKFADECTL внутри плагина можно воспользоваться функцией SetSystemVariable :
В результате выполнения этого кода затемнение заблокированных слоев будет отключено.
Перед изменением переменной LAYLOCKFADECTL стоит сохранить ее текущее значение, чтобы вернуть переменную в исходное состояние после того, как плагин закончит работу.
К сожалению, метод Terminate() не всегда отрабатывает корректно, и исходное значение может не восстановиться. Но мы хотя бы попытались.)
На этом пока все. В следующий раз напишу о создании простых объектов и блоков.
pavian
Просмотр профиля
имеется с виду обычный файл, но некоторые объекты определяются как
acad_proxy_entity, с которыми я ничего не могу сделать (даже тупо удалить)
что это и как енто переразбить хотя-бы в линии
спасибо за ответы
pavian
Просмотр профиля
point111
Просмотр профиля
чего так расстраиваться? значит народ просто не знает.
Ничего ты с этими объектами не сделаешь, потому что, при их создании использовались библы (dll) которых у тебя просто нет. Попроси создателя файла "взорвать" такие объекты, или сказать чем он пользовался (могу предположить, что файл создан с помощью нахлобучки типа SPDS)
pavian
Просмотр профиля
но может кто-нить знает, что с этим можно прямо в автокаде(2006) сделать, не утанавливая всякого рода примочек?
point111
Просмотр профиля
ну как бы тебе попроще объяснить.
вот дали тебе файл *max сделаный с помощью плага, которого у тебя нет, как ты будешь управлять этим файлом без плага? Просто автокад в некоторых случаях может показать объекты, а макс сразу их выкидывает.
pavian
Просмотр профиля
point111
Просмотр профиля
и то верно, чё тут думать, прыгать надо
А попробовать почитать что нить о программировании на ObjectArx для автокада слабо? чтобы мысли дурные в голову не лезли.
pavian
Просмотр профиля
Eine
Просмотр профиля
Всё зависит от того, что хочется сделать с такими объектами.
1. Если просто надоел диалог с предупреждением/напоминанием: отключить в опциях.
3. Разбить некоторые прокси "на линии" может оказаться невозможным, так как зачастую это неграфические объекты (словари, расширенные данные и т.д.). Тот же СПДС записывает в рисунок прокси в качестве "автографа", даже если в рисунке нет ни одного объекта собственно СПДС, и ничего поделать с этим уже нельзя.
ЗЫ: по-моему последнее — оптимально.
pavian
Просмотр профиля
2 Eine: забил и причем давно
всем спасибо за ответы!
Yehat
Просмотр профиля
Рассмотрим на простом примере, как свойства объектов AutoCAD экспортируются в AutoLISP . Пусть требуется получить координаты начальной точки отрезка.
Загрузите функцию. Для запуска последующих функций нужно набирать их выражения в окне Console среды Visual LISP . Для получения координат начальной точки выполните следующие действия:
- Запустите функцию, введя в окне Console (make-aline) .
- Присвойте переменной LineEntity имя созданной сущности: (setq LineEntity (entlast)) ↵
- С помощью функции ENTGET получите список свойств этого объекта. Для этого введите в окне Console среды Visual LISP следующее выражение: (setq LinePropertyList (entget LineEntity)) ↵
- Извлеките из списка свойств группу с кодом 10: (setq StartOfLineList (assoc 10 LinePropertyList)) ↵
- Получите список только с координатами (setq StartOfLine (cdr (assoc 10 LinePropertyList))) ↵
Если требуется получить одновременно несколько свойств объекта, то нужно несколько раз повторить всю последовательность операций. Чтобы не писать один и тот же код многократно, можно создать простую функцию-интерфейс. В этой функции нужно объединить все выполненные выше операции для получения информации из любой группы свойств объекта, а не только из группы с кодом 10.
Определяемая функция является функцией с аргументом. Параметры, стоящие в скобках, - это формальные параметры. Вместо них могут быть подставлены фактические параметры. Проверьте, например, работу этой функции, используя определенную ранее переменную LineEntity :
Можно специализировать этот интерфейс , определив специально функцию, извлекающую данные только из группы с кодом 10. Для такой функции понадобится лишь один параметр - имя сущности. Код группы будет включен в вызов функции :
Проверьте работу этой функции, используя определенную ранее переменную LineEntity :
Изменить свойства объекта можно с помощью функций CONS, SUBST, ENTMOD . Функция CONS создает новый список , добавляя в него первый элемент. Ее используют, если хотят присвоить группе с определенным кодом значения заданного списка. Ведите, например, в окне Console такой код:
Используя переменные NewStartPoin и LinePropertyList , можно подставить вновь созданный список в группу с кодом 10. Это делается с помощью функции SUBST :
Чтобы внести выполненные в списках изменения в реальный объект AutoCAD , можно воспользоваться функцией ENTMOD :
Создадим функцию- интерфейс , которая модифицирует группу с любым кодом для произвольного объекта:
В данной функции применены все выполнявшиеся ранее действия. Рассмотрим работу этой функции.
В первой и второй строках определяется функция 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 следующий код:
Функция изменит координаты начальной точки отрезка.
По этому принципу можно определить отдельную функцию, которая модифицирует группу с кодом 10 или с любым другим кодом.
Введите и загрузите эту функцию. Затем в окне CONSOLE введите следующий код, чтобы изменить координаты начальной точки отрезка на 15, -5,0.
В окне AutoCAD убедитесь, что начальная точка отрезка изменилась.
Разработка приложений на языке LISP
Несколько выполняемых совместно и связанных между собой LISP -программ можно объединить в один проект. Каждый такой проект может работать в исходных текстах или в компилированных файлах с расширением FAS . Компиляция проекта в единый FAS - файл дает преимущества по скорости загрузки и выполнения.
Новый проект создается по команде Project - New Project . После введения имени проекта открывается диалоговое окно Project Properties с двумя вкладками (рис.5.2).
Проекты открываются по команде Project - Open Project . Окно проекта содержит перечень файлов и панель инструментов с командами, аналогичными командам в меню (рис.5.3). Файлы открываются двойным щелчком на их имени. Загрузить весь проект можно, щелкнув по кнопке Load Project FAS . Можно работать также с каждым файлом в отдельности.
Другой вид приложений - VLX -приложения, в состав которых могут входить не только LSP -файлы, но и DSL -файлы диалоговых окон, FAS -файлы и текстовые TXT -файлы. Все включаемые компоненты собираются в единый файл приложения с расширением VLX . Для создания нового VLX -приложения нужно вызвать мастера по команде File - Make Application - New Application Wizard (рис.5.4). Выбор режима, определяющего тип приложения, возможен из двух вариантов: SIMPLE или EXPERT . Простое приложение может состоять только из LSP и FAS -файлов. В сложном приложении могут присутствовать также DSL, PRJ и TXT -файлы.
Загрузить файл можно по команде File - Load File , либо с консоли с помощью функции Load , либо в сеансе AutoCAD .
Помимо примитивов, в рисунке всегда присутствует неграфическая информация : описания блоков, таблицы слоев, видовых экранов, типов линий, размерных стиле и пр. Все они хранятся в базе данных примерно в таком же виде, как примитивы.
Для доступа к табличным объектам в языке AutoLISP используют функции: tblnext, tblobjname, tblsearch . В качестве названий таблиц в этих функциях могут фигурировать только следующие текстовые строки:
- BLOCK - таблица описаний блоков;
- LAYER - таблица слоев;
- LTYPE - таблица типов линий;
- STYLE - таблица текстовых стилей;
- DIMSTYLE - таблица размерных стилей;
- UCS - таблица именованных систем координат;
- VIEW - таблица именованных видов;
- VPORT - таблица конфигураций видовых экранов;
- APPID - таблица имен приложений.
Рассмотрим на примерах схему использования этих функций.
(setq listlay1 (tblnext "LAYER" T)) - возвращает список с данными первого слоя рисунка, например, такого типа:
Это список точечных пар. DXF -коды означают:
- 0 - имя таблицы;
- 2 - имя слоя;
- 6 - тип линий примитивов слоя BYLAYER ;
- 62 - цвет слоя по умолчанию;
- 70 - состояние слоя.
Для примитивов подобный список возвращает функция entget .
(setq listlay2 (tblnext "LAYER")) - возвращает список с данными второго слоя рисунка, например, такого типа:
Если запустить функцию (setq lay2name (tblobjname "Layer" "Inner")) , то она возвратит . Теперь с помощью функции entget можно получить тот же список , что и для listlay2 в предыдущем примере.
С помощью этих функций можно проанализировать наличие в чертеже таких элементов, как описания блоков, пользовательские системы координат, текстовые стили.
Свойствами, аналогичными таблицам, обладают словари. Существуют словари стилей мультилиний , групп, таблиц, растровых изображений, вкладок листов. Пользовательские приложения могут создавать в чертеже свои словари.
Операции над словарями и их элементами осуществляют функции: dictadd, dictnext, dictremove, dictrename, dictsearch, namedobjdict . Здесь нет операции модификации записи. Поэтому при необходимости нужно вначале удалить старую запись . Затем добавить в словарь новую.
Файлы AutoLISP можно загрузить либо непосредственно в AutoCAD , либо в среде Visual LISP . Все файлы процедур должны иметь расширение . LSP . Однако для безопасности и ускорения работы процедуры AutoLISP можно компилировать в файлы проекта с расширением .PRJ или .VLX . Программа сначала загружает одноименные файлы с расширением .VLX . Если такого файла нет, то программа ищет файл .PRJ . Если и его нет, то загружается файл . LSP . Однако, если файл LSP более новый, чем другие, то он загрузится в первую очередь .
Загpузить файл " Circle. LSP " в AutoCAD можно следующими способами:
- из командной строки выражением LISP (load "circle") ;
- командой appload - откроется окно Load/Appload Applications . Если файл будет использоваться постоянно, то его нужно добавить в набор Start Suit с помощью кнопки Content . Эту операцию можно выполнить путем перетаскивания пиктограммы файла в окне Load/Appload Applications . Процедура будет загружаться при каждом запуске программы AutoCAD ;
- командой Tools - AutoLISP - Load Application - откроется диалоговое окно Load/Appload Applications ;
- командой Tools - Load Application - откроется окно Load/Appload Applications .
Если файл находится в каталоге, не включенном в список маршрутов поддержки, то необходимо задать полный маршрут файла:
Обычно все процедуры 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 загружается при открытии каждого чертежа.
Порядок загрузки файлов:
- ACAD2010. LSP
- ACAD. LSP
- ACADDOC2010. LSP
- ACADDOC. LSP
Файлы AutoLISP , загруженные для одного конкретного чертежа со своими переменными, не будут доступны в остальных чертежах. Для совместного использования функций в нескольких чертежах вместо команды ( load "circle" ) нужно применить команду ( vl-load-all "circle" ). Действие функций файла будет распространяться не только на все открытые чертежи, но и на все чертежи, которые будут открыты в данном сеансе.
Создайте приветствие на экране. Загрузите в файл C:\Programm Files\AutoCAD2010 \Support\acad. lsp такую процедуру:
Проанализируйте каждую группу списка свойств текстового примитива.
Ключевые термины
Сущность объекта ( entity ) - список параметров объекта в базе данных.
Имя сущности ( entity name ) - параметр сущности с кодом DXF , равным -1.
Набор объектов - совокупность объектов, выделенных по команде ssget ( Selection Set Get - получение набора выделения).
Файлы инициализации - четыре файла AutoLISP , автоматически загружаемые в AutoCAD . Для пользователей предназначены два файла: ACAD. LSP и ACADDOC. LSP .
Проект - несколько выполняемых совместно и связанных между собой LISP -программ.
Краткие итоги
Любой объект AutoCAD описывается в базе данных программы списком своих параметров. С помощью функций доступа и модификации возможно редактирование этих параметров и изменение объекта.
Аннотация: Язык VBA предоставляет широкие возможности программирования в среде AutoCAD. В лекции показана возможность управления окружением AutoCAD и даны технологии создания и редактирования слоев и объектов. Разбирается работа с текстом и размерностями, с блоками и листами, с трехмерными поверхностями и сплошными 3D объектами.
Цель лекции: изучить принципы и конкретные технологии программирования на VBA .
Введение. Обзор команд. Объектная модель
Введение
Интерфейс AutoCAD ActiveX/VBA дает некотoрые преимущества по сравнению с другими методами создания приложений AutoCAD :
- Высокая скорость выполнения процесса, так как в отличие от AutoLISP -приложений выполнение команд происходит внутри процесса;
- Простота использования, обусловленная простотой языка программирования;
- Большие возможности межпрограмного обмена, так как VBA и ActiveX разрабатывались для взаимодействия с другими Windows -приложениями.
Понятие внедренных и глобальных проектов VBA
Приложение Autocad VBA представляет собой набор программных модулей, модулей классов и форм. Пороект может быть сохранен как в рисунке (внедренный), так и во внешнем файле. Внедренный проект автоматически загружается при открытии рисунка. Ограничение внедренных проектов в том, например, что они не могут закрыть рисунок, внутри которого находятся. Глобальные проекты в этом плане более гибки, при этом однако пользователь должен знать где расположен файл в котором хранятся макросы. Глобальный проект проще передавать другим пользователям и в нем удобно хранить общие макросы. В любой момент могут быть использованы оба типа проектов. На уровне двоичного кода проект Autocad VBA не совместим с проектом Visual Basic , однако обмен формами, модулями и классами можно производить через экспорт- импорт. (Команды IMPORT и EXPORT VBA ).
Загрузка существующего проекта
При загрузке проекта все глобальные процедуры, называемые так же макросами, становятся доступными для использования. Загрузить проект можно через VBA -менеджер или с командной строки VBALOAD . Кроме того автокад грузит автоматически проект с именем acad. dvb , который может найти в путях файлов поддержки. При загрузке проекта может появиться предупреждение, что он содержит макросы, а значит может содержать и вирусы. Выгрузка проекта командной VBAUNLOAD приводит к высвобождению памяти ранее занятой проектом. Внедрить проект в рисунок можно с помощью VBA -менеджера, он же позволяет извлечь проект из рисунка, при этом предлагая сохранить его в отдельном файле. Чтобы среда разработки VBA автоматически загрузилась при загрузке AutoCAD , в файл acad.arx нужно внести строку acadvba.arx .
Определение компонентов проекта
Проект может состоять из различных компонентов:
- объекты;
- формы;
- стандартные модули;
- модули класса;
- ссылки.
Добавить компонент можно через меню Insert , компоненты так же можно импортировать из файлов ( .frm, . bas , .cls ).
Обзор команд VBA AutoCAD
- VBAIDE - открывает окно VBA IDE , позволяющее редактировать, запускать и отлаживать программы.
- VBALOAD - загружает проект.
- VBARUN - запускает макрос на выполнение.
- VBAUNLOAD - выгружает проект, освобождая память.
- VBAMAN - показывает окно менеджера VBA .
- VBASTMT - позволяет выполнить команду VBA в командной строке AutoCAD .
Основные понятия объектной модели AutoCAD
Все объекты AutoCAD организованы в виде иерархической структуры. Корнем дерева является объект Application .
Через объект Application можно получить доступ к следующим объектам:
- Preferences;
- Documents;
- MenuBar;
- MenuGroups;
Через объект Preferences можно получить доступ к следующим объектам
- PreferencesDisplay;
- PreferencesDrafting;
- PreferencesFiles;
- PreferencesOpenSave;
- PreferencesOutput;
- PreferencesProfiles;
- PreferencesSelection;
- PreferencesSystem;
- PreferencesUser.
Через объект Documents можно получить доступ к объекту Document а через него к большинству других объектов и коллекций:
В двух последних расположены объекты AutoCAD , видимые на рисунке:
Доступ к иерархии объектов. Коллекции, свойства и методы
Связь VBA с активным чертежом обеспечивается посредством объекта ThisDrawing . С его помощью можно получить немедленный доступ ко всем свойствам и методам объекта Document а также ко всем другим объектам в иерархии.
Когда используются глобальные проекты, ThisDrawing всегда ссылается на активный документ. При использовании внедренных проектов ThisDrawing всегда ссылается на документ, содержащий проект. Например, следующая строка кода в глобальном проекте сохраняет любой чертеж, который в данный момент активен:
Ссылка на объекты в иерархии объектов
Доступ к объекту можно получить непосредственно или через объектную переменную. Для непосредственной сслыки на объект достаточно указать полный путь к нему в иерархии. Например, следующий фрагмент кода добавляет линию в пространство модели:
Для доступа к объекту через объектную переменную поступаем следующим образом. Определяем переменную желаемого типа, после чего устанавливаем переменную так, чтобы она ссылалась на нужный объект. К примеру следующий код определит объектную переменную moSpace типа AcadModelSpace так, чтобы она ссылалась на текущее пространство модели :
В примере добавляем линию в пространство модели , используя эту переменную:
Корневой объект Application расположен в иерархии выше объекта Document . Выше показано, что объект ThisDrawing обеспечивает доступ к объекту Document . А у объекта Document есть свойство Application , которое и является ссылкой на объект Application . Пример обращения:
Коллекции объектов
Объект Collection - является предопределенным объектом содержащим все вхождения подобных объектов. Существуют следующие объекты коллекции:
Доступ к коллекции
Большинство коллекций доступны через объект Document , т.к. он содержит свойства для каждой из коллекций. Следующий код устанавливает ссылку объектной переменной на коллекцию Layers :
Коллекции Documents, MenuBar и MenuGroups доступны через объект Application . Он содержит свойства для каждой из этих коллекций. Следующий пример определяет объектную переменную и создает ссылку через нее на коллекцию:
Добавление нового элемента коллекции
Следующий пример создает слой и добавляет его в коллекцию:
Перебор членов коллекции
Для выбора нужного члена коллекции используется метод Item . В качестве параметра ему передается номер ( Index ) объекта в коллекции либо его символьный идентификатор. Пример демонстрирует перебор всех слоев с отображением их имен
Пример поиска слоя с именем ABC :
Не следует использовать методы редактирования примитивов ( Copy, Array, Mirror и др.) на любом объекте который одновременно перебирается с помощью механизма For Each . В случае необходимости нужно закончить перебор, создать временный массив эквивалентный коллекции и в этом массиве выполнить редактирование.
Удаление члена коллекции
Пример удаления слоя:
Удаленный объект восстановлению не подлежит.
Понятие свойств и методов
Каждый объект обладает связанными с ним свойствами и методами. Свойства описывают некоторые характеристики присущие объекту, а методы позволяют выполнять действия над объектами, в частности, менять и читать свойства. Например, объект окружность имеет свойство Центр, которое представляет трехмерную координату центра окружности. Чтобы сменить свойство достаточно задать ему другое значение. Окружность как целое имеет метод Offset , который создает новый объект на указанном смещении от существующего. Полный перечень свойств и методов есть в ActiveX and VBA Reference .
Понятие родительского объекта
Каждый объект имеет своего родителя с которым он постоянно связан. Доступ к каждому объекту можно осуществить следуя от родительского объекта к дочернему. Кроме того все объекты имеют свойство Application , как непосредственную ссылку на корневой объект.
Библиотеки типов
Описание объектов, свойств и методов хранятся в библиотеке типов, с помощью которой браузеры и приложения могут определить характеристики объектов. Прежде чем использовать объекты автоматизации, следует создать ссылку на библиотеку типов. Это нужно для того, чтобы глобальные функции были доступны непосредственно без подготовки. Вызовы функций при этом могут контролироваться компилятором на корректность. Увеличивается надежность и читабельность программы.
Получение первого примитива из базы данных рисунка
Применение variant в методах и свойствах
Для передачи массива данных AutoCAD использует тип Variant который может принимать данные любого типа за исключением строк фиксированной длины и типов данных, определяемых пользователем. Может также принимать значения Empty, Error, Nothing, NULL . Чтобы узнать какой именно тип данных хранятся в переменной типа Variant , нужно обратиться к функции VarType или TypeName .
Тип данных Variant используется для передачи массива данных из/в AutoCAD ActiveX Automation . В AutoCAD VBA -входные массивы автоматически преобразуются в тип Variant . Однако c выходными массивами все не так просто. Метод CreateTypedArray преобразует массив в Variant , содержащий "смесь" из Integer, Double и т.д. Эту "смесь" можно передать в любой метод или любое свойство AutoCAD , которые принимают массив чисел как Variant .
В примере преобразуются три массива координат сплайна с передачей их методу AddSpline .
Интерпретация variant-массивов
Передаваемая AutoCAD ActiveX Automation информация массива возвращается как тип Variant , если типы данных элементов массива известны. Иначе применяем функции VarType Typename . Для перебора элементов массива удобен метод For Each . Пример вычисления расстояния между двумя точками введенными пользователем:
Использование других языков программирования
Чтобы использовать приведенные примеры не в VBA а в VB следует, во-первых, сослаться на библиотеку типов, во-вторых заменить все ссылки ThisDrawing Для этого определить переменную для приложения AutoCAD (myApp) и для активного документа ( myDoc ). Если AutoCAD запущен, метод GetObject возвращает объект AutoCAD Application . Если AutoCAD не запущен, то вызывается обработчик ошибок. Затем метод CreateObject пытается создать объект AutoCAD Application , как в следующем примере:
Здесь уже используем acadDoc -переменную для ссылки на текущий рисунок AutoCAD . Если запущены несколько сеансов, AutoCAD -функция GetObject возвращает первое вхождение из Windows Running Object Table (ROT) .
Следующий пример демонстрирует создание линии в VB и VBA
Управление окружением AutoCAD
Открытие, сохранение и закрытие чертежа
Коллекция Documents и объект Document обеспечивают доступ к файловым функциям. Для этого следует использовать один из методов Add, Close, Save, SaveAs, Import, Export . Пример открытия рисунка:
Читайте также: