Логотип сайта поддержки пользователей САПРО сайте поддержки пользователей САПР Translate to:

Глава 5 Примитивы и механизм доступа

Всеобъемлющие функции AutoLISPа "set" обеспечивают доступ к примитивам AutoCADа, к графическому экрану и к механизмам ввода. Вы можете выбирать примитивы, восстанавливать их величины и модифицировать их. Наборы выбора (selection - sets) можно поместить в переменные LISPа, это позволяет работать коллекции примитивов. Для прямого создания примитивов нет функций, однако, можно использовать функцию COMMAND , чтобы подчиниться обычным командам AutoCAD для выполнения этого.

5.1. Специальные типы данных

Два специальных типа данных AutoLISPа являются инструментом, обеспечивающим доступ к примитивам AutoCAD: имя примитива (entity name) и набор выбора (selection - set). Этими типами данных манипулируют только функции, которые действуют на основании их, и их внутренняя структура не касается программиста LISP. Имя примитива имеет значение в указателе файла, обслуживающем редактор чертежей AutoCAD, в котором AutoLISP может найти базу данных примитивов или их векторы (если есть вывод на экран). Наборы выбора это просто коллекция имен примитивов.

Имена примитивов и наборы выбора действительны только в течение сеанса редактирования, в котором они применяются AutoCADом.

5.2. Манипуляция функцией selection - set

Следующие функции выполняют различные действия на основании функции selection - sets (наборы выбора).

5.2.1. (ssget [< режим >] [<точ1> [<точ2>]])

Вы можете применять функцию selection - set с функцией SSGET. Аргументом < режим > является строковая константа, которая означает тип выполняемого выбора примитива. Это могут быть буквы " W " , " C " , " L" , или " P " , названия режимов в AutoCADе " Window" (окно) , Crossing "(пересечение) , " Last " (последний), " Previous" (предыдущий). < точ1 > и < точ2 > это аргументы точки в списках , которые определяют точки , уместные для выбора. Обозначение точки без аргумента < режим > эквивалентно выбору примитива указанием единственной точки. Если все аргументы опущены , SSGET подскажет пользователю через механизм AutoCADа " Select objects: "(выберите объекты), позволяя интерактивный выбор набора.

Примеры
(ssget)                    ;Cпрашивает пользователя общий выбор примитива
(ssget "P")                ;Выбирает самый новый выбранный набор.
(ssget "L")                ;Выбирает последний примитив,прибавленный к базе данных.
(ssget '(2 2))             ;Выбирает примитив,проходящий через точку 2, 2 .
(ssget "W" '(0 0) '(5 5))  ;Выбирает примитивы внутри окна с координатами точек 0,0 5, 5 .
(ssget "C" '(0 0) '(1 1))  ;Выбирает примитивы пересекающие бокс с координатами точек 0,0 1, 1 .

Выбранные объекты высвечиваются, когда SSGET используется без аргументов. Нет информации о том, сколько выбранных примитивов сохраняется (как альтернативу смотри функцию ENTSEL , описанную ниже). Selection -sets временно поглощают щели файла AutoCAD , поэтому LISPу не разрешается иметь более 6-и одновременно открытых файлов. Если этот предел достигнут , AutoCAD откажется создавать любые другие наборы выбора (selection -sets) и возвратит " nil " на все вызовы AutoCADа.

Переменная набора выбора может быть передана AutoCADу в ответ на любую подсказку "Select objects:" в выборе "Last". Она выберет все объекты в наборе LISPа, как бы просматривая их в окошко (обратите внимание, примитивы, выбранные этим способом, не нуждаются в выводе на экран).

5.2.2. (sslength <ss>)

Эта функция возвращает целое число, содержащее количество примитивов в наборе выбора <ss>. Наборы никогда не содержат дубликатов примитивов.

5.2.3. (ssname <ss> <index>)

Эта функция возвращает имя примитива <index>-го элемента набора <ss>. Если <index> отрицательное или больше самого большего вычисляемого примитива в наборе выбора, возвращается "nil". Первый элемент набора имеет индекс "0". Имена примитивов в наборе, применяемых с функцией SSGET , всегда будут именами главных примитивов. Подпримитивы (Block attributes и Polyline vertices) не будут возвращаться ( но, смотри описанную ниже функцию ENTNEXT, которая делает доступными их).

5.2.4. (ssadd [<ename> [<ss>]])

Если вызывается без аргументов, функция SSADD создает новый набор выбора без членов. Если вызывается с единственным аргументом имени примитива, функция SSADD создает новый набор выбора, содержащий это единственное имя примитива. Если вызывается - с именем примитива и с набором выбора, она добавляет имя примитива к набору. Функция SSADD всегда возвращает новый или модифицированный набор. Запомните, что при добавлении примитива к набору, новый примитив физически присоединяется к существующему набору, и набор, проходящий как <ss>, возвращается, как результат. Таким образом, если другим переменным присваивается категория - набор, они будут отражать также сложение. Если в наборе уже есть примитив с таким же названием, действие функции SSADD будет проигнорировано; сообщения об ошибке не будет.

5.2.5. (ssdel <ename> <ss>)

Функция SSDEL удаляет имя примитива <ename> из набора <ss> и возвращает имя набора <ss>. Запомните, что примитивы физически удаляются из набора, как оппозиция новому набору, возвращающемуся с удаленным элементом. Если в наборе нет примитива, возвращается "nil".

5.2.6. (ssmemb <ename> <ss>)

Эта функция проверяет, является ли имя примитива <ename> членом набора выбора <ss>. Если это так, функция SSMEMB возвращает имя примитива <ename>. Если нет, возвращает "nil".

5.3. Функции имени примитива (entity name)

Следующие функции выполняют различные действия с именем примитива, включая ввод. Имена примитивов могут проходить в AutoCADе в ответ на любую подсказку " Select objects: " , для которой ответ "Last" действителен. В результате будет выбрано название примитива, как если бы он просматривался в окошко.

5.3.1. (entnext [<ename>])

Если вызывается без аргументов, эта функция возвращает имя примитива первого не удаленного примитива в базе данных. Если функция ENTNEXT вызывается с аргументом примитива <ename>, она возвращает имя первого не удаленного примитива, следующего за <ename> в базе данных. Если нет следующего примитива в базе данных, возвращается "nil". Функция ENTNEXT возвращает и главные примитивы и подпримитивы.

Примитивы, выбранные функцией SSGET - главные примитивы, нет атрибутов блоков или вершин полилиний. Вы можете добраться до внутренней структуры этих сложных примитивов посредством простого приема, через подпримитивы, функцией ENTNEXT. Если вы однажды примените имя подпримитива, вы можете действовать подобным образом в любом другом случае. Если вы приобрели имя подпримитива через функцию ENTNEXT, вы можете найти родительский примитив, двигаясь вперед от функции ENTNEXT до функции SEQEND, чтобы обнаружить примитив, затем, извлекая -2 группу из такого примитива, который является главным именем примитива.

5.3.2. (entlast)

Эта функция возвращает имя последнего не удаленного главного примитива в базе данных. Эта функция часто применяется, чтобы дать имя новому примитиву, который только что был прибавлен через функцию COMMAND. Примитив не нужно выводить на экран, и также не нужно выбирать уровень.

5.3.3. (entsel [<prompt>])

Она иногда желательна, как действие на примитивы, чтобы одновременно выбрать примитив и обозначить точку, с помощью которой примитив был выбран. Примеры этого в AutoCADе можно найти в функции Object Snap и в командах BREAK , TRIM , EXTEND . Функция ENTSEL позволяет программам AutoLISPа выполнить это действие. Функция ENTSEL выбирает отдельный примитив, требуя, чтобы выбор был сделан точкой. Она возвращает список, в котором первый элемент - имя выбранного примитива, второй элемент - координаты точки, используемой для выбора примитива. Если строка содержит <подсказку>, эта строка может быть использована, чтобы спросить пользователя о примитиве. Иначе, по умолчанию появится подсказка "Select object:" . Следующий диалог иллюстрирует использование функции ENTSEL и возвращаемый список.

   Command: Line
   From point: 1 , 1
   To point: 6 , 6
   To point: RETURN
   Command: (setq e (entsel "Please choose an entity:"))
   Please choose an entity: 3 , 3
   (< Entity name: 60000014> (3.000000 3.000000))

Возвращаемая функцией ENTSEL форма в виде списка, удовлетворяет AutoCAD в ответ на любую его подсказку выбрать объект. Это будет трактоваться AutoCADом, как выбор определенного примитива, указанного точкой.

5.4. Функции данных примитива (entity data)

Следующие функции позволяют вам восстановить и модифицировать данные определенных примитивов. Имена примитивов применяются для того, чтобы определить примитивы, с которыми надо работать.

5.4.1. (entdel <ename>)

Удаляет примитив, обозначенный <ename>, в текущем чертеже, или восстанавливает примитив, если он был предварительно удален в этом сеансе редактирования. Удаляемые примитивы вычищаются из чертежа, покидая редактор чертежей, итак, функция ENTDEL может восстанавливать их только в течение сеанса редактирования, когда они были удалены. Функция ENTDEL работает только в главных примитивах, атрибуты и вершины полилиний не могут быть удалены, независимо от их родительских примитивов (вы можете использовать функцию COMMAND , чтобы работать функцией ATTEDIT, или команду PEDIT, чтобы выполнить это).

5.4.2. (entget <ename>)

Примитив, который называется <ename> восстанавливается из базы данных и возвращается как список, содержащий эти определяемые данные. Результирующий список кодируется, как структурированный список LISP, элементы которого могут быть легко восстановлены функцией ASSOC. Объекты в результирующем списке кодируются в кодах DXF системы AutoCAD для каждой части входных данных. Для примера рассмотрим вычерчивание и затем восстановление LINE следующей последовательностью команд:

   Command: LINE
   From point: 1 , 2
   To point: 6 , 6
   To point: RETURN
   Command: (setq a (entget (entlast)))
установит А, равное списку (делает останов для прочтения):
      ( ( -1 . <Entity name: 60000014>)
            (0 .  "LINE")
            (8 .  "0")
            (10 1.000000 2.000000)
            (11 6.000000 6.000000)
      )

Пункт -1 в начале списка содержит имя примитива, которым этот список представлен. Функция ENTMOD, описанная ниже, использует это, чтобы идентифицировать примитив, который модифицирован.

Отдельные точечные пары, представляют переменные, которые могут быть легко восстановлены с помощью функции ASSOC, функция CDR обычно выводит их значения. Коды для компонентов примитива те же самые, что использует DXF , и приводятся в приложении С Руководства AutoCAD. Так же, как в DXF , заголовок элемента примитива (цвет и тип линии, сложный примитив флага (функция ATFLAG), экструзия толщины и выключение набора Z) выводится, если переменная не по умолчанию. В функциях, не таких как DXF, не обязательно выводить точность поля примитива, равную ли их значениям по умолчанию или нет. Намерение сделать это является упрощенным вариантом программ, которые всегда могут принимать эти поля присутствующими для основных алгоритмов, по котором они работают. Запомните, что подсписки для точек - это не точечные пары, подобные остальным. Соглашением является то, что функция CDR подсписка –это групповая переменная. Так как точка- это список двух действительных чисел, это составляет всю совокупность трех элементов списка. Функция CDR группы является списком, изображающим точку, соглашением является также, то что функция CDR всегда возвращает переменную сохраненной.

Когда описываемые функции обрабатывают эти списки, обязательно сделайте им аккуратные подсписки. Польза для функции ASSOC от этого гарантирована. Группа -1 ,содержащая имя примитивов, позволяет произвести некоторые действия, чтобы просто принять список примитива, и избежать необходимости сохранять имя примитива в параллельной структуре. Примитив SEQEND в конце Poliline или набор атрибутов содержит -2группу, чьи CDR являются заголовком в этом примитиве. Это позволит найти заголовок в подпримитивах, двигаясь вперед к SEQEND , затем, используя функцию CDR -2 группы, как имя примитива, восстановить структурированный главный примитив. Следующий пример хорошо иллюстрирует комплексные примитивы, представленные как список.

   Command: ELEV
   New current elevation <0.0000>: 3.5
   New current thickness <0.0000>: 0
   Command: LINETYPE ?/Create /Load/Set: SET 
   New entity linetype <BYLAYER>: DASHED
   Command:COLOR
   New entity color <BYLAYER>: BLUE
   Command: LAYER
   ?/Make/Set/New/On/Off/Color/Ltype/Freeze/Thaw: MAKE
   New current layer <0>: ANNOTATION
   ?/Make/Set/New/On/Off/Color/Ltype/Freeze/Thaw: RETURN
   Command: TEXT
   Start point or Align/Center/Fit/Middle/Right/Style: 2 ,2
   Height <0.2000>: .3
   Rotation angle <0>: 30
   Text: So long , and thanks for all the fish!
   Command: (setq e (entget (entlast)))

В этом случае Е будет устанавливать в списке то, следует ниже. Рассмотрение приложения С Руководства к AutoCADу придаст смысл этому ясному списку.

      ( (-1 . <Entity name: 6000003C>)
            (0 . "TEXT")
            (8 . "ANNOTATION")
            (6 . "DASHED"
            (62.  5)
            (38 . 3.500000)
            (10 2.000000 2.000000)
            (40 . 0.300000)
            (1 . "So long , and thanks for all the fish!")
            (50 . 0.523598)
            (41 . 1.000000)
            (51 . 0.000000)
            (7 . "STANDARD")
            (71 . 0)
            (72 . 0)
            (11 0.000000 0.000000)
      )

5.4.3. (entmod <elist>)

Список <elist> проходит функцию ENTMOD, в формате возвращающей его функции ENTGET, и обновляет информационную базу данных примитива, имя которого определено совокупностью -1 в <elist>. Однако, главный механизм, с помощью которого LISP обновляет базу данных, это восстановление примитивов функцией ENTGET, модификация списка, определяющего примитив (запомните, что для этого очень полезна функция SUBST AutoLISPа) и обновляющего примитив в базе данных с помощью функции ENTMOD.

Функция ENTMOD имеет некоторые ограничения по изменениям, которые она делает. Во - первых, нельзя изменять типы примитивов. (Если вы хотите сделать это , примените только функцию ENTDEL и сделайте новый примитив командой COMMAND ). AutoCAD должен знать все объекты, которые упоминаются в списке примитивов, до того как выполнена функция ENTMOD. Так, стиль текста, тип линии, форма и имена блоков должны быть предварительно определены в чертеже, до того, как функция ENTMOD может их использовать в списке примитивов. Исключением в этом случае является имя уровня , __ENTMOD освободит новый уровень по умолчанию, используя команду "LAYER NEW" , если в этом списке указывается предварительно не определенный уровень.

Функция ENTMOD выполняет некоторую последовательность действий, как команда DXFIN, проверяя список, содержит ли он, данные из файла DXF. Если обнаружена серьезная ошибка, такая серьезная, что база данных не обновляется, возвращается "nil". В противном случае, функция ENTMOD возвращает список в качестве аргумента. Функция ENTMOD не изменит внутренние поля, такие как имя примитива, в совокупности -2 функции SEQEND, попытки изменить такие поля просто игнорируются.

Когда обновляется главный примитив, функция ENTMOD будет модифицировать примитив и обновит изображение на экране (включая подпримитивы). Когда функция ENTMOD обычно обновляет подпримитив ( вершины полилиний , атрибуты блоков ), подпримитив будет обновлен в базе данных, но изображение на экране не обновляется. После всех модификаций, которые сделаны с данными подпримитивами, можно использовать функцию ENTUPD, описанную ниже, для обновления изображения на экране.

5.4.4. (entupd <ename>)

Как описано выше, когда функция ENTMOD модифицирует вершины полилиний или атрибуты блоков, полный комплект примитива не обновляется на экране. Например, если были модифицированы 100 вершин сложных полилиний, пересчет и перечерчивание Polyline, так же как и каждой вершины, которая была изменена, будет сделано неприемлемо медленно. Обычно, можно применить функцию ENTUPD, чтобы модифицированную Polyline или блоки обновить на экране. Функция ENTUPD назовет именем примитива любую часть Poliline или блока. Нет необходимости иметь заголовок примитива, функция ENTUPD найдет заголовок. Когда функция ENTUPD предназначена для полилиний и атрибутов блоков, ее можно вызвать для любого примитива. Она всегда будет восстанавливать примитив на экране, включая все подпримитивы.

5.4.5. Ограничения

Имена примитивов (entity names) и наборы выбора (selection- sets) действительны только в течение сеанса редактирования, в котором они применяются в AutoCADе. Так, если вы попытаетесь произвести какие-нибудь последующие действия, пока активны команды PLINE или ATTEDIT , будет возвращено " nil" и запрос функции не будет выполнен.

 ENTMOD  чтобы модифицировать существующий примитив
 ENTUPD  чтобы восстановить модифицированный сложный примитив
 ENTDEL  чтобы не удалять и восстановить уничтоженный примитив

5.5. Применение в AutoCADе имен примитивов и наборов выбора

Имена примитивов (entity name) и наборы выбора (selection-sets) необходимы для того, чтобы ввести из LISPа объекты выбора в ответ на подсказку. Таким образом, примитивы, названные LISPом, могут работать по командам AutoCADа. Подсказку "Select objects:" LISP может снабдить именем примитива, который определяет единственный примитив или набор выбора, чтобы выбрать все примитивы в наборе. Передача имен примитивов и набора выбора из LISPа возможна в выборе "Last"(обе части, как способность выбирать примитивы, не взирая на видимость, так и не специфицировать выбранные точки).

Всякий раз, когда AutoCAD позволяет сделать выбор объекта точкой, списки в программе, возвращаемые функцией ENTSEL, допустят процедуру выбора. Они выбирают примитив из списка, определяя точку в списке, как выбранную точку. Это позволяет LISPу перейти к вводу выбранных точек такими командами, как BREAK, TRIM и EXTEND. Помните, что списки формы ENTSEL могут использоваться для других выборов тоже, так же точно, как точка, выбираемая позволяющей командой. Списки формы ENTSEL не могут использоваться с командами FILLET и CHAMFER, которые применяют два примитива и точки из механизма выбора.

5.6. Доступ к таблице символов

Приведенные ниже функции TBLNEXT и TBLSEARCH снабжены таблицей символов, которая доступна только для чтения из AutoCADа уровня, типа линии, именованного вида, стиля текста и определения блока.

5.6.1. (tblnext <table name> [<first>])

Эта функция используется для просмотра всех таблиц символов. Первый аргумент - это идентификатор символа интересующей вас таблицы. Действительны имена "LAYER" , "LTYPE" , "VIEW" , "STYLE" и "BLOCK".

Именам не нужен верхний регистр. Когда присутствует второй аргумент, и не "nil", таблица символов переводится на начало и первый элемент в ней восстанавливается, в противном случае, восстанавливается следующий элемент в таблице. Когда совсем нет элементов в таблице, возвращается "nil". Удаленные элементы таблицы не возвращаются.

Когда элемент обнаружен, он возвращается, как список точечных пар DXF кодов и значений, подобно тому, который возвращает функция ENTGET.

Пример:
(tblnext "layer" T)                 ;восстанавливает первый уровень:
 
		 может вернуть:
 
 	     	((0 . "LAYER")                ;символьный тип
 	     	(2 . "0")                     ;имя символа
	     	(70 . 0)                      ;флаги
	     	(62 . 7)                      ;цвет, негатив выключен
	    	(6 . "CONTINUOUS")            ;тип линии
	     )

Обратите внимание, что совокупности "-1" нет. AutoCAD запоминает последний элемент, возвращаемый из таблицы, и просто возвращает один из следующих элементов, при каждом вызове TABNEXTом этой таблицы. Когда вы начинаете просмотр таблицы, вы должны быть уверены, что второй аргумент не "nil", чтобы перемотать таблицу и вернуть первый элемент. Элементы, восстановленные из таблицы " BLOCK" , включают в себя совокупность "-2" с именем первого примитива в определении блока (или любого). Итак, назовем блок "BOX"

(tblnext "block")       ;восстанавливает определение блока
	  
       может вернуть:
      
	  ((0 . "BLOCK")                          ;тип символа
            (2 . "BOX")                       ;имя символа
            (70 . 0)                          ;флажки
            (10 9.000000 2.000000 0.000000)   ;Х,У,Z
            (-2 . <Entity name: 40000126)) ;первый примитив
      )

Имя примитива в совокупности "-2" принимается функциями ENTGET и ENTNEXT ,но ни какими другими функциями. Это значит, что вы не можете модифицировать такой примитив функцией ENTMOD или использовать функции SSADD или ENTSEL , чтобы поместить его в selectin-set. Применяя совокупность "-2"имени примитива в функции ENTNEXT, вы можете сканировать примитивы, сжимая определения блока; функция ENTNEXT возвращает "nil" после последнего примитива в определение блока.

5.6.2. (tblsearch <table name> <symbol>

Эта функция просматривает таблицу символов, идентифицируемую <table name> (то же самое, что функция TBLNEXT), отыскивая имя символа присвоенного <symbol>. Оба имени автоматически приводятся к верхнему регистру. Когда обнаружено имя элемента, подобное тому, которое дал <symbol>, эта запись возвращается в формате, описанном функцией TBLNEXT. Если такой элемент не обнаружен, возвращается "nil".

Например:
(tblsearch "style" "standard")      ;устанавливает стиль текста

 может вернуть:
 
      ((0 . "STYLE")                      ;тип символа
            (2 . "STANDARD")              ;имя символа
            (70 . 0)                      ;флажки
            (40 . 0.000000)               ;фиксирование высоты
            (41 . 1.000000)               ;фактор ширины
            (50 . 0.000000)               ;угол
            (71 . 0)                      ;генерирование флажков
            (3 . "txt")                   ;самый первый font file
            (4 . "")                      ;большой font file
      )

Порядок вводов восстановлен из TBLNEXT без воздействия функции TBLSEARCH.

5.7. Доступ к графическому экрану и устройствам ввода

Функции AutoLISPа, описанные в этом разделе, обеспечивают прямой доступ к графическому экрану AutoCADа, и устраивают вход из LISPа, и позволяют средствами LISP-команд взаимодействовать с пользователем, как если бы выполнение было без AutoCADа. Эти команды могут устроить беспорядок на экране. Однако, любое повреждение, которое они наносят, может быть отменено последовательностью:

      (grtext)
      (redraw)

однако нет нужды касаться этого. Эти функции только для опытных пользователей. Большинству применений LISPа не нужны эти функции. Пользователей предупреждаем, что действия этих функций могут быть изменены от выпуска к выпуску системы AutoCAD и, следовательно, Autodesk, поэтому нет гарантии указанной выше совместимости применений этих функций. Применение функций GRTEXT и GRREAD также может быть неподходяще, для работы на любой жесткой конфигурации, если пользователь не очень внимателен, чтобы аккуратно следовать правилам их использования, приведенным ниже.

5.7.1. (grclear)

Эта функция очищает графический экран AutoCADа. (В системах с одним экраном она переключит графический экран с текстового режима на первый). Подсказка, статус и меню остаются неизменными. Оригинал может быть перевыведен на графический экран функцией REDRAW.

5.7.2. (grdraw <from> <to> <color> [<highlight>])

Функция GRDRAW вычерчивает вектор между двумя точками . <from> и <to> являются точками (списки из двух действительных чисел), которые определяют конечные точки вектора. Конечные точки определяются, как плавающие точки для вычерчивания координат и будет clipped, как требование, чтобы вывести на экран. Вектор будет нарисован с цветным выводом, если аргумент <color> целое число, определяемое в группе -1 в "XOR ink", которая заканчивает любое его вычерчивание и уничтожается, когда перечерчено. Если аргумент <highlight> целое число и не "0", будет нарисован вектор так, как механизм дисплея высветит выбранные объекты (обычно по-точечно). Если <highlight> пропущен или имеет значение 0, будет использован нормальный режим вывода на экран.

5.7.3. (grtext [<box> <text> [<highlight>]])

Функция GRTEXT позволяет AutoLISPу выводить текст частями на графический экран в AutoCADе. Если вызывается с аргументом <box> от 0 и до самого высокого численного значения бокса в меню экрана минус 1, функция выведет на экран дисплея строковый аргумент <text>, в указанный в меню бокс. Текст<text> будет сокращен, если он слишком длинный , и непригоден для бокса, и пустота заполнится пробелами, если текст короче. Если присутствует факультативный аргумент (целое число) <highlight> и он не 0 , в предназначенном боксе будет высвечиваться текст. Если <highlight> присутствует и 0, текст в предназначенном боксе не будет высвечиваться ( запомните, что при высвечивании другого текста, бокс автоматически отменяет предыдущий текст, который был высвечен). Когда вы пишете в боксе, текст сначала должен быть написан без аргумента <highlight>, затем высвечен. Такая же текстовая строка, какая в оригинале вводится в бокс, должна высвечиваться и не высвечиваться. Результатом несоблюдения этих правил будут LISP программы, которые ведут себя по-разному на разных дисплеях. Запомните, что эта функция просто выводит на экран дисплея текст, находящийся в площади экрана ; она не изменяет элементы экранного меню.

Если функция GRTEXT вызывается боксом номер -1, текст будет выведен на экран в режиме статуса линии. Длина линии зависит от дисплея ( большинство их допускает , по крайней мере , 40 разновидностей, за исключением замечательного Color Graphics Adaptor фирмы IBM ). Текст будет сокращен, чтобы пригнать его к имеющемуся в распоряжении пространству.

Если используется бокс с номером -2, текст будет написан в координатах статуса линии. Запомните, что если слежение координат включено, величины, записанные в это поле, перепишутся, как только указатель пошлет другой набор координат. Каждый из номеров , -1 или -2 , игнорирует аргумент <highlight> , если он присутствует.

Наконец, функция DRTEXT может быть вызвана без аргументов, что бы восстановить всю площадь текста на экране, с его стандартными переменными.

5.7.4. (grread [<trac>])

Функция GRREAD позволяет вам непосредственно следить за механизмом входа AutoCADа, выслеживая указанные механизмы, когда они изменяются. Этой функции нужны только специфические команды, большинство входов в AutoLISP пройдут через различные функции GETxxx , такие как GETSTRING , GETREAL и подобные. Аргумент <track> , если он имеется и не "nil" , дает возможность вернуть координаты из указанных механизмов, когда они двигаются, не требуя выбора нажатием клавиш. Этот механизм AutoCAD обычно использует для протягивания.

Функция GRREAD возвращает список, в котором первый элемент это код, определяющий тип входа. Второй элемент списка - любое целое число или список точек, зависящих от типа входа. Коды для первого элемента в списке следующие:

  2   характеризует клавиатуру - в кодах ASCII, также и для вторго элемента
  3   выбираемая точка - координаты , как список
  4   выбираемый элемент меню экрана- номер бокса , также и для второго элемента
  5   режим протягивания координат , также и для второго элемента.
      Возвращается только , если второй аргумент определен и он не "nil"
  6   BUTTONS выбираемый пункт меню - номер клавиши это второй элемент
  7   TABLET1 оцифровываемый пункт меню - номер бокса это второй элемент
  8   TABLET2 оцифровываемый пункт меню - номер бокса это второй элемент
  9   TABLET3 оцифровываемый пункт меню - номер бокса это второй элемент
  10  TABLET4 оцифровываемый пункт меню - номер бокса это второй элемент
  11  AUXI оцифровываемый пункт меню - номер бокса это второй элемент
  12  координаты, связанные с указателем клавиш , возвращаемые, как
      второй элемент. Всегда следует тип 6 , чтобы возвратить список
  13  выбор высвеченного пункта меню экрана при помощи ввода с клавиатуры

Ввод CTRL C в то время как идет GRREAD , вызовет прерывание (abort) LISP программы с клавиатуры. Любой другой вход пройдет прямо к GRREAD ,давая этим возможность закончить контроль над механизмом входа.

5.8. Образцы программ

Следующие LISP программы иллюстрируют возможности, описанные в этой главе.

5.8.1. Удаление уровня

Эта программа выполняет команду DELLAYER , чтобы удалить все примитивы определенного уровня.

      ; Удаление всех примитивов на определенном уровне
 
      (defun C : DELLAYER (/ e l)
            (setq l (strcase (getstring "\nLayer to delete?")))
 
            ; Запуск черчения сканированием первого примитива
            (setq e (entnext))
 
            ; Проверка уровней этих примитивов (8 групп)
            (while e
                  (if (= l (cdr (assoc 8 (entget e))))
                  ; Корректирование уровня... удаление этого уровня
                        (entdel e)
                  )
                  ; Взять следующий примитив
                  (setq e (entnext e))
 
            ; Останов до тех пор пока не будет больше примитивов
            )
      )

Функция DELLAYER проверяет 8 групп ( имя уровня ) каждого примитива чертежа, просматривая примитивы на специфицируемом уровне. Тестированием других групп вы можете выполнить команды, чтобы проверить все примитивы особых типов ( окружности, может быть) или все примитивы особых вычислений и прочее.

5.8.2. Установление текущего уровня

Эта программа выполняет команду SETLAYER , давая возможность изменить текущий уровень, просто указывая на существующий объект этим уровнем.

      ; Установить текущий уровнь этого существующего объекта
 
      (defun C:SETLAYER ( / e n)
            (setq e (car (entsel "Pick an object on the desired layer: ")))
            (if e 
                  (progn
                        ; Взять входные данные групп
                        (setq e (entget e))
                        ; Группа 8 - это имя уровня
                        (setq n (cdr (assoc 8 e)))
                        ; Результат выполнения команды "LAYER SET"
                        (command "LAYER" "SET" n "")
                  )
            )
      )

Вы можете использовать подобный подход , чтобы установить текущий цвет, тип линии, возвышение или толщину этих специфицируемых объектов.

5.8.3. Изменение уровня примитива

Это вариации команды SETLAYER , приведенной выше. Лучше, чем установление текущего уровня , эта команда изменяет выбранные объекты, для того чтобы иметь тот же самый уровень , как и у другого выбранного объекта.

      ; Изменение уровня примитива
 
      (defun C:CHGLAYER (/ ss e n)
            (princ "Select objects to be change ...\n")
            ; Основной набор выбора (selection-set)
            (setq ss(ssget))
 
            ; Если любые выбранные объекты.... 
            (if ss (progn 
                   (setq e (car (entsel "Pick an object on the desired layer: ")))
 
                   ; Если объект был выбран
                   (if e
                        (progn 
                              ; Перейди на эту группу данных
                              (setq e (entget e))
 
                              ; Группа 8 - это имя уровня
                              (setq n (cdr (assoc 8 e)))
                              (command "CHANGE" SS "" "PROP" "LAYER" n "")
                        )
                   )
            )
      )
      )

В этом примере наборы выбора (selection - set) объектов, которые можно изменить, устанавливаются символом SS. Можно применять однажды установленное имя уровня (из 8 группы выбранного объекта), выбор набора (selection - set) SS проходит к команде "CHANGE Properties" (изменение собственности), чтобы вызвать эффект желаемого изменения.

5.8.4. Текстовый редактор

Программа, приведенная ниже, выполняет команду CHGTEXT для основного редактирования текстов. Она допускает, что вы обозначаете "new string" (новая строка), чтобы ею заменить в каждом случае старую строку ("old string"), которая обнаружена в выбранном тексте. Вы можете легко расширять это, чтобы любой текст по вашему желанию редактировался.

      ; Изменение подстроки в выбранном текстовом примитиве
 
      (defun C:CHGTEXT (/ p l n e os as ns s nsl osl sl si chf chm)
            (setq p (ssget))              ; Выберите объекты
            (if p (progn                  ; Если любые объекты выбраны...
                  (setq osl (strlen (setq os (getstring "\nOld string: "t))))
                  (setq nsl (strlen (setq ns (getstring "\nNew string: "t))))
                  (setq l 0 chm 0 n (sslength p))
                  (while (< l n)    ; Для каждого выбранного объекта...
                  (if (= "TEXT"     ; Смотри тип примитива ТЕКСТ (группа 0)
                              (cdr (assoc 0 (setq e (entget (ssname p l))))))
                        (progn      ; Обнаружен один... смотри старую строку
                              (setq chf nil si 1)
                              (setq s (cdr (setq as (assoc 1 e))))
                              (while (= osl (setq sl (strlen
                                          (setq st (substr s si osl)))))
                                          (if (= st os) (progn
                                    (setq s (strcat (substr s 1 (1 si)) ns
                                                      (substr s (+ si ost))))
                                    (setq chf t) ; Обнаружена старая строка
                              ))
                              (setq si (1+ si))
                        )
                        (if chf (progn    ; Заменитель новой строки на старую
                              (setq e (subst (cons 1 s) as e))
                              (entmod e)        ; Текстовый примитив
                              (setq chm (1+ chm))
                        ))
                  )
            )
            (setq l (1+ l))
            )
      ))
      (princ "Changed")                   ; Печать полностью измененных линий
      (princ chm)
      (princ " text lines.")
      (terpri)
)

Здесь, набор выбора Р (selесtion -set P) исследуется для примитивов текста , содержащих в себе специфицируемую старую строку( "old string"). Для каждого подобранного примитива текста, функции STRCAT и SUBSTR обычно формируют новую текстовую строку, которая во всех случаях заменяет старую строку (old string) на новую строку (new string). Используя SUBST,вы построите новую строку, заменяющую группу 1 в текстовом примитиве, и затем обычно ENTMOD откорректирует примитив в базе данных чертежа и на экране.

5.8.5. Обновление данных

Считайте, по соглашению ,что вы вставляете блок, называемый "TITLE", в каждый чертеж и , что этот блок имеет атрибуты , называемые "REVDATE", которые означают данные последней ревизии. Следующая программа выполняет команду REVISE, которая обнаруживает этот блок и корректирует его атрибуты. Сначала определяется пара функциональных утилит.

   ; Ввод текущих данных в формате MM/DD/YY
 
   (defun mmddyy (/ x)
      (setq x (getvar "CDATE"))                 ; Текущие данные
      (setq x (rtos x 2 0))                     ; Обращение к строке
      (setq date (strcat (substr x 5 2) "/"     ; MM
                        (substr x 7 2) "/"      ; DD
                        (substr x 3 2)))        ; YY
   )
 
   ; Возврат содержания примитива поля "num"
 
   (defun fld (num)
        (cdr (assoc num d))
   )
   ; Поиск аттрибутов REVDATE в блоке TITLE и обновление
 
   (defun C:REVISE (/ e d date done)
        (setq done nil)
        (setq e (entnext)                         ; Первый объект в чертеже
        (while e
              (setq d (entget e)                  ; Получение групп данных примитива
 
               (if (and (= (fld 0) "INSERT")      ; Имеется ли INSERT ?
                          (= (fld 2) "TITLE")     ; имя TITLE?
                          (= (fld 66) 1))         ; АТТРИбУТЫ?
                   (progn
                          (setq e (entnext e))    ; Получение подпримитива
                                                  ; (аттрибута)
                          (while e
                          (setq d (entget e))     ; Получение подпримитивов
                                                  ; групп данных

        (cond ((and (= (fld 0) "ATTRIB")          ; Искать
                          (= (fld 2) "REVDATE"))  ; Аттрибуты
                                                  ; REVDATE
                          (mmddyy)
                          (setq d (subst (cons 1 date) (assoc1 d))
                                                  ; Новые данные
 
                                      (entmod d)  ; Изменение аттрибутов
                                                  ; переменных
                                      (entupd e)  ; Регенерация блока
                             (setq e nil done T)) ; Были выполнены
                 ((= (fld 0) "ENDSEQ")
                                    (setq e nil)) ; Нет аттрибутов REVDATE;
                                                  ; останов сканирования
                         (T (setq e (entnext e))) ; Ввод следующего подпримитива
                              )
                        )
                  )
              (setq e (entnext e))                ;Нет блока TITLE, вход
                                                  ; следующего примитива
        )
        )
        (if done "Revision date updated" "No REVDATE attribute found")
  )

Команда REVISE проверяет группу 0 (тип примитива) каждого примитива в чертеже , просматривая упоминаемый блок (функция INSERT), который назван " TITLE". Затем она сканирует подпримитивы этого блока (его атрибуты), просматривая атрибуты "REVDATE". Обнаруженная переменная атрибутов изменится и блок введется.

5.8.6. Список типов линий

Этот пример использует функции доступа к таблице символов, чтобы внести в список имена и определения всех текуще-загруженных типов линий.

; Пустая-полная данная строка ,которая определяет количество
      ; знаков.

(defun strfill (s len)
      (substr (strcat s "                     ") 1 len)
)
; Возврат переменной , связанной с отдельной группой примитива
 
(defun fld (num lst)
      (cdr (assoc num lst))
 
; Список загруженных типов линий
 
(defun C:LTYPES (/ a cl d f lt s x)
     (textscr)                                  ; Вывод текста
                                                ; на экран
     (write line " Linetype  Align Segs  Description")
     (terpri) 
     (setq cl (getvar "CELTYPE") f " ")         ; Текущий тип линии,
                                                ; "регистр" флажка
 
     ; Если текущий тип линии "BYLAYER", справься о текущем уровне
     ; Провести линию и изменить "регистр" флажка с"" на "L"
 
     (setq cl 
     (cond ((= cl "BYBLOCK") "")
     ((= cl "BYLAYER") (setq f "L ")
           (fld 6 (tblsearch "LAYER" (getvar "CLAYER"))))
           (T cl)
      )) 
      (setq x (tblnext "LTYPE" T))              ; Первый тип линии
         (while x
            (setq lt (fld 2 x)                  ; Имя типа линии
            d (fld 3 x)                         ; Простое описание типа
                                                ; линии
                  a (fld 72 x)                  ; Выравненный код
                  s (fld 73 x)                  ; Длина каждого штриха
 
          )
          (write line
              (strcat
              (if (=lt cl) f " ")                ; Регистр флажка прими-
                                                 ; тива линии
             (strfill lt 12)                     ; Редактор имени
                                                 ; уровня
             (strfill (chr a) 7)                 ; Выравненный код
             (strfill (itoa s) 6)                ; Длина черточки
                                                 ; элементов
             (substr d 1 30)                     ; Описание типа линии
       ))
       (if (> s 0) (progn                     ; Если любой отдельный
                                                 ; элемент,редактируйте его
       (setq x (member (assoc 49 x) x))          ; Введите список каждого
                                                 ; элемента
       (while x
                   (setq s (cdar x))             ; Введите длину штриха
                   (write line
                      (strcat
                         (strfill " " 27)
                            (cond ((= s 0) "Dot")
                               ((> s 0) (strcat "Pen down" (rtos s 2 4)))
                                  (T (strcat "Pen up"    (rtos (abs s) 2
                                4)))
                        )))
               (setq x (cdr x))                    ; Введите следующий
                                                   ; элемент
         )))
         (setq x (tblnext "LTYPE"))                ; Введите следующий
                                                   ; тип линии
         )
         (terpri)
  )

5.8.7. Воображаемое окошко (ZOOM Window)

Эта программа использует функции механизма доступа, который выполняет фантазию ZOOM Window (масштаб в окошке), позволяющую вам установить триггер между перемещенным и измененным размером в боксе.

; ZOOM Window подобен ZOOM Dynamic, исключает выполнение на те-
; кущем дисплее без ручной клавиатуры , кроме клавиш пробел ,
; возврат и клавиши со стрелкой.
 
(defun drawbox ()                                     ; Вычерчивание бокса
       (grdraw ll ul 1) (grdraw ul ur 1)
       (grdraw ur lr 1) (grdraw lr ll 1)
       (if (= mode 0) (cenx) (arrow)
)

(defun cenx ()                                        ; Определение центра Х
       (grdraw x1 x2 1) (grdraw x3 x4 1)
)

(defun arrow ()                                       ; Вычерчивание стрелок
       (grdraw a1 a4 1) (grdraw a2 a4 1) (grdraw a3 a4 1)
)

(defun newbox ()                                      ; Переопределение па-
                                                      ; раметров бокса &
                                                      ; draw
      (setq deltay (* deltax aspect))                 ; Допускает , что del-
                                                      ; tax & был центр
 
      ; Переустановка в более высокий уровень
      (setq xcen (car center) ycen (cadr center))
 
      ; Понижение/повышение X/Y для бокса
      (setq lx (- xcen deltax) ux (+ xcen deltax))
 
      (setq ly (- ycen deltay) uy (+ ycen deltay))
      (setq ll (list lx ly) ul (list lx ly))          ; Углы бокса
      (setq ur (list ux uy) lr (list ux ly))
 
      ; Повышение/понижение Y перекрестия & стрелки
      (setq yp (+ ycen arm) ym (- ycen arm))
 
      ; Левый наклон стрелки
      (setq al (list (- ux arm) yp) a2 (list (-ux arm) ym))
 
      (setq a3 (list (- ux arm arm) ycen))            ; Хвост стрелки
 
      ; Правый конец всех трех
      (setq a4 (list ux ycen))
      (setq x1 (list (- xcen arm) ym) x2 (list (+ xcen arm) yp))
 
      ; Концы по X
      (setq x3 (list (- xcen arm) yp) x4 (list (+ xcen arm) ym))
      (drawbox)
      )
 
(defun C:ZW (/ arm aspect center deltax inp loop mode prev pt sourse)
 
      ; Запуск на центр экрана
      (setq center (getvar "VIEWCTR"))
 
      ; Попытка переместить курсор с центра
      (setvar "LASTPOINT" (setq prev center))
 
      (setq aspect (/ (cadr (aetq aspect (getvar "SCREENSIZE")))
           (car aspect)))
 
           ; Использование 1/4 бокса экрана
           (setq deltax (* 0.25 (getvar "VIEWSIZE")))
 
           ; Первоначальный режим движения в боксе
           (setq arm (* 0.1 deltax) mode 0 loop T)
           (newbox)
              (while loop
                (setq inp grread T))          ; Выход прослеженный
 
                ; Изолирование источника и # или точки
                 (setq source (car inp) pt (cadr inp))
                 (cond ((= source 3)           ; "Pick"(выбрать) клавишей?
                             (cenx) (arrow)    ; Уничтожить Х & начертить
                                               ; или дефекты многочисленны
 
                ; Триггер в режиме бокса
                (setq mode (- 1 mode))
 
                ; Попытка переместить курсор с центра
                (setvar "LASTPOINT" center))
                       ((= source 5))          ; Выслеженная точка?
 
               ; Если ее сдвинуть...
               (if (or (/= (car prev) (car pt))
                       (/= (cadr prev) (cadr pt)))
 
                ; Изменить или сдвинуть бокс
                       (progn
                           (if (= mode 0)
                               (setq center pt)
                               (setq deltax (+ deltax (- (car pt)
                                  (car prev)))))
                                  (setq prev pt)
                                  (drawbox)         ; Удалить старый блок
 
              ; Ввести новый центр/размер и чертеж
                (newbox)
             )))
          ((or (and (= source 6) (= pt 0))          ;lst меню
                                                    ; клавиш(CR)
                      (and (= source 2)             ; или клавиатура
                                                    ; и
                      (or (= pt 13) (= pt 32))))    ; CR или бланк?
                (drawbox)                           ; Удалить старый
                                                    ; бокс

                (command "ZOOM" "W" ll ur)
                (setq loop nil))                    ; Выход
                                  (T                ;Любая grread переменная
                (drawbox)                           ; Удалить старый
                                                    ; блок
                (setq loop nil a " ^cancel "))      ; Выход
 
                  )
            )

5.8.8. Idle (работать вхолостую)

Наконец, это та программа, которая иллюстрирует функции прямого вывода на экран, также как и использование функции " ERROR".

; Команда IDLE
 
 (defun "ERROR" (s)                  ; Ошибка наверху (или CTRL C)
 (redraw)                            ; Перечерчивание на экране
 (grtext)                            ; Повторный вызов меню/статус
                                     ; текста на экране
  )
 
 (defun C:IDLE ()
     (setq vc (getvar "viewctr"))        ; Вызов центральной точки на
                                         ; экран
     (setq cx (car vc))
     (setq cy (cadr vc))
     (setq vc (/ (getvar "viewsize") 2))
     (setq xmin (- cx vs))               ; Вычислить сторону квадрата
     (setq xmax (+ cx vs))
     (setq ymin (- cy vs))
     (setq ymax (+ cy vs))
     (setq xdir (/ vs 10) ydir xdir)
     (setq cx (+ cx (* xdir 7)))
     (setq cy (- cy (* ydir 3)))
     (grclear)                           ; Чистый графический экран
 
     ; В статусе свободного участка
     (grtext -1 "            That's entertainment!')
 
     ; В координатах свободного участка
     (grtext -2 "Press CANCEL to stop.")
 
     ; Набор начальной точки
     (setq lp (list cx cy))
 
     (while t                            ; Цикл навсегда ( ....до CTRL C)
                 (setq nx (+ cx xdir))   ; Набор конечной координаты Х
          (if (or (> nx xmax) (< nx xmin))
              (progn
                   (setq xdir (- xdir))    ; Соответствующий каталог Х
                   (setq nx cx)
          )
      )
      (setq ny (+ cy ydir))                     ; Набор конечной Y координаты
      (if (or (> ny ymax) (< ny ymin))
            (progn
                  (setq ydir (- ydir))          ; Соответствующий каталог Y
                  (setq ny cy)
            )
      )
      (setq cx nx cy ny)
      (grdraw lp (setq lp (list nx ny)) -1)     ; Вычерчивание с"XOR ink"
      )
)



Copyright © Сайт поддержки пользователей САПР by Victor Tkachenko