NANOCAD ШОУ
dwg.ru forum rss xml
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму |

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

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

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

Red Nova вне форума Вставить имя

Со школы не ладится у меня с программированием. Все предметы щелкал, а на экзамене по информатике (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.
Просмотров: 1297002
 
Непрочитано 28.07.2008, 16:47
#181
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,575
Отправить сообщение для VVA с помощью ICQ Отправить сообщение для VVA с помощью Skype™


andery, Да, это правильный результат. Вот эти грабли мы и будеи преодолевать. (Только пересохрани в формате 2004 Автокада, а то не все смогут открыть)
Цитата:
SHIFT + Правая кнопка мыши, а дальше none
Правильно, только по нашим условиям "_non", так как сам писал здесь
Цитата:
0 NONe
А я постом ниже жирным выделил необходимое.
Т.е. получается, что в ответ на запрос командой точки (будь то _line, _circle или _pline) можно вводить выделенные жирным опции, как то _endp, _non и т.д.
Раз мы можем вводить это руками, значит мы можем это передать и в command. Т.е. вырисовывается 2 способа борьбы с "OSMODE"
1. Сохранить в переменную, обнулить (или отключить), а потом восстановить
2. Перед вводом каждой точки в command временно отключать привязку с помощью опции "_non"
Хочу увидеть оба варианта в лиспе
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 28.07.2008 в 17:22.
VVA вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 28.07.2008, 17:06
#182
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,964
Отправить сообщение для Red Nova с помощью Skype™


VVA,
Первый вариант ты уже видел
Код:
[Выделить все]
(setq old_osmode (getvar "osmode"))
(setvar "osmode" 0)
; программа
(setvar "osmode" old_osmode)
И второй вариант.
Код:
[Выделить все]
(command "_pline" "_non" pt1 pt2 pt3 pt4 "_c")
(Setq object (entlast))
(command "_circle" "_non" base "_non" R)
(command "_rotate" "_non" object "" "_non" base "_non" pause)
Думаю второй вариант менее проблематичный (не связываемся с функцией error)
__________________
Блог
Red Nova вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 17:07
#183
Кулик Алексей aka kpblc
Moderator

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


И не совсем верный второй вариант. Надо:
Код:
[Выделить все]
(command "_pline" "_non" pt1 "_non" pt2 "_non" pt3 "_non" pt4  "_c")
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 28.07.2008, 17:12
#184
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,964
Отправить сообщение для Red Nova с помощью Skype™


Кулик Алексей aka kpblc,
__________________
Блог
Red Nova вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 17:16
#185
andery


 
Регистрация: 27.12.2007
Сообщений: 132
Отправить сообщение для andery с помощью ICQ


Цитата:
(command "_circle" "_non" base "_non" R)
Зачем перед R ставить _non ?
Это ведь не точка....
andery вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 17:19
#186
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,575
Отправить сообщение для VVA с помощью ICQ Отправить сообщение для VVA с помощью Skype™


Red Nova, Алексей уже подсказал. Я нужное слово выделил в #181 поярче.
Давай остановимся на 1-м варианте. Покажи код целиком, чтобы идти дальше.

*** Добавлено
andery, В принципе не обязательно, если в переменной R - число. Но в Автокаде радиус можно "показать" 2-мя точками. Просто нужно отдавать себе отчет, что у тебя в переменной R.
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 17:23
#187
andery


 
Регистрация: 27.12.2007
Сообщений: 132
Отправить сообщение для andery с помощью ICQ


У меня такое получилось с использованием 1-го варианта:
Код:
[Выделить все]
(defun c:колонна (/)
  	(setq old_osmode (getvar "osmode"))
	(setvar "osmode" 0)
  	(setq old_osnapcoord (getvar "osnapcoord"))
  	(setvar "osnapcoord" 0)
	(initget (+ 1 2 4))
	(setq a (getdist"\nВведите ширину колонны:"))
	(initget (+ 1 2 4))
	(setq b (getdist"\nВведите высоту колонны:"))
	(setq p (getpoint "\nУкажите центр колоны:<по умолчанию (0,0)>"))
	(if (null p) (setq p '(0 0 0))
	)
	(setq x1 (- (car p) (/ a 2))) 
	(setq y1 (- (car (cdr p)) (/ b 2)))
	(setq x2 (+ (car p) (/ a 2)))
	(setq y2 (+ (car (cdr p)) (/ b 2)))

  	(command "._pline"
		(list x1 y1)
		(list x1 y2)
		(list x2 y2)
		(list X2 y1)
		"_close"
	)
  
  	(Setq object (entlast))
  	(command "_circle" p (/ a 2))
	(command "_rotate" object "" p pause) 	)

  	(setvar "osmode" old_osmode)
	(setvar "osnapcoord" old_osnapcoord)
  )
andery вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 28.07.2008, 17:26
#188
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,964
Отправить сообщение для Red Nova с помощью Skype™


VVA, Учитывая отслежку Osmode
Код:
[Выделить все]
 (defun C:Колонна (/ dimensionX dimensionY base R object old_osmode )
(setq old_osmode (getvar "osmode"))
(setvar "osmode" 0)
(initget 7)
(setq dimensionX (getreal "Введите ширину колонны: "))
(initget 7)
(setq dimensionY (getreal "Введите толщину колонны: "))
(setq base 
    (cond
         ((getpoint "\Введите точку вставки колонны <0,0,0> :"))
         (t '(0. 0. 0.)))
     ) 
(setq pt1
     ( list ( - ( car base ) ( / dimensionX  2.0 ) )
            ( - (cadr base ) ( / dimensionY  2.0 ) )
     )
)
(setq pt2
     ( list ( - ( car base ) ( / dimensionX  2.0 ) )
            ( + (cadr base ) ( / dimensionY  2.0 ) )
     )
)
(setq pt3
     ( list ( + ( car base ) ( / dimensionX  2.0 ) )
            ( + (cadr base ) ( / dimensionY  2.0 ) )
     )
)
(setq pt4
     ( list ( + ( car base ) ( / dimensionX  2.0 ) )
            ( - (cadr base ) ( / dimensionY  2.0 ) )
     )
)
(Setq  R  ( / dimensionX  2.0 ))
(command "_pline" pt1 pt2 pt3 pt4 "_c")
(Setq object (entlast))
(command "_circle" base R)
(command "_rotate" object "" base pause)
(setvar "osmode" old_osmode)
)
__________________
Блог
Red Nova вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 17:31
#189
andery


 
Регистрация: 27.12.2007
Сообщений: 132
Отправить сообщение для andery с помощью ICQ


Кстати при таком варианте, при прерывании команды "колонна" эскейпом
osmode=0, ИМХО как-то неправильно...
andery вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 28.07.2008, 17:44
#190
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,964
Отправить сообщение для Red Nova с помощью Skype™


andery,
Подозреваю что далее у нас урок обработки ошибок методом переопределения функции error
__________________
Блог

Последний раз редактировалось Red Nova, 28.07.2008 в 22:35.
Red Nova вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 28.07.2008, 20:39
#191
Кулик Алексей aka kpblc
Moderator

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


Ссылка на пример переопределенного обработчика уже была
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 00:04
#192
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,575
Отправить сообщение для VVA с помощью ICQ Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от Red Nova Посмотреть сообщение
andery,
Подозреваю что далее у нас урок обработки ошибок методом переопределения функции error
Ну положим не error, а *error*. А так в общем правильно. Если мы будем использовать 1-й вариант (сохранение OSMODE в переменной и восстановление), то мы не застрахованы, что при повороте колонны пользователь нажмет ESC и програма прекратит свою работу. Но OSMODE мы вначале установили равным 0, а назад не восстановили, так как програма прекратила работу. Пользователь недоволен и высказывает СПРАВЕДЛИВО нам свое фи.
Цитата:
Кстати при таком варианте, при прерывании команды "колонна" эскейпом
osmode=0, ИМХО как-то неправильно...
В Автолиспе существует специально объявленная функция *error*, которой передается один аргумент- сообщение об ошибке.
Есть 2 варианта:
1-й как показал Алексей здесь можно ГЛОБАЛЬНО переназначить обработчик ошибок:
создать свою функцию с 1-м аргументом (см. (defun kpblc-error (message) ... по ссылке
присвоить стандартному обработчику указатель на свой обработчик ошибок. Пример ф-ции приведу здесь
;|
Код:
[Выделить все]
============================================================================= 
*    Переназначение обработки ошибок. 
*    Переназначен или нет обработчик проверяется по значению 
* переменной *kpblc-error* 
=============================================================================|; 
(defun kpblc-error-init () 
  (if (not *kpblc-error*) 
    (setq *kpblc-error* *error* ;;;_Сохраняем в ГЛОБАЛЬНОЙ переменной *kpblc-error* указатель на *error*
     *error* kpblc-error  ;;; Присваиваем переменной *error* указатель на нашу ф-цию kpblc-error
     ) ;_ end of setq 
    (setq *error*     *kpblc-error* 
     *kpblc-error* nil 
     ) ;_ end of setq 
    ) ;_if 
  (princ) 
  ) ;_defun
2-й тоже описан несколькими постами ниже (см пост от Ср 21 Июн , 2006 10:50)
Суть его в том, что мы не сохраняем и восстанавливаем глобально ф-цию
*error*, а объявляем ее ЛОКАЛЬНОЙ переменной и в теле самой ф-ции объявляем ф-цию *error*. Т.е конструкция принимает вид
Код:
[Выделить все]
(defun c:myfunc_witherror( / *error* oldOSM base) 
(defun *error*(msg) 
;; Определяем действия, которые надо выполнить 
;; в случае ошибки выполнения основного кода 
) 
;; Чего-то там делаем в c:myfunc_witherror
) ;_ end of defun
Т.е. получается, что время жизни ф-ции *error* - пока существует ф-ция c:myfunc_witherror.
Здесь есть еще один нюанс: Всем КРАСНЫМ ф-циям, объявленным внутри СИНИХ функций доступны ЛОКАЛЬНЫЕ переменные СИНИХ функций как ГЛОБАЛЬНЫЕ. Я могу спокойно проверять значение переменной, объявленной как локальная в ф-ции верхнего уровня (СИНЕЙ)
Код:
[Выделить все]
(defun c:myfunc_witherror( / *error* oldOSM base) 
(defun *error*(msg) 
(princ msg) ;_ печатаем сообщение
(if oldOSM (setvar "OSMODE" oldOSM)) ;_Если oldOSM задано, то присваиваем переменной OLDOSM значение oldOSM
) 
;; Чего-то там делаем в c:myfunc_witherror
) ;_ end of defun
В случае ошибки в ф-ции c:myfunc_witherror (как то нажатие ESC пользователем) управление передастся ф-ции *error* и мы восстановим переменную OSMODE в сохраненное ранее значение в переменной oldOSM
Ну вот попытался в картинках объяснить как это работает. Хотелось бы увидеть команду КОЛОННА с *error* по 2-му варианту
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 29.07.2008 в 00:14.
VVA вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 00:42
#193
Кулик Алексей aka kpblc
Moderator

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


Следующим шагом рекомендовал бы заняться метками отмены
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 29.07.2008, 09:52
#194
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,964
Отправить сообщение для Red Nova с помощью Skype™


Понять бы еще что значит (msg)
Код:
[Выделить все]
(defun C:Колонна (/ dimensionX dimensionY base R object oldOSM)
 (defun *error*(msg) 
 (princ msg) ; Отменено пользователем
 (if oldOSM (setvar "OSMODE" oldOSM)) 
 ) 
 (setq oldOSM (getvar "osmode"))
 (setvar "osmode" 0)
 (initget 7)
 (setq dimensionX (getreal "Введите ширину колонны: "))
 (initget 7)
 (setq dimensionY (getreal "Введите толщину колонны: "))
 (setq base 
    (cond
         ((getpoint "\Введите точку вставки колонны <0,0,0> :"))
         (t '(0. 0. 0.)))
     ) 
 (setq pt1
     ( list ( - ( car base ) ( / dimensionX  2.0 ) )
            ( - (cadr base ) ( / dimensionY  2.0 ) )
     )
 )
 (setq pt2
     ( list ( - ( car base ) ( / dimensionX  2.0 ) )
            ( + (cadr base ) ( / dimensionY  2.0 ) )
     )
 )
 (setq pt3
     ( list ( + ( car base ) ( / dimensionX  2.0 ) )
            ( + (cadr base ) ( / dimensionY  2.0 ) )
     )
 )
 (setq pt4
     ( list ( + ( car base ) ( / dimensionX  2.0 ) )
            ( - (cadr base ) ( / dimensionY  2.0 ) )
     )
 )
 (Setq  R  ( / dimensionX  2.0 ))
 (command "_pline" pt1 pt2 pt3 pt4 "_c")
 (Setq object (entlast))
 (command "_circle" base R)
 (command "_rotate" object "" base pause)
 (setvar "osmode" oldOSM)
)
__________________
Блог
Red Nova вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 10:11
#195
Кулик Алексей aka kpblc
Moderator

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


поставь точку останова и выполняй пошагово
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 10:28
#196
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,575
Отправить сообщение для VVA с помощью ICQ Отправить сообщение для VVA с помощью Skype™


Цитата:
Понять бы еще что значит (msg)
msg - это тоже переменная, только она расположена перед слэшем, значит это АГРУМЕНТ функции. Почитай Команда или функция?, defun, и 1.4 Соглашения по обозначениям
Мы добились главного. Если пользователь прервет ф-цию, то восстановятся объектные привязки до вызова команды Колонна.
Для иллюстрации примера делаем следующее:
  1. В командной строке набираем OSMODE и задаем значение 33 (Конточка+ Пересечение)
  2. Грузим лисп из #188 и в момент запроса угла поворота нажимаем ESC.
  3. Проверяем значение OSMODE
И так
  1. В командной строке набираем OSMODE и задаем значение 33 (Конточка+ Пересечение)
  2. Грузим лисп из #194 и в момент запроса угла поворота нажимаем ESC.
  3. Проверяем значение OSMODE
У меня еще задание. Все знают, что привязку (OSMODE) можно ОТКЛЮЧАТЬ, т.е. сохраняется перечень установленных режимов, а потом ВКЛЮЧАТЬ.
Задание для самостоятельной работы: Написать функции
disable_osmode - Функция отключения режима(ов) объектной привязки
enable_osmode - Функция включения режима(ов) объектной привязки
В справке про OSMODE об этом написано.
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 10:54
#197
andery


 
Регистрация: 27.12.2007
Сообщений: 132
Отправить сообщение для andery с помощью ICQ


У меня такие вопросы по поводу Граблей№1,
1.Зачем делать osnapcoord=0 ? Ведь "наступаем" на грабли тока при этом значении.
2.Не лучше ли делать osnapcoord=1 (1 - Ввод с клавиатуры пере регулирует установки объектной привязки., ведь при этом у нас никогда "не убежит" точка, т.к. мы ее вводим "вручную")? А потом возращать прошлое значение.
3. Если делаем колонну, зачем osmode делать 0 ?
А если пользователь при вставке колонны хочет пользоваться привязками?
andery вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 11:00
#198
Кулик Алексей aka kpblc
Moderator

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


"А если пользователь хочет пользоваться привязками" - то надо либо отключать их только на момент рисования, либо вообще использовать некомандные методы.
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 11:14
#199
andery


 
Регистрация: 27.12.2007
Сообщений: 132
Отправить сообщение для andery с помощью ICQ


Переформулирую вопрос:
В нашей функции "колонна" ,если мы выставляем osnapcoord=1, в каком случае мы наступим на грабли? (в каком случае точка может "убежать")
andery вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 29.07.2008, 11:29
#200
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,575
Отправить сообщение для VVA с помощью ICQ Отправить сообщение для VVA с помощью Skype™


1,2. Это дело вкуса. Можно делать и так. Это просто пример. Можно вообще использовать некомандные методы и забыть про привязку. Плюс еще OSNAPCOORD появилась в 13-й версии Автокада, а я эти проблемы решал в 10-й версии. Привычка.
3. А никто не застявляет обнулять OSMODE сразу как запомнили значение. Можно обнулить перед вызовом _PLINE. Это так Red Nova захотел, а пользователь andery указал ему на этот СУЩЕСТВЕННЫЙ недостаток. Неудобно пользоваться командой Колонна, так как невозможно привязаться к существующему пересечению осей. Ну и наконец привязку можно ОТКЛЮЧАТЬ
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума вставить имя Обратить внимание модератора на это сообщение  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Cкидки на VetCAD++
Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Быстрый переход

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

|| Главная || Каталог САПР || Тендеры || Публикации || Объявления || Биржа труда || Download || Галерея ||
|| Библиотека || Кунсткамера || Каталог предприятий || Контакты || Файлообменник || Блоги ||