Рисунок в системе 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 возвращает имя последнего нестертого примитива в базе данных.
(entlast)
Функция возвращает nil, если в рисунке нет неудаленных примитивов (например, когда вы только что создали новый рисунок); иначе возвращается имя последнего примитива в следующем виде:
<Имя объекта: 14а4158>
(< Entity name: 14а4158>)
Полученное имя следует сохранить в переменной, например:
(setq eela (entlast))
Функция часто используется для получения имени нового примитива, который добавлен при помощи функции COMMAND.
Функция entnext позволяет перейти в рисунке к следующему примитиву (подпримитиву):
(entnext [<примитив>])
В качестве аргумента функции entnext может выступать ранее полученное имя примитива текущего рисунка. Если функция вызывается без аргумента, то она возвращает имя первого неудаленного примитива в базе рисунка. При наличии аргумента функция возвращает имя следующего примитива, либо nil, если база графических объектов рисунка исчерпана.
(setq e1 (entnext)) — возвращает имя первого неудаленного примитива;
(setq e2 (entnext е1)) — возвращает имя примитива, следующего за e1;
(setq еЗ (entnext е2)) — возвращает имя примитива, следующего за e2.
Функция entlast возвращает имя последнего основного примитива. Это означает, что если последним созданным графическим объектом рисунка является сложный объект (например, полилиния типа POLYLINE), то вслед за ним в базе рисунка следуют подпримитивы, т. е. вершины (имя примитива — VERTEX), а завершается перечисление подпримитивов полилинии примитивом SEQEND.
Пример (в предположении, что объект типа POLYLINE является последним основным примитивом):
(setq eela (entlast)) — возвращает имя основного примитива последней полилинии;
(setq v1 (entnext eela)) — возвращает имя примитива, являющегося первой вершиной полилинии;
(setq v2 (entnext v1)) — возвращает имя примитива, являющегося второй вершиной полилинии.
Замечание: В легкой полилинии (примитиве типа LWPOLYLINE) нет подпримитивов и информация обо всех вершинах может быть извлечена из основного примитива.
Функция entsel предлагает пользователю указать один объект, выдавая соответствующий запрос:
(entsel [запрос] )
Функция возвращает список, состоящий из двух элементов: имени выбранного примитива и точки, которой пользователь указал объект (такая точка, как правило, оказывается вне примитива, поскольку точность указания мышью зависит от величины прицела). Можно указать объект вводом с клавиатуры ключевого слова Последний (Last) — тогда в возвращаемом списке координаты точки будут нулевыми.
(setq esl (entsel "Выберите объект: ")) — возвращает (<Имя объекта: 14а9960> (301.7 138.4 0.0)).
Имя указанного объекта можно извлечь из такого списка с помощью функции car.
Функция entdel позволяет удалять неудаленные основные примитивы и восстанавливать примитивы, ранее удаленные в данном сеансе редактирования:
(entdel <примитив>)
Функция возвращает имя удаляемого (восстанавливаемого) примитива. Следует иметь в виду, что при операции сохранения рисунка все примитивы, помеченные как удаленные, из рисунка стираются и уже больше не могут быть восстановлены.
Функция entget является основным инструментом извлечения информации о примитиве, т. к. получает список с его характеристиками:
(entget <примитив>)
Здесь аргумент <примитив> — это имя примитива для получения его данных.
Предположим, в рисунке первым объектом является отрезок (тип примитива — LINE). Тогда выражение (setq le (entget (entnext) ) ) должно вернуть такой список:
((-1 . <Имя объекта: 14а4158>) (0 . "LINE") (330 . <Имя объекта: 14a40f8>) (5 . "2В") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 201.536 140.622 0.0) (11 285.148 96.5053 0.0) (210 0.0 0.0 1.0))
В этом списке элементами являются точечные пары и списки, причем первыми элементами в них выступают целые числа, называемые DXF-кодами. Под соответствующим кодом находятся данные определенного типа: код -1 указывает имя примитива (<имя объекта: l4a4l58>), код 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.5 140.6 0.0);
(cdr (assoc 11 le)) — возвращает (285.1 96.5 0.0).
Кроме того, по коду 62 можно было бы извлечь номер цвета примитива, по коду 6 — имя типа линии, по коду 48 — собственный масштаб типа линии, по коду 311 — вес линии (умноженный на 100). В рассмотренном выше списке le точечных пар с такими DXF-кодами нет, т.к. для них действуют значения по умолчанию: ПОСЛОЮ (BYLAYER) или 1.
Рассмотрим, какой примерный список можно было бы получить для окружности (объекта типа CIRCLE):
((-1 . <Имя объекта: 14а4160>) (0 . "CIRCLE") (330 . <Имя объекта: 14a40f8>) (5 . "2С") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") (10 387.691 142.198 0.0) (40 . 27.8941) (210 0.0 0.0 1.0))
Для окружности DXF-коды -l, 0, 410, 8, 210 имеют тот же смысл, что и для всех примитивов (в том числе и для примитива типа "LINE"). Под кодом 40 находится радиус окружности, а точечная пара с DXF-кодом 10 хранит в себе данные о центре.
Поэтому для рассматриваемой окружности:
(cdr (assoc 40 le)) — возвращает 27.8 (радиус);
(cdr (assoc 10 le) ) — возвращает (387.6 142.1 0.0).
Сравнивая справочную информацию, выдаваемую командой СПИСОК (LIST), и список, получаемый с помощью функции entget, можно получить геометрический смысл DXF-кодов для примитивов других типов.
Если построить в программе список, описывающий примитив (кроме точечной пары с флагом -1), то можно создать в рисунке такой примитив с помощью следующих функций:
• (entmake <список>) — создает новый примитив по списку, структура которого аналогична структуре списка, возвращаемого функцией entget; возвращаемое значение — аргумент <список> или nil, если создание объекта невозможно;
• (entmakex <список>) — создает новый примитив или неграфический объект по списку, аналогично функции entmake; возвращаемое значение — имя нового примитива или nil, если создание объекта невозможно.
Пример: (entmake '((0 . "CIRCLE") (10 500.0 0.0 0.0) (40 . 50.0))) - создает новый примитив — окружность с центром в точке (500 0 0) и радиусом 50; остальные свойства (слой, цвет и т. д.), данные о которых отсутствуют в списке, берутся по умолчанию.
Функция entmod похожа на функцию entmake, но получает в качестве аргумента список, который содержит точечную пару с DXF-кодом -1 (т. е. имя существующего в рисунке примитива) и модифицирует примитив в соответствии с новым списком (в списке могут изменяться любые данные, кроме имени примитива, типа примитива и метки):
Для перерисовки примитива на экране следует воспользоваться функцией entupd:
(entupd <примитив>)
Здесь аргумент <примитив> — это имя примитива в том виде, в котором оно выводится, например, функцией entlast.
Другие функции доступа к примитивам:
• (handent <метка>) — возвращает имя примитива или неграфического объекта по его метке; аргумент <метка> — это текстовая строка с шестнадцатеричной меткой в том виде, в каком она возвращается функцией entget;
(handent "5A2") вернет <Имя примитива: 60004722>
• (nentsel [запрос] ) — в Book2000
(nentselp [запрос] [<точка>]) — в Book2000
Следующая группа функций — это функции, работающие с наборами выбора. Набор — это временное множество, в которое входят имена основных примитивов рисунка (как правило, они собираются по какому-то признаку-фильтру). Неосновные примитивы (составные части блока или вершины полилинии) не могут входить в набор. Имя набора обычно сохраняется в переменной, чтобы затем можно было извлекать из набора нужные примитивы.
Функция ssget формирует набор по запросу или признаку:
(ssget [<метод>] [<точка1> [<точка2>]] [<список>] [<фильтр>])
Аргумент <метод> —метод выбора примитивов:
• "С" — выбор секущей рамкой;
• "F" — выбор секущей линией;
• "L" — выбор последнего видимого примитива;
• "Р" — последний сформированный ранее набор;
• "W" — выбор рамкой;
• "X" — вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана, с учетом аргумента <фильтр> (в этом случае аргумент <фильтр> не должен быть опущен);
• "А" — вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана;
• ":Е" — все примитивы, попадающие в прицел устройства указания;
• ":N" — выбор основных примитивов с помощью подпримитивов (вершин полилинии или сети, компонент блока); используется только при графическом варианте выбора и только для указания рамкой, секущей рамкой и точкой; может привести к повторяемости примитивов в наборе, поскольку, например, можно отметить одну и ту же полилинию с помощью любой из ее вершин (см. также функцию ssnamex);
• ":S" — допускает выбор только одного объекта.
Аргумент <точка1> при отсутствии аргумента <точка2> определяет дополнительное условие для включения в набор: включаемый примитив должен проходить через точку, заданную аргументом <точка1>. Если заданы оба аргумента <точка1> и <точка2>, то заданные ими точки являются углами простой или секущей рамки (когда в качестве метода выбора применяются рамки, т. е. "W" или "С").
Аргумент <список> представляет собой список, элементами которого являются точки, используемые в методах "F", "WP", "СР".
Аргумент <фильтр> — это список со структурой, аналогичной структуре списка, возвращаемого функцией entget, что позволяет оставить только те примитивы, которые удовлетворяют дополнительным признакам (например, определенному цвету, слою, весу и т. д.).
Возвращаемое значение функции ssget — имя созданного набора (или nil, если создать набор невозможно).
(ssget) — выдает стандартный запрос:
Выберите объекты:
(Select objects:)
и далее создает набор в соответствии с дальнейшими указаниями пользователя;
(ssget '(15.78 320.1)) — создает набор из примитивов, проходящих через точку (15.78 320.1);
(ssget "_с" '(1.57 -40.4) '(15.78 320.1)) — создает набор из примитивов, выбираемых секущей рамкой с углами в точках (1.57 -40.4) и (15.78 320.1);
(ssget "_x" '((0 . "POLYLINE") (8 . "WALLS"))) — создает набор из всех примитивов рисунка, являющихся полилиниями типа POLYLINE и лежащими на слое WALLS;
В рисунке одновременно может быть открыто не более 128 наборов выбора. При достижении такого предела функция ssget отказывается создавать следующие наборы и возвращает nil. Чтобы удалить ненужные наборы, следует присвоить значение nil переменным, хранящим имена этих наборов.
Для манипуляций с наборами в языке AutoLISP предусмотрены следующие функции:
• (ssadd [<примитив> [<набор>] ]) — добавление примитива в набор; если аргумент <набор> опущен, а аргумент <примитив> задан, то создается новый набор из одного примитива; если оба аргумента опущены, то создается новый пустой набор (но его значение не равно nil); возвращается имя набора;
• (ssdel <примитив> <набор>) — удаление примитива из набора; возвращается имя набора, если операция удаления выполнена, или nil, если примитив не содержится в наборе и удалить его нельзя;
• (sslength <набор>) — возвращает количество примитивов в наборе;
(setq sset (ssget "p")) ;помещает последний объект в набор SSET
(sslength sset) ;возвращает 1
• (ssmemb <примитив> <набор>) — проверка вхождения примитива в набор; возвращается имя примитива, если он входит в набор, или nil — если не входит;
• (ssname <набор> <номер>) — возвращает имя примитива с порядковым номером <номер> из набора; аргумент <номер> должен быть либо целым числом от 0 до 32 767, либо целым числом в вещественной форме больше 32767.0; нумерация примитивов в наборе начинается с нуля; возвращается имя примитива или nil;
(setq sset (ssget)) ;создает набор под именем SSET
(setq ent1 (ssname sset 0)) ;получает имя первого примитива в SSET
(setq ent4 (ssname sset 3)) ;получат имя четвертого примитива в SSET
• (ssnamex <набор> [<номер>]) — извлечение примитива из набора по порядковому номеру, но при этом выдается дополнительная информация о методах формирования набора (см. ниже); если аргумент <номер> опущен, то выводится информация обо всех примитивах набора;
• (sssetfirst <набор1> [<набор2>]) — включает ручки у примитивов, входящих в наборы, заданные аргументами <набор1> и <набор2>, но еще и подсвечивает пунктиром примитивы из набора2 (что означает выбор их для следующей операции редактирования);
• (ssgetfirst) — возвращает список с именами двух наборов, аналогичных по назначению аргументам <набор1> и <набор2> функции sssetfirst (у примитивов набора1 включены только ручки, у примитивов набора2 включены ручки и подсвечивание).
Функция ssnamex возвращает список, в котором элементами являются описания способа выбора примитивов, попавших в набор. Если аргумент <номер> не задан, то длина возвращаемого списка равна количеству элементов, определяемых аргументом <набор>. Если аргумент <номер> задан и задан корректно, то возвращаемым значением будет список из одного элемента — описания способа выбора примитива с порядковым номером, равным значению аргумента <номер>. Если же аргумент <номер> задан неправильно, то функция ssnamex вернет nil.
Описание способа выбора примитива — это список из трех элементов: (<метод> <примитив> <данные>). Параметр <метод> — целое число, которое соответствует методу выбора функции ssget и может принимать такие значения:
• 0 — неинтерактивный выбор ("L", "А", "X" и т. п.);
• 1 — выбор указанием точки;
• 2 - "W" или "WP";
• 3 - "С" или "СР";
• 4 - "F".
Если на месте параметра <метод> стоит отрицательное число, то оно определяет многоугольник выбора (см. описание многоугольника ниже).
Параметр <примитив> описания способа выбора примитива является его именем в том виде, в котором оно выводится функцией entiast. Параметр <данные> может быть либо только числом 0, либо числом 0 и списком, уточняющим выбор, либо числом 0 и номером многоугольника. В уточняющем списке может быть точка, с помощью которой выбран объект. Если использован номер многоугольника (а он должен быть отрицательным: —1 , —2 и т. п.), то далее будет следовать описание многоугольника с соответствующим номером.
Описание многоугольника— это список такого вида: (<номер_многоуголь-ника> <точка1> ... <точкаN>). Нумерация многоугольников начинается с —1 и наращивается путем добавления -1 к очередному номеру.
Описание точки (<точка1> и т. п.) — это список из трех (или двух) элементов: (<код> <база> [<вектор>] ). Описание точки зависит от вида, на котором она выбиралась, и фактически представляет собой описание прямой, луча или отрезка. Параметр <код> является кодом описания точки (0 — прямая, 1 — луч, 2 — отрезок), параметр <база> представляет собой начальную точку описания, а необязательный параметр <вектор> — это либо направление, в котором продолжается бесконечная линия (прямая или луч), либо смещение в сторону, характерное для отрезка.
Пример:
Если в набор nab5 включен один объект, который был указан точкой (7.51 16.02) на обычном виде сверху в МСК, то выражение
(ssnamex nab5 0) возвращает примерно следующее: ((1 <имя объекта: 14аа560> 0 (0 (7.51 16.02 0.0)))).
В этом примере возвращенный функцией ssnamex список состоит из одного элемента (списка), в котором присутствуют следующие составные части:
• <метод> — равен 1 (соответствует выбору указанием точки);
• <примитив> — <Имя объекта: 14аа560>;
• <данные> — 0 (0 (7.51 16.02 0.0)), что соответствует точке (7.51 16.02 0.0), примененной для выбора примитива.
Другие примеры значений, возвращаемых функцией ssnamex:
((0 <Имя объекта: 14ае578> 0)) — один примитив, выбранный неин-терактивным методом (например, "L");
((3 <Имя объекта: 14ае568> О -1) (3 <Имя объекта: 14ае578> 0 -1) (-1 (0 (-147.787 129.133 0.0)) (0 (-64.2728 129.133 0.0)) (0 (- 64.2728 22.3376 0.0)) (0 (-147.787 22.3376 0.0)))) — два примитива, выбранных секущим прямоугольником с номером —1 (для прямоугольника заданы четыре точки);
((1 <Имя объекта: 14ае560> 0 (0 (74.2672 64.8218 0.0))) (2 <Имя объекта: 14ае570> 0 -1) (2 <Имя объекта: 14ае568> 0 -1) (-1 (0 (-177.446 158.755 0.0)) (0 (40.3151 158.755 0.0)) (0 (40.3151 83.1407 0.0)) (0 (-177.446 83.1407 0.0)))) — три примитива, первый из которых выбран указанием с помощью точки (74.2672 64.8218 0.0), а второй и третий выбраны рамкой, которая фигурирует как многоугольник с номером -1.
В этих примерах параметр <вектор> описания точек нигде не использован, т. е. объекты выбирались на виде сверху в МСК.
Наборы — удобный инструмент для выбора нужных примитивов рисунка с заданными свойствами. После формирования набора затем из него с помощью функции ssname (или ssnamex) извлекаются нужные объекты, с которыми далее выполняются необходимые операции (например: удаление, модификация и т. д.).
Функции, рассматриваемые в данном разделе, работают с примитивами рисунка, обращаясь непосредственно к их внутренней структуре. AutoLISP имеет средства выбора графических объектов, как по их порядковому номеру, так и по определенным признакам (цвету, слою и т. п.).
Функция entlast возвращает имя последнего нестертого примитива в базе данных.
(entlast)
Функция возвращает nil, если в рисунке нет неудаленных примитивов (например, когда вы только что создали новый рисунок); иначе возвращается имя последнего примитива в следующем виде:
<Имя объекта: 14а4158>
(< Entity name: 14а4158>)
Полученное имя следует сохранить в переменной, например:
(setq eela (entlast))
Функция часто используется для получения имени нового примитива, который добавлен при помощи функции COMMAND.
Функция entnext позволяет перейти в рисунке к следующему примитиву (подпримитиву):
(entnext [<примитив>])
В качестве аргумента функции entnext может выступать ранее полученное имя примитива текущего рисунка. Если функция вызывается без аргумента, то она возвращает имя первого неудаленного примитива в базе рисунка. При наличии аргумента функция возвращает имя следующего примитива, либо nil, если база графических объектов рисунка исчерпана.
(setq e1 (entnext)) — возвращает имя первого неудаленного примитива;
(setq e2 (entnext е1)) — возвращает имя примитива, следующего за e1;
(setq еЗ (entnext е2)) — возвращает имя примитива, следующего за e2.
Функция entlast возвращает имя последнего основного примитива. Это означает, что если последним созданным графическим объектом рисунка является сложный объект (например, полилиния типа POLYLINE), то вслед за ним в базе рисунка следуют подпримитивы, т. е. вершины (имя примитива — VERTEX), а завершается перечисление подпримитивов полилинии примитивом SEQEND.
Пример (в предположении, что объект типа POLYLINE является последним основным примитивом):
(setq eela (entlast)) — возвращает имя основного примитива последней полилинии;
(setq v1 (entnext eela)) — возвращает имя примитива, являющегося первой вершиной полилинии;
(setq v2 (entnext v1)) — возвращает имя примитива, являющегося второй вершиной полилинии.
Замечание: В легкой полилинии (примитиве типа LWPOLYLINE) нет подпримитивов и информация обо всех вершинах может быть извлечена из основного примитива.
Функция entsel предлагает пользователю указать один объект, выдавая соответствующий запрос:
(entsel [запрос] )
Функция возвращает список, состоящий из двух элементов: имени выбранного примитива и точки, которой пользователь указал объект (такая точка, как правило, оказывается вне примитива, поскольку точность указания мышью зависит от величины прицела). Можно указать объект вводом с клавиатуры ключевого слова Последний (Last) — тогда в возвращаемом списке координаты точки будут нулевыми.
(setq esl (entsel "Выберите объект: ")) — возвращает (<Имя объекта: 14а9960> (301.7 138.4 0.0)).
Имя указанного объекта можно извлечь из такого списка с помощью функции car.
Функция entdel позволяет удалять неудаленные основные примитивы и восстанавливать примитивы, ранее удаленные в данном сеансе редактирования:
(entdel <примитив>)
Функция возвращает имя удаляемого (восстанавливаемого) примитива. Следует иметь в виду, что при операции сохранения рисунка все примитивы, помеченные как удаленные, из рисунка стираются и уже больше не могут быть восстановлены.
Функция entget является основным инструментом извлечения информации о примитиве, т. к. получает список с его характеристиками:
(entget <примитив>)
Здесь аргумент <примитив> — это имя примитива для получения его данных.
Предположим, в рисунке первым объектом является отрезок (тип примитива — LINE). Тогда выражение (setq le (entget (entnext) ) ) должно вернуть такой список:
((-1 . <Имя объекта: 14а4158>) (0 . "LINE") (330 . <Имя объекта: 14a40f8>) (5 . "2В") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 201.536 140.622 0.0) (11 285.148 96.5053 0.0) (210 0.0 0.0 1.0))
В этом списке элементами являются точечные пары и списки, причем первыми элементами в них выступают целые числа, называемые DXF-кодами. Под соответствующим кодом находятся данные определенного типа: код -1 указывает имя примитива (<имя объекта: l4a4l58>), код 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.5 140.6 0.0);
(cdr (assoc 11 le)) — возвращает (285.1 96.5 0.0).
Кроме того, по коду 62 можно было бы извлечь номер цвета примитива, по коду 6 — имя типа линии, по коду 48 — собственный масштаб типа линии, по коду 311 — вес линии (умноженный на 100). В рассмотренном выше списке le точечных пар с такими DXF-кодами нет, т.к. для них действуют значения по умолчанию: ПОСЛОЮ (BYLAYER) или 1.
Рассмотрим, какой примерный список можно было бы получить для окружности (объекта типа CIRCLE):
((-1 . <Имя объекта: 14а4160>) (0 . "CIRCLE") (330 . <Имя объекта: 14a40f8>) (5 . "2С") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") (10 387.691 142.198 0.0) (40 . 27.8941) (210 0.0 0.0 1.0))
Для окружности DXF-коды -l, 0, 410, 8, 210 имеют тот же смысл, что и для всех примитивов (в том числе и для примитива типа "LINE"). Под кодом 40 находится радиус окружности, а точечная пара с DXF-кодом 10 хранит в себе данные о центре.
Поэтому для рассматриваемой окружности:
(cdr (assoc 40 le)) — возвращает 27.8 (радиус);
(cdr (assoc 10 le) ) — возвращает (387.6 142.1 0.0).
Сравнивая справочную информацию, выдаваемую командой СПИСОК (LIST), и список, получаемый с помощью функции entget, можно получить геометрический смысл DXF-кодов для примитивов других типов.
Если построить в программе список, описывающий примитив (кроме точечной пары с флагом -1), то можно создать в рисунке такой примитив с помощью следующих функций:
• (entmake <список>) — создает новый примитив по списку, структура которого аналогична структуре списка, возвращаемого функцией entget; возвращаемое значение — аргумент <список> или nil, если создание объекта невозможно;
• (entmakex <список>) — создает новый примитив или неграфический объект по списку, аналогично функции entmake; возвращаемое значение — имя нового примитива или nil, если создание объекта невозможно.
Пример: (entmake '((0 . "CIRCLE") (10 500.0 0.0 0.0) (40 . 50.0))) - создает новый примитив — окружность с центром в точке (500 0 0) и радиусом 50; остальные свойства (слой, цвет и т. д.), данные о которых отсутствуют в списке, берутся по умолчанию.
Функция entmod похожа на функцию entmake, но получает в качестве аргумента список, который содержит точечную пару с DXF-кодом -1 (т. е. имя существующего в рисунке примитива) и модифицирует примитив в соответствии с новым списком (в списке могут изменяться любые данные, кроме имени примитива, типа примитива и метки):
Для перерисовки примитива на экране следует воспользоваться функцией entupd:
(entupd <примитив>)
Здесь аргумент <примитив> — это имя примитива в том виде, в котором оно выводится, например, функцией entlast.
Другие функции доступа к примитивам:
• (handent <метка>) — возвращает имя примитива или неграфического объекта по его метке; аргумент <метка> — это текстовая строка с шестнадцатеричной меткой в том виде, в каком она возвращается функцией entget;
(handent "5A2") вернет <Имя примитива: 60004722>
• (nentsel [запрос] ) — в Book2000
(nentselp [запрос] [<точка>]) — в Book2000
Следующая группа функций — это функции, работающие с наборами выбора. Набор — это временное множество, в которое входят имена основных примитивов рисунка (как правило, они собираются по какому-то признаку-фильтру). Неосновные примитивы (составные части блока или вершины полилинии) не могут входить в набор. Имя набора обычно сохраняется в переменной, чтобы затем можно было извлекать из набора нужные примитивы.
Функция ssget формирует набор по запросу или признаку:
(ssget [<метод>] [<точка1> [<точка2>]] [<список>] [<фильтр>])
Аргумент <метод> —метод выбора примитивов:
• "С" — выбор секущей рамкой;
• "F" — выбор секущей линией;
• "L" — выбор последнего видимого примитива;
• "Р" — последний сформированный ранее набор;
• "W" — выбор рамкой;
• "X" — вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана, с учетом аргумента <фильтр> (в этом случае аргумент <фильтр> не должен быть опущен);
• "А" — вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана;
• ":Е" — все примитивы, попадающие в прицел устройства указания;
• ":N" — выбор основных примитивов с помощью подпримитивов (вершин полилинии или сети, компонент блока); используется только при графическом варианте выбора и только для указания рамкой, секущей рамкой и точкой; может привести к повторяемости примитивов в наборе, поскольку, например, можно отметить одну и ту же полилинию с помощью любой из ее вершин (см. также функцию ssnamex);
• ":S" — допускает выбор только одного объекта.
Аргумент <точка1> при отсутствии аргумента <точка2> определяет дополнительное условие для включения в набор: включаемый примитив должен проходить через точку, заданную аргументом <точка1>. Если заданы оба аргумента <точка1> и <точка2>, то заданные ими точки являются углами простой или секущей рамки (когда в качестве метода выбора применяются рамки, т. е. "W" или "С").
Аргумент <список> представляет собой список, элементами которого являются точки, используемые в методах "F", "WP", "СР".
Аргумент <фильтр> — это список со структурой, аналогичной структуре списка, возвращаемого функцией entget, что позволяет оставить только те примитивы, которые удовлетворяют дополнительным признакам (например, определенному цвету, слою, весу и т. д.).
Возвращаемое значение функции ssget — имя созданного набора (или nil, если создать набор невозможно).
(ssget) — выдает стандартный запрос:
Выберите объекты:
(Select objects:)
и далее создает набор в соответствии с дальнейшими указаниями пользователя;
(ssget '(15.78 320.1)) — создает набор из примитивов, проходящих через точку (15.78 320.1);
(ssget "_с" '(1.57 -40.4) '(15.78 320.1)) — создает набор из примитивов, выбираемых секущей рамкой с углами в точках (1.57 -40.4) и (15.78 320.1);
(ssget "_x" '((0 . "POLYLINE") (8 . "WALLS"))) — создает набор из всех примитивов рисунка, являющихся полилиниями типа POLYLINE и лежащими на слое WALLS;
В рисунке одновременно может быть открыто не более 128 наборов выбора. При достижении такого предела функция ssget отказывается создавать следующие наборы и возвращает nil. Чтобы удалить ненужные наборы, следует присвоить значение nil переменным, хранящим имена этих наборов.
Для манипуляций с наборами в языке AutoLISP предусмотрены следующие функции:
• (ssadd [<примитив> [<набор>] ]) — добавление примитива в набор; если аргумент <набор> опущен, а аргумент <примитив> задан, то создается новый набор из одного примитива; если оба аргумента опущены, то создается новый пустой набор (но его значение не равно nil); возвращается имя набора;
• (ssdel <примитив> <набор>) — удаление примитива из набора; возвращается имя набора, если операция удаления выполнена, или nil, если примитив не содержится в наборе и удалить его нельзя;
• (sslength <набор>) — возвращает количество примитивов в наборе;
(setq sset (ssget "p")) ;помещает последний объект в набор SSET
(sslength sset) ;возвращает 1
• (ssmemb <примитив> <набор>) — проверка вхождения примитива в набор; возвращается имя примитива, если он входит в набор, или nil — если не входит;
• (ssname <набор> <номер>) — возвращает имя примитива с порядковым номером <номер> из набора; аргумент <номер> должен быть либо целым числом от 0 до 32 767, либо целым числом в вещественной форме больше 32767.0; нумерация примитивов в наборе начинается с нуля; возвращается имя примитива или nil;
(setq sset (ssget)) ;создает набор под именем SSET
(setq ent1 (ssname sset 0)) ;получает имя первого примитива в SSET
(setq ent4 (ssname sset 3)) ;получат имя четвертого примитива в SSET
• (ssnamex <набор> [<номер>]) — извлечение примитива из набора по порядковому номеру, но при этом выдается дополнительная информация о методах формирования набора (см. ниже); если аргумент <номер> опущен, то выводится информация обо всех примитивах набора;
• (sssetfirst <набор1> [<набор2>]) — включает ручки у примитивов, входящих в наборы, заданные аргументами <набор1> и <набор2>, но еще и подсвечивает пунктиром примитивы из набора2 (что означает выбор их для следующей операции редактирования);
• (ssgetfirst) — возвращает список с именами двух наборов, аналогичных по назначению аргументам <набор1> и <набор2> функции sssetfirst (у примитивов набора1 включены только ручки, у примитивов набора2 включены ручки и подсвечивание).
Функция ssnamex возвращает список, в котором элементами являются описания способа выбора примитивов, попавших в набор. Если аргумент <номер> не задан, то длина возвращаемого списка равна количеству элементов, определяемых аргументом <набор>. Если аргумент <номер> задан и задан корректно, то возвращаемым значением будет список из одного элемента — описания способа выбора примитива с порядковым номером, равным значению аргумента <номер>. Если же аргумент <номер> задан неправильно, то функция ssnamex вернет nil.
Описание способа выбора примитива — это список из трех элементов: (<метод> <примитив> <данные>). Параметр <метод> — целое число, которое соответствует методу выбора функции ssget и может принимать такие значения:
• 0 — неинтерактивный выбор ("L", "А", "X" и т. п.);
• 1 — выбор указанием точки;
• 2 - "W" или "WP";
• 3 - "С" или "СР";
• 4 - "F".
Если на месте параметра <метод> стоит отрицательное число, то оно определяет многоугольник выбора (см. описание многоугольника ниже).
Параметр <примитив> описания способа выбора примитива является его именем в том виде, в котором оно выводится функцией entiast. Параметр <данные> может быть либо только числом 0, либо числом 0 и списком, уточняющим выбор, либо числом 0 и номером многоугольника. В уточняющем списке может быть точка, с помощью которой выбран объект. Если использован номер многоугольника (а он должен быть отрицательным: —1 , —2 и т. п.), то далее будет следовать описание многоугольника с соответствующим номером.
Описание многоугольника— это список такого вида: (<номер_многоуголь-ника> <точка1> ... <точкаN>). Нумерация многоугольников начинается с —1 и наращивается путем добавления -1 к очередному номеру.
Описание точки (<точка1> и т. п.) — это список из трех (или двух) элементов: (<код> <база> [<вектор>] ). Описание точки зависит от вида, на котором она выбиралась, и фактически представляет собой описание прямой, луча или отрезка. Параметр <код> является кодом описания точки (0 — прямая, 1 — луч, 2 — отрезок), параметр <база> представляет собой начальную точку описания, а необязательный параметр <вектор> — это либо направление, в котором продолжается бесконечная линия (прямая или луч), либо смещение в сторону, характерное для отрезка.
Пример:
Если в набор nab5 включен один объект, который был указан точкой (7.51 16.02) на обычном виде сверху в МСК, то выражение
(ssnamex nab5 0) возвращает примерно следующее: ((1 <имя объекта: 14аа560> 0 (0 (7.51 16.02 0.0)))).
В этом примере возвращенный функцией ssnamex список состоит из одного элемента (списка), в котором присутствуют следующие составные части:
• <метод> — равен 1 (соответствует выбору указанием точки);
• <примитив> — <Имя объекта: 14аа560>;
• <данные> — 0 (0 (7.51 16.02 0.0)), что соответствует точке (7.51 16.02 0.0), примененной для выбора примитива.
Другие примеры значений, возвращаемых функцией ssnamex:
((0 <Имя объекта: 14ае578> 0)) — один примитив, выбранный неин-терактивным методом (например, "L");
((3 <Имя объекта: 14ае568> О -1) (3 <Имя объекта: 14ае578> 0 -1) (-1 (0 (-147.787 129.133 0.0)) (0 (-64.2728 129.133 0.0)) (0 (- 64.2728 22.3376 0.0)) (0 (-147.787 22.3376 0.0)))) — два примитива, выбранных секущим прямоугольником с номером —1 (для прямоугольника заданы четыре точки);
((1 <Имя объекта: 14ае560> 0 (0 (74.2672 64.8218 0.0))) (2 <Имя объекта: 14ае570> 0 -1) (2 <Имя объекта: 14ае568> 0 -1) (-1 (0 (-177.446 158.755 0.0)) (0 (40.3151 158.755 0.0)) (0 (40.3151 83.1407 0.0)) (0 (-177.446 83.1407 0.0)))) — три примитива, первый из которых выбран указанием с помощью точки (74.2672 64.8218 0.0), а второй и третий выбраны рамкой, которая фигурирует как многоугольник с номером -1.
В этих примерах параметр <вектор> описания точек нигде не использован, т. е. объекты выбирались на виде сверху в МСК.
Наборы — удобный инструмент для выбора нужных примитивов рисунка с заданными свойствами. После формирования набора затем из него с помощью функции ssname (или ssnamex) извлекаются нужные объекты, с которыми далее выполняются необходимые операции (например: удаление, модификация и т. д.).