Примеры программ использования функций для работы с примитивами и наборами



Каждая из этих программ ‒ не только иллюстрация, но и практически полезная функция, которая может пригодиться пользователю, работающему с редактором ACAD. Эти программы иллюстрируют возможности расширения системы AutoCAD с помощью AutoLISP. [2, 6]

; Программа 9: Удаление предпоследнего элемента

; чертежа

( DEFUN С: ERASE 2 ( )

( SETQ secondlast ( ENTDEL ( ENTLAST )))

(ENTDEL (ENTLAST))

(ENTDEL secondlast)

)

Известно, что в редакторе ACAD имеется команда ERASE (“СОТРИ”), которая позволяет стереть последний элемент чертежа или элемент, указываемый конструктором. Однако, оба эти способа могут оказаться неудобными в следующей ситуации: проектировщик создает сложный насыщенный чертеж и ему не сразу удается правильно построить нужный элемент. Конструктор хотел бы повторить попытку, но при этом сохранить неправильный элемент в качестве «отправной точки», а после удачного построения ‒ стереть этот элемент. Имея описанную выше функцию, он сможет это сделать, подав команду ERASE.

Программа 9 решает задачу просто и изящно:

стирается последний примитив (но его имя записывается в переменную secondlast);

стирается примитив, ставший последним, т.е. бывший предпоследний;

путем повторного применения функции ENTDEL по отношению к примитиву secondlast стертый последний элемент восстанавливается на экране.

Программа 10, приведенная ниже, дает возможность значительно упростить решение задачи, нередко встречающейся на практике при конструировании сложных объектов, ‒ перенесение всех примитивов, находящихся на одном слое, на другой слой.

Средства ACAD позволяют решить такую задачу только с помощью метода последовательного указания всех переносимых примитивов (долгого и неудобного).

Рассмотрим алгоритм, реализуемый программой 10. [2, 6]

1. Установить переменную found в NIL (значение NIL свидетельствует о том, что на слое не найдено ни одного примитива).

2. Ввести с клавиатуры и запомнить имена старого и нового слоя.

3. Выдать сообщение о том, что поиск начался.

4. Записать в entn имя первого примитива чертежа.

5. ПОКА entn существует ЦИКЛ

Получить в cnt список, соответствующий entn

ЕСЛИ имя слоя в списке ent совпадает с именем

старого слоя ТО

Заменить слой примитива новым слоем

Установить found =t (примитив найден)

ВСЕ ЕСЛИ

 Записать в entn имя очередного примитива

ВСE ЦИКЛ ПОКА

6. ЕСЛИ founds NIL (примитив отсутствует) ТО

Выдать сообщение об отсутствии примитивов

на слое

7. ВСЕ ЕСЛИ

8. КОНЕЦ

Программа 10 может выглядеть следующим образом.

; Программа 10. Перенос примитивов с одного слоя

; на другой

(DEFUN 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)

)

Возможно, два ключевых действия в программе 10 нуждаются в комментариях.

1. Функция (ASSOC 8 ent) выполняет ассоциативный поиск в списке ent, являющемся описанием примитива в базе данных чертежа. Это описание, как указывалось, само состоит из списков ‒ точечных пар, среди которых обязательно имеется пара вида (8.имя_слоя). Этот подсписок и выделяется из общего списка ent с помощью ASSOC. Функция CDR «обрезает» этот подсписок, сохраняя вторую его часть ‒ имя слоя.

2. Аргументы команды CHANGE (“Изменить”) перечисляются в соответствии с тем, как происходили бы ответы на вопросы этой команды в диалоге с ACAD:

entn ‒ имя примитива в ответ на запрос объекта;

“ “ указывает, что выбор объектов закончен;

“p” указывает на то, что нужно изменить одно из свойств объекта;

“LA” говорит о том, что этим свойством является слой;

newlyr указывает новое имя слоя;

“ “ соответствует нажатию ENTER, завершающему выполнение команды.

Обратите внимание на ряд моментов в программе 10, не относящихся непосредственно к ее основной задаче, но свидетельствующих о программистской культуре ее автора:

1. Используются локальные переменные.

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

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

4. Перед началом работы программы эхо команд отключается, что позволяет ускорить выполнение цикла программы. После завершения работы эхо команд вновь включается, чтобы обеспечить последующий нормальный диалог конструктора с редактором ACAD. [2, 6]

Рассматриваемая далее программа 11, составленная на базе программы, приведенной в работе [7], может оказаться полезной для тех, кто решает задачи разводки коммуникаций, например трубопроводов в пространстве, где важным критерием является суммарная длина трасс. Предлагаемая программа позволяет вычислять суммарную длину всех полилиний, имеющихся в чертеже. Если изменить вид «фильтра» в функции SSGET, то можно просчитывать полилинии, обладающие каким-либо общим свойством, например, находящиеся на заданном слое. Для понимания программы необходимо иметь представление о том, как устроен в базе данных список, соответствующий полилинии, которая является сложным примитивом, содержащим в качестве субпримитивов вершины полилинии. Достаточно знать следующее.

1. В набор, образуемый с помощью SSGET, попадают только основные примитивы. Тип примитива для полилинии ‒ POLYLINE.

2. Для того чтобы попасть на первую вершину полилинии, нужно применить функцию ENTNEXT, где аргументом является имя основного примитива (типа PLINE). Субпримитив вершины полилинии имеет тип VERTEX. Субсписок, содержащий координаты вершин, имеет код 10.

3. Для перемещения к следующей вершине также используется ENTNEXT, где аргументом является имя субпримитива ‒ предыдущей вершины.

4. Признаком окончания списка для полилинии служит примитив типа SEQEND.

Рассмотрим алгоритм, реализуемый программой 11. [2, 6]

1. Записать 0 в суммарную длину трасс tsum.

2. Составить набор sspline, содержащий все полилинии чертежа.

3. Определить число полилиний в наборе – ssl.

4. ЕСЛИ ssl > 0 ТО

Записать номер первой полилинии 0 в num

ПОКА num < = ssl-1 ЦИКЛ.

5. Получить имя очередной полилинии npline по ее номеру в

наборе – num.

6. Получить имя первого субпримитива en.

7. Записать в pi nil.

8. Получить е1 - список для примитива en.

9. ПОКА тип en равен VERTEX ЦИКЛ (т.е. субпримитив есть вершина)

ЕСЛИ pl= nil ТО

Записать в р1 точку - вершину

ИНАЧЕ

Найти расстояние от р1 до точки - вершины и прибавить

это расстояние к tsum

Записать в р1 точку - вершину

ВСЕ ЕСЛИ

10. Получить имя очередного примитива en

11. Получить el - список для примитива en

ВСЕ ЦИКЛ ПОКА

12. Увеличить пит на единицу

13. ВСЕ ЦИКЛ ПОКА

14. ВСЕ ЕСЛИ

15. Выдать значение суммарной длины трасс tsum

16. КОНЕЦ

Рассмотрим, как может выглядеть программа 11. [2, 6]

; Программа 11: Определение суммарной длины

; полилиний

( DEFUN LTRASS (/ sspline ssl num npline pi en el tsum )

(SETQ tsum 0)

(SETQ sspline (SSGET “X” ‘((0. “POLYLINE”))))

(SETQ ssl (SSLENGTH sspline))

(IF(>ssl 0)

(PROGN

(SETQ num 0)

(WHILE (<= num (-ssl 1))

(SETQ npline (SSNAME sspline num))

(SETQ en (ENTNEXT npline))

(SETQ el (ENTGET en))

(SETQ p1 nil)

(WHILE (= (CDR (ASSOC 0 el)) “VERTEX”)

(IF (NULL p1)

(SETQ p1 (CDR (ASSOC 10 el)))

(SETQ tsum (+ tsum (DISTANCE p1

(SETQ p1 (CDR (ASSOC 10 el))))))

);if

(SETQ en (ENTNEXT en))

(SETQ el (ENTGET en))

); while

(SETQ num (1+num))

); while

);progn

);if

(PROMPT “\n Общая длина трасс =”)

(PRINC tsum)

(PRINC)

)


Дата добавления: 2019-09-13; просмотров: 258; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!