Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу) - Страница 210
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Ответ
Поиск в этой теме
Непрочитано 20.07.2008, 20:12 1 |
Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)
Red Nova
 
ՃԱՐՏԱՐԱԳԵՏ, տ.գ.թ.
 
Торонто
Регистрация: 23.10.2007
Сообщений: 1,990

Со школы не ладится у меня с программированием. Все предметы щелкал, а на экзамене по информатике (Visual foxpro) программку типа суммирования столбцов списал у соседа (это уже в университете).
Не смотря на эте намерен научится писать программы для Автокада на лиспе, скачал книгу Хювенена, несколько примеров создания программ, но после получасового “смотрения” таких книг мое мышление явно притормаживает.
Решил пойти другим путем.
Нашел самый короткий лисп из моей коллекции, и прошу программистов с этого форума пошагово объяснить какой символ что означает. Надеюсь на вашу помощь.


Код:
[Выделить все]
(defun c:make-blocks-explodeable (/ adoc)
  (vl-load-com)
  (vla-startundomark
    (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
    ) ;_ end of vla-startundomark
  (vlax-for blk_def (vla-get-blocks adoc)
    (if (and (equal (vla-get-isxref blk_def) :vlax-false)
             (equal (vla-get-islayout blk_def) :vlax-false)
             ) ;_ end of and
      (vl-catch-all-apply '(lambda () (vla-put-explodable blk_def :vlax-true)))
      ) ;_ end of if
    ) ;_ end of vlax-for
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun
_____________________________________________________________________________________________________________

Прошло много лет и топик теперь представляет из себя площадку для обучения азов программирования для многих начинающих.
Так что начинающие лиспогрызы приветствуются .
__________________
Блог

Последний раз редактировалось Red Nova, 12.07.2017 в 05:43.
Просмотров: 2048764
 
Непрочитано 25.03.2022, 07:51
#4181
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


По-моему, такого не существует. Только если постоянно эксперименты ставить. И то не факт, что удастся все варианты предусмотреть.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.03.2022, 09:49
#4182
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
Подскажите, как надо правильно.
Код:
[Выделить все]
 (command-s "_.arrayrect" Fas_one "" "_col" 1 1 "_r" 3 653 "" "")
koMon вне форума  
 
Непрочитано 25.03.2022, 17:46
#4183
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


ArrayRectangular
Сергей812 вне форума  
 
Непрочитано 25.03.2022, 22:36
#4184
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


koMon Благодарствую, все работает.
Что означает вторая единица?
Код:
Alxndr1697 вне форума  
 
Непрочитано 26.03.2022, 15:47
#4185
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


Количество столбцов, расстояние между столбцами. Можно заменить на "" яд.
koMon вне форума  
 
Непрочитано 26.03.2022, 22:03
#4186
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Цитата:
Сообщение от koMon Посмотреть сообщение
Можно заменить на "" яд.
Проверил, - можно.
Alxndr1697 вне форума  
 
Непрочитано 26.03.2022, 22:29
#4187
Browning Zed


 
Регистрация: 17.01.2014
Сообщений: 97


Приветствую. Споткнулся о простой, казалось бы, вопрос. Как можно зациклить вставку блока с последующим безболезненным выходом из цикла? Пробовал:
Код:
[Выделить все]
 (while (vl-cmdf "_.-insert" "ИМЯ_БЛОКА" "_S" 1.0 "_R" 0.0 "\\"))
и попадаю в "вечный" цикл, без возможности выхода по эскейпу, энтеру или пробелу. Как можно решить проблему?
Browning Zed вне форума  
 
Непрочитано 27.03.2022, 00:31
1 | #4188
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


ну так vl-cmdf
Цитата:
Always returns T.
с 2015 акада)

Вариант от Алексея
Сергей812 вне форума  
 
Непрочитано 27.03.2022, 08:37
#4189
Browning Zed


 
Регистрация: 17.01.2014
Сообщений: 97


Спасибо за решение.

Последний раз редактировалось Browning Zed, 27.03.2022 в 09:33.
Browning Zed вне форума  
 
Непрочитано 31.03.2022, 07:33
#4190
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Требуется помощь. Функции по отдельности работают, а вот в "кучу" собрать не могу. Причиной остановки указывает последнюю строчку (выделил красным) . Полагаю, что-то не так с переменными. Честно признаюсь, эта тема (аргументы, переменные, что где прописывать) мне непонятна, если кто может, - объясните, пожалуйста.


Код:
[Выделить все]
dialog_fasad_sup: dialog {label = "Фасад ящика (горизонтальный)";
:spacer{height=1;}
:column {label = "Точки ввода :";
:spacer{height=1;}
:image {key = "sld"; width  = 15; aspect_ratio = 1.8; color= 4;}
        }//end column точки ввода
:spacer{height=1;}
:boxed_column {label = "Параметры фасада :";
:spacer{height=1;}
:radio_row {key = "Tip_f"; label = "Тип фасада :";
                           
            :radio_button {key = "o_nkl"; label = "Накладной"; value = "1";}
            :radio_button {key = "o_vkl"; label = "Вкладной"; value = "0";}
            }//end radio_row
                                                :spacer{height=1;}
:row {:boxed_column {:boxed_column {label = "Количество фасадов :";
:spacer{height=1;}
             :edit_box {key = "o_Col_vo";         label = "Количество :";               value = "1";   edit_width = 4;}
               }//end column количество
:spacer{height=2;}
:boxed_column {label = "Толщина материала :";
             :edit_box {key = "o_B_mat_fas";      label = "Фасада :";                   value = "16";   edit_width = 4;}
             :edit_box {key = "o_B_mat_corp";     label = "Корпуса :";                  value = "16";   edit_width = 4;}
               }//end column толщина материала
               }
:spacer{height=1;}             
:boxed_column {label = "Зазоры фасада :";
//:spacer{height=1;}
             :edit_box {key = "o_Z_r";            label = "Зазор между фасадами :";     value = "3";   edit_width = 4;}
             :edit_box {key = "o_otst_up_front";  label = "Отступ от корпуса вперед :"; value = "0";   edit_width = 4;}
             :edit_box {key = "o_otst_top";       label = "Отступ сверху :";            value = "1.5"; edit_width = 4;}
             :edit_box {key = "o_otst_bottom";    label = "Отступ снизу :";             value = "1.5"; edit_width = 4;}
             :edit_box {key = "o_otst_left";      label = "Отступ слева :";             value = "1.5"; edit_width = 4;}
             :edit_box {key = "o_otst_right";     label = "Отступ справа :";            value = "1.5"; edit_width = 4;}
               }//end column зазоры
               }//end row
}//end параметры фасада

:spacer{height=1;}
:boxed_row {label = "";
             ok_cancel;}

       
                         }//end dialog

Код:
[Выделить все]
(DEFUN c:Fasad_sup (/ H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right
		    le edata le2 Vibor)

;***********************************функция fasad_n***************************************

(defun fasad_n ( H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right /
	      oldosm oldlay P_0 P_L P_H H_box L_box B_mat_corp B_mat_fas Z_r otst_top otst_bottom otst_left otst_right
	      H_fas_one L_fas H_fas_N Col_vo P_0_fas Fas_one)

  (command-s "._UNDO" "_be")
  (defun *error*(msg) 
  (princ msg) 
 )
(command-s "_.UCS" "_w")

  (setq P_0 (getpoint "\nУкажите левую внутреннюю нижнюю точку бокса <Отмена> :"))
  (setq P_L (getpoint "\nУкажите правую внутреннюю нижнюю точку бокса <Отмена> :"));ось x
    (if (/= (cadr P_L) (cadr P_0))
      (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
  (setq P_H (getpoint "\nУкажите левую внутренюю верхнюю точку бокса <Отмена> :"));ось z
    (if (/= (cadr P_H) (cadr P_0))
      (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
  (setq H_box (distance P_0 P_H));высота бокса
  (setq L_box (distance P_0 P_L));длина (ширина) бокса

  (setq oldosm (getvar "osmode"))
  (setvar "osmode" 0)
  (setq oldlay (getvar "clayer"))
    (if (null (tblsearch "layer" "ФАСАД"))
      (command-s "_.-LAYER" "_N" "ФАСАД" "")
     )
      (command-s "_.-layer" "_make" "ФАСАД" "_color" "3" "" "")

  (setq H_fas_one (- (- (+ H_box (* 2 B_mat_corp)) otst_top) otst_bottom))  
  (setq L_fas (- (- (+ L_box (* 2 B_mat_corp)) otst_left) otst_right))
  (setq H_fas_N (/ (- H_fas_one (* Z_r (1- Col_vo))) Col_vo))
  (setq P_0_fas (list (+ (- (car P_0) B_mat_corp) otst_left) (- (cadr P_0) otst_up_front) (+ (- (caddr P_0) B_mat_corp) otst_bottom)))

	(command-s "_.box" P_0_fas (list (+ (car P_0_fas) L_fas) (- (- (cadr P_0_fas) B_mat_fas) otst_up_front) (+ (caddr P_0_fas) H_fas_N)))
	   (setq Fas_N (entlast))
              (if (not (equal Fas_N (entlast))) (alert "Построение не удалось"))
                 (regapp "AVCNames")
                    (setq le (entget (entlast)))
                       (setq edata (list (list -3 (list "AVCNames" (cons 1000 "Фасад")))))
                          (setq le2 (append le edata))
                             (entmod le2)
  (command-s "_.ucs" "x" 90)
  (command-s "_.arrayrect" Fas_N "" "_col" 1 1 "_r" Col_vo (+ H_fas_N Z_r) "" "")

  (command-s "_.UCS" "_w")

(setvar "osmode" oldosm)
   (setvar "clayer" oldlay)
   (command-s "._UNDO" "_end")
  (princ)
   );end defun fasad

;***********************************функция fasad_v***************************************

(defun fasad_v ( H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right /
	      oldosm oldlay P_0 P_L P_H H_box L_box B_mat_corp B_mat_fas Z_r otst_top otst_bottom otst_left otst_right
	      H_fas_one L_fas H_fas_N Col_vo P_0_fas Fas_one)

  (command-s "._UNDO" "_be")
  (defun *error*(msg) 
  (princ msg) 
 )
(command-s "_.UCS" "_w")

  (setq P_0 (getpoint "\nУкажите левую внутреннюю нижнюю точку бокса <Отмена> :"))
  (setq P_L (getpoint "\nУкажите правую внутреннюю нижнюю точку бокса <Отмена> :"));ось x
    (if (/= (cadr P_L) (cadr P_0))
      (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
  (setq P_H (getpoint "\nУкажите левую верхнюю внутренюю точку бокса <Отмена> :"));ось z
    (if (/= (cadr P_H) (cadr P_0))
      (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
  (setq H_box (distance P_0 P_H))
  (setq L_box (distance P_0 P_L))

  (setq oldosm (getvar "osmode"))
  (setvar "osmode" 0)
  (setq oldlay (getvar "clayer"))
    (if (null (tblsearch "layer" "ФАСАД"))
      (command-s "_.-LAYER" "_N" "ФАСАД" "")
     )
      (command-s "_.-layer" "_make" "ФАСАД" "_color" "3" "" "")

  (setq H_fas_one (- (- H_box otst_top) otst_bottom))  
  (setq L_fas (- (- L_box otst_left) otst_right))
  (setq H_fas_N (/ (- H_fas_one (* Z_r (1- Col_vo))) Col_vo))
  (setq P_0_fas (list (+ (car P_0) otst_left) (- (+ (cadr P_0) B_mat_fas) otst_up_front) (+ (caddr P_0) otst_bottom)))

	(command-s "_.box" P_0_fas (list (+ (car P_0_fas) L_fas) (- (cadr P_0_fas) B_mat_fas) (+ (caddr P_0_fas) H_fas_N)))
	   (setq Fas_N (entlast))
              (if (not (equal Fas_N (entlast))) (alert "Построение не удалось"))
                 (regapp "AVCNames")
                    (setq le (entget (entlast)))
                       (setq edata (list (list -3 (list "AVCNames" (cons 1000 "Фасад")))))
                          (setq le2 (append le edata))
                             (entmod le2)
  (command-s "_.ucs" "x" 90)
  (command-s "_.arrayrect" Fas_N "" "_col" 1 1 "_r" Col_vo (+ H_fas_N Z_r) "" "")

  (command-s "_.UCS" "_w")

  (setvar "osmode" oldosm)
  (setvar "clayer" oldlay)
  (command-s "._UNDO" "_end")
  (princ)
   );end defun fasad

;**************************функция raz_fasad*****************************************************

 (defun raz_fasad (/ )
   (setq Col_vo (atof (get_tile "o_Col_vo")))
   (setq B_mat_fas (atof (get_tile "o_B_mat_fas")))
   (setq B_mat_corp (atof (get_tile "o_B_mat_corp")))
   (setq Z_r (atof (get_tile "o_Z_r")))
   (setq otst_up_front (atof (get_tile "o_otst_up_front")))
   (setq otst_top (atof (get_tile "o_otst_top")))
   (setq otst_bottom (atof (get_tile "o_otst_bottom")))
   (setq otst_left (atof (get_tile "o_otst_left")))
   (setq otst_right (atof (get_tile "o_otst_right")))

   (setq Vibor (get_tile "Tip_f"))

   );end raz_fasad

;****************************************************************************

  (if (= Vibor "o_nkl")
    (fasad_n)
      (princ)
   )
    (if (= Vibor "o_vkl")
    (fasad_v)
      (princ)
   )
;********************************Функция Slide******************************

  (defun slide (/ dx dy)
    (setq dx (dimx_tile "sld")
	  dy (dimy_tile "sld")
     )
    (start_image "sld")
    (slide_image -1  -1  (1+ dx) (1+ dy) "2" )
    (end_image)
   );end slide

;*********************************Диалоговое окно*************************************

(setq dcl_id (load_dialog "D:/MyLISP/002_FASAD/dialog_fasad_sup.DCL"))
  (if (not (new_dialog "dialog_fasad_sup" dcl_id)) (exit))

     (slide)

       (action_tile "accept" "(raz_fasad) (slide) (done_dialog 1)")
         (action_tile "cancel" "(done dialog 0)")
           (setq ddi (start_dialog))
             (unload_dialog dcl_id)

(if (= ddi 1) (Fasad_sup H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right Vibor))
(princ)

   );end defun fasad_sup

Последний раз редактировалось Alxndr1697, 31.03.2022 в 08:02.
Alxndr1697 вне форума  
 
Непрочитано 31.03.2022, 19:43
1 | #4191
Browning Zed


 
Регистрация: 17.01.2014
Сообщений: 97


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
Честно признаюсь, эта тема (аргументы, переменные, что где прописывать) мне непонятна, если кто может, - объясните, пожалуйста.
Попробую по-простому объяснить синтаксис функций в AutoLISP, надеюсь гуру программирования не будут меня больно бить ногами.

Выглядит он так:
(defun foo ( a b / c d ) < тело функции > )

Разберем по порядку каждый элемент:
defun – начало определения функции. Любая функция или команда, определяемая пользователем, обязательно начинается со слова defun.

foo – имя функции. Обрати внимание, что если имя функции начинается на c:, тогда AutoCAD определяет эту функцию как команду. Таким образом, если имя функции будет foo она будет определена непосредственно как функция, но, если имя будет c:foo, она будет определена как команда, это важно!

Теперь разберемся со скобками, идущими после имени функции. Элементы внутри скобок могут содержать параметры функции и локальные переменные. Все зависит от варианта написания того, что содержится в скобках. Рассмотрим каждый из них:
Вариант 1.
(defun foo ( a b / c d ) < тело функции > )
В данном случае, функция содержит как параметры функции, так и локальные переменные.
Элементы, которые идут до слеша – a b, это параметры функции.
Элементы, расположенные после слеша – c d, это локальные переменные.
Вариант 2.
(defun foo ( a b ) < тело функции > ) или то же самое (defun foo ( a b / ) < тело функции > )
Функция содержит только параметры функции.
Вариант 3.
(defun foo ( / c d ) < тело функции > )
Функция содержит только локальные переменные.
Вариант 4.
(defun foo () < тело функции > ) или то же самое (defun foo nil < тело функции > )
Функция не имеет ни параметров функции, ни локальных переменных.

И теперь важный момент – если ты определяешь функцию как команду, то бишь вместо foo пишешь c:foo, то такая функция не должна содержать параметров функции, это будет являться ошибкой.

Параметры функции нужны, чтобы функция могла принимать входящие значения. Например, определим простейшую функцию создания круга:
Код:
[Выделить все]
(defun MakeCircle ( color ) (entmake (list '(0 . "CIRCLE") (cons 62 color) '(10 4.0 4.0 0.0) '(40 . 1.0))))
Пока не будем подробно вникать в списки сущностей, но обратим внимание на то, что параметр color, является цветом создаваемого круга, и присутствует в двух местах: в начале – в качестве входящего значения, а после повторяется снова – где значение непосредственно задействуется.
Вызов функции с параметром, осуществляется следующим образом: (имя_функции параметр_функции)
Подобным образом, попробуем вызвать нашу функцию с применением разных значений в качестве параметра функции color:
(MakeCircle 1)
- создан круг красного цвета
(MakeCircle 3)
- создан круг зеленого цвета
(MakeCircle 5)
- создан круг синего цвета
и т.д.

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

Теперь разберем, что из себя представляют локальные переменные. Начать нужно с того, что сами переменные могут быть двух типов: локальные и глобальные. Локальные переменные могут быть активны только в функции, в которой они были определены, и после завершения этой функции вычищаются из памяти компьютера. Глобальные же переменные всегда находятся в памяти.
В AutoLISP переменные могут быть установлены с помощью двух функций setq и set. Таким образом, все значения, заданные с помощью этих функций, будут являться переменными.

Проведем небольшой эксперимент и создадим команду, где определим переменную. Команда будет в двух вариантах. В первом варианте команды мы зададим переменную var как локальную.
Введем в командную строку:
Код:
[Выделить все]
(defun c:Hello ( / var )  (setq var "Здравствуй, мир!") (princ))
Затем, запустим команду Hello, а после введем в командную строку (princ var), и командная строка вернет nil, что значит переменной var не существует в памяти компьютера.
Теперь определим ту же команду, но переменную var оставим глобальной:
Код:
[Выделить все]
(defun c:Hello nil (setq var "Здравствуй, мир!") (princ))
Запускаем команду Hello, а после, также введем в командную строку (princ var). Но теперь командная строка вместо nil вернет "Здравствуй, мир!". То есть, в памяти компьютера хранится переменная, которая содержит строковое значение "Здравствуй, мир!".

При определении в функции переменных должно выполняться обязательное правило: переменные должны всегда задаваться как локальные, за исключением тех редких случаев, когда переменные могут потребоваться как глобальные. Но ты должен четко понимать, когда, где и зачем переменная может потребоваться как глобальная, и если этого понимания нет – тогда локализуй переменные. Возвращаясь к вышесказанному – если в функции присутствуют слова setq или set, значит в функции есть переменные, и они, за исключением редких случаев должны быть локализованы. Добавлю также, что локализовываться могут не только переменные, но и функции которые вложены в другие функции, – они так и называются – локальные функции.


Думаю, синтаксис функций в общих словах я объяснил. И теперь исходя из изложенного проверь свой код:
То, что ты выделил красным, это вызов некой функции Fasad_sup с кучей аргументов (параметров функции), и эта функция ранее не была определена! В начале ты определяешь команду c:Fasad_sup, а не функцию.
И, забегая вперед, скажу: функция запускаемая внутри функции, которая носит с ней одно и то же имя, называется рекурсивной, и применяется в специфических случаях. Это явно не тот случай.

Последний раз редактировалось Browning Zed, 31.03.2022 в 20:37.
Browning Zed вне форума  
 
Непрочитано 31.03.2022, 20:14
| 1 #4192
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


терминологическое уточнение
Цитата:
Сообщение от Browning Zed Посмотреть сообщение
Локальные переменные могут быть активны только в функции,
не активные - а у переменных есть области видимости. И для лиспа всего два варианта - локальная видимость в пределах функции или глобальная для всего кода лиспа. Причем чтобы создать переменную с глобальной видимостью - в лиспе достаточно просто забыть указать переменную в теле функции или ошибиться с написанием идентификатора переменной в коде.
Сергей812 вне форума  
 
Непрочитано 31.03.2022, 20:42
#4193
Browning Zed


 
Регистрация: 17.01.2014
Сообщений: 97


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
терминологическое уточнение

не активные - а у переменных есть области видимости. И для лиспа всего два варианта - локальная видимость в пределах функции или глобальная для всего кода лиспа. Причем чтобы создать переменную с глобальной видимостью - в лиспе достаточно просто забыть указать переменную в теле функции или ошибиться с написанием идентификатора переменной в коде.
Да, спасибо за уточнение.
От себя также добавлю, что по теме "область видимости в AutoLISP" есть замечательная статья на сайте Алексея Кулика.
Browning Zed вне форума  
 
Непрочитано 01.04.2022, 07:40
#4194
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Browning Zed, спасибо, очень доходчиво.


----- добавлено через ~6 мин. -----
Цитата:
Сообщение от Browning Zed Посмотреть сообщение
Составив такую функцию, можно впоследствии запускать ее определив только нужное значение, а не дублировать одни и те же строки кода
Наконец-то применю)))

Насчет имен, у меня, вроде, разные везде. Или, это просто предупреждение

Последний раз редактировалось Alxndr1697, 01.04.2022 в 07:48.
Alxndr1697 вне форума  
 
Непрочитано 03.04.2022, 18:11
#4195
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Переделал программу. Теперь причиной остановки указывает выражение (выделил красным), которое в программах, по отдельности работало нормально.
Да что в нем не так???





Код:
[Выделить все]
(DEFUN c:Fasad_sup (/ H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right
		    le edata le2 Part_name)

;*********************************Функция re_name****************************************

(defun re_name (Part_name / le edata le2 )
(regapp "AVCNames")
(setq le (entget (entlast)))
(setq edata (list (list -3 (list "AVCNames" (cons 1000 Part_name)))));формирование подсписка расширенных данных и включение в список
(setq le2 (append le edata));присоединение расширенных данных к примитиву
(entmod le2)
(entget (entlast) '("AVCNames"))
 );end re_name

;***********************************функция fasad***************************************

(defun fasad (H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right /
	      oldosm oldlay P_0 P_L P_H H_box L_box B_mat_corp B_mat_fas Z_r otst_top otst_bottom otst_left otst_right
	      H_fas_one L_fas H_fas_N Col_vo P_0_fas Fas_one Vibor)

  (command-s "._UNDO" "_be");начало группы для отмены (Begin).
  (defun *error*(msg) 
  (princ msg) 
 )
(command-s "_.UCS" "_w")

  (setq P_0 (getpoint "\nУкажите левую внутреннюю нижнюю точку бокса <Отмена> :"))
  (setq P_L (getpoint "\nУкажите правую внутреннюю нижнюю точку бокса <Отмена> :"));ось x
    (if (/= (cadr P_L) (cadr P_0))
       (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
  (setq P_H (getpoint "\nУкажите левую внутреннюю верхнюю точку бокса <Отмена> :"));ось z
    (if (/= (cadr P_H) (cadr P_0))
       (progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XZ"))
       (exit))
     )
   (setq H_box (distance P_0 P_H))
   (setq L_box (distance P_0 P_L))

  (setq oldosm (getvar "osmode"))
  (setvar "osmode" 0)
  (setq oldlay (getvar "clayer"))
    (if (null (tblsearch "layer" "ФАСАД"))
       (command-s "_.-LAYER" "_N" "ФАСАД" "")
     )
       (command-s "_.-layer" "_make" "ФАСАД" "_color" "3" "" "")

;**************************fasad_n*****************************************
   
 (if (= Vibor "o_nkl")
   (progn
      (setq H_fas_one (- (- (+ H_box (* 2 B_mat_corp)) otst_top) otst_bottom))  
      (setq L_fas (- (- (+ L_box (* 2 B_mat_corp)) otst_left) otst_right))
      (setq H_fas_N (/ (- H_fas_one (* Z_r (1- Col_vo))) Col_vo))
      (setq P_0_fas (list (+ (- (car P_0) B_mat_corp) otst_left) (- (cadr P_0) otst_up_front) (+ (- (caddr P_0) B_mat_corp) otst_bottom)))

	(command-s "_.box" P_0_fas (list (+ (car P_0_fas) L_fas) (- (- (cadr P_0_fas) B_mat_fas) otst_up_front) (+ (caddr P_0_fas) H_fas_N)))
	(setq Fas_N (entlast))
        (if (not (equal Fas_N (entlast))) (alert "Построение не удалось"))
        (re_name "Фасад")
        (princ)
    )
 )
;***************************fasad_v****************************************

(if (= Vibor "o_vkl")
  (progn
     (setq H_fas_one (- (- H_box otst_top) otst_bottom))  
     (setq L_fas (- (- L_box otst_left) otst_right))
     (setq H_fas_N (/ (- H_fas_one (* Z_r (1- Col_vo))) Col_vo))
     (setq P_0_fas (list (+ (car P_0) otst_left) (- (+ (cadr P_0) B_mat_fas) otst_up_front) (+ (caddr P_0) otst_bottom)))

	(command-s "_.box" P_0_fas (list (+ (car P_0_fas) L_fas) (- (cadr P_0_fas) B_mat_fas) (+ (caddr P_0_fas) H_fas_N)))
	(setq Fas_N (entlast))
        (if (not (equal Fas_N (entlast))) (alert "Построение не удалось"))
        (re_name "Фасад")
        (princ)
   )
 )
;**************************************************************************

  (command-s "_.ucs" "x" 90)
  (command-s "_.arrayrect" Fas_N "" "_col" 1 1 "_r" Col_vo (+ H_fas_N Z_r) "" "")

  (command-s "_.UCS" "_w")
  (setvar "osmode" oldosm)
  (setvar "clayer" oldlay)
  (command-s "._UNDO" "_end")
  (princ)
   );end defun fasad

;**************************функция raz_fasad*******************************

 (defun raz_fasad (/ )

   (setq Vibor (get_tile "Tip_f"))

   (setq Col_vo (atof (get_tile "o_Col_vo")))
   (setq B_mat_fas (atof (get_tile "o_B_mat_fas")))
   (setq B_mat_corp (atof (get_tile "o_B_mat_corp")))
   (setq Z_r (atof (get_tile "o_Z_r")))
   (setq otst_up_front (atof (get_tile "o_otst_up_front")))
   (setq otst_top (atof (get_tile "o_otst_top")))
   (setq otst_bottom (atof (get_tile "o_otst_bottom")))
   (setq otst_left (atof (get_tile "o_otst_left")))
   (setq otst_right (atof (get_tile "o_otst_right")))

   

   );end raz_fasad

;***************************Функция Slide**********************************

  (defun slide (/ dx dy)
    (setq dx (dimx_tile "sld")
	  dy (dimy_tile "sld"))
    (start_image "sld")
    (slide_image -1  -1  (1+ dx) (1+ dy) "2" )
    (end_image)
   );end slide

;************************Диалоговое окно**********************************

(setq dcl_id (load_dialog "D:/MyLISP/002_FASAD/dialog_fasad_sup.DCL"))
  (if (not (new_dialog "dialog_fasad_sup" dcl_id)) (exit))

   (action_tile "accept" "(raz_fasad) (slide) (done_dialog 1)")
   (action_tile "cancel" "(done dialog 0)")
   (setq ddi (start_dialog))
   (unload_dialog dcl_id)

(if (= ddi 1) (fasad H_box L_box Col_vo B_mat_fas B_mat_corp Z_r otst_up_front otst_top otst_bottom otst_left otst_right))
(princ)

   );end defun fasad_sup

Последний раз редактировалось Alxndr1697, 03.04.2022 в 19:09.
Alxndr1697 вне форума  
 
Непрочитано 03.04.2022, 19:15
#4196
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Какое сообщение об ошибке?
Offtop: Сугубо ИМХО: код следует переработать полностью. Начиная с переименования функций и их локализации и документирования, заканчивая общим принципом. Могу, если хочется, снять видосик, почему этот код не подлежит отладке.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 03.04.2022, 20:14
#4197
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Текстового сообщения нет, просто выделение.
Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Могу, если хочется, снять видосик, почему этот код не подлежит отладке.
Конечно хочется, не то слово!
Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
заканчивая общим принципом.
Вот, его-то, я никак не поймаю, видимо.
Миниатюры
Нажмите на изображение для увеличения
Название: 2022-04-03_201855.jpg
Просмотров: 22
Размер:	54.6 Кб
ID:	246486  

Последний раз редактировалось Alxndr1697, 03.04.2022 в 20:23.
Alxndr1697 вне форума  
 
Непрочитано 03.04.2022, 20:25
#4198
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


в посте №4193 дали ссылку, как запихивать функции внутрь других функций) вот и наблюдаем внутри функции-команды кашу из других функций
Сергей812 вне форума  
 
Непрочитано 04.04.2022, 10:14
#4199
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Alxndr1697, видосик записать не удалось - что-то не то у меня с виртуалкой. Так что текстом
Прежде чем читать - все это личное мнение, никого ни к чему не обязывающее.

Дисклеймер: будет много ссылок на мой сайтик.

Представленный код невозможно протестировать. В принципе невозможно.
Причина номер раз - это использование диалога (которого, естественно, у меня нет). Я понимаю, что можно покопаться по форуму и найти тот самый dcl. Но как-то подобное не комильфо - не проще ли создавать диалог "на лету"?
Причина номер два - именования функций и переменных. Функция re_name (к примеру), судя по названию, должна там что-то переименовывать. А делает она совсем другое.
Причина номер три - это видимость функций и переменных. Все внутренние функции объявлены как глобальные. Отличный шанс выстрелить себе в ногу
Далее. Мое искреннее убеждение состоит в том, что любая (подчеркиваю - любая!), даже локальная, функция должна работать только с теми данными, которые в нее прилетели и не лезть во внешние переменные. Та же raz_fasad (кстати, по имени можно решить заранее - что оно делает?) у меня была бы переписана примерно так:
Код:
[Выделить все]
 (defun _kpblc-list-add-or-subst (lst key value)
                                ;|
  *    Производит замену или дополнение элемента списка новым
  *    Параметры вызова:
    lst     ; обрабатываемый список
    key     ; ключ
    value   ; устанавливаемое значение
  |;
  (if (not value)
    (vl-remove-if (function (lambda (x) (= (car x) key))) lst)
    (if (cdr (assoc key lst))
      (subst (cons key value) (assoc key lst) lst)
      (cons (cons key value) (vl-remove-if (function (lambda (x) (= (car x) key))) lst))
    ) ;_ end of if
  ) ;_ end of if
) ;_ end of defun

(defun raz_fasad (key value ref-list)
                 ;|
  *    Обработка диалога
  *    Параметры вызова:
    key      ; имя контрола в диалоге
    value    ; установленное значение контрола
    ref-list ; список с данными, передавать по ссылке
  |;
  (cond
    ((= key "Tip_f")
     (set ref-list (_kpblc-list-add-or-subst (eval ref-list) (strcase key t) value))
    )
    (t
     (set ref-list (_kpblc-list-add-or-subst (eval ref-list) (strcase key t) (atof value)))
    )
  ) ;_ end of cond
) ;_ end of defun
И в таком случае вызов диалога становится немного другим (при условии, конечно, что dcl в принципе существует):
Код:
[Выделить все]
 (setq dcl_lst '(("tip_f" . "")
                ("o_col_vo" . 0.)
                ("o_b_mat_fas" . 0.)
                ("o_b_mat_corp" . 0.)
                ("o_z_r" . 0.)
                ("o_otst_up_front" . 0.)
                ("o_otst_top" . 0.)
                ("o_otst_bottom" . 0.)
                ("o_otst_left" . 0.)
                ("o_otst_right" . 0.)
               )
) ;_ end of setq
(if (setq dcl_file (findfile "D:/MyLISP/002_FASAD/dialog_fasad_sup.DCL"))
  (progn
    (setq dcl_id (load_dialog dcl_file))
    (if (not (new_dialog "dialog_fasad_sup" dcl_id "(raz-fasad $key $value 'dcl_lst)"))
      (exit)
    ) ;_ end of if
  ) ;_ end of progn
) ;_ end of if
Естественно, что в таком случае action_tile для accept становится тоже другим. Примерно так:
Код:
[Выделить все]
 (action_tile "accept" "(done_dialog 1)")
Следом - переименование функций. Локальные функции я обычно называю по принципу fun_<И тут название>. Тот же raz_fasad станет как fun_dcl-callback, re_name - fun_addxdata. И т.д.

Дальше - я бы постарался максимально отказаться от использования командных методов. Так, например
Код:
[Выделить все]
 (if (null (tblsearch "layer" "ФАСАД"))
  (command-s "_.-LAYER" "_N" "ФАСАД" "")
) ;_ end of if
(command-s "_.-layer" "_make" "ФАСАД" "_color" "3" "" "")
Стало бы
Код:
[Выделить все]
 (setq layer (vla-add (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) "Фасад"))
(vla-put-color layer 3)
(vla-put-lock layer :vlax-false)
(vl-catch-all-apply (function (lambda () (vla-put-freeze layer :vlax-false))))
(setvar "clayer" (vla-get-name layer))
А
Код:
[Выделить все]
 (command-s "_.box"
я бы заменил на
Код:
с соответствующими параметрами.

На предмет переопределения глобального обработчика *error* я уже когда-то высказывался. Кстати, у тебя там не возвращаются обратно системные переменные. И метка окончания отмены не ставится, что может привести к неприятным последствиям.

Ну и по поводу запроса точек и прочего

Сорян, накидали работы. Пока заканчиваю.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 04.04.2022, 10:41
#4200
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


По поводу наименования функций - чтобы не запутаться, можно придерживаться псевдоиерархии:

Fasad_%Тип фасада%_Create - создание фасада
Fasad_%Тип фасада%_Create_%Fun01%
Fasad_%Тип фасада%_Create_%Fun02% - это подфункции создания отдельных частей фасада данного типа
Fasad_%Тип фасада%_Create_%Fun03%

и не надо их куда-то прятать, уже по идентификатору функции видно - где она должна вызываться. И что функция Fasad_%Тип фасада%_Create не может (не должна, точнее) вызываться внутри Fasad_%Тип фасада%_Create_%Fun01%. И данные передаются в эти подфункции через аргументы.

И если под рукой тот же эксель - не ленитесь делать простейшие таблички копипастом: название функции, назначение аргументов, возвращаемое значение, примечание. В табличном виде гораздо проще воспринимать информацию, чем в простынях кода.
Сергей812 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Сейсмозащита и сейсмоизоляция существующих, построенных зд. IANationalInformAgentstvo Прочее. Архитектура и строительство 216 20.01.2015 16:51
Мониторы LCD CRT Разное 94 17.06.2008 10:51
ЮМОР 2006 =) Perezz!! Разное 1122 04.01.2007 00:46