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

Программа (zns) – полуавтоматическая установка номера сваи

Оглавление

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

1. Описание технологии процесса ручной нумерации.

Установленные блоки в виде свай на поле чертежа необходимо последовательно пронумеровать по порядку, установленному проектировщиком. С помощью команды Автокада - редактирования атрибутов, легко изменить номер у одного блока. Когда же эти изменения касаются сотен свай, процесс становится трудоемким и очень утомительным. Для изменения номера в обычном порядке, надо указать курсором на блок, чтобы открылась таблица изменения атрибута, найти строку атрибута, где изменить номер, затем закрыть таблицу, т.е. для изменения номера сваи необходимо сделать 4-5 операций, при этом необходимо внимательно и сосредоточено следить за экраном при выполнении операций, чтобы не допустить ошибки. Программа позволяет изменить этот же номер сваи просто щелкнув курсором по блоку один раз. Кроме экономии времени проектировщик получает психологическую разгрузку – картина чертежа не меняется в связи с появлением и исчезновением таблицы изменения атрибутов, когда надо переносить внимание с одной картины на другую.

2. Разбор решения задачи для создания программы.

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

3. Создание структуры программы.

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

После этого необходимо выполнить два условия:

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

При продолжении работы цикла наступает конец блока, в котором была произведена замена номера сваи. В этом случае происходит запрос указать новую сваю на чертеже. И так далее, пока не закончатся все сваи.

4. Написание программы с текстовыми пояснениями, чтобы изучающему человеку не заглядывать в справочник Autolisp.

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

(defun zns ()
Программная объединяющая функция простановки номеров свай на поле чертежа. Функция defun под именем /zns/ объединяет все выражения и функции программы. В сеансе Автокада она вызывается с помощью команды: (load "имя_файла") - загрузка файла, после чего в скобках указывается (имя_файла) для исполнения. Для нашего случая (load "zns") - загрузка файла, после чего - (zns) для исполнения, полную запись необходимо указать в командной строке Автокада или в пункте меню
(setq nnp (getstring "\n ВВЕДИТЕ начальный N СВАИ\n: "))
getstring – функция ввода символьной строки с клавиатуры и записи ее в переменную nnp с помощью функции setq. В нашем случае мы вводим число в виде символа. Почему же нам не иметь переменную nnp с содержанием в виде числа. Это будет объяснено дальше
(setq nnp1 (atoi nnp))
Функция atoi изменяет символьное содержание переменной nnp в числовое (целое) значение, которое присваивается переменной nnp1
(setq a1 (car(entsel"\n ВЫБЕРИТЕ СВАЮ для измене-ния N \n: "))
Команда entsel позволяет выбрать примитив из чертежа, указав на него курсором. Понятно, что это будет блок, определяющий сваю. Возвращает же выражениесписок, где первый элемент - это имя выбранного примитива, а второй элемент – это координаты точки, использованной для указания примитива. Функция car позволяет выбрать из списка первый элемент списка, т.е. имя примитива
(princ "a =")(princ a1)(terpri)
Стандартный вывод информации в текстовое окно Автокада о значении переменной /а1/
(setq a1 (entnext a1))
Прокрутка информационной структуры рисунка Автокада на 1 шаг – получение нового имени примитива, следующего за именем блока, в данном случае получение имени примитива, которым является атрибут блока, куда помещается номер сваи
(setq b1 (cdr(assoc '2 (entget a1))))
Получение имени атрибута. Выражение для получения из информационной структуры примитива рисунка - имени атрибута (например S51), выражение можно записать и другим способом - последовательным написанием каждой функции: (setq b1 (entget a1)) - список информационной структуры примитива (СИСП),(setq b1 (assoc '2 b1))- нахождение в (СИСП) по ключу (паролю) '2 ключевой пары имени примитива (2 . имя_атрибута) (setq b1 (cdr b1)) - получение значения второго члена ключевой пары, т.е. имени примитива
(setq tip (cdr(assoc '0 (entget a1))))
Получение типа примитива. Выражение для получения из информационной структуры примитива рисунка - типа примитива, в данном случае тип для атрибута ATTRIB. Выражение можно записать и другим способом - последовательным написанием каждой функции: (setq t1 (ent-get a1)) - список информационной структуры примитива (СИСП),(setq t1 (assoc '0 t1)) - нахождение в (СИСП) по ключу (паролю) '0 ключевой пары типа примитива (0 . тип_примитива), (setq tip (cdr t1)) - получение значения второго члена ключевой пары, т.е. типа примитива (ATTRIB)
(while b1
Цикл 1, если примитив существует, мы попадаем в цикл и вращаемся вместе с ним, пока существует b1, то есть имя атрибута
(if (or (equal tip "ATTDEF")
(equal tip "ATTRIB"))
Условие 0. Если тип примитива является атрибутом, мы попадаем внутрь условия, функция equal сравнивает значение переменной tip с образцом в кавычках, т.е. с обозначением атрибута в типе примитива. Функция логического сравнения выражений or позволяет получить истину для условия, если хотя бы одно из двух выражений будет истиной и получить доступ в условие
(progn
Функция progn позволяет объединить разные выражения находящиеся внутри первого условия в одно выражение. Если этого не сделать, то произойдет сбой или ошибка выполнения программы
(princ "b1 =")(princ b1)(terpri)
Вывод информации на экран с данными о переменной b1. Мы ищем имя атрибута
(setq b11 (substr b1 1 1))
Получение из имени атрибута первого символа это самый легкий способ его выделения, в связи с тем, что имена атрибутов отличаются S51,S61 и т.д. общим признаком остается 1 символ, т.е. S. Для выделения служит функция substr ,которая из переменной b1 начиная с 1 символа берет выражение длиной 1 символ. (две 1 1)
(princ "b11 =")(princ b11)(terpri)
Вывод информации на экран о переменной b11
(setq b12 "S" b11 (equal b12 b11))
Проверка соответствия 1 символа букве S с помощью функции equal и запись результата проверки (t или nil) в переменную b11
(if b11 (progn
Условие 1. Если b11 существует, то мы попадаем в условие
(setq b1 (subst (cons 1 nnp)
(assoc '1 (entget a1)) (entget a1)))
Действия внутри условия – выражение позволяет заменить в списке старый элемент на новый. Например чтобы заменить в блоке выражение атрибута – номер сваи и т.д. надо получить доступ к списку блока. Это выражение и является основным орудием в этой операции. Рассмотрим его внимательнее: (cons 1 nnp) позволяет сконструировать новое выражение ключевой пары (1 . «101»). Эта пара и заменит в информационной структуре блока старое выражение, т.е. заменит - на номер сваи. (assoc '1 (entget a1)) выражение помогает найти по ключу '1 старое выражение в информационной структуре блока. Оставшееся выражение (entget a1) является списком информационной структуры блока, в котором и заменяется «старое» выражение, на новое. Это важнейшее выражение в языке Автолисп
(entmod b1)(entupd a1)
(setq nnp1 (+ nnp1 1)
nnp (itoa nnp1))
Функция (entmod b1) модифицирует выражение в списке, а функция (entupd a1) преобразует выражение на чертеже. После замены и установки номера в свае, необходимо в переменной nnp1 изменить номер на следующее значение, т.е. добавить единицу. Этим и занята функция (+ nnp1 1) .Следующее выражение (itoa nnp1) превращает число в символьное выражение и оно записывается в переменную nnp
))
Конец условия 1, две скобки – одна закрывает групповую функцию prong, которая помогает объединять все выражения и функции в теле условия, вторая скобка закрывает условие
(setq a1 (entnext a1))
Выражение для перелистывания примитивов и получения имени следующего примитива или подпримитива, т.е. функция entnext с именем /а1/- предыдущего примитива, дает имя следующего примитива, которое записывается в переменную /а1/
(if a1 (progn
Условие 2. Если следующий примитив существует, то мы попадаем в это условие
(setq d1 (cdr(assoc '0 (entget a1))))
Выражение для получения из информационной структуры примитива рисунка - типа примитива, выражение можно записать и другим способом - последовательным написанием каждой функции : (setq b (entget a)) - список информационной структуры примитива (СИСП) , (setq b (assoc '0 b)) – нахождение в (СИСП) по ключу (паролю) '0 ключевой пары, типа примитива (0.тип_примитива), (setq b (cdr b)) - получение значения второго члена ключевой пары, т.е. типа примитива. Наша задача - отбор всех примитивов с типом INSERT, а затем из всего числа блоков, выбор блоков свай
(setq b1 (cdr(assoc '2 (entget a1))))
Получение имени блока из (СИСП) , аналогично /d1/ - см. рассмотренное выше выражение для получение типа примитива
(if (equal d1 "SEQEND")(progn  
     (setq b1 nil)
Условие 3. Если тип примитива является выражением SEQEND – это означает, что рассматриваемый блок сваи закончился и нужно выбирать следующую сваю
(setq a1 (car(entsel"\n ВЫБЕРИТЕ 
  СВАЮ для изменения N \n: ")))
Команда entsel позволяет выбрать примитив из чертежа, указав на него курсором. Понятно, что это будет блок, определяющий сваю. Возвращает же выражение - список, где первый элемент - это имя выбранного примитива, а второй элемент – это координаты точки, использованной для указания примитива. Функция car позволяет выбрать из списка первый элемент списка, т.е. имя примитива. Данное выражение работает в цикле, т.е. повторяется каждый раз, когда заканчивается блок рассматриваемой сваи
(setq b1 (cdr(assoc '2 (entget a1))))
Получение имени блока из (СИСП) , аналогично /d1/ - см. рассмотренное выше выражение для получение типа примитива
))
Конец условия 3 по определению конца сваи
))
Конец условия 2 по определению существовя следующего примитива
))
Конец условия 1 по определению равенства первого символа символу "S" в имени блока
(if (not a1)(progn 
(setq a1 nil b1 nil)))
Если не выбрано ни одной сваи, то обнуляются переменные, с помощью которых работает цикл
))
Конец условия 0 по определению существования атрибута
(if a1 (progn 
(setq a1 (entnext a1))
(setq tip (cdr(assoc '0 (entget a1))))
(setq b1 (cdr(assoc '2 (entget a1)))) 
))
Условиеесли существует примитив, то определяется имя следующего элемента блока, т.е. атрибута содержащего номер сваи и определяется значение переменной tip и b1
)
Конец цикла 1. Цикл закончится только тогда, когда не будет существования примитива.
(setq a1 nil b1 nil b11 nil)
Дополнительное уничтожение переменных, при возможном их существовании
)
Окончание программной функции defun по нумерации свай чертежа

Полный текст программы "zns.lsp"

(defun zns() 
; ФУНКЦИЯ ИЗМЕНЕНИЯ N сваи
(textscr)(princ "==========================================")(terpri)
(setq nnp (getstring"\n ВВЕДИТЕ начальный N СВАИ\n: "))
(setq nnp1 (atoi nnp))
(setq a1 (car(entsel"\n ВЫБЕРИТЕ СВАЮ для изменения N \n: ")))
(princ "a =")(princ a1)(terpri)
(setq b1 t)(setq a1 (entnext a1))
(setq b1 (cdr(assoc '2 (entget a1)))) 
(setq tip (cdr(assoc '0 (entget a1))))
(while b1 
  (if (or (equal tip "ATTDEF")(equal tip "ATTRIB"))
     (progn 
     (princ "b1 =")(princ b1)(terpri)(setq b11 (substr b1 1 1))
     (princ "b11 =")(princ b11)(terpri)
     (setq b12 "S" b11 (equal b12 b11))
     (if b11 (progn 
          (setq b1 (subst (cons 1 nnp) (assoc '1 (entget a1)) (entget a1)))
          (entmod b1)(entupd a1)(setq nnp1 (+ nnp1 1) nnp (itoa nnp1))
     ))
     (setq a1 (entnext a1))
     (if a1 
        (progn 
        (setq d1 (cdr(assoc '0 (entget a1)))) ;тип примитива
        (setq b1 (cdr(assoc '2 (entget a1)))) ;тип примитива
        (if (equal d1 "SEQEND")(progn (setq b1 nil)
            (setq pro "")
            (if (equal pro "")(progn 
               (setq a1 (car(entsel"\n ВЫБЕРИТЕ СВАЮ для изменения N \n: ")))
               (setq b1 (cdr(assoc '2 (entget a1)))) ;тип примитива
            ))
        ))
    ))
    (if (not a1)(progn (setq a1 nil b1 nil))) 
  ))
  (if a1 (progn (setq a1 (entnext a1))(setq tip (cdr(assoc '0 (entget a1))))
         (setq b1 (cdr(assoc '2 (entget a1)))) 
  ))
)
(setq a1 nil b1 nil b11 nil)
)

Текст программы можно писать редактором «Блокнот» , который создает файлы с раcширением «txt», после написания программы расширение файла надо изменить на «lsp», Этот прием самый простой, не считая написание файлов в Visual LISP в Автокаде.

Оглавление



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