Тема: LISP. Отрисовка произвольной трассы из отрезков и дуг.

;********** SETI.LSP ***********************************
; Программа отрисовки сети из сопряженных отрезков.
; Автор Громов Владимир 2009 г.
; Макрос для загрузки:
; ^C^C(if (not C:СЕТИ) (load "seti")) СЕТИ
;
(defun C:СЕТИ ( / echo rd pt1 pt2 pt3 ent1 ent2)
(setq echo (getvar "CMDECHO"))
(setvar "CMDECHO" 0)
(if (null rds) (setq rds "150"))
(princ (strcat "\n Радиус сопряжения <" rds ">: "))
(setq rd (getint))
(if (= rd nil) (setq rd (atoi rds)) (setq rds (itoa rd)))
(vl-cmdf "_FILLET" "_r" rd)
(initget 7)
(setq pt1 (getpoint "\n Начальная точка: "))
(initget 7)
(setq pt2 (getpoint pt1 "\n Вторая точка: "))
(vl-cmdf "_LINE" pt1 pt2 "")
(setq ent1 (entlast))
(initget 7)
(setq pt3 (getpoint pt2 "\n Следующая точка: "))
(vl-cmdf "_LINE" pt2 pt3 "")
(setq ent2 (entlast))
(vl-cmdf "_fillet" ent1 ent2)
(while pt3
   (setq pt2 pt3)
   (setq ent1 ent2)
   (setq pt3 (getpoint pt2 "\n Следующая точка <Enter-Конец> "))
   (if pt3
       (progn
       (vl-cmdf "_LINE" pt2 pt3 "")
       (setq ent2 (entlast))
       (vl-cmdf "_fillet" ent1 ent2)
       )
       (princ "\n Конец.")
   )
)
(setvar "CMDECHO" echo)
(princ)
)
(princ "\n Ввести в командной строке СЕТИ")

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Вариант с преобразованием отрезков и дуг в полилинию.

;********** SETI_PL.LSP *****************************************
; Программа отрисовки сети из сопряженных отрезков
; с последующим объединением в полилинию.
; Автор Громов Владимир 2009 г.
; Макрос для загрузки:
; ^C^C(if (not C:СЕТИ_ПЛ) (load "seti_pl")) СЕТИ_ПЛ
;
(defun C:СЕТИ_ПЛ ( / echo rd pt1 pt2 pt3 ent1 ent2)
(setq echo (getvar "CMDECHO"))
(setvar "CMDECHO" 0)
(setq ss (ssadd))
(if (null rds) (setq rds "150"))
(princ (strcat "\n Радиус сопряжения <" rds ">: "))
(setq rd (getint))
(if (= rd nil) (setq rd (atoi rds)) (setq rds (itoa rd)))
(vl-cmdf "_FILLET" "_r" rd)
(initget 7)
(setq pt1 (getpoint "\n Начальная точка: "))
(initget 7)
(setq pt2 (getpoint pt1 "\n Вторая точка: "))
(vl-cmdf "_LINE" pt1 pt2 "")
(setq ent1 (entlast))
(ssadd ent1 ss)
(initget 7)
(setq pt3 (getpoint pt2 "\n Следующая точка: "))
(vl-cmdf "_LINE" pt2 pt3 "")
(setq ent2 (entlast))
(ssadd ent2 ss)
(vl-cmdf "_fillet" ent1 ent2)
(ssadd (entlast) ss)
(while pt3
   (setq pt2 pt3)
   (setq ent1 ent2)
   (setq pt3 (getpoint pt2 "\n Следующая точка <Enter-Конец> "))
   (if pt3
       (progn
       (vl-cmdf "_LINE" pt2 pt3 "")
       (setq ent2 (entlast))
       (ssadd ent2 ss)
       (vl-cmdf "_fillet" ent1 ent2)
       (ssadd (entlast) ss)
       )
       (princ "\n Конец.")
   )
)
(vl-cmdf "_PEDIT" "_m" ss "" "_yes" "_join" "" "")
(vl-load-com)
(setq dlina (vlax-get-property (vlax-ename->vla-object (entlast)) 'length))
(princ "\n Длина трассы = ") (princ dlina)
(setvar "CMDECHO" echo)
(princ)
)
(princ "\n Ввести в командной строке СЕТИ_ПЛ")

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Очень хорошо, спасибо!
А можно ли задействовать Ctrl+U (Undo) - при ошибочно указанной точке отменить последний отрисованный отрезок и продолжить отрисовку далее без прерывания программы?

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

На эту тему я пока не думал. Но подумаю.

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Вот так сюрприз -
Command: СЕТИ
Радиус сопряжения <50>:  Unknown command "FILLET".  Press F1 for help.
Unknown command "R".  Press F1 for help.
50
AA-2009 eng
вышел из положения подставив точку
._fillet

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Yuriy пишет:

Вот так сюрприз -
Command: СЕТИ
Радиус сопряжения <50>: Unknown command "FILLET". Press F1 for help.
Unknown command "R". Press F1 for help.
50
AA-2009 eng
вышел из положения подставив точку
._fillet

Что это - в AA2009 команда переопределена?

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир Громов,

похоже переопределена

и в AA-2008-eng  тоже

хотя из командной строки вызывается

Command: fillet
Current settings: Mode = Trim, Radius = 0.000
Select first object or [Undo/Polyline/Radius/Trim/Multiple]:
...



но при этом -
Command: (command "_fillet")
_fillet Unknown command "FILLET".  Press F1 for help.




спасает точка

Command: (command "._fillet")
._fillet
Current settings: Mode = TRIM, Radius = 0.000
Select first object or [uNdo/Polyline/Radius/Trim/mUltiple]:
...

(изменено: Владимир Громов, 18 февраля 2009г. 11:42:04)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Действительно, в AA2009 РУС такая же история.

Как же я себя неуютно тут чувствую, в этом новом формате форума.

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир Громов пишет:

Как же я себя неуютно тут чувствую, в этом новом формате форума.

Мы приложим все усилия для создания уюта... но все пожелания по добавлению и исправлению функционала прошу оставлять в специальном разделе.

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Nike, Вариант с отменой (опубликован http://forum.dwg.ru/showpost.php?p=3570 … tcount=18)

;;;********** SETI.LSP ***********************************
;;; Программа отрисовки сети из сопряженных отрезков.
;;; Автор Громов В.В. 2009 г.
;;; Корректировка для опции Отмени (UNDO)
;;; Владимир Азарко (VVA) 
;;; Макрос для загрузки:
;;; ^C^C(if (not C:СЕТИ)(load "seti"));СЕТИ;
;;; ^C^C(if (not C:СЕТИ_ПЛ)(load "seti"));СЕТИ_ПЛ;
;;;
 
(defun C:СЕТИ_ПЛ ()(seti t))
(defun C:СЕТИ ()(seti nil))
(princ "\n Ввести в командной строке СЕТИ_ПЛ или СЕТИ")
(defun seti ( toPline / echo rd pt1 pt2 ent1 ent2 U_M *error* old_FRD eLast ss)
;;;Функция seti - отрисовка сетей
;;; Аргумент toPline = t - собирать в полилинию
;;;          toPline = nil - нет
  (vl-load-com)
  ;;;Объявляем локальную ф-цию *error*
  (defun *error* (msg / image_set)
;;;Прерываем активную команду  
(while (> (getvar "CMDACTIVE") 0)(command))
(princ msg)
(setvar "FILLETRAD" old_FRD)
(setvar "USERS1" "")  ;;;Чистим переменные
(setvar "USERS2" "")  ;;;Чистим переменные
 (princ)
  )
;;;Проверяем установки UNDO и устанавливает All control
  (setq U_M (getvar "UNDOCTL"))
  (cond
    ((= (logand U_M 1) 0)(command "_.UNDO" "_All"))  ;;; Отключено UNDO
    ((= (logand U_M 3) 3)(command "_.UNDO" "_Control" "_All")) ;;; Разрешена отмена одной операции
    (t nil)
  ) ;_ end of cond
(setq U_M (getvar "UNDOMARKS")) ;;;VVA Запоминаем счетчик отмен UNDO
(setq old_FRD  (getvar "FILLETRAD"))
(setvar "USERS1" "")  ;;;Чистим переменные
(setvar "USERS2" "")  ;;;Чистим переменные
(setq echo (getvar "CMDECHO"))
(setvar "CMDECHO" 0)
(if toPline  
;;; Запоминаем в eLast последний примитив
(if (null(setq eLast (entlast)))
    (progn (entmake '((0 . "point") (10 0.0 0.0 0.0)))
       (setq eLast (entlast))(entdel eLast)))
  )
(if (not(numberp *RDS*))(setq *RDS* (getvar "FILLETRAD")))
(princ "\n Радиус сопряжения <")(princ  *RDS*)(princ ">: ")
(if (setq rd (getint))(setq *RDS* rd)(setq rd *RDS*))
(setvar "FILLETRAD" rd)  
(initget 7)
(setq pt1 (getpoint "\n Начальная точка: "))
(initget "Отмени Undo _Undo Undo")
(while (setq pt2 (getpoint pt1 "\nСледующая точка [Отмени] <выход>: "))
  (cond
     ((listp pt2) ;_Указана точка
      ;;;Запоминаем в переменных USERR1 и USERR2 X и Y указанной точки
      ;;;в мировых координатах. Это позволит пользователю прозрачно менять ПСК
      (setvar "USERR1" (car (trans pt1 1 0))) ;;;Запоминаем X точки pt1 в МСК
      (setvar "USERR2" (cadr (trans pt1 1 0)));;;Запоминаем Y точки pt1 в МСК
      (command "_.UNDO" "_M")                 ;;;Ставим метку UNDO
      (command "_.LINE" "_none" pt1 "_none" pt2 "")
      (setvar "USERS1" (getvar "USERS2"))  ;;;Перемещаем метку 2-го примитива в 1-й
      (setvar "USERS2" (cdr(assoc 5 (entget (entlast))))) ;;Метка последнего примитива
      (if (and (setq ent1 (handent (getvar "USERS1")))  ;;; Примитив существует
               (setq ent2 (handent (getvar "USERS2")))  ;;; Примитив существует
               (entget ent1)  ;;; Примитив не удален
               (entget ent2)  ;;; Примитив не удален
               )
        (vl-cmdf "_.FILLET"  ent1 ent2)
 
        ;;;Сопрягаем
        )
      (setq pt1 pt2)
      )
     ((= pt2 "Undo")
      (if (< U_M (getvar "UNDOMARKS")) ;;;Если есть что отменять
        (progn
       (command "_.UNDO" "_B")
       (setq pt1 (list (getvar "USERR1") (getvar "USERR2")))
           (setvar "LASTPOINT" (setq pt1 (trans pt1 0 1)))
          )
        (alert "Отменять больше нечего")
        )
      )
     (t nil)
     )
 (initget "Отмени Undo _Undo Undo")
)
  ;;;Нужно собрать все в полилинию
  (if (and toPline eLast)
    (progn
     (setq ss (ssadd))
     (while (setq  eLast (entnext  eLast))(ssadd  eLast ss))
     (if (= (sslength ss) 0)(setq ss nil)) ;;; Пустой набор
     (if ss ;;;что-то есть
       (if (and (getvar "PEDITACCEPT") (= (getvar "PEDITACCEPT") 1))
         (vl-cmdf "_pedit" "_Multiple" ss "" "_Join" 0 "")
         (vl-cmdf "_pedit" "_Multiple" ss "" "_Y" "_Join" 0 "")
         )
       )
     (setq ss nil)
      )
    )
(setvar "CMDECHO" echo)
(setvar "FILLETRAD" old_FRD)
(princ)
)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир Азарко,
Спасибо!
Кстати, мне кажется, что переменные USERS* нужно вначале запомнить, а затем восстановить.
Я например, ими пользуюсь :)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир Азарко,
Спасибо!
Кстати, мне кажется, что переменные USER* нужно вначале запомнить, а затем восстановить.
Я например, ими пользуюсь :)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир, ну, и здесь скажу тебе спасибо.

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Владимир Азарко,

Опробовал, работает !!!

Заменил только функцию запроса радиуса на (getdist)

Онаружил невозможность отмены завершенной команды за один раз, происходит последовательная отмена каждого шага программы. Подстановка (command "_undo" "_g") и (command "_undo" "_e") помогла, но перестала работать пошаговая отмена. Пришлось убрать  :(

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

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

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Пошаговая отмена в процессе отрисовки, конечно-же важнее.
Но может быть и полная, может быть реализована совместно с пошаговой?

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Nike,,Yuriy, Вроде получилось. Пробуйте.

;;;********** SETI.LSP *********************************** 
;;; Программа отрисовки сети из сопряженных отрезков. 
;;; Автор Громов В.В. 2009 г. 
;;; Корректировка для опции Отмени (UNDO)
;;; 20.02.2009 Восстановление переменных, отмена команды за 1 раз
;;; Владимир Азарко (VVA) 
;;; Макрос для загрузки: 
;;; ^C^C(if (not C:СЕТИ)(load "seti"));СЕТИ; 
;;; ^C^C(if (not C:СЕТИ_ПЛ)(load "seti"));СЕТИ_ПЛ; 
;;; 

(defun C:СЕТИ_ПЛ ()(seti t)) 
(defun C:СЕТИ ()(seti nil)) 
(princ "\n Ввести в командной строке СЕТИ_ПЛ или СЕТИ") 
(defun seti ( toPline / rd pt1 pt2 ent1 ent2 U_M *error* eLast ss usr_list) 
;;;Функция seti - отрисовка сетей 
;;; Аргумент toPline = t - собирать в полилинию 
;;;          toPline = nil - нет 
  (vl-load-com) 
  ;;;Объявляем локальную ф-цию *error* 
  (defun *error* (msg / image_set) 
;;;Прерываем активную команду   
(while (> (getvar "CMDACTIVE") 0)(command)) 
(princ msg) 
(mapcar '(lambda(x)(setvar (car x)(cdr x))) usr_list)
(vla-EndUndoMark (vla-get-activedocument (vlax-get-acad-object)))    
(princ) 
  )
;;;Проверяем установки UNDO и устанавливает All control 
  (setq U_M (getvar "UNDOCTL")) 
  (cond 
    ((= (logand U_M 1) 0)(command "_.UNDO" "_All"))  ;;; Отключено UNDO 
    ((= (logand U_M 3) 3)(command "_.UNDO" "_Control" "_All")) ;;; Разрешена отмена одной операции 
    (t nil) 
  ) ;_ end of cond
(setq usr_list  (mapcar '(lambda(x)(cons x (getvar x))) '("USERR1" "USERR2" "USERS1" "USERS2" "FILLETRAD" "CMDECHO")))
(vla-StartUndoMark (vla-get-activedocument (vlax-get-acad-object)))
;(setq U_M (getvar "UNDOMARKS")) ;;;VVA Запоминаем счетчик отмен UNDO
(setq U_M 0) ;;;VVA Устанавливаем счетчик отмен UNDO  
(setvar "USERS1" "")  ;;;Чистим переменные 
(setvar "USERS2" "")  ;;;Чистим переменные 
(setvar "CMDECHO" 0) 
(if toPline   
;;; Запоминаем в eLast последний примитив 
(if (null(setq eLast (entlast))) 
    (progn (entmake '((0 . "point") (10 0.0 0.0 0.0))) 
       (setq eLast (entlast))(entdel eLast))) 
  ) 
(if (not(numberp *RDS*))(setq *RDS* (getvar "FILLETRAD"))) 
(princ "\n Радиус сопряжения <")(princ  *RDS*)(princ ">: ") 
(if (setq rd (getdist))(setq *RDS* rd)(setq rd *RDS*)) 
(setvar "FILLETRAD" rd)   
(initget 7) 
(setq pt1 (getpoint "\n Начальная точка: ")) 
(initget "Отмени Undo _Undo Undo") 
(while (setq pt2 (getpoint pt1 "\nСледующая точка [Отмени] <выход>: ")) 
  (cond 
     ((listp pt2) ;_Указана точка 
      ;;;Запоминаем в переменных USERR1 и USERR2 X и Y указанной точки 
      ;;;в мировых координатах. Это позволит пользователю прозрачно менять ПСК 
      (setvar "USERR1" (car (trans pt1 1 0))) ;;;Запоминаем X точки pt1 в МСК 
      (setvar "USERR2" (cadr (trans pt1 1 0)));;;Запоминаем Y точки pt1 в МСК 
      (command "_.UNDO" "_M")                 ;;;Ставим метку UNDO 
      (command "_.LINE" "_none" pt1 "_none" pt2 "") 
      (setvar "USERS1" (getvar "USERS2"))  ;;;Перемещаем метку 2-го примитива в 1-й 
      (setvar "USERS2" (cdr(assoc 5 (entget (entlast))))) ;;Метка последнего примитива 
      (if (and (setq ent1 (handent (getvar "USERS1")))  ;;; Примитив существует 
               (setq ent2 (handent (getvar "USERS2")))  ;;; Примитив существует 
               (entget ent1)  ;;; Примитив не удален 
               (entget ent2)  ;;; Примитив не удален 
               ) 
        (vl-cmdf "_.FILLET"  ent1 ent2) 

        ;;;Сопрягаем 
        )
      (setq U_M (1+ U_M)) ;;;VVA
      (setq pt1 pt2) 
      ) 
     ((= pt2 "Undo") 
      (if (> U_M 0) ;;;Если есть что отменять 
        (progn 
       (command "_.UNDO" "_B")
       (setq U_M (1- U_M)) ;;;VVA
       (setq pt1 (list (getvar "USERR1") (getvar "USERR2"))) 
           (setvar "LASTPOINT" (setq pt1 (trans pt1 0 1))) 
          ) 
        (alert "Отменять больше нечего") 
        ) 
      ) 
     (t nil) 
     ) 
(initget "Отмени Undo _Undo Undo") 
) 
  ;;;Нужно собрать все в полилинию 
  (if (and toPline eLast) 
    (progn 
     (setq ss (ssadd)) 
     (while (setq  eLast (entnext  eLast))(ssadd  eLast ss)) 
     (if (= (sslength ss) 0)(setq ss nil)) ;;; Пустой набор 
     (if ss ;;;что-то есть 
       (if (and (getvar "PEDITACCEPT") (= (getvar "PEDITACCEPT") 1)) 
         (vl-cmdf "_pedit" "_Multiple" ss "" "_Join" 0 "") 
         (vl-cmdf "_pedit" "_Multiple" ss "" "_Y" "_Join" 0 "") 
         ) 
       ) 
     (setq ss nil) 
      ) 
    )
(vla-EndUndoMark (vla-get-activedocument (vlax-get-acad-object)))
(mapcar '(lambda(x)(setvar (car x)(cdr x))) usr_list)
(princ) 
)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

> [b]Владимир
Азарко,[/b]

Все работает! 
Спасибо!!!

прочитал фразу

Это позволит пользователю прозрачно менять ПСК


вроде никогда не требовалось просто решил попробовать

Command: СЕТИ_ПЛ
Радиус сопряжения <38394.2>:  Specify second point:
Начальная точка:
Следующая точка [Отмени] <выход>:
Следующая точка [Отмени] <выход>:
Следующая точка [Отмени] <выход>:
Следующая точка [Отмени] <выход>: 'ucs

Point or option keyword required.



Command: line
Specify first point: 'ucs
Invalid point.


Похоже прозрачно менять систему координат не умею (((

(изменено: Владимир Азарко, 4 марта 2009г. 09:50:38)

Re: LISP. Отрисовка произвольной трассы из отрезков и дуг.

Немного не так выразился. В другом месте при отрисовке нужно было менять ПСК по желанию пользователя. Для пользователя это выглядело прозрачно. Чтобы присмене ПСК не потерять точку и хранил ее координаты в МСК с последующим переводом в ПСК