TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Alexander Rivilis on March 17, 2006, 12:26:27 PM

Title: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 17, 2006, 12:26:27 PM
That is my small contribution for lisp-programmers. :)
I hope this function will be useful:
Code: [Select]
;;
;; Alexander Rivilis, DynDraw\DynDraw.lsp
;; For book N.Poleshchuk.
;; "AutoCAD: Application Development, Tuning and Customization" 2006
;;
;;--------------------------------------------------------------------
;;                           (DynDraw)
;;--------------------------------------------------------------------
;;
;; Call:
;;  (dyndraw
;;    <call_back>      - name of callback-function (STR)
;;    <input_prompt>   - prompt string (STR)
;;    <keyword_list>   - keyword string (as initget-string) (STR)
;;    <input_flag>     - input parameters flag (INT)
;;    <cursor_type>    - type of cursor (INT)       
;;    <base_point>     - base point or nil
;;  )
;;
;; Parameters and its value:
;;
;;  1) <call_back>
;;     String with name of callback-function. Function *MUST* be registered
;;     with help of: (vl-acad-defun '<call_back>)
;;     
;;     This function has only one parameter. Depending on <input_flag>
;;     its can be:
;;     1) (X Y Z)      - point,    if <input_flag> is acqurePoint
;;     2) REAL         - distance, if <input_flag> is acqureDist
;;     3) REAL         - angle,    if <input_flag> is acqureAngle
;;     4) STR          - keyword   if <keyword_list> is not empty
;;                       other string - if <input_flag> is AcceptOtherInputString
;;
;;     Function *MUST* return one of values:
;;     1) nil          - exit;
;;     2) (X Y Z)      - point - change current point;
;;     3) (list ...)   - list - as list of dyndraw-finction
;;                       for changing all parameters;
;;                       параметров;
;;     4) STR          - for exit and returning STR;
;;     5) T            - for continue without changing;
;;                     
;;  2) <input_prompt>
;;     Simple prompt as for all getXXXX - functions.
;;
;;  3) <keyword_list> 
;;     String of keywords, as for (initget) function;
;;
;;  4) <input_flag>   
;;     Input flag - mast be the sum of one or more  of next values
;;     
;;
;;     GovernedByOrthoMode             1
;;     NullResponseAccepted            2
;;     DontEchoCancelForCtrlC          4
;;     DontUpdateLastPoint             8
;;     NoDwgLimitsChecking            16
;;     NoZeroResponseAccepted         32
;;     NoNegativeResponseAccepted     64
;;     Accept3dCoordinates           128
;;     AcceptMouseUpAsPoint          256
;;     AnyBlankTerminatesInput       512
;;     InitialBlankTerminatesInput  1024
;;     AcceptOtherInputString       2048
;;
;;     and only one of next value:
;;
;;     acqurePoint        0  -  return point;
;;                           
;;     acqureDist      8192  -  return distance;
;;       
;;     acqureAngle    16384  -  return angle;
;;                             
;;
;;  5) <cursor_type>
;;     Type of cursor (INT) - one of next values:
;;     NoSpecialCursor      -1      No special cursor specified
;;     Crosshair             0      Full screen cross hair
;;     RectCursor            1      Rectangular cursor
;;     RubberBand            2      Rubber band line
;;     NotRotated            3      (AutoCAD internal use only)
;;     TargetBox             4      Target Box type
;;     RotatedCrosshair      5      (AutoCAD internal use only)
;;     CrossHairNoRotate     6      Crosshairs forced non-rotated
;;     Invisible             7      Invisible cursor
;;     EntitySelect          8      Entity selection target cursor
;;     Parallelogram         9      Parallelogram cursor
;;     EntitySelectNoPersp  10      Pickbox, suppressed in persp
;;     PkfirstOrGrips       11      Auto-select cursor
;;
;;  6) <base_point>
;;     Base point or nil - for current cursor position.
;;
;; Function return one of next values:
;;     1) (X Y Z)      - point,    if <input_flag> is acqurePoint
;;     2) REAL         - distance, if <input_flag> is acqureDist
;;     3) REAL         - angle,    if <input_flag> is acqureAngle
;;     4) STR          - string,   from callback-function
;;     5) nil          - user abort
;;
;;The Particularities of the use and remarks:
;; 1) callback-function may not use interactive functions in all cases except
;;    it parameter is string (keyword)
;; 2) If this function is using for dynamic redrawing of database resident entities
;;    then in callback-function these entities must be updating with (entupd) or
;;    (vla-Update).
;; 3) If you using (grdraw) and/or (grvecs),
;;    you do not forget calling (redraw) for refreshing graphic window.
;;--------------------------------------------------------------------

;;--------------------------------------------------------------------
;;      Testing program for DynDraw
;;--------------------------------------------------------------------
(defun C:DYN_TEST ( / p_prev p_base p min_step
                      ang dist p1 p2 p3 _bm _ce
                  )
  ;; Minimal distance between points
  (setq min_step 1e-6)
  (if (null dyndraw) (progn
    (arxload "dyndraw.arx")
  )) ;_endof if progn
  ;;
  (setq _bm (getvar "blipmode") _ce (getvar "cmdecho"))
  (setvar "blipmode" 0) (setvar "cmdecho" 0)
  ;; Registering callback-function
  (vl-acad-defun 'dyn_call_back)
  (setq p (getvar "LASTPOINT"))
 
  (while
    (and dyndraw p (/= (type p) 'STR)
         (= (type (setq p (getpoint "\nBase point (ENTER - exit): "))) 'LIST))
    (setq p_base p p_prev p)
    (setq p
      (dyndraw
         ;; Name of callback - finction
         "dyn_call_back"
         ;; Prompt string
         "\nSelect point [Base point]: "
         ;; Keyword string
         "B _ B"   
         ;; Input flag
         (+ 2 128 2048) ;; Allow entering empty and 3D-points
         ;; Cursor type
         2 ;;  RubberBand
         ;; Base point (in UCS)
         p
      )
    )
    (redraw)
   
    (if (= (type p) 'LIST) (progn
      ;; Adding to databse
      (setq ang   (angle p_base p)
            dist  (* (distance p_base p) (sqrt 2))
            p1    (polar p (+ ang (* pi 0.75)) dist)
            p2    (polar p1 (+ ang (* pi 1.25)) dist)
            p3    (polar p2 (+ ang (* pi 1.75)) dist)
      )
      (command "_.undo" "_begin")
      (command "_.pline" "_none" p "_w" 0 0 "_none" p1  "_none" p2  "_none" p3 "_c")
      (command "_.undo" "_end")
    )) ;_endof if progn
  ) ;_endof while
  (if (= (type p) 'STR)
    (princ (strcat "\nUser input string: <" p ">"))
  )

  (setvar "blipmode" _bm) (setvar "cmdecho" _ce)
  (princ)
) ;_endof defun
;;--------------------------------------------------------------------
;;               Example of callback function
;;--------------------------------------------------------------------
(defun dyn_call_back (p / p1 p2 p3)
 (cond
  ((= (type p) 'STR) ;; User select a keyword
    (redraw) ;; Clear screen
    (cond
     ((= p "B") ;; User want to change base point
      (if (setq p (getpoint p_base "\nSelect new base point: "))
        (setq p_base p
              p  (list
                  "dyn_call_back"
                  "\nSelect new point: "
                  "" ;; No keywords
                  (+ 2 128 2048) ;; Allow entering empty and 3D-points
                  2 ; RubberBand
                  p
                 )
         )
      )
     )
     (T
      ;; Return this string
      (princ (strcat "\nUnknown keyword <" p ">!!!"))
     )
    ) ;_endof cond
  )
  ((= (type p) 'LIST) ;; Dragging with point
    (if (null p_base) (setq p_base p p_prev p))
    (if (and p_prev (> (distance p_prev p) min_step)) (progn
      (setq p_prev p)
      (setq input p
            ang   (angle p_base p)
            dist  (* (distance p_base input) (sqrt 2))
            p1    (polar input (+ ang (* pi 0.75)) dist)
            p2    (polar p1 (+ ang (* pi 1.25)) dist)
            p3    (polar p2 (+ ang (* pi 1.75)) dist)
       )
       (redraw) ;; Clear screen
       (grdraw input p1 -1)
       (grdraw p1 p2 -1)
       (grdraw p2 p3 -1)
       (grdraw p3 input -1)
    ))
  )
 ) ;_endof cond
 p
) ;_endof defun

Last version: http://www.maestrogroup.com.ua/support/dyndraw.zip
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Kerry on March 17, 2006, 06:22:16 PM
Hi Alexander,
Interesting code !

Is the ARX for AC2004, 05 and 06 ?
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 18, 2006, 04:01:21 AM
Hi Alexander,
Interesting code !
Is the ARX for AC2004, 05 and 06 ?
Yes. :) This code is only example of using dyndraw-function.
With help of (grread) we can not using menu, object snap, etc.
With (dyndraw) we can use all above. 
P.S.: I've reattached arx file for AutoCAD 2002 and AutoCAD 2004...2006


Title: Re: Dynamic drawing and substitution of grread-function
Post by: zoltan on March 25, 2006, 09:16:43 AM
This is a really awesome piece of work.   I was working on something like this using GrRead, but It could not do the OSNAPS and menues like this.

My question:
If the callback function trows an error, how do you stop the DynDraw function for contiuing to call the callback function?
I can't put a breakpoint in the callback function to trace it.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 25, 2006, 10:18:20 AM
If the callback function trows an error, how do you stop the DynDraw function for contiuing to call the callback function?
I can't put a breakpoint in the callback function to trace it.
Oh! It is very difficult question. Callback-function must be error-free because error in it may crash AutoCAD.
As I think you can not trace this function - it was called from ObjectARX application with worldDraw() method of custom class and debuger can not provide tracing of such type of function.
Try to catch errors with help of (vl-catch-all-apply ...) function.

If callback-function return Nil - DYNDRAW stop calling callback-function end also exit with Nil value.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: zoltan on March 25, 2006, 11:23:46 AM
Thank you.  I quess I just have to make sure that the call-back function works.

Can you explain in detail all of the input flags? (at least the not-so-obvious ones)

Does AnyBlankTerminatesInput have to be set in order for the callback function to end the loop by reterning nil?
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 25, 2006, 11:51:40 AM
Can you explain in detail all of the input flags? (at least the not-so-obvious ones)
It will be a hard work! :)
Does AnyBlankTerminatesInput have to be set in order for the callback function to end the loop by reterning nil?
No! AnyBlankTerminatesInput - this flag mean that if user press blank - input of string is terminated.
Sush as (getstring) do it.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: zoltan on March 26, 2006, 08:44:35 AM
When the user hits escape at the prompt for a point, the DynDraw function ends and returns nil to the calling function.  At this point the top level program should exit because the user canceled the command.  If the user hits enter or space bar at the prompt to accept a default value, the DynDraw function exits and returns nil to the calling function.  Is there a way to differentiate between the two?

Could you make the DynDraw function accept a default value as a parameter, so if the user hits Enter or Space at the prompt, the DynDraw function will return the default value and if the user hits Escape to cancel the function, the DynDraw function exits and returns nil?

I have a callback function which when given a point, draws information to the screen.  When the callback function receives a string as an option keyword, much like you example, the user is asked to enter values for the input instead of picking a point on screen.  At this point the callback function returns nil so the DynDraw function will exit.  I have multiple options for the user to enter data that will end the DynDraw loop.  I need to be able to differentiate between their outputs.

If the call-back function returns nil, the DynDraw function should return the last value of the call-back functions parameter, so the main calling function can determine which option keyword ended the DynDraw loop.


Also, what do you think would be causing my use of the DynDraw function to not end when my call-back function returns nil?
I am using input flags 2 32 64.

Thanks in advance,
Zoltan
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 27, 2006, 11:00:01 AM
First of all I've reattached dyndraw.zip! Try new dyndraw.arx
When the user hits escape at the prompt for a point, the DynDraw function ends and returns nil to the calling function.  At this point the top level program should exit because the user canceled the command.  If the user hits enter or space bar at the prompt to accept a default value, the DynDraw function exits and returns nil to the calling function.  Is there a way to differentiate between the two?
Now if NullResponseAccepted or AcceptOtherInputString adding to <input_flag>, and you press Enter or blank - callback-function will be called with empty string (""), if escape - DynDraw return with nil.
Could you make the DynDraw function accept a default value as a parameter, so if the user hits Enter or Space at the prompt, the DynDraw function will return the default value and if the user hits Escape to cancel the function, the DynDraw function exits and returns nil?
I don't like adding new parameter to DynDraw. More simplest way is check parameter in callback function and if it is equal "" - use default value.

If the call-back function returns nil, the DynDraw function should return the last value of the call-back functions parameter, so the main calling function can determine which option keyword ended the DynDraw loop.
What about to try in callback-function save last value in *global* variable? :)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: zoltan on March 27, 2006, 11:19:56 AM
Thanks for the update. I will try it.

Is the ARX you reattached the 2002 or 2006 version?
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 27, 2006, 01:24:14 PM
Is the ARX you reattached the 2002 or 2006 version?
I've reattached both versions.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on April 01, 2006, 03:40:16 PM
I've done some modification of dyndraw and re-post it in first message of this topic.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on April 04, 2006, 06:26:57 AM
New modifications and bugfixes (with help of Evgeniy Elpanov):
1) When error occur in callback-function dyndraw exit with nil value.
2) Debugger can debug callback-function.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: CAB on April 04, 2006, 08:42:01 AM
Thanks for sharing this routine Rivilis. :-)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on April 04, 2006, 08:52:00 AM
Thanks fopr sharing this routine Rivilis. :-)
I very hope this routine will be usefull for advanced VisualLisp programmers. :)
Next modification will be adoptation for AutoCAD 2007 - Done!
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Pepe on March 06, 2008, 02:02:29 PM
Hi Alexander!

A useful program, Dyndraw  :-)! Thank you for writing it.

I'm trying to write my first program using Dyndraw, and I found my first problem using the <input_flag>  1, "GovernedByOrthoMode".

Here's the code I wrote where i found the problem. It only draws a "elastic" red rectangle, nothing else.

When I use "ORTHOMODE" the rectangle doesn't follow the ortho directions. It only works using  <cursor_type> 1, "RectCursor" or 2, "RubberBand".

Is that a bug or I did anything wrong?

Code: [Select]
(defun grv (qb / an pa pb pc pd pm)
  (if lv (grvecs (subst 0 1 lv)))
  (setq pm (/ pi 2)
an (angle qa qb)
pa (polar qa (+ an pm) 0.25)
pb (polar qb (+ an pm) 0.25)
pc (polar qb (- an pm) 0.25)
pd (polar qa (- an pm) 0.25)
lv (list 1 pa pb 1 pb pc 1 pc pd 1 pd pa)
)
  (grvecs lv)
  qb
  )

(defun C:BLCK (/ lv qa qb)
  (arxload "dyndraw2004")
  (vl-acad-defun 'grv)
  (setq qa (getpoint "\nStartpoint: "))
  (while (null qb)
    (setq qb (dyndraw "grv" "\nTo Point: " "" 657 0 qa))
    )
  (princ)
  )
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 06, 2008, 11:57:50 PM
When I use "ORTHOMODE" the rectangle doesn't follow the ortho directions. It only works using  <cursor_type> 1, "RectCursor" or 2, "RubberBand".
Is that a bug or I did anything wrong?
IMHO it is not a bug but not all combination of input_flag and cursor_type can be useful.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: cmwade77 on January 05, 2010, 02:17:24 PM
I am wondering if there is a version that will work with 2010 and newer?
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on January 05, 2010, 08:38:36 PM
I am wondering if there is a version that will work with 2010 and newer?
Yes! http://www.maestrogroup.com.ua/support/dyndraw.zip
DynDraw2010x32.arx for AutoCAD 2010 x86
DynDraw2010x64.arx for AutoCAD 2010 x64
But I did not tested it.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Lee Mac on May 02, 2010, 05:21:52 PM
Superb work Alexander, I created this using your Arx supplement, have I implemented your function correctly?

Code: [Select]
;; An example of Text Placement using a grRead substitute,
;; Function by Lee Mac, using DynDraw by Alexander Rivilis

(defun c:test ( / vers step bit v str prev obj doc point )

  (setq vers
    '((18.0 . "2010")
      (17.2 . "2009")
      (17.1 . "2008")
      (17.0 . "2007")
      (16.2 . "2006")
      (16.1 . "2005")
      (16.0 . "2004")
      (15.6 . "2002"))
  )
 
  (setq step 1e-6
        bit (if (eq "X86"
                  (strcase
                    (getenv "PROCESSOR_ARCHITECTURE")
                  )
                )
              "x32" "x64"
             )
  )

  (cond
    (
      (not
        (setq v
          (cdr
            (assoc
              (atof
                (getvar 'ACADVER)
              )
              vers
            )
          )
        )
      )
     (princ "\n** Not Compatible in this Version **")
    )
    (
      (and
        (null dyndraw)
        (not
          (arxload
            (strcat "DynDraw" v
              (if (eq "2010" v) bit "") ".arx"
            )
          )
        )
      )
     (princ "\n** Arx File not Found **")
    )
    (
      (not
        (eq ""
          (setq str
            (getstring t "\nSpecify Text String: ")
          )
        )
      )
   
      (vl-acad-defun 'UpdateTextCallBack)
     
      (setq obj
        (MCMText
          (if
            (or
              (eq AcModelSpace
                (vla-get-ActiveSpace
                  (setq doc
                    (vla-get-ActiveDocument
                      (vlax-get-acad-object)
                    )
                  )
                )
              )
              (eq :vlax-true (vla-get-MSpace doc))
            )
            (vla-get-ModelSpace doc)
            (vla-get-PaperSpace doc)
          )
          (getvar 'VIEWCTR) 0. str
        )
      )
      (setq point
        (dyndraw "UpdateTextCallBack"
          "\nSpecify Point for Text [String] : "
          "String"
          (+ 2 128 2048)
          -1
          nil
        )
      )
      (and (vl-consp point)
        (vla-put-InsertionPoint obj (vlax-3D-point point))
      )   
    )
  )
)

(defun UpdateTextCallBack ( argument / tmp )

  (cond
    (
      (eq 'STR (type argument))

      (if (eq "String" argument)
        (if
          (not
            (eq ""
              (setq tmp
                (getstring t "\nSpecify New String: ")
              )
            )
          )
          (vla-put-TextString obj tmp)
        )
        (princ "\n** Invalid Keyword **")
      )
     (setq argument t)
    )
    (
      (vl-consp argument)

      (or prev (setq prev argument))

      (if (< step (distance prev argument))
        (progn
          (setq prev argument)

          (vla-put-InsertionPoint Obj (vlax-3D-point argument))
          (vla-update obj)
        )
      )
    )
  )
  argument
)


(defun MCMText ( block point width string / o )
  (vla-put-AttachmentPoint
    (setq o
      (vla-AddMText block
        (vlax-3D-point point) width string
      )
    )
    acAttachmentPointMiddleCenter
  )
  (vla-put-InsertionPoint o
    (vlax-3D-point point)
  ) 
  o
)

(http://www.theswamp.org/screens/leemac/DynText.gif)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Pepe on May 04, 2010, 12:25:27 PM
A good example, Lee Mac, thank you very much indeed...but...

Code: [Select]
(setq vers
    '((18.0 . "2010") ;no quite sure here...
      (17.2 . "2007") ;neither here...
      (17.1 . "2007")
      (17.0 . "2007")
      (16.2 . "2004")
      (16.1 . "2004")
      (16.0 . "2004")
      (15.6 . "2002"))
  )

 (Oops!...) :wink:
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Lee Mac on May 08, 2010, 10:52:10 AM
Another example I created recently :-)

(http://www.theswamp.org/screens/leemac/DynSlat.gif)

Code: [Select]
;; An example of Dynamic Slat creating using a grRead substitute,
;; Function by Lee Mac, using DynDraw by Alexander Rivilis

(defun c:slat ( / line vers step bit v n p1 p2 p3 pi/2 i prev )
  ;; Lee Mac  ~  08.05.10

  (defun line (s e)
    (entmakex
      (list
        (cons 0 "LINE")
        (cons 10 s)
        (cons 11 e)
      )
    )
  )

  (setq vers
    '((18.0 . "2010")
      (17.2 . "2009")
      (17.1 . "2008")
      (17.0 . "2007")
      (16.2 . "2006")
      (16.1 . "2005")
      (16.0 . "2004")
      (15.6 . "2002"))
  )
 
  (setq step 1e-6
        bit (if (eq "X86"
                  (strcase
                    (getenv "PROCESSOR_ARCHITECTURE")
                  )
                )
              "x32" "x64"
             )
  )

  (cond
    (
      (not
        (setq v
          (cdr
            (assoc
              (atof
                (getvar 'ACADVER)
              )
              vers
            )
          )
        )
      )
     (princ "\n** Not Compatible in this Version **")
    )
    (
      (not
        (and
          (setq n
            (getint "\nSpecify Number of Slats: ")
          )
          (setq p1
            (getpoint "\nPick First Corner Point: ")
          )
        )
      )
      (princ "\n*Cancel*")
    )
    (
      (and
        (null dyndraw)
        (not
          (arxload
            (strcat "DynDraw" v
              (if (eq "2010" v) bit "") ".arx"
            )
          )
        )
      )
     (princ "\n** Arx File not Found **")
    )
    (   
      (vl-acad-defun 'UpdateSlatCallBack)
     
      (setq p2
        (dyndraw "UpdateSlatCallBack"
          "\nPick Second Point [Number] : "
          "Number"
          (+ 1 2 128 2048)
          -1
          nil
        )
      )
     
      (redraw)
     
      (if (vl-consp p2)
        (progn
          (setq i (/ (- (cadr p2) (cadr p1)) n)
             pi/2 (/ pi 2.) p3 (cons (car p2) (cdr p1)))
          (
            (lambda ( j )
              (repeat (1- n)
                (apply (function line)
                  (mapcar
                    (function
                      (lambda ( point )
                        (trans point 1 0)
                      )
                    )
                    (list
                      (polar p1 pi/2 (* (setq j (1+ j)) i))
                      (polar p3 pi/2 (* j i))
                    )
                  )
                )
              )
            )
            0
          )
        )
      )
    )
  )
  (princ)
)

(defun UpdateSlatCallBack ( argument / tmp )

  (cond
    (
      (eq 'STR (type argument))

      (redraw)

      (if (eq "Number" argument)
        (if
          (setq tmp
            (getint "\nSpecify Number of Slats: ")
          )
          (setq n tmp)
        )
        (princ "\n** Invalid Keyword **")
      )
     (setq argument t)
    )
    (
      (vl-consp argument)

      (or prev (setq prev argument))

      (if (< step (distance prev argument))
        (progn
          (setq prev argument p2 argument)

          (setq i    (/ (- (cadr p2) (cadr p1)) n)
                pi/2 (/ pi 2.)
                p3   (cons (car p2) (cdr p1))
                p4   (cons (car p1) (cdr p2)))

          (redraw)
          (grvecs (cons -3 (list p1 p3 p3 p2 p1 p4 p4 p2)))
         
          (
            (lambda ( j )
              (repeat (1- n)
                (grvecs
                  (cons -30
                    (list (polar p1 pi/2 (* (setq j (1+ j)) i))
                          (polar p3 pi/2 (* j i))
                    )
                  )
                )
              )
            )
            0
          )
        )
      )
    )
  )
  argument
)

I really like this function :-)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: qjchen on July 21, 2010, 10:18:23 PM
Thank you very much, Alexander
and thank you Lee Mac too :)

After reading through your example, now I can write a such function that I always search for:

Find the perpendicular line to a curve through a point on the curve by grread like method.

Code: [Select]
;;; Thanks great to  Alexander Rivilis very very much
;;; and thanks to Lee Mac too
;;; http://www.theswamp.org/index.php?topic=9133.0
;;; by qjchen@gmail.com
;;; Find the perpendicular line to a curve through a point on the curve.
(defun C:test ( / curve-obj ent p)
  (if (null dyndraw) (progn (arxload "dyndraw.arx")))
  (prompt "\n Please select a curve first:")
  (setq curve-obj (vlax-ename->vla-object (car (entsel))))
  (vl-acad-defun 'dyn_call_back)
  (setq p (dyndraw "dyn_call_back" "\nPlease select a point: " "Number" 0 -1 nil))        
   (if (= (type p) 'LIST) (myfun p))
   (redraw)
  (princ)
)

(defun dyn_call_back (p)
  (mygrdraw p)
  p
)

(defun mygrdraw(p / p1)
  (redraw)
  (setq p1 (vlax-curve-getClosestPointTo curve-obj p))
  (grdraw p1 (polar p1 (+ (/ pi 2) (angle (list 0 0 0) (vlax-curve-getFirstDeriv curve-obj (vlax-curve-getParamAtPoint curve-obj (vlax-curve-getClosestPointTo curve-obj p))))) (* 0.3 (getvar "viewsize"))) 2)
)

(defun myfun(p)
 (entmakeline1 p (polar p (+ (/ pi 2) (angle (list 0 0 0) (vlax-curve-getFirstDeriv curve-obj (vlax-curve-getParamAtPoint curve-obj p)))) (* 0.3 (getvar "viewsize"))))
)


;;entmake line
(defun entmakeline1 (pt1 pt2)
  (if (> (distance pt1 pt2) 1e-5)
    (entmake (list (cons 0 "LINE")(cons 6 "BYLAYER") (cons 10 pt1) (cons 11 pt2) ))
  )
  (princ)
)

Title: Re: Dynamic drawing and substitution of grread-function
Post by: cjw on July 23, 2010, 02:32:57 AM
Thank you very much, Alexander.
I am waiting the substitution of grread-function for very long time.  :-D

Can anybody tell me what's wrong with the code under.

(defun C:TT (/ LOOP P)
  (vl-acad-defun 'CALL-BACK)
  (setq LOOP t)
  (while LOOP
    (setq P (dyndraw
         "CALL-BACK"
         "TEST..."
         "B"
         (+ 2 128 2048)
         0
         NIL
       )
    )
    (and (= (type P) 'list) (setq LOOP NIL))
  )
)


;; It work, but slowly.
(defun CALL-BACK (ARG)
  (command "._POINT" "_NON" ARG)
)

;; It can't work.
(defun CALL-BACK (ARG)
  (entmake (list (cons 0 "POINT")
       (cons 100 "AcDbEntity")
       (cons 8 "0")
       (cons 100 "AcDbPoint")
       (cons 10 ARG)
      )
  )
)


And How to "Dynamic" move SelectionSet with ssget.

(setq SS (ssget))

(command "._MOVE" SS "" "_NON" PT1 "_NON" PT2)

Title: Re: Dynamic drawing and substitution of grread-function
Post by: Hugo on March 28, 2012, 01:37:18 AM
dyndraw will no longer run on Autocad2013   :-( :-(


dyndraw läuft auf Autocad2013 nicht mehr
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on March 28, 2012, 01:56:20 AM
dyndraw will no longer run on Autocad2013   :-( :-(


dyndraw läuft auf Autocad2013 nicht mehr

Are you sure?  :-) Try to download last version.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Hugo on March 28, 2012, 02:10:38 AM
Thank you again, it works now.   ^-^ ^-^

Danke jetzt funktioniert es wieder.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: reltro on June 25, 2012, 12:38:43 PM
Hello,
I wrote a lil workround for DynDraw, but I have a Problem:
When I Pan with the MiddleMouseButton Autocad chrases in Fatal Way...

U may can give me a an answer about this, i don't know, bug?

I'm working with acad2012 and 2013...
I have tried the examples above, from LeeMac -> same Problem, so i don't think its a problem of my workaround...

[EDIT]
A UserBreak with {ESC} -> fires every time an error,wich is displayed, but not cancel dyndraw with 'nil
Why This?


hope for help
lg reltro

Ps.: 2 .lsp-files in the Attachment
Title: Re: Dynamic drawing and substitution of grread-function
Post by: martinle on June 27, 2012, 12:22:13 AM
Another example I created recently :-)

(http://www.theswamp.org/screens/leemac/DynSlat.gif)

Code: [Select]
;; An example of Dynamic Slat creating using a grRead substitute,
;; Function by Lee Mac, using DynDraw by Alexander Rivilis

(defun c:slat ( / line vers step bit v n p1 p2 p3 pi/2 i prev )
  ;; Lee Mac  ~  08.05.10

  (defun line (s e)
    (entmakex
      (list
        (cons 0 "LINE")
        (cons 10 s)
        (cons 11 e)
      )
    )
  )

  (setq vers
    '((18.0 . "2010")
      (17.2 . "2009")
      (17.1 . "2008")
      (17.0 . "2007")
      (16.2 . "2006")
      (16.1 . "2005")
      (16.0 . "2004")
      (15.6 . "2002"))
  )
 
  (setq step 1e-6
        bit (if (eq "X86"
                  (strcase
                    (getenv "PROCESSOR_ARCHITECTURE")
                  )
                )
              "x32" "x64"
             )
  )

  (cond
    (
      (not
        (setq v
          (cdr
            (assoc
              (atof
                (getvar 'ACADVER)
              )
              vers
            )
          )
        )
      )
     (princ "\n** Not Compatible in this Version **")
    )
    (
      (not
        (and
          (setq n
            (getint "\nSpecify Number of Slats: ")
          )
          (setq p1
            (getpoint "\nPick First Corner Point: ")
          )
        )
      )
      (princ "\n*Cancel*")
    )
    (
      (and
        (null dyndraw)
        (not
          (arxload
            (strcat "DynDraw" v
              (if (eq "2010" v) bit "") ".arx"
            )
          )
        )
      )
     (princ "\n** Arx File not Found **")
    )
    (   
      (vl-acad-defun 'UpdateSlatCallBack)
     
      (setq p2
        (dyndraw "UpdateSlatCallBack"
          "\nPick Second Point [Number] : "
          "Number"
          (+ 1 2 128 2048)
          -1
          nil
        )
      )
     
      (redraw)
     
      (if (vl-consp p2)
        (progn
          (setq i (/ (- (cadr p2) (cadr p1)) n)
             pi/2 (/ pi 2.) p3 (cons (car p2) (cdr p1)))
          (
            (lambda ( j )
              (repeat (1- n)
                (apply (function line)
                  (mapcar
                    (function
                      (lambda ( point )
                        (trans point 1 0)
                      )
                    )
                    (list
                      (polar p1 pi/2 (* (setq j (1+ j)) i))
                      (polar p3 pi/2 (* j i))
                    )
                  )
                )
              )
            )
            0
          )
        )
      )
    )
  )
  (princ)
)

(defun UpdateSlatCallBack ( argument / tmp )

  (cond
    (
      (eq 'STR (type argument))

      (redraw)

      (if (eq "Number" argument)
        (if
          (setq tmp
            (getint "\nSpecify Number of Slats: ")
          )
          (setq n tmp)
        )
        (princ "\n** Invalid Keyword **")
      )
     (setq argument t)
    )
    (
      (vl-consp argument)

      (or prev (setq prev argument))

      (if (< step (distance prev argument))
        (progn
          (setq prev argument p2 argument)

          (setq i    (/ (- (cadr p2) (cadr p1)) n)
                pi/2 (/ pi 2.)
                p3   (cons (car p2) (cdr p1))
                p4   (cons (car p1) (cdr p2)))

          (redraw)
          (grvecs (cons -3 (list p1 p3 p3 p2 p1 p4 p4 p2)))
         
          (
            (lambda ( j )
              (repeat (1- n)
                (grvecs
                  (cons -30
                    (list (polar p1 pi/2 (* (setq j (1+ j)) i))
                          (polar p3 pi/2 (* j i))
                    )
                  )
                )
              )
            )
            0
          )
        )
      )
    )
  )
  argument
)

I really like this function :-)


Her lee Hello!

slat.lsp looks great. It is not bit on acad 2012 64th Would it be possible that it will work on this version?

Best regards Martin
sorry for my english
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Lee Mac on June 27, 2012, 04:49:56 AM
Hi Martin,

If there is a dyndraw.arx version available for AutoCAD 2012 64-bit, then yes, I'm sure that my code could be manipulated to work in this version.

Lee
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Tharwat on June 27, 2012, 06:27:43 AM

If there is a dyndraw.arx version available for AutoCAD 2012 64-bit, then yes, I'm sure that my code could be manipulated to work in this version.

Lee

You're code worked nicely here on 2010 .

I liked the crack of grread function to have that dynamic way with osnap setting on .

But it seems that it's up to Cad 2010 from the name of file ! Am I right ?
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on June 27, 2012, 06:35:22 AM
Change:

Code: [Select]
  (setq vers
    '((18.0 . "2010")
      (17.2 . "2009")
      (17.1 . "2008")
      (17.0 . "2007")
      (16.2 . "2006")
      (16.1 . "2005")
      (16.0 . "2004")
      (15.6 . "2002"))
  )
with:
Code: [Select]
  (setq vers
    '((19.0 . "2013")
      (18.2 . "2010")
      (18.1 . "2010")
      (18.0 . "2010")
      (17.2 . "2008")
      (17.1 . "2008")
      (17.0 . "2007")
      (16.2 . "2004")
      (16.1 . "2004")
      (16.0 . "2004")
      (15.6 . "2002"))
  )
Also change:
Code: [Select]
(if (eq "2010" v) bit "") ".arx"with:
Code: [Select]
(if (or (eq "2008" v) (eq "2010" v) (eq "2013" v)) bit "") ".arx"
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Lee Mac on June 27, 2012, 06:43:55 AM
Thank you Alexander, and thank you also for your work on the superb dyndraw.arx utility.  :-)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Tharwat on June 27, 2012, 06:54:14 AM
A very nice work Alexander .

Thank you so much for sharing this precious work .
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on June 27, 2012, 06:57:01 AM
Thank you Alexander, and thank you also for your work on the superb dyndraw.arx utility.  :-)
A very nice work Alexander .
Thank you so much for sharing this precious work .
Thanks!  :-)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Tharwat on June 27, 2012, 02:29:45 PM
Hi Alexander .

I could not load the arx files at home with OS 64 and windows 7 Autocad 2009 and 2012
It gives a message ' Unable to Dyn Draw ******* '

Thanks
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on June 28, 2012, 08:44:11 AM
Hi Alexander .

I could not load the arx files at home with OS 64 and windows 7 Autocad 2009 and 2012
It gives a message ' Unable to Dyn Draw ******* '

Thanks
Sorry but I can not test DynDraw with x64 OS. Try manually load appropriate arx-file with _APPLOAD command before testing samples.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Tharwat on June 28, 2012, 08:49:11 AM
Hi .

Appload is the one that I used to load the arx files .

All loaded nicely on OS 32 at the office , but at home OS 64 without a chance to success or to pass . :-(

Any other solution please ? .
Title: Re: Dynamic drawing and substitution of grread-function
Post by: CAB on June 28, 2012, 09:03:19 AM
Works here ACAD2006 .
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Alexander Rivilis on June 28, 2012, 09:22:53 AM
Hi .

Appload is the one that I used to load the arx files .

All loaded nicely on OS 32 at the office , but at home OS 64 without a chance to success or to pass . :-(

Any other solution please ? .
I've tried load DynDraw2010x64.arx with AutoCAD 2012 x64 with Win7 x64 and it is loaded without errors and working well. Command SLAT (by Lee) with my correction above are also working if DynDraw2010x64.arx is in directories in which AutoCAD searching or loaded before.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: Lee Mac on June 28, 2012, 11:32:19 AM
To provide another example, I have rewritten my 'hvlines' program from here (http://www.theswamp.org/index.php?topic=12813.msg440380#msg440380) to use dyndraw:

(http://www.theswamp.org/lilly_pond/leemac/dyndrawhvlines.gif)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: chlh_jd on July 12, 2012, 09:44:41 AM
Thanks Alexander's Classic
My old dyn arrow-leader code can be simplified
Code: [Select]
(defun c:test (/ dyn_leader_call_back *error* p1 p2 p3 p p_base)
  ;;dyndraw arrow leader , e.g.
  ;;by GSLS(SS)
  (defun dyn_leader_call_back (p)
   (cond ((= (type p) 'STR)
  (redraw)
)
((= (type p) 'LIST)
  (if (> (distance p p_base) 1e-6)
    (progn
      (redraw)
      (if (<= (distance p1 p) (distance p p3))
(ss:grvecs:leader (list p1 p2 p3 450. 150.) nil)
(ss:grvecs:leader (list p3 p2 p1 450. 150.) nil)
      )
      (setq p_base p)
    )
  )
)
   )
   p
 )
  (setq _cm (getvar "cmdecho")
_ps (getvar "PICKSTYLE")
_oe *error*
  )
  (defun *error* (msg)
    (if (or (= msg "Function cancelled")
    (= msg "quit / exit abort")
)
      (princ msg)
      (princ (strcat "\n错误: " msg))
    )
    (vla-EndUndoMark
      (vla-get-ActiveDocument (vlax-get-acad-object))
    )
    (setvar "cmdecho" _cm)
    (setvar "PICKSTYLE" _ps)
    (vl-acad-undefun "dyn_leader_call_back")
    (setq *error* _oe)
    (princ)
  ) 
  (setvar "cmdecho" 0)
  (setvar "PICKSTYLE" 0)
  (vl-acad-defun "dyn_leader_call_back")
  (setq p1 (getpoint "\nSelect First Point of Lead Arrow :"))
  (setq p2 (getpoint p1 ">>Sencond Point :"))
  (grdraw p1 p2 3 3)
  (setq p3 (getpoint p2 ">>Third Point :"))
  (grdraw p2 p3 3 3)
  (setq p p3
p_base p
  )
  (if (and dyndraw (>= (distance p1 p2) 500.) (>= (distance p2 p3) 500.) p p_base (/= (type p) 'STR))
    (progn     
       (setq p
      (dyndraw
;; Name of callback - finction
"dyn_leader_call_back"
;; Prompt string
"\nSelect Direction of the Arrow |^|"
;; Keyword string
""
;; Input flag
8
;; Cursor type
-1
;; Base point (in UCS)
p
       )
       )       
       (redraw)
       (if (= (type p) 'LIST)
(progn
   (vla-startundomark
     (vla-get-activedocument (vlax-get-acad-object))
   )
   (if (<= (distance p1 p) (distance p p3))
     (command "_pline"  p1 "w"  0 150 (polar p1 (angle p1 p2) 450.)  "w"  0  0  p2 "_none" p3 "")
     (command "_pline" p3 "w" 0 150(polar p3 (angle p3 p2) 450.)"w" 0 0 p2 "_none"  p1   "")
   )    
   (vla-EndUndoMark
     (vla-get-ActiveDocument (vlax-get-acad-object))      
   )    
)
       ) ;_endof if progn
    )
  )
  (setvar "cmdecho" _cm)
  (setvar "PICKSTYLE" _ps)
  (vl-acad-undefun "dyn_leader_call_back")
  (setq *error* _oe)
  (princ)
)
(defun ss:grvecs:leader (l mat / p1 p2 p3 p4 p5 p6 len wid ang)
  (if (and (= (length l) 5)
   (setq p1 (car l))
   (setq p2 (cadr l))
   (setq p3 (caddr l))
   (setq len (cadddr l))
   (setq wid (last l))
   (> (distance p1 p2) len)
   (setq ang (angle p1 p2))
   (setq p4 (polar p1 ang len))
   (setq p5 (polar p4 (+ ang (/ pi 2.)) (/ wid 2.)))
   (setq p6 (polar p4 (- ang (/ pi 2.)) (/ wid 2.)))
      )
    (if (and mat
     (= (length mat) 4)
     (apply '= (cons 'list (mapcar 'type mat)))
)
      (grvecs (list 3 p1 p5 3 p1 p6 3 p5 p6 3 p4 p2 3 p2 p3) mat)
      (grvecs (list 3 p1 p5 3 p1 p6 3 p5 p6 3 p4 p2 3 p2 p3))
    )
  )
)
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on December 17, 2013, 03:25:20 AM
hello

i try adjust my routine to work with DynDraw. looks like all seems to be fine.
i wish to update one thing. can SPACE or ENTER run part of my code instead of EXIT ?
Code: [Select]
"\nSpecify through point: [Rotate/Angle/REset/Exit] <Rotate>: "can this be done with DynDraw ?

thanks
kruuger
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on December 17, 2013, 05:27:53 PM
i think i got this:
Code: [Select]
    ( (eq 'STR (type *pt))
      (redraw)
      (cond
        ( (eq "Angle" *pt)
          (if (eq (type (_AngleXLine)) 'REAL)
            (setq *NewXline* res)
            T
          )
          T
        )
        ( (eq "REset" *pt)
          (setq *NewXline* (/ pi 2))
          T
        )
        ( (eq "Exit" *pt)
          *pt
        )
        ( T ; Rotate
          (setq *NewXline* (+ *NewXline* (* pi 0.5)))
          T
        )
      )
    )
attached updated code
k.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on December 23, 2013, 04:23:20 PM
i'm trying to finish my routine but i'm stuck:
- don't know why but i can't open command line window F2 (when i'm in loop of program). window is closed immediately when i hit F2.
- also have a problem with Undo option. when i delete the last object created in loop my command line still show Undo.
Code: [Select]
"\nSpecify through point: [Rotate/Angle/Crosshair/REset/Undo/Exit] <Rotate>: "appreciate with any help.
thanks
kruuger
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on February 11, 2014, 05:47:27 AM
i'm trying to finish my routine but i'm stuck:
- don't know why but i can't open command line window F2 (when i'm in loop of program). window is closed immediately when i hit F2.
- also have a problem with Undo option. when i delete the last object created in loop my command line still show Undo.
Code: [Select]
"\nSpecify through point: [Rotate/Angle/Crosshair/REset/Undo/Exit] <Rotate>: "appreciate with any help.
thanks
kruuger
is there any solution for F2 ?
thanks
Title: Re: Dynamic drawing and substitution of grread-function
Post by: bilançikur on February 12, 2014, 07:31:05 AM
@ Kruuger: I have always had the problem with F2 using AutoCAD and using ZWCAD. When running the vanilla program there is no problem but when loading certain .lsp & .arx/.zrx files the problem seems to appear. I have no clue why this happens.

I found out (in my situation at least) that when you only see the commandline (the F2 textfield) as minimized: press shift + right click on it in the F2 screen in the taskbar. THen it will show.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: irneb on February 12, 2014, 07:59:38 AM
There is 2 possibilities:
My guess is it's the VLIDE, there's a long standing bug where it swaps around the active window incorrectly at times.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on February 12, 2014, 09:43:20 AM
There is 2 possibilities:
  • VLIDE might cause some strange things to happen. Check if the issue is still occurring if you appload the LSP into a new ACad session without starting VLIDE
  • The grread loop might be forcing a graphscr, though it "shouldn't", but it could.
My guess is it's the VLIDE, there's a long standing bug where it swaps around the active window incorrectly at times.
i noticed something now. F2 window is not closed but send back. We can see them on second monitor.
Also Lee routine works fine: http://www.theswamp.org/index.php?topic=9133.msg472689#msg472689
i use while loop (similar to Alexander). his works (F2) my not :(
k.
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on December 15, 2018, 06:05:12 AM
Hi All

Did anyone try to pass updated variable to dyndraw prompt?
Using global one but dont see any changes. if i run command once again all is ok but thats not my goal :(
Please see more info in attached video.

thanks
kruuger
Title: Re: Dynamic drawing and substitution of grread-function
Post by: kruuger on March 30, 2021, 05:32:30 AM
Hi All

Did anyone try to pass updated variable to dyndraw prompt?
Using global one but dont see any changes. if i run command once again all is ok but thats not my goal :(
Please see more info in attached video.

thanks
kruuger
any chance to fix this?
"Did anyone try to pass updated variable to dyndraw prompt?"
kruuger
thanks