Тема: LISP.Этюд на тему: функция GRREAD и объектная привязка.

Загружать все определения.

; GRREAD-WITH-SNAP.
; Вызов функции: (grread-with-snap "_end").
; Демонстрирует техническую возможность привязки к конечной точке при использовании функции GRREAD.
; Автоматически масштабируемый маркер привязки создается функцией TEMP_END (см ниже).
; При условии наличия функций TEMP_MID, TEMP_INT, TEMP_NEA и т.д, аналогичных функции TEMP_END и умеющих рисовать
; временные маркеры для соответствующих типов привязки, становится возможен вызов функции GRREAD-WITH-SNAP
; с аргументами "_mid", "int", "_nea" и т.д..
(defun grread-with-snap (snt
             /
             acadapp;
             markercolor;
             lst
             pt
             )
  (vl-load-com)
  (setq acadapp (vlax-get-acad-object))
  (setq markercolor (autocolor))
  (princ "\nSelect vertex: ")
  ;
  (while (and (setq lst (grread T 5 2)) (= (car lst) 5))
    (redraw)
    (if (setq pt (osnap (cadr lst) "_end"))
      (apply (read (strcat "temp" snt)) (list pt (autosize 0.1) markercolor))
      (setq pt (cadr lst))
    );
  );
  (redraw)
  pt;
); end defun.
; TEMP_END.
; Рисует вокруг указанной точки временный маркер (квадрат) указанного цвета со сторонами, ориентированными вдоь осей ПСК.
; Возврат: список с координатами точки, вокруг которой отрисован маркер.
(defun temp_end (pt; ПСК координаты точки.
         size; размер стороны маркера в единицах чертежа.
         col; цвет маркера.
         /
         h
         x y z;
         xmax ymax xmin ymin;
         )
  (setq h (/ size 2.0) x (car pt) y (cadr pt) z (caddr pt) xmin (- x h) ymin (- y h) xmax (+ x h) ymax (+ y h))
  (grdraw (list xmin ymax z) (list xmax ymax z) col)
  (grdraw (list xmax ymax z) (list xmax ymin z) col)
  (grdraw (list xmax ymin z) (list xmin ymin z) col)
  (grdraw (list xmin ymin z) (list xmin ymax z) col)
  pt;
); end defun.
; AUTOSIZE.
; Вычисляет размер маркера, масштабируемый с учетом высоты текущего ВЭ.
(defun autosize (size; условный размер (подбирается экспериментально).
         ; ACADAPP
         /
         asmsize
         )
  (setq asmsize (vlax-get-property (vlax-get-property (vlax-get-property ACADAPP 'preferences) 'drafting) 'autosnapmarkersize))
  (* size (/ (getvar 'viewsize) asmsize))
); end defun.
; AUTOCOLOR.
; Вычисляет текущий цвет маркеров автопривязки.
(defun autocolor (;|ACADAPP|;)
  (vlax-get-property (vlax-get-property (vlax-get-property ACADAPP 'preferences) 'drafting) 'autosnapmarkercolor)
); end defun.
; *** EOF ***

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

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

(defun menu-pop500 (d / lst p s)
  ; Choice function of OSNAP through the shortcut menu.
  ; Only, as an example.
  ; Is checked up in AutoCad 2004-2007 (En)
  ; by ElpanovEvgeniy
  ; (2006-10-11)
  ; (menu-pop500 (grread t 5))
  (setq
    lst (reverse
          (menu-index
            ((lambda (x) (list (1- (vla-get-count x)) x))
              (vla-item
                (vla-get-menus
                  (vla-item
                    (vla-get-menugroups
                      (vlax-get-acad-object)
                    ) ;_  vla-get-MenuGroups
                    "ACAD"
                  ) ;_  vla-item
                ) ;_  vla-get-Menus
                "&Object Snap Cursor Menu"
                ;|
 " *Object Snap Cursor Menu "
For localization into other languages, it is possible to use function bu kpblc
(cond
  ((vl-string-search "419" (setq p(vlax-product-key)))
    ;; The Russian version
   "&Контекстное меню привязки")
  ((vl-string-search "409" p)
   ;; The English version
    "&Object Snap Cursor Menu"
    ))
|;
              ) ;_  vla-item
            )
          ) ;_  menu-index
        ) ;_  reverse
  ) ;_  setq
  (while (and
           (listp d)
           (or (= (car d) 5)
               (= (car d) 11)
               (= (car d) 12)
               (= (car d) 25) ; For old version AutoCad
           ) ;_  or
         ) ;_  and
    (cond
      ((= (car d) 25) (menucmd "POP500=*")) ; For old version AutoCad
      ((equal d '(11 0)) (menucmd "POP500=*"))
      ((= (car d) 11) (setq s (nth (- (cadr d) 500) lst)))
    ) ;_  cond
    (if s
      (setq d s)
      (setq d (grread t 5))
    ) ;_  if
  ) ;_  while
  (substr s 1 4)
) ;_  defun
(defun menu-index (l)
  ; Creation of the list of choices of choice of OSNAP
  ; Is checked up in AutoCad 2004-2007 (En)
  ; by ElpanovEvgeniy
  ; (2006-10-11)
                  ;|
(menu-index
 ((lambda (x) (list (1-(vla-get-count x)) x))
  (vla-item
   (vla-get-menus
    (vla-item
     (vla-get-menugroups
      (vlax-get-acad-object)
      ) ;_  vla-get-MenuGroups
     "ACAD"
     ) ;_  vla-item
    ) ;_  vla-get-Menus
   "&Object Snap Cursor Menu"
   ) ;_  vla-item
  )
 ) ;_  menu-index
 |;
  (if (not (minusp (car l)))
    (cond
      ((= (vla-get-type (vla-item (cadr l) (car l))) 0)
       (cons
         (vla-get-macro (vla-item (cadr l) (car l)))
         (menu-index (cons (1- (car l)) (cdr l)))
       ) ;_  cons
      )
      ((= (vla-get-type (vla-item (cadr l) (car l))) 1)
       (menu-index (cons (1- (car l)) (cdr l)))
      )
      ((= (vla-get-type (vla-item (cadr l) (car l))) 2)
       (append
         (menu-index
           ((lambda (x) (list (1- (vla-get-count x)) x))
             (vla-get-submenu (vla-item (cadr l) (car l)))
           ) ;_  menu-index
         ) ;_  menu-index
         (menu-index (cons (1- (car l)) (cdr l)))
       ) ;_  append
      )
    ) ;_  cond
  ) ;_  if
) ;_  defun
(defun get_osmode nil
  ; Function create list osmode macro
  ; for result (getvar "OSMODE")
  ; by Evgeniy Elpanov
  ; (get_osmode)
  (mapcar
    (function cdr)
    (vl-remove-if
      (function
        (lambda (x)
          (zerop (logand (getvar "OSMODE") (car x)))
        ) ;_  lambda
      ) ;_  function
      '((1 . "_end")
        (2 . "_mid")
        (4 . "_cen")
        (8 . "_nod")
        (16 . "_qua")
        (32 . "_int")
        (64 . "_ins")
        (128 . "_per")
        (256 . "_tan")
        (512 . "_nea")
  ;(1024 . "_qui") ; Is not realized
        (2048 . "_app")
  ;(4096 . "_ext") ; Is not realized
  ;(8192 . "_par") ; Is not realized
       )
    ) ;_  substr
  ) ;_  mapcar
) ;_  defun
(defun osmode-grvecs-lst (/ -ASS ASS COL)
  ; Function create list
  ; for drawing icons osmode with the function grvecs
  ; by Evgeniy Elpanov
  ; (osmode-grvecs-lst)
  (setq
    col  (atoi (getenv "AutoSnapColor"))
    ass  (atof (getenv "AutoSnapSize"))
    -ass (- ass)
  ) ;_  setq
  (list
    (list
      "tracking"
      col
      (list (* -ass 0.2) 0.)
      (list (* ass 0.2) 0.)
      col
      (list 0. (* -ass 0.2))
      (list 0. (* ass 0.2))
    ) ;_  list
    (list
      "_end"
      col
      (list -ass -ass)
      (list -ass ass)
      col
      (list (1- -ass) (1- -ass))
      (list (1- -ass) (1+ ass))
      col
      (list -ass ass)
      (list ass ass)
      col
      (list (1- -ass) (1+ ass))
      (list (1+ ass) (1+ ass))
      col
      (list ass ass)
      (list ass -ass)
      col
      (list (1+ ass) (1+ ass))
      (list (1+ ass) (1- -ass))
      col
      (list ass -ass)
      (list -ass -ass)
      col
      (list (1+ ass) (1- -ass))
      (list (1- -ass) (1- -ass))
    ) ;_  list
    (list
      "_mid"
      col
      (list -ass -ass)
      (list 0. ass)
      col
      (list (1- -ass) (1- -ass))
      (list 0. (1+ ass))
      col
      (list 0. ass)
      (list ass -ass)
      col
      (list 0. (1+ ass))
      (list (1+ ass) (1- -ass))
      col
      (list ass -ass)
      (list -ass -ass)
      col
      (list (1+ ass) (1- -ass))
      (list (1- -ass) (1- -ass))
    ) ;_  list
    (list
      "_cen"
      7
      (list (* -ass 0.2) 0.)
      (list (* ass 0.2) 0.)
      7
      (list 0. (* -ass 0.2))
      (list 0. (* ass 0.2))
      col
      (list -ass 0.)
      (list (* -ass 0.86) (* ass 0.5))
      col
      (list (* -ass 0.86) (* ass 0.5))
      (list (* -ass 0.5) (* ass 0.86))
      col
      (list (* -ass 0.5) (* ass 0.86))
      (list 0. ass)
      col
      (list 0. ass)
      (list (* ass 0.5) (* ass 0.86))
      col
      (list (* ass 0.5) (* ass 0.86))
      (list (* ass 0.86) (* ass 0.5))
      col
      (list (* ass 0.86) (* ass 0.5))
      (list ass 0.)
      col
      (list ass 0.)
      (list (* ass 0.86) (* -ass 0.5))
      col
      (list (* ass 0.86) (* -ass 0.5))
      (list (* ass 0.5) (* -ass 0.86))
      col
      (list (* ass 0.5) (* -ass 0.86))
      (list 0. -ass)
      col
      (list 0. -ass)
      (list (* -ass 0.5) (* -ass 0.86))
      col
      (list (* -ass 0.5) (* -ass 0.86))
      (list (* -ass 0.86) (* -ass 0.5))
      col
      (list (* -ass 0.86) (* -ass 0.5))
      (list -ass 0.)
    ) ;_  list
    (list
      "_nod"
      col
      (list -ass -ass)
      (list ass ass)
      col
      (list -ass ass)
      (list ass -ass)
      col
      (list -ass 0.)
      (list (* -ass 0.86) (* ass 0.5))
      col
      (list (* -ass 0.86) (* ass 0.5))
      (list (* -ass 0.5) (* ass 0.86))
      col
      (list (* -ass 0.5) (* ass 0.86))
      (list 0. ass)
      col
      (list 0. ass)
      (list (* ass 0.5) (* ass 0.86))
      col
      (list (* ass 0.5) (* ass 0.86))
      (list (* ass 0.86) (* ass 0.5))
      col
      (list (* ass 0.86) (* ass 0.5))
      (list ass 0.)
      col
      (list ass 0.)
      (list (* ass 0.86) (* -ass 0.5))
      col
      (list (* ass 0.86) (* -ass 0.5))
      (list (* ass 0.5) (* -ass 0.86))
      col
      (list (* ass 0.5) (* -ass 0.86))
      (list 0. -ass)
      col
      (list 0. -ass)
      (list (* -ass 0.5) (* -ass 0.86))
      col
      (list (* -ass 0.5) (* -ass 0.86))
      (list (* -ass 0.86) (* -ass 0.5))
      col
      (list (* -ass 0.86) (* -ass 0.5))
      (list -ass 0.)
    ) ;_  list
    (list
      "_qua"
      col
      (list 0. -ass)
      (list -ass 0.)
      col
      (list 0. (1- -ass))
      (list (1- -ass) 0.)
      col
      (list -ass 0.)
      (list 0. ass)
      col
      (list (1- -ass) 0.)
      (list 0. (1+ ass))
      col
      (list 0. ass)
      (list ass 0.)
      col
      (list 0. (1+ ass))
      (list (1+ ass) 0.)
      col
      (list ass 0.)
      (list 0. -ass)
      col
      (list (1+ ass) 0.)
      (list 0. (1- -ass))
    ) ;_  list
    (list
      "_int"
      col
      (list -ass -ass)
      (list ass ass)
      col
      (list -ass (1+ -ass))
      (list ass (1+ ass))
      col
      (list (1+ -ass) -ass)
      (list (1+ ass) ass)
      col
      (list -ass ass)
      (list ass -ass)
      col
      (list -ass (1+ ass))
      (list ass (1+ -ass))
      col
      (list (1+ -ass) ass)
      (list (1+ ass) -ass)
    ) ;_  list
    (list
      "_ins"
      col
      (list (* -ass 0.1) (* -ass 0.1))
      (list -ass (* -ass 0.1))
      col
      (list -ass (* -ass 0.1))
      (list -ass ass)
      col
      (list -ass ass)
      (list (* ass 0.1) ass)
      col
      (list (* ass 0.1) ass)
      (list (* ass 0.1) (* ass 0.1))
      col
      (list (* ass 0.1) (* ass 0.1))
      (list ass (* ass 0.1))
      col
      (list ass (* ass 0.1))
      (list ass -ass)
      col
      (list ass -ass)
      (list (* -ass 0.1) -ass)
      col
      (list (* -ass 0.1) -ass)
      (list (* -ass 0.1) (* -ass 0.1))
      col
      (list (1- (* -ass 0.1)) (1- (* -ass 0.1)))
      (list (1- -ass) (1- (* -ass 0.1)))
      col
      (list (1- -ass) (1- (* -ass 0.1)))
      (list (1- -ass) (1+ ass))
      col
      (list (1- -ass) (1+ ass))
      (list (1+ (* ass 0.1)) (1+ ass))
      col
      (list (1+ (* ass 0.1)) (1+ ass))
      (list (1+ (* ass 0.1)) (1+ (* ass 0.1)))
      col
      (list (1+ (* ass 0.1)) (1+ (* ass 0.1)))
      (list (1+ ass) (1+ (* ass 0.1)))
      col
      (list (1+ ass) (1+ (* ass 0.1)))
      (list (1+ ass) (1- -ass))
      col
      (list (1+ ass) (1- -ass))
      (list (1- (* -ass 0.1)) (1- -ass))
      col
      (list (1- (* -ass 0.1)) (1- -ass))
      (list (1- (* -ass 0.1)) (1- (* -ass 0.1)))
    ) ;_  list
    (list
      "_tan"
      col
      (list -ass ass)
      (list ass ass)
      col
      (list (1- -ass) (1+ ass))
      (list (1+ ass) (1+ ass))
      col
      (list -ass 0.)
      (list (* -ass 0.86) (* ass 0.5))
      col
      (list (* -ass 0.86) (* ass 0.5))
      (list (* -ass 0.5) (* ass 0.86))
      col
      (list (* -ass 0.5) (* ass 0.86))
      (list 0. ass)
      col
      (list 0. ass)
      (list (* ass 0.5) (* ass 0.86))
      col
      (list (* ass 0.5) (* ass 0.86))
      (list (* ass 0.86) (* ass 0.5))
      col
      (list (* ass 0.86) (* ass 0.5))
      (list ass 0.)
      col
      (list ass 0.)
      (list (* ass 0.86) (* -ass 0.5))
      col
      (list (* ass 0.86) (* -ass 0.5))
      (list (* ass 0.5) (* -ass 0.86))
      col
      (list (* ass 0.5) (* -ass 0.86))
      (list 0. -ass)
      col
      (list 0. -ass)
      (list (* -ass 0.5) (* -ass 0.86))
      col
      (list (* -ass 0.5) (* -ass 0.86))
      (list (* -ass 0.86) (* -ass 0.5))
      col
      (list (* -ass 0.86) (* -ass 0.5))
      (list -ass 0.)
    ) ;_  list
    (list
      "_per"
      col
      (list -ass -ass)
      (list -ass ass)
      col
      (list (1- -ass) (1- -ass))
      (list (1- -ass) (1+ ass))
      col
      (list ass -ass)
      (list -ass -ass)
      col
      (list (1+ ass) (1- -ass))
      (list (1- -ass) (1- -ass))
      col
      (list -ass 0.)
      (list 0. 0.)
      col
      (list -ass -1.)
      (list 0. -1.)
      col
      (list 0. 0.)
      (list 0. -ass)
      col
      (list -1. 0.)
      (list -1. -ass)
    ) ;_  list
    (list
      "_nea"
      col
      (list -ass -ass)
      (list ass ass)
      col
      (list -ass ass)
      (list ass ass)
      col
      (list (1- -ass) (1+ ass))
      (list (1+ ass) (1+ ass))
      col
      (list -ass ass)
      (list ass -ass)
      col
      (list ass -ass)
      (list -ass -ass)
      col
      (list (1+ ass) (1- -ass))
      (list (1- -ass) (1- -ass))
    ) ;_  list
    (list
      "_app"
      col
      (list -ass -ass)
      (list ass ass)
      col
      (list ass -ass)
      (list -ass ass)
      col
      (list -ass -ass)
      (list -ass ass)
      col
      (list (1- -ass) (1- -ass))
      (list (1- -ass) (1+ ass))
      col
      (list -ass ass)
      (list ass ass)
      col
      (list (1- -ass) (1+ ass))
      (list (1+ ass) (1+ ass))
      col
      (list ass ass)
      (list ass -ass)
      col
      (list (1+ ass) (1+ ass))
      (list (1+ ass) (1- -ass))
      col
      (list ass -ass)
      (list -ass -ass)
      col
      (list (1+ ass) (1- -ass))
      (list (1- -ass) (1- -ass))
    ) ;_  list
    ;; Is not realized
    ;;    (list
    ;;    "_par"
    ;;      col
    ;;      (list (* -ass 0.8) -ass)
    ;;      (list ass (* ass 0.8))
    ;;      col
    ;;      (list -ass (* -ass 0.8))
    ;;      (list (* ass 0.8) ass)
    ;;    )
  ) ;_  list
) ;_  defun
(defun c:test (/ GR O OSM-LST OSMODE S TP)
  ; Example drawing icons osmode with
  ; Return point, for osmode
  ; by Evgeniy Elpanov
  ; (c:test)
  (setq osm-lst (osmode-grvecs-lst)
        osmode  (get_osmode)
  ) ;_  setq
  (while (or (= (car (setq gr (grread nil 5 0))) 5)
             (= (car gr) 11)
             (= (car gr) 25) ; For old version AutoCad
         ) ;_  or
    (if (or (= (car gr) 11)
            (= (car gr) 25)
        ) ;_  or
      (setq osmode (list (menu-pop500 gr)))
      (progn
        (if (setq
              o (vl-remove-if
                  (function null)
                  (mapcar
                    (function
                      (lambda (x / o)
                        (if (setq o (osnap (cadr gr) x))
                          (list (distance (cadr gr) o) o x (cadr gr))
                        ) ;_  if
                      ) ;_  lambda
                    ) ;_  function
                    osmode
                  ) ;_  mapcar
                ) ;_  vl-remove-if
            ) ;_  setq
          (setq
            o (cdar
                (vl-sort
                  o
                  (function
                    (lambda (a b)
                      (< (car a) (car b))
                    ) ;_  lambda
                  ) ;_  function
                ) ;_  vl-sort
              ) ;_  cdar
          ) ;_  setq
        ) ;_  if
        (setq s (/ (getvar "viewsize") (cadr (getvar "SCREENSIZE"))))
        (cond
          ((not o))
          ((WCMATCH (cadr o) "_end,_mid,_cen,_nod,_int,_ins")
           (setq tp (car o))
           (setvar "lastpoint" tp)
           (setq o (cons (trans (car o) 1 3) (cdr o)))
           (redraw)
           (grvecs
             (cdr (assoc "tracking" osm-lst))
             (list (list s 0. 0. (caar o))
                   (list 0. s 0. (cadar o))
                   (list 0. 0. s 0.)
                   '(0. 0. 0. 1.)
             ) ;_  list
           ) ;_  grvecs
           (grvecs
             (cdr (assoc (cadr o) osm-lst))
             (list (list s 0. 0. (caar o))
                   (list 0. s 0. (cadar o))
                   (list 0. 0. s 0.)
                   '(0. 0. 0. 1.)
             ) ;_  list
           ) ;_  grvecs
          )
          ((WCMATCH (cadr o) "_nea,_qua,_app")
           (setq o (cons (trans (car o) 1 3) (cdr o)))
           (redraw)
           (grvecs
             (cdr (assoc (cadr o) osm-lst))
             (list (list s 0. 0. (caar o))
                   (list 0. s 0. (cadar o))
                   (list 0. 0. s 0.)
                   '(0. 0. 0. 1.)
             ) ;_  list
           ) ;_  grvecs
          )
          ((and tp (not (equal tp (car o) 1e-8)))
           (redraw)
           (grdraw (car o) tp 7 1)
           (setq o (cons (trans (car o) 1 3) (cdr o)))
           (grvecs
             (cdr (assoc (cadr o) osm-lst))
             (list (list s 0. 0. (caar o))
                   (list 0. s 0. (cadar o))
                   (list 0. 0. s 0.)
                   '(0. 0. 0. 1.)
             ) ;_  list
           ) ;_  grvecs
          )
        ) ;_  cond
        (if tp
          (grvecs
            (cdr (assoc "tracking" osm-lst))
            (list (list s 0. 0. (car (trans tp 1 3)))
                  (list 0. s 0. (cadr (trans tp 1 3)))
                  (list 0. 0. s 0.)
                  '(0. 0. 0. 1.)
            ) ;_  list
          ) ;_  grvecs
        ) ;_  if
      ) ;_  progn
    ) ;_  if
  ) ;_  while
  (redraw)
  (if o
    (osnap (caddr o) (cadr o))
    (cadr gr)
  ) ;_  if
) ;_  defun

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

Проверил свою программу на акаде 2008 - по правой кнопке мыши выскакивает стандартное меню, вместо меню выбора привязок...
Сейчас нет времени править, на более ранних версиях все работает (если у кого то есть время и желание - я не возражаю). Для проверки и демонстрации используйте команду test в автокаде.

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

> >Пастух
Красивый этюд!

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

> Евгений Елпанов
Глюк с меню проявляется и в 2006 акаде. Если до запуска вашей функции было вызвано любое контекстное меню, то в вашей программе будет отображаться именно оно, если вызвать до запуска контекстное меню с привязками, то в программе все будет отображаться как надо.
Интересно узнать победили ли вы этот глюк и если да, то каким образом?

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

> Donhuan
Задачи, которые я решал, при написании этого кода, были решены. Весь код - демонстрация возможности использования привязок, совместно с grread. Контекстное меню, легко организовать, добавив свой раздел в файл меню, подобно экспрессам.
ps. Завершать, этот демонстрационный код, нет никакого желания.

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

Вроде нашел решение:
- в начале функции вставить (для нелокализованной версии):

(menucmd "P0=SNAP")

- вызов меню производить:

(menucmd "P0=*")

вместо

(menucmd "POP500=*")

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

> Donhuan
это решение, только для конкретной версии.
Универсального решения, я не могу предложить...

Re: LISP.Этюд на тему: функция GRREAD и объектная привязка.

Если брать в расчет только контекстное меню привязок, то можно и так:

(menucmd "P0=POP0")
(menucmd "P0=*")

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

(menucmd "P0=псевдоним_меню")
(menucmd "P0=*")

Хуже то, что у vla-объектов нет свойства "псевдоним", а имена меню локализации как раз подверглись. В общем, чтобы чувсвовать себя уверенно, надо иметь таблицу соответствий псевдонимов и имен меню всех версий AutoCAD, в которых должна работать программа. Если пользоваться только своими меню, то это вообще не проблема.