(SETQ Новый_элемёнт (LIST Ключ
Новое_значение)
Объект (SUBST Новый_элемент
Элемент Объект))
);if
);progn
);if
)
Возможности работы со списками проиллюстрированы в Программе 13 (см.
Приложение). Без использования списка в этой программе невозможно было бы
проставить размеры длин ступеней вала, так как местоположение первой размерной
линии может быть выбрано только тогда, когда все ступени вала построены (точнее,
все диаметры ступеней введены). В связи с этим при построении ступеней требуется
запоминать точки для последующего построения размеров. Это можно сделать только
с помощью списка.
Рассмотрим, как используются функции работы со списками в Программе 13.
При построении первой ступени формируется список sp, состоящий из одного
элемента -списка точек р2 и рЗ:
(SETQ sp (LIST (LIST p2 p3)))
При построении каждой следующей ступени в этот список добавляется новая пара
точек:
(SETQ sp (CONS (LIST p2 p3) sp))
Обратим внимание на то, что новая пара добавляется в начало списка, т.е.
порядок следования пар точек в списке обратен порядку построения ступеней
вала.
Для построения диаметров организуется цикл с помощью функции FOREACH:
(FOREACH рр sp...),
т.е. на каждом шаге цикла выбирается очередной элемент списка sp и
записывается в рр.
Верхняя и нижняя точки для простановки размера выделяются из рр следующим
образом:
(SETQ p1 (CAR рр) p2 (CADR рр))
(Отметим, что диаметры будут проставляться, начиная с последней ступени, т.е.
в том порядке, в котором организован список sp.)
Чтобы проставить размеры длин, необходимо сначала проставить один
горизонтальный размер с опорой на базовую точку, а затем последовательно
проставлять остальные размеры от базы. Для этого:
список sp "переворачивается":
(SETQ sp (REVERSE sp))
первая пара точек выделяется:
(SETQ рр (NTH 0 sp))
вторая (нижняя) точка из пары выделяется:
(SETQ sp (CDR sp))
После этого организуется цикл по простановке размеров с помощью FOREACH
аналогично тому, как это было сделано при простановке диаметров. Однако теперь
уже размеры будут проставляться в том же порядке, в каком изображался вал, т.е.
слева-направо.
На примере Программы 13 можно также видеть, как функции LIST, CAR и CADR
используются для внутрипрограммного построения точек. Например,
(SETQ p3 (LIST (- (CAR p1) 10) (CADR p1)))
определяет точку p3, координата Х которой смещена на десять единиц влево по
отношению к точке р1. Аналогичный результат был бы получен с помощью (POLAR pi
PI 10).
Помимо возможностей Автолиспа, свойственных и другим языкам программирования,
а также возможностей по обработке списков, двойственных версиям языка Лисп, в
Автолиспе имеются и специфические возможности, связанные с тем, что программа на
Автолиспе работает в среде, созданной системой AutoCAD. Эта среда
характеризуется:
определенными параметрами (системными переменными AutoCAD);
определенной организацией экрана (графического или текстового);
наличием изображения (чертежа), построенного на графическом экране и
состоящего из примитивов и блоков;
определенной организацией данных об изображении в памяти ЭВМ - наличием
графической базы данных чертежа, в которой содержатся описания примитивов и
блоков, значения системных переменных, таблицы слоев, типов линий и т.д.
Программа на Автолиспе может воспринимать особенности этой среды и оказывать
влияние на нее.
Помимо описанных ранее способов задания точки в программе имеется возможность
задания точки путем объектной привязки, т.е. так же, как это делается в
графическом диалоге с помощью команды OSNAP:
(OSNAP < точка > < режим >)
Предполагается, что на чертеже имеется объект, проходящий через заданную <
точку >.
Аргумент < режим > - это строка текста, характеризующая режим привязки
точно так же, как для команды OSNAP. Например:
"CEN" - центр окружности или дуги;
"BND" - конечная точка отрезка, дуги;
"INS" - базовая точка блока и др.
Если точка, соответствующая заданному режиму, не найдена, то возвращается
NIL.
В ходе выполнения программа может влиять на состояние экрана.
(GRAPHSCR), (TEXTSCR)
С помощью этих функций можно переключать экран с текстового на графический и
обратно.
Переключение экрана в текстовый режим может оказаться целесообразным, если
программа выводит последовательность строк текста с помощью функций типа
PRINT.
(GRCLEAR)
Функция очищает поле чертежа графического экрана.
(REDRAW)
Функция позволяет восстановить картину, стертую с помощью GCLEAR. Кроме того,
EDRAW может применяться для перерисовывания текущего экрана и выполнять ту же
роль, что и команда графического редактора REDRAW.
(MENUCMD < текст >)
Эта функция позволяет переключаться среди подстраниц в меню ACAD, т.е.,
например, вводить на экран тот раздел меню, который в данный момент необходим
пользоватею. Это дает возможность упростить диалог пользователя при
комбинированной работе с программой и графическим редактором.
Аргумент < текст > имеет следующий вид:
"<тип меню> = < имя раздела меню>"
Для экранного меню <тип меню> - S (другиe типы см. в "Руководстве
пользователя"(АВТОКАД, версия 10. Autodesk Ltd., 1989)).
Таким образом (MENUCMD "S = S3 ") будет лзывать на экран раздел меню S3.
Применение этой функции предполагает знание структуры файла меню, который
используется в процессе работы данной программы (например, стандартного файла
меню ACAD.MNU).
Все перечисленные здесь функции возвращают NIL.
Тем, кто полностью освоил графический редактор ACAD, известно, что при вызове
ACAD устанавливаются по умолчанию значения множества системных переменных,
влияющих на режим работы с редактором. В ходе графического диалога эти значения
можно переустанавливать командой SETVAR. Полный список системных переменных, их
типов и значений приведен в "Руководстве пользователя".
(GETVAR <имя переменной >)
С помощью этой функции значение системной переменной может быть считано в
программу. < Имя переменной > должно указываться как строка текста.
(SETVAR < имя переменной > < значение переменной >)
С помощью этой функции значение системной переменной может быть
переустановлено. Возвращается устанавливаемое значение.
Следует иметь в виду, что некоторые системные переменные определены только
для гения (см. "Руководство пользователя"). Такие переменные нельзя
переустановить. Примеры:
(SETQ A (GETVAR "ANOBASE"))
возвращается и записывается в А действительное число, определяющее
направление угла 0 в этом чертеже.
(SETVAR "CMDECHO" 0)
задается значение 0 для переменной CMDECHO, что приведет к исчезновению "эха"
выполняемых команд.
Режим, заданный в последнем примере, удобен на практике, в особенности тогда,
когда программа интенсивно выдает пользователю полезные сообщения, между
которыми эхо команд будет восприниматься как "шум". В любом случае отключение
эха ускоряет выполнение программы.
В ходе работы с редактором ACAD создаются также символьные таблицы LNTYPE,
LAYER другие, определяющие типы линий, слои, ви-ы, блоки, гарнитуры шрифтов.
Данные из этих таблиц могут быть прочитаны с помощью функций TBLNEXT,TBLSEARCH,
описанных в "Руководстве по программированию".
Программы на Автолиспе могут работать с бъектами специальных типов -
графическими бъектами. К таким объектам относятся:
примитивы ACAD, имеющиеся на экране в процессе работы программы;
совокупности таких примитивов, называемые в Автолиспе наборами.
Графические объекты могут быть "введены в программу", т.е. возможно
именование этих объектов с помощью имен переменных, так же как именование чисел,
строк текстов, точек. После этого можно оперировать с этими объектами, обращаясь
к ним по именам. В том числе можно анализировать и изменять характеристики этих
объектов, что приводит к изменению изображения на экране.
Для лучшего представления о том, как происходит работа с примитивами и
наборами, полезно понять следующее. При выделении каким-либо способом примитива
или набора из базы данных Автолисп формирует внутрипрограммное имя этого объекта
(примитива или набора). На самом деле - это не имя, а ссылка на объект, но для
программиста это не имеет значения. Программист поступает следующим образом: он
записывает это "имя" в какую-либо переменную с помощью SETQ. Затем эта
переменная может быть использована для любого указания на объект. Например, она
может быть подставлена в качестве аргумента в команду, требующую указания
примитива или группы примитивов. Далее такая технология будет проиллюстрирована
на примере.
Основное средство определения наборов примитивов - функция SSGET.
(SSGET [<режим>] [<точка1> [<точка2>]])
Функция возвращает определение (внутрипрограммное имя) выбранного примитива
или отбора (совокупности примитивов), которое может быть "записано" в неременную
Автолиспа (с помощью SETQ);
Если аргумент < режим > отсутствует, то создается набор, выбранный
средствами графического редактора (указание на объекты, захват в рамку и т.п.).
При этом программа выдает такой же запрос на указание способа выбора объетов, а
затем запросы на выбор, как и при работе с графическим редактором.
Возможны следующие значения режима:
"Р", в русском варианте "Т" - выбирается текущий набор;
"L", русское "П" - выбирается последний сформированный на чертеже
примитив;
"W", русское "Р" < точка1 > <точка2> - выбираются примитивы,
попавшие в рамку с углами в < точке1 > и <точке2>;
"С", русское "С" <точка1> <точка2> - выбираются примитивы,
пересекаемые рамкой. Кроме этих возможны еще две конструкции:
(SSGET < точка >)
Здесь выбираются примитивы, проходящие через < точку >.
(SSGET "х" < фильтр >)
Здесь < фильтр > - список, элементами которого являются одна или
несколько точечных пар. Каждая точечная пара строится по следующей форме:
(< код >.< значение >) Здесь <код> - одно из принятых в
Автолиспе чисел, показывающих, по какому признаку выбираются примитивы,
например;
0 - примитивы одного типа;
2 - примитивы, входящие в один блок (INSERT) ;
6 - по типу линии;
7 - по гарнитуре шрифта;
8 - по имени слоя;
62 - по цвету и др.
< значение > - значение признака.
Например,
(SSGET "X" '((8 . "SLI")))
вернет набор, включающий все примитивы, находящиеся на слое, именованном как
"SLI";
(SSGET "X" '((0. "LINE") (62 .1)))
вернет набор, состоящий из всех линий красного цвета (1 - номер красного
цвета).
Выполнение последовательности функций
(SETQ sdel (SSGET "X" '((6 . "CENTER"))))
(COMMAND "ERASE" sdel)
приведет к стиранию всех примитивов, изображенных осевыми линиями.
Следующие функции позволяют анализировать набор, получаемый с помощью
SSGET
(SSLENGTH < набор >)
Функция SSLENGTH возвращает целую величину, представляющую число примитивов в
наборе. Таким образом, программа может "узнать", сколько объектов было выделено
пользователем. По известному числу примитивов можно организовать цикл по
обработке последовательно каждого примитива.
Здесь и далее < набор > - это имя переменной набора, т.е. переменной,
определенной ранее следующим образом:
(SETQ < набор > (SSGET...))
(SSNAME < набор > < номер >)
Функция SSNAME возвращает внутрипрог-раммное имя примитива из < набора
>, идущего под соответствующим номером.
Здесь < номер > - целая величина. Первый по порядку примитив имеет
номер 0. Если < номер > меньше 0 или больше максимального номера примитива
в наборе, то возвращается NIL. Таким образом, конструкция вида
(SETQ < переменная > (SSNAME < набор > <номер>))
позволяет выделить примитив из < набора >, записав его имя в <
переменную >.
(SSMEMB <примитив> <набор>)
Функция SSMEMB проверяет, входит ли < примитив > в < набор >.
Если да, то возвращается имя примитива, если нет, - то NIL.
Здесь и далее < примитив > - имя переменной, значение которой записано
с помощью SETQ, например, путем применения функции SSNAME.
Следующие функции позволяют изменять состав набора:
(SSADD [< примитив > [< набор >]])
Функция SSADD без аргументов создает новый пустой набор. SSADD с аргументом
< примитив > создает новый набор, содержащий только указанный примитив.
Если указаны оба аргумента, то функция добавляет указанный примитив в набор.
Если этот примитив в наборе уже имеется, то ничего не изменится. Функция
возвращает имя набора. Например,
(SETQ S (SSADD р1))
Эта конструкция формирует новый набор, состоящий из одного примитива.
Предполагается, что pi - переменная, в которую ранее было записано имя
примитива. Имя созданного набора записывается в переменную S, которую теперь
можно использовать для указания на набор.
(SSDEL <примитив> <набор>)
Функция удаляет < примитив > из < набора >, если он там
присутствовал, иначе - ничего не меняется. Возвращается имя набора.
Пример работы с набором:
(SETQ SS (SSGET))
; Здесь образуется пауза, в ходе которой пользователь
; укажет несколько объектов на экране (примитивов).
; После нажатия <ENTER> программа определяет
; набор. Формируется внутрипрограммное имя
;этого набора, которое возвращается функцией SSGET в переменную SS
;Теперь в программе данный набор можно обозначить как SS.
(SETQ L (SSLENGTH SS))
;Определено количество примитивов в наборе SS и записано в L.
(SETQ SL (SSNAME SS (1-L)))
;Выделен последний примитив в наборе SS, его внутрипрограммное
;имя возвращено функцией SSNAME в переменную SL
(SETQ SN (SSADD SL))
;Создан новый набор, содержащий последний
;примитив из набора SS. Имя нового набора записано в переменную SN.
(SETQ SS (SSDEL SL SS))
;Из SS удален последний элемент. Получавшийся в результате набор будет ;также
назван SS.
(COMMAND "ERASE" SS)
;Набор SS удаляется с экрана, т.е. стираются все примитивы, ранее ;
помеченные пользователем, кроме последнего (SL).
Примитивы в ACAD могут быть простыми (линия, окружность, строки текста,...)
или составными (полилинии, вставки блоков). Составные примитивы делятся на
субпримитивы.
Например, для полилинии субпримитивами являются вершины, для вставки блоков -
атрибуты. С помощью функций типа SS, рассмотренных в п.5.5, могут быть получены
либо наборы примитивов, либо примитивы (простые или составные), но не
субпримитивы. Функции, рассматриваемые в данном параграфе, позволяют работать с
примитивами и субпримитивами.
Выбор примитивов:
(ENTNEXT [<примитив>])
Функция возвращает внутрипрограммное имя примитива или субпримитива:
если < примитив > не указан, то возвращается первый из примитивов
чертежа (неудаленных);
если указан простой примитив, то ENTNEXT возвращает примитив, следующий за
указанным;
если указан составной примитив; то ENTNEXT возвращает первый субпримитив
указанного примитива;
если указан субпримитив, то ENTNEXT возвращает субпримитив, принадлежащий
тому же примитиву, что и указанный, и следующий за указанным;
если запрашиваемый объект отсутствует, то возвращается NIL.
(ENTLAST).
Функция возвращает внутрипрограммное имя последнего примитива на чертеже
(неудаленного). Субпримитив с помощью ENLAST не выделяется.
(ENTSEL [ < подсказка > ])
Эта функция создает паузу и может вывести текст < подсказки >.
Пользователь в ответ должен указать примитив на экране.
Функция возвращает результат в виде списка из двух элементов:
первый элемент - внутрипрограммное имя примитива;
второй элемент - точка, в которой было проведено указание, эта точка
возвращается в виде списка координат.
Возвращаемый результат может быть "записан в переменную" с помощью SETQ. Эта
переменная впоследствии может быть задана в ответ на любую команду ACAD (в
функции COMMAND), требующую выбрать объект и учитывающую точку указания. Кроме
того, результат, записанный в данную переменную, может быть "разложен .на
составные части": (CAR < переменная >) возвращает имя примитива, (CADR
< переменная >) вернет точку указания.
Удаление, восстановление и обновление примитивов:
(ENTDEL < примитив >)
С помощью этой функции примитив может быть удален из чертежа. Субпримитивы
таким способом не удаляются.
Пока не кончился сеанс работы с данным чертежом, удаленный примитив может
быть восстановлен с помощью той же функции (ENTDEL < примитив >)
(REDRAW < примитив >)
Функция возобновляет изображение примитива после очистки экрана функцией
GRCLEAR. Таким образом, рассмотренная в п.5.3 функция REDRAW может также
управлять изображением примитива:
(REDRAW <примитив> <режим>)
Действие REDRAW зависит от значения аргумента < режим >: 1 - примитив
перерисовывается; 2 - примитив стирается; 3 - примитив подсвечивается; 4 -
подсветка примитива отменяется.
Каждый примитив с точки зрения системы AutoCAD представляет собой достаточно
сложную совокупность данных. Представление об этих данных дают правила
расположения данных в DXF-файле, который является текстовым описанием чертежа
(см. "Руководство пользователя").
Программа на Автолиспе может сформировать сложный список, в котором будут
содержаться все данные о примитиве. После этого средствами обработки списков
можно выделять, анализировать и модифицировать отдельные лепные. За модификацией
данных примитива может следовать отображение модифицированного примитива на
чертеже.
Таким образом, программа на Автолиспе может анализировать и видоизменять
чертеж, построенный, например, в режиме диалога с редактором ACAD.
Формирование списка данных примитива:
(ENTGET < примитив >)
Функция формирует и возвращает список, содержащий данные о примитиве.
Структура списка напоминает перечень данных о примитиве в DXF-файле и зависит
от типа примитива и от того, насколько характеристики примитива соответствуют
умолчанию.
Правила построения списка:
каждый элемент списка является списком (будем называть его субсписком);
большинство субсписков имеют вид точечных пар (кроме субсписков, описывающих
точки);
первый элемент каждого субсписка - это код данных, второй элемент (и
последующие) - значение (значения), соответствующие коду;
первый субсписок имеет вид (-1 . имя-примитива);
второй: (0. тип-примитива);
третий: (8. имя-слоя);
далее следуют некоторые атрибуты примитива в том случае, если их значения
отличаются от значений по умолчанию, набор этих атрибутов зависит от версии
ACAD, примером может служить (62. код-цвета);
далее следуют характеристики примитива, состав которых зависит от типа
примитива.
Например, для отрезка прямой (тип = "LINE"):
(10 координаты-начальной-точки)
(11 координаты-конечной-точки)
Для окружности (тип = "CIRCLE"):
(10 координаты-центра)
(40. радиус)
Для дуги (тип = "ARC"):
(10 координаты-центра)
(40. радиус)
(50 . начальный-угол)
(51. конечный-угол)
Пример списка, возвращаемого функцией ENTGET для окружности, находящейся на
слое "О", синего цвета (номер цвета - 5) с центром в точке (2 2 0) и с радиусом
1.5, изображенной пунктирной линией ("DASHED"):
((-1. <внутрипрограммное-имя-примитива>)
(0 . "CIRCLE")
(8. "0")
(6 . "DASHED")
(62.5)
(10 2.0 2.0 0.0) (40. 1.5)
)
Модификация примитива:
(ENTMODE < примитив >)
С помощью этой функции можно изменить изображение примитива на экране.
Предполагается, что до обращения к ENTMOD происходила модификация данных в
списке, полученном с помощью ENTGET.
Пример:
(SETQ PR (ENTNEXT))
; Выделяется первый примитив в базе данных,
; имя которого возвращается в PR
(SETQ SPR (ENTGET PR))
;Формируется список из данных, описывающих примитив PR, этот список
;возвращается в SPR
; Здесь следуют операции над списком SPR
; по изменению каких-либо данных в этом списке
(ENTMODE SPR)
После выполнения последней функции на экране вместо примитива PR, ранее
выбранного пользователем, появится "обновленный" примитив, отличающийся
какими-либо характеристиками. Для программы это по-прежнему будет примитив PR, и
с ним можно продолжать работу.
На применение ENTMODE накладываются некоторые ограничения:
не может быть изменен тип примитива;
такие атрибуты как Тип линии (и некоторые другие), могут принимать только те
значения, которые к данному моменту определены в сеансе работы с ACAD;
однако слой может быть задан и новый, отсутствовавший к данному моменту.
Функция ENTMODE может выполняться над примитивом или субпримитивом. Если
ENTMODE выполняется над субпримитивом, то видимого изменения на экране не
происходит. 122
(ENTUPD < примитив >)
С помощью этой функции можно изменить изображение примитива после того, как
изменены субприпримитивы этого примитива с помощью ENTMODE.
Однократное изменение сложного примитива происходит гораздо быстрее, чем его
многократная перерисовка после изменения каждого субпримитива.
Приведенные ниже примеры демонстрируют различные применения функций для
работы с примитивами и наборами. Каждая из этих программ - не только
иллюстрация, но и практически полезная функция, которая может пригодиться
конструктору, работающему с редактором AC AD. Эти программы иллюстрируют
возможности расширения системы AutoCAD с помощью Автолиспа.
; Программа 10: Удаление предпоследнего элемента
; чертежа [4]
(DEFUN С: ERASE2 ( )
(SETQ secondlast (ENTDEL (ENTLAST)))
(ENTDEL (ENTLAST))
(ENTDEL secondlast)
)
Известно, что в редакторе ACAD имеется команда ERASE ("СОТРИ"), которая
позволяет стереть последний элемент чертежа или элемент, указываемый
конструктором. Однако, оба эти способа могут оказаться неудобными в следующей
ситуации: конструктор создает сложный насыщенный чертеж и ему не сразу удается
правильно построить нужный элемент. Конструктор хотел бы повторить попытку, но
при этом сохранить неправильный элемент в качестве "отправной точки", а после
удачного построения - стереть этот элемент. Имея описанную выше функцию, он
сможет это сделать, подав команду ERASE2.
Программа" 10 решает задачу просто и изящно:
стирается последний примитив (но его имя записывается в переменную
secondlast);
стирается примитив, ставший последним, т.е. бывший предпоследний;
путем повторного применения функции ENTDEL по отношению к примитиву
secondlast стертый последний элемент восстанавливается на экране.
Программа 11, приведенная ниже, дает возможность значительно упростить
решение задачи, нередко встречающейся на практике при конструировании сложных
объектов, - перенесение всех примитивов, находящихся на одном слое, на другой
слой [6]
.
Средства ACAD позволяют решить такую задачу только с помощью метода
последовательного указания всех переносимых примитивов -долгого и неудобного.
Алгоритм, реализуемый Программой 11:
Установить переменную found в NIL (found "NIL свидетельствует о том, что на
слое не найдено ни одного примитива).
Ввести с клавиатуры и запомнить имена старого и нового слоя.
Выдать сообщение о том, что поиск начался.
Записать в entn имя первого примитива чертежа
ПОКА entn существует ЦИКЛ
Получить в cnt список, соответствующий entn
ЕСЛИ имя слоя в списке ent совпадает с именем
старого слоя ТО
Заменить слой примитива новым слоем
Установить found =t (примитив найден)
ВСЕ ЕСЛИ
Записать в entn имя очередного примитива
ВСE ЦИКЛ ПОКА
ЕСЛИ founds NIL (примитив отсутствует) ТО
Выдать сообщение об отсутствии примитивов
на слое
ВСЕ ЕСЛИ
КОНЕЦ
; Программа 11 Перенос примитивов с одного слоя
; на другой
(DEPUN C:CNGLAY (/cmd entn ent)
(SETVAR "CMDECHO" 0)
(SETQ found NIL)
(SETQ oldlyr (STRCASE (GETSTRINO
"\n Введите старое имя слоя:"))
newlyr (STRCASE (OETSTRING
"\n Введите новое имя слоя:")))
(PRINC "\n Ведется поиск примитивов на слое")
(SETQ entn (ENTNEXT))
(WHILE (/=entn nil)
(SETQ ent (ENTGET entn))
(IF ( = (CDR (ASSOC 8 ent) oldlyr)
(PROGN
(COMMAND "CHANGE" entn""
"p" "LA" newlyr"")
(SETQ found t)
);progn
);if
(SETQ entn (ENTNEXT entn))
); while
(IF (NOT found)
(PRINC (STRCAT "\n На слое" oldlyr" нет примитивов"))
);if
(SETVAR "CMDECHO" 1)
)
Возможно, два ключевых действия нуждаются в комментариях.
1. Функция (ASSOC 8 ent) выполняет ассоциативный поиск в списке ent,
являющемся описанием примитива в базе данных чертежа. Это описание, как
указывалось, само состоит из списков - точечных пар, среди которых обязательно
имеется пара вида (8.имя_слоя). Этот подсписок и выделяется из общего списка ent
с помощью ASSOC. Функция CDR "обрезает" этот подсписок, сохраняя вторую его
часть -имя слоя.
2. Аргументы команды CHANGE ("Изменить") перечисляются в соответствии с тем,
как происходили бЫ ответы на вопросы этой команды в диалоге 1: ACAD:
entn - имя примитива в ответ на запрос объекта;
" " указывает, что выбор объектов закончен;
"p" указывает на то, что нужно изменить одно из свойств объекта;
"LA" говорит о том^что этим свойством является слой;
newlyr указывает новое имя слоя;
" " соответствует нажатию ENTER,завершающему выполнение команды.
Обратите внимание на ряд моментов в программе, не относящихся непосредственно
к ее основной задаче, но свидетельствующих о программистской культуре ее
автора:
1. Используются локальные переменные.
2. Выдаются функционально необязательные, но полезные сообщения о том, что
поиск происходит, и о том, что поиск не дал результатов. Первое сообщение
позволяет конструктору не нервничать во время затянувшейся паузы, второе -
повторить операцию, указав другое имя слоя, если при прежнем указании произошла
ошибка.
3. С помощью функции STRCASE обеспечивается возможность ввода имен слоев как
с верхнего, так и с нижнего регистра клавиатуры, в то время как в базе данных
чертежа хранятся имена, набранные заглавными буквами (т.е. в нижнем
регистре).
4. Перед началом работы программы эхо команд отключается, что позволяет
ускорить выполнение цикла программы. После завершения работы эхо команд вновь
включается, чтобы обеспечить последующий нормальный диалог конструктора с
редактором ACAD.
Рассматриваемая далее программа 12, составленная на базе программы,
приведенной в работе [5]
, может
оказаться полезной для тех, кто решает задачи разводки коммуникаций, например
трубопроводов в пространстве, где важным критерием является суммарная длина
трасс. Предлагаемая программа позволяет вычислять суммарную длину всех
полилиний, имеющихся в чертеже. (Если изменить вид "фильтра" в функции SSGET, то
можно просчитывать полилинии, обладающие каким-либо общим свойством, например,
находящиеся на заданном слое). Для понимания программы необходимо иметь
представление о том, как устроен в базе данных список, соответствующий
полилинии, которая является сложным примитивом, содержащим в качестве
субпримитивов вершины полилинии. Достаточно знать следующее.
1. В набор, образуемый с помощью SSGET, попадают только основные примитивы.
Тип примитива для полилинии - POLYLINE.
2. Для того чтобы попасть на первую вершину полилинии, нужно применить
функцию ENTNEXT, где аргументом является имя основного примитива (типа PLINE).
Субпримитив вершины полилинии имеет тип VERTEX. Субсписок, содержащий координаты
вершин, имеет код 10.
3. Для перемещения к следующей вершине также используется ENTNEXT, где
аргументом является имя субпримйтива - предыдущей вершины.
4. Признаком окончания списка для полилинии служит примитив типа SEQEND.
Алгоритм, реализуемый Программой 12:
Записать 0 в суммарную длину трасс tsum
Составить набор sspline, содержащий все полилинии чертежа
Определить число полилиний в наборе - ssl
ЕСЛИ ssl > 0 ТО
Записать номер первой полилинии 0 в num
ПОКА num < = ssl-1 ЦИКЛ
Получить имя очередной полилинии npline по ее номеру в