Curve Catalog

AutoLisp DCL Curve Graphing with curve “recipes” – equation, x value ranges, x value increment – saved and retrieved in an excel CSV file. Curve parameters in an excel list can be edited, sorted and re-organized. A sub-form Curve Catalog is popped up, data filled from the CSV file. User selects curve. Parameters are input to the Graph screen.

The code to Read the Excel.CSV file was written by Lee Mac and downloaded from his premier lisp site.
http://www.lee-mac.com/readcsv.html

Graphing mathematical equations with autolisp –
as an example,
(setq strfunc “(* a x x )”)
(setq a 2) returns 2
(setq x 2.1) returns 2.1
Strfunc returns “(* a x x )”
(read strfunc) returns (* A X X)
(eval (read strfunc)) returns 8.82

With this we can set up a function to return a result for any legal lisp statement and values x a b c d.
The function is passed as a string, strfunc. X is passed in as a Real. X will vary with each call from xmin to xmax by increment xinc,
The global vars for a_dim b_dim c_dim and d_dim do not vary.

(defun func_eval (x strfunc / a b c d)
(setq a a_dim b b_dim c c_dim d d_dim )
(setq result (eval (read strfunc))) )

The equations must be input in lisp form, prefix notation with the operator first in a list, expressions nested. As long as it is legal lisp, the above code will interpret it. The loop to draw the curve is basic lisp using the command function for either line or pline.

;; location of
;; graph.lsp and dcl
;; catalog.lsp and dcl
;; curve_catalog.csv

 (setq graph_progdir "c:\\lisp\\graph\\")


(defun c:graph ()
   ;catalog sub form program
  (load (strcat graph_progdir "catalog.lsp"))

 (setq dcl_id (load_dialog (strcat graph_progdir "graph.dcl")))
  (if (< dcl_id 0)
    (progn
      (alert "The graph.DCL file could not be loaded.")
      (exit) ) )

  (if (not (new_dialog "graph" dcl_id))
    (progn
      (alert "DCL file loaded but not definition, internal problem with files" )
      (exit) )   )

  (set_graph_vars)
  (action_tile "catalog" "(catalog) (set_graph_vars)")
  (action_tile "graphlines" "(savevars) (done_dialog 2)")
  (action_tile "graphpolylines" "(savevars) (done_dialog 3)")
  (action_tile "cancel" "(done_dialog 0)")

  (setq ddiag (start_dialog))
  (unload_dialog dcl_id)
  (if (= ddiag 2) (graphlines) )
  (if (= ddiag 3) (graphpolylines) )
)


(defun savevars	()
  (setq xmin (atof (get_tile "xmin")))
  (setq xmax (atof (get_tile "xmax")))
  (setq xinc (atof (get_tile "xinc")))
  (setq a_dim (atof (get_tile "a_dim")))
  (setq b_dim (atof (get_tile "b_dim")))
  (setq c_dim (atof (get_tile "c_dim")))
  (setq d_dim (atof (get_tile "d_dim")))
  (setq strfunc (get_tile "equation"))
)


(defun set_graph_vars ()
  (if xmin
    (set_tile "xmin" (rtos xmin 2 2))
    (set_tile "xmin" "-3.0")  )

  (if xmax
    (set_tile "xmax" (rtos xmax 2 2))
    (set_tile "xmax" "3.0")  )

  (if xinc
    (set_tile "xinc" (rtos xinc 2 2))
    (set_tile "xinc" "0.1")  )

  (if a_dim
    (set_tile "a_dim" (rtos a_dim 2 2))
    (set_tile "a_dim" "2")  )

  (if b_dim
    (set_tile "b_dim" (rtos b_dim 2 2))
    (set_tile "b_dim" "3")  )

  (if c_dim
    (set_tile "c_dim" (rtos c_dim 2 2))
    (set_tile "c_dim" "4")  )

  (if d_dim
    (set_tile "d_dim" (rtos d_dim 2 2))
    (set_tile "d_dim" "5")  )

    ;initial equation ax^2 + bx + c	
  (if (null strfunc)
    (set_tile "equation" "(+ (* a X X) (* b X) c)")
    (set_tile "equation" strfunc)  )
)


(defun func_eval (x strfunc / a b c d)
  (setq	a a_dim    b b_dim   c c_dim   d d_dim  )
  (setq result (eval (read strfunc))) )


(defun graphlines ()	;working with all global variables from savevars

  (setq numlines (/ (- xmax xmin) xinc))
  (setq i 1)
  (setq x1 xmin)
  (setq y1 (func_eval x1 strfunc))

  (repeat (fix numlines)

    (setq x2 (+ xmin (* i xinc)))
    (setq y2 (func_eval x2 strfunc))

    (setq pt1 (list x1 y1))
    (setq pt2 (list x2 y2))

    (command "line" pt1 pt2)
    (command)

    (setq x1 x2)
    (setq y1 y2)

    (setq i (1+ i))
  )
)


(defun graphpolylines ()    ;working with all global variables from savevars

  (setq numlines (/ (- xmax xmin) xinc))
  (setq x1 xmin)
  (setq y1 (func_eval x1 strfunc))
  (setq pt1 (list x1 y1))

  (command "pline" pt1)

  (setq i 1)
  (repeat (fix numlines)

    (setq x2 (+ xmin (* i xinc)))
    (setq y2 (func_eval x2 strfunc))

    (setq pt2 (list x2 y2))

    (command pt2)
    (setq i (1+ i))
  )
  (command)
)

Graph.DCL is straightforward

Each curve then is defined by its lisp string, xmin, xmax, xinc and the specific values of A B C and D if they are used. Those 8 variables can be saved in an Excel file, a list of curve recipes, and input to the Graph program through a nested dialog called Catalog. A couple extra information columns are added.

The Excel format is called CSV, Comma Separated Values. It is actually a text file. It can be loaded directly into a text editor. Autolisp has tools to read this format. Excel is very handy for displaying and managing it. Lee Mac’s program reads the table and returns a list of rows with each cell a separate item in the sub-list. With Lisp tools we can take that and re-display the CSV file in DCL list boxes.

I only make one list box active to user selection, the box with the legal lisp equation. the other boxes are for user reference. all list boxes are given the same height and handled the same way so the rows line up. When the user selects an equation, its parameters are written to the textboxes, however he has to select OK to dismiss the dialog and use the parameters. Selecting cancel will abandon the values and return the previous screen with the values unchanged.

Here is Catalog LSP, called from the button on Graph. much of its length is just from loading the 10 listboxes and dealing with variables.

;catalog_lsp called from graph_lsp


(defun catalog_setup ()
(setq file (strcat graph_progdir "curve_catalog.csv"))

;;*********************************************
;; Read CSV code from
;;http://www.lee-mac.com/readcsv.html
;;*********************************************
(setq data (LM:readcsv file))


(setq theList1  (mapcar 'car data))
(setq theList2  (mapcar 'cadr data))
(setq theList3  (mapcar 'caddr data))

(setq theList4  (mapcar '(lambda (abc) (nth 3 abc)) data))
(setq theList5  (mapcar '(lambda (abc) (nth 4 abc)) data))
(setq theList6  (mapcar '(lambda (abc) (nth 5 abc)) data))
(setq theList7  (mapcar '(lambda (abc) (nth 6 abc)) data))
(setq theList8  (mapcar '(lambda (abc) (nth 7 abc)) data))
(setq theList9  (mapcar '(lambda (abc) (nth 8 abc)) data))
(setq theList10  (mapcar '(lambda (abc) (nth 9 abc)) data))
)


(defun catalog ()
(catalog_setup)

  (setq dcl_id (load_dialog (strcat graph_progdir "catalog.dcl")))
  (if (< dcl_id 0)
    (progn  (alert "The catalog.DCL file could not be loaded.")
      (exit) ) )

  (if (not (new_dialog "catalog" dcl_id))
    (progn (alert "DCL file loaded but not definition, internal problem with files")
      (exit) ) )

  (set_catalog_vars)

  (start_list "list1" 3)
  (mapcar 'add_list theList1)
  (end_list)

  (start_list "list2" 3)
  (mapcar 'add_list theList2)
  (end_list)

  (start_list "list3" 3)
  (mapcar 'add_list theList3)
  (end_list)

  (start_list "list4" 3)
  (mapcar 'add_list theList4)
  (end_list)

  (start_list "list5" 3)
  (mapcar 'add_list theList5)
  (end_list)

  (start_list "list6" 3)
  (mapcar 'add_list theList6)
  (end_list)

  (start_list "list7" 3)
  (mapcar 'add_list theList7)
  (end_list)

  (start_list "list8" 3)
  (mapcar 'add_list theList8)
  (end_list)

  (start_list "list9" 3)
  (mapcar 'add_list theList9)
  (end_list)

  (start_list "list10" 3)
  (mapcar 'add_list theList10)
  (end_list)

  ;only list that is pickable is lisp equation
  (action_tile "list3" "(list-pick)")

  (action_tile "ok" "(savevars) (done_dialog 2)")
  (action_tile "cancel" "(done_dialog 0)")

  (setq ddiag (start_dialog))
  (unload_dialog dcl_id)

  ;(if (= ddiag 2) (nothing) )
  ;not required - savevars in ok button writes vars
  ;catalog button in graph lsp reads vars to screen 
 )


(defun savevars	()
  (setq xmin (atof (get_tile "xmin")))
  (setq xmax (atof (get_tile "xmax")))
  (setq xinc (atof (get_tile "xinc")))

  (setq a_dim (atof (get_tile "a_dim")))
  (setq b_dim (atof (get_tile "b_dim")))
  (setq c_dim (atof (get_tile "c_dim")))
  (setq d_dim (atof (get_tile "d_dim")))

  (setq strfunc (get_tile "equation"))
)


(defun list-pick ()
  (setq listval (get_tile "list3"))
  (setq curve_recipe (nth (atoi listval) data))

  (set_tile "equation" (nth 2 curve_recipe))
  (set_tile "xmin" (nth 3 curve_recipe))
  (set_tile "xmax" (nth 4 curve_recipe))
  (set_tile "xinc" (nth 5 curve_recipe))
  (set_tile "a_dim" (nth 6 curve_recipe))
  (set_tile "b_dim" (nth 7 curve_recipe))
  (set_tile "c_dim" (nth 8 curve_recipe))
  (set_tile "d_dim" (nth 9 curve_recipe))
 )

;code same as set_graph_vars, keeping them separate for now
(defun set_catalog_vars ()
  (if xmin
    (set_tile "xmin" (rtos xmin 2 2))
    (set_tile "xmin" "-3.0") )

  (if xmax
    (set_tile "xmax" (rtos xmax 2 2))
    (set_tile "xmax" "3.0") )

  (if xinc
    (set_tile "xinc" (rtos xinc 2 2))
    (set_tile "xinc" "0.1") )

  (if a_dim
    (set_tile "a_dim" (rtos a_dim 2 2))
    (set_tile "a_dim" "2") )

  (if b_dim
    (set_tile "b_dim" (rtos b_dim 2 2))
    (set_tile "b_dim" "3") )

  (if c_dim
    (set_tile "c_dim" (rtos c_dim 2 2))
    (set_tile "c_dim" "4") )

  (if d_dim
    (set_tile "d_dim" (rtos d_dim 2 2))
    (set_tile "d_dim" "5") )

    ;initial equation ax^2 + bx + c	
  (if (null strfunc)
    (set_tile "equation" "(+ (* a X X) (* b X) c)")
    (set_tile "equation" strfunc) )
 )

and last, the DCL file for Catalog, again much of its length is repeating operations for the many listboxes


catalog:dialog {
    	     label = "Curve Catalog";

             :row {
                    :list_box {
                                label ="Notes";
            	                  key = "list1";
            		       height = 35;
            		        width = 35;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                   :list_box {
                                label ="Description";
            	                  key = "list2";
            		       height = 35;
            		        width = 35;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="Function - *** PICK FROM THIS LIST ***";
            	                  key = "list3";
            		       height = 35;
            		        width = 50;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="Xmin";
            	                  key = "list4";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="Xmax";
            	                  key = "list5";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="Xinc";
            	                  key = "list6";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="A_Dim";
            	                  key = "list7";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="B_Dim";
            	                  key = "list8";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="C_Dim";
            	                  key = "list9";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }

                  :list_box {
                                label ="D_Dim";
            	                  key = "list10";
            		       height = 35;
            		        width = 7;
            	      multiple_select = false;
            	     fixed_width_font = true;
            	                value = "0"; }
                }



           :row {
                      :edit_box {
                                   label = "Xmin";
                                     key = "xmin";}
                      :edit_box {
                                   label = "Xmax";
                                     key = "xmax";}
                      :edit_box {
                                   label = "Xinc";
                                     key = "xinc";}
               
                      :edit_box {
                                   label = "A_dim";
                                     key = "a_dim";}
                      :edit_box {
                                   label = "B_dim";
                                     key = "b_dim";}
                      :edit_box {
                                   label = "C_dim";
                                     key = "c_dim";}
                      :edit_box {
                                   label = "D_dim";
                                     key = "d_dim";}
                    }

               :row {
                      :edit_box {
                                   label = "Y = ";
                                     key = "equation";}
                     }
  
	     :row {
                    : button {
                               label = "OK";
            	                 key = "ok";
            		  is_default = true; }

                    : button {
                               label = "Cancel";
            	                 key = "cancel";
            	          is_default = false;
            	           is_cancel = true; }
                   }
    	
           }

AutoLisp DCL Equation Graphing

here is a start. equations have to be input in Lisp format. prototype, barely tested beyond initial ah ha!

Both line and polyline mode are enabled. The program remembers variables from run to run, so if you input a new equation, it will come up on next run.



(defun c:graph ()

  (setq dcl_id (load_dialog "c:\\lisp\\graph\\graph.dcl"))
  (if (< dcl_id 0)
    (progn
      (alert "The graph.DCL file could not be loaded.")
      (exit) ) )

  (if (not (new_dialog "graph" dcl_id))
    (progn
      (alert "DCL file loaded but not definition, internal problem with files")
      (exit) ) )

  (setgraphvars)

  (action_tile "graphlines" "(savevars) (done_dialog 2)")
  (action_tile "graphpolylines" "(savevars) (done_dialog 3)")
  (action_tile "cancel" "(done_dialog 0)")

  (setq ddiag (start_dialog))

  (unload_dialog dcl_id)

  (if (= ddiag 2)
    (graphlines) )
  
  (if (= ddiag 3)
    (graphpolylines) )
)


(defun savevars	()
  (setq xmin (atof (get_tile "xmin")))
  (setq xmax (atof (get_tile "xmax")))
  (setq xinc (atof (get_tile "xinc")))

  (setq a_dim (atof (get_tile "a_dim")))
  (setq b_dim (atof (get_tile "b_dim")))
  (setq c_dim (atof (get_tile "c_dim")))
  (setq d_dim (atof (get_tile "d_dim")))

  (setq str_equation (get_tile "equation"))
)


(defun setgraphvars ()
  (if xmin
    (set_tile "xmin" (rtos xmin 2 2))
    (set_tile "xmin" "-3.0") )

  (if xmax
    (set_tile "xmax" (rtos xmax 2 2))
    (set_tile "xmax" "3.0") )

  (if xinc
    (set_tile "xinc" (rtos xinc 2 2))
    (set_tile "xinc" "0.1") )

  (if a_dim
    (set_tile "a_dim" (rtos a_dim 2 2))
    (set_tile "a_dim" "2") )

  (if b_dim
    (set_tile "b_dim" (rtos b_dim 2 2))
    (set_tile "b_dim" "3") )

  (if c_dim
    (set_tile "c_dim" (rtos c_dim 2 2))
    (set_tile "c_dim" "4") )

  (if d_dim
    (set_tile "d_dim" (rtos d_dim 2 2))
    (set_tile "d_dim" "5") )
  
			;initial equation ax^2 + bx + c	
  (if (null str_equation)
    (set_tile "equation" "(+ (* a X X) (* b X) c)")
    (set_tile "equation" str_equation) ) )


(defun resetgraph ()
  (set_tile "xmin" "-3.0")
  (set_tile "xmax" "3.0")
  (set_tile "xinc" "0.1")

  (set_tile "a_dim" "2")
  (set_tile "b_dim" "3")
  (set_tile "c_dim" "4")
  (set_tile "d_dim" "5")

  (setq str_equation "(+ (* a X X) (* b X) c)") ;initial equation
  (set_tile "equation" str_equation)	; ax^2 + bx + c
)


(defun func_eval (x strfunc / a b c d)
  (setq	a a_dim   b b_dim   c c_dim   d d_dim )
  (setq result (eval (read strfunc)))
)


(defun graphlines ()	;working with all global variables from savevars
		
  (setq strfunc str_equation)	; could clean this up

  (setq numlines (/ (- xmax xmin) xinc))
  (setq i 1)
  (setq x1 xmin)
  (setq y1 (func_eval x1 strfunc))

  (repeat (fix numlines)

    (setq x2 (+ xmin (* i xinc)))
    (setq y2 (func_eval x2 strfunc))

    (setq pt1 (list x1 y1))
    (setq pt2 (list x2 y2))

    (command "line" pt1 pt2)
    (command)

    (setq x1 x2)
    (setq y1 y2)

    (setq i (1+ i))
  )
)

		
(defun graphpolylines ()   ;working with all global variables from savevars

  (setq strfunc str_equation)	; eval read strfunc

  (setq numlines (/ (- xmax xmin) xinc))
  (setq x1 xmin)
  (setq y1 (func_eval x1 strfunc))
  (setq pt1 (list x1 y1))

  (command "pline" pt1)

  (setq i 1)
  (repeat (fix numlines)

    (setq x2 (+ xmin (* i xinc)))
    (setq y2 (func_eval x2 strfunc))

    (setq pt2 (list x2 y2))

    (command pt2)
    (setq i (1+ i))
  )

  (command)

)

Graphs below are cos, sin and cos * sin
(cos X) White
(sin X) Red
(* (sin X) (cos X)) Blue

Autocad DCL Dialog Forms

Dialog Control Language – DCL – was introduced in its final form 25 years ago. If you have created forms with VBA, DCL has a tiny fraction of the capability. It uses archaic unfamiliar terms and it is evidently hard to describe as no one does it well. My advice is to find a template and create some working code as you try to read about it. The best template and teaching approach I have used is Jeffery Sanders website. He has a good basic template at the bottom of the very first page.

JefferySanders AutoLisp DCL Tutorial

There are two components – the DCL file and the Lisp file. The DCL file looks confusing at first but its not. The basic element is the Tile, in VBA that is called a Control. There are only a few Tiles that the user actually uses – textbox, button, listbox, popup list, radio button and toggle. There are several other column and row spacings which are technically tiles but you can leave them out of your first programs. Each Tile has attributes, in VBA called Properties. The most important attribute is called a Key, in VBA that is just the Name. The structure of tile and attributes is not hard to learn if you just start typing. Develop your own style of formatting and indenting. As you add rows and column objects, indent the Tiles so the Colon for each level is in a vertical line on the page.

Here is my style that i can read at a glance without counting brackets.

The visual lisp IDE has a DCL preview tool that is essential to get working. It is broken by default (or perhaps neglect). AfraLISP has clear instructions here to change permissions on your autocad installation folder.

AfraLisp Previewing DCL Files

Autodesk help has a LSP-DCL example overview.

Example: Quick Overview of Dialog Boxes (DCL)

DCL

hello  : dialog {
	          label = "sample box";
               	  : text { label = "Hello world"; }
       ok_only;
}

LSP

(defun C:HELLO ( / dcl_id )
  (setq dcl_id (load_dialog "hello.dcl")) ; Load the DCL file.
  (if (not (new_dialog "hello" dcl_id))   ; Initialize the dialog.
    (exit)                                ; Exit if this does not work.
  )
  (start_dialog)                          ; Display the dialog box.
  (unload_dialog dcl_id)                  ; Unload the DCL file.
 (princ)
)

Running this quickly shows it runs, displays and closes but it does not do anything. There is no input from the user. The mystery of these files remains – how is user input processed when they close?

start-dialog is running when the dialog is displayed, when the dialog is closed, start-dialog returns a status number. if the builtin ok_cancel buttons are used in the dcl file, the numbers are 0 for cancel and 1 for ok. that is what is happening behind the scenes in the program above, though there is no ok button.

You can start modifying the above program by adding an ok button, and capture the integer returned by start_dialog as it closes the dialog. The built-in ok_cancel buttons have built-in keys of “accept” and “cancel.” With that knowledge you can build an action_tile statement in your lisp program that is run when that button is pushed. Eventually we need to run our own program when the ok button is pushed.

(action_tile “accept” “(done_dialog 1)”) will cause the start_dialog exit and return the number 1 when the ok button is pushed. that happens to be the same number as the default, you could choose any number and start_dialog will return that number. The string of lisp commands is quoted so it does not evaluate when first loaded. This is why you just have to start running code because its so hard to explain. This area of how it closes and how user input is captured is the key part that is hardest to get from the manuals.

To make this overview program do something user related lets take this intermediate step where we add an edit_box, an ok_cancel assembly and examine the start_dialog return values. Adding some error checking to the dcl loading is straightforward.

DCL

hello2  : dialog {
           label = "hello2";

                  : edit_box {
                               label = "type in the box";
                                 key = "hellobox";
                                  value = "hello world";
                                  width = 50; }

ok_cancel;
}

LSP

(defun c:hello2 ( / dcl_id)

;'can the file be found and loaded
;'load_dialog returns positive integer when successful
;'returns a negative integer when not successful

  (setq dcl_id (load_dialog "c:\\lisp\\dcl\\hello.dcl"))
  (if (< dcl_id 0)
   (progn
      (alert "The Hello.DCL file could not be loaded.")
      (alert "Check DCL file location is in Search Path")
      (exit)))

;'(alert (rtos dcl_id))

 ;'new_dialog returns T or nil
 (if (not (new_dialog "hello2" dcl_id))
        (progn
        (alert "DCL file loaded but not definition, internal problem with files")
        ;'this might even be inconsistent capitalization of the dialog name
        (exit)))

;'as an experiment uncomment these lines
;'these numbers are returned by start_dialog
;'they mean whatever you want them to mean - they overwrite default 0 and 1
;'accept and cancel are the built-in key names you need to know for the ok_cancel sub-assembly
;'(action_tile "accept" "(done_dialog 3)")
;'(action_tile "cancel" "(done_dialog 12)")

;'by default start_dialog returns 0 if cancel, 1 if OK, -1 if all boxes term_dialog
;'alternatively, if done_dialog argument is an integer > 1
;'then start_dialog returns that value which is user-application defined

(setq d (start_dialog))
(unload_dialog dcl_id)

(alert (itoa d))
)

now maybe we have some understanding of how the built-in buttons pass values behind the scenes to the start-dialog, we can do the same thing with explicitly created buttons in the dcl. we don’t have to do that, but perhaps it is simpler to see how it works. The last most important piece of the puzzle, where and how do we save user input? i take this technique from the jefferysanders template above, create a (savevars) function and put it in the action_tile statement for the ok button. Test the number returned by start_dialog after exiting the dialog to see if it gets used. now the helloworld demo file returns whatever the user types in to the box.

DCL

hello3  : dialog {
           label = "hello3";

                  : edit_box {
                               label = "type in the box";
                                 key = "hellobox";
                                  value = "hello world";
                                  width = 50; }

                  : row {
              
                          : button {
                                     key = "accept";
                                   label = " Okay ";
                              is_default = true; }
                          : button {
                                     key = "cancel";
                                   label = " Cancel ";
                              is_default = false;
                               is_cancel = true; }
                        }
 }

LSP

(defun c:hello3 ( / dcl_id)

;'can the file be found and loaded
;'load_dialog returns positive integer when successful
;'returns a negative integer when not successful

  (setq dcl_id (load_dialog "c:\\lisp\\dcl\\hello.dcl"))
  (if (< dcl_id 0)
   (progn
      (alert "The Hello.DCL file could not be loaded.")
      (alert "Check DCL file location is in Search Path")
      (exit)))

 ;'new_dialog returns T or nil
 (if (not (new_dialog "hello3" dcl_id))
        (progn
        (alert "DCL file loaded but not definition, internal problem with files")
        ;'this might even be inconsistent capitalization of the dialog name
        (exit)))

;'now using explicitly created button tiles rather than built-in
;'but it is not necessary, same results are with hello2.dcl
(action_tile "cancel" "(done_dialog 0)")
(action_tile "accept" "(savevars) (done_dialog 1)")


;'by default start_dialog returns 0 if cancel, 1 if OK, -1 if all boxes term_dialog
(setq d (start_dialog))


(unload_dialog dcl_id)

;'pop up contents of edit_box if ok is pushed
(if (= d 1) (alert textval))
)


(defun savevars ()
(setq textval (get_tile "hellobox")))

Lisp Parabola

This is pretty simple. Its a start. Func1 defines the equation ax^2 + bx + c with the specific values of a b and c and returns the value when passed the current value of X.  C:para calls the parabola function and sets the x minimum, maximum and x increment.

screenshot from the visual lisp editor.
2017-03-05_2

if instead of unconnected lines, we want to graph with a 2D Polyline, the command is PLine, it takes the same point list. We start the Pline command with the first point, then enter the loop and calculate the next point each time through the loop, leaving the command processor running and just feeding it one point each time.

2017-03-05_4

For graphing polar equations – Polar Coordinates – P(R,Ɵ) – A point is defined by how far it is from the origin (R – Radius) and what angle (Ɵ – Theta) a line from the origin to the point makes with the horizontal axis. (I am using A for angle instead of Ɵ in the code)

To change the command from separate lines to connected polyline, we start the pline command outside the loop and only calculate one point in the loop, just as for the rectangular cartesian program.

AutoLisp 2.5

about 1986 R.C. Bradlee published a Xeroxed page book “Programming Autocad” which featured the Autolisp command set as of autocad version 2.5. Selection Sets had just been added. Entity names could be retrieved and properties modified but new entitities had to be added with the Command function (command “Line” pnt1 …). This would be a good starter section for learning the language, not overwhelming but not trivial. Some or most of the links seem to paste in from the Autodesk 2017 help reference. I rearranged and edited the entries into my own idea of fuzzy categories. A disclaimer – this is not an official list of Lisp 2.5 but just my reconstruction. Some functions i left out either inadvertently, or i assume they are obsolete, or simply i dont see a need for them.

Descriptions below all belong to Autodesk. Here is there notice cut / pasted from their help page.

Except where otherwise noted, this (Autodesk) work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.  Please see the Autodesk Creative Commons FAQ for more information.

Math and booleans are first and easiest to master.

+ (add)  (+ [number number …]) Returns the sum of all numbers
– (subtract)  (- [number number …]) Subtracts the second and following numbers from the first and returns the difference
* (multiply)  (* [number number …]) Returns the product of all numbers
/ (divide)  (/ [number number …]) Divides the first number by the product of the remaining numbers and returns the quotient
1+ (increment)  (1+ number) Returns the argument increased by 1 (incremented)
1- (decrement)  (1- number) Returns the argument reduced by 1 (decremented)
abs  (abs number) Returns the absolute value of the argument
atan  (atan num1 [num2]) Returns the arctangent of a number in radians
cos  (cos ang) Returns the cosine of an angle expressed in radians
exp  (exp number) Returns the constant e (a real) raised to a specified power (the natural antilog)
expt  (expt base power) Returns a number raised to a specified power
fix  (fix number) Returns the conversion of a real into the nearest smaller integer
float  (float number) Returns the conversion of a number into a real
gcd  (gcd int1 int2) Returns the greatest common denominator of two integers
log  (log number) Returns the natural log of a number as a real
max  (max [number number …]) Returns the largest of the numbers given
min  (min [number number …]) Returns the smallest of the numbers given
rem  (rem [num1 num2 …]) Divides the first number by the second, and returns the remainder
sin  (sin ang) Returns the sine of an angle as a real expressed in radians
sqrt  (sqrt number) Returns the square root of a number as a real
~ (bitwise NOT)  (~ int) Returns the bitwise NOT (1’s complement) of the argument
logand  (logand [int int …]) Returns the result of the logical bitwise AND of a list of integers
logior  (logior [int int …]) Returns the result of the logical bitwise inclusive OR of a list of integers
lsh  (lsh [int numbits]) Returns the logical bitwise shift of an integer by a specified number of bits
atom  (atom item) Verifies that an item is an atom
boundp  (boundp sym) Verifies whether a value is bound to a symbol
listp  (listp item) Verifies that an item is a list
not  (not item) Verifies that an item evaluates to nil
null  (null item) Verifies that an item is bound to nil
numberp  (numberp item) Verifies that an item is a real or an integer
minusp  (minusp number) Verifies that a number is negative
zerop  (zerop number) Verifies that a number evaluates to zero
= (equal to)  (= numstr [numstr …]) Returns T if all arguments are numerically equal, and returns nil otherwise
/= (not Equal to)  (/= numstr [numstr …]) Returns T if the arguments are not numerically equal, and nil if the arguments are numerically equal
> (greater than)  (< numstr [numstr …]) Returns T if each argument is numerically less than the argument to its right, and returns nil otherwise
>= (greater than or equal to)  (<= numstr [numstr …]) Returns T if each argument is numerically less than or equal to the argument to its right, and returns nil otherwise
< (less than)  (> numstr [numstr …]) Returns T if each argument is numerically greater than the argument to its right, and returns nil otherwise
<= (less than or equal to)  (>= numstr [numstr …]) Returns T if each argument is numerically greater than or equal to the argument to its right, and returns nil otherwise
and  (and [expr …]) Returns the logical AND of a list of expressions
boole  (boole func int1 [int2 …]) Serves as a general bitwise Boolean function
eq  (eq expr1 expr2) Determines whether two expressions are identical
equal  (equal expr1 expr2 [fuzz]) Determines whether two expressions are equal
or  (or [expr …]) Returns the logical OR of a list of expressions
angtos  (angtos angle [mode [precision]]) Converts an angular value in radians into a string
ascii  (ascii string) Returns the conversion of the first character of a string into its ASCII character code (an integer)
atof  (atof string) Returns the conversion of a string into a real
atoi  (atoi string) Returns the conversion of a string into an integer
chr  (chr integer) Returns the conversion of an integer representing an ASCII character code into a single-character string
itoa  (itoa int) Returns the conversion of an integer into a string
rtos  (rtos number [mode [precision]]) Converts a number into a string

Lists and Loops contain the core LIST Processing commands

type  (type item) Returns the type of a specified item
eval  (eval expr) Returns the result of evaluating an AutoLISP expression
quote  (quote expr) Returns an expression without evaluating it
repeat  (repeat int [expr …]) Evaluates each expression a specified number of times, and returns the value of the last expression
while  (while testexpr [expr …]) Evaluates a test expression, and if it is not nil, evaluates other expressions; repeats this process until the test expression evaluates to nil
if  (if testexpr thenexpr [elseexpr]) Conditionally evaluates expressions
cond  (cond [(test result …) …]) Serves as the primary conditional function for AutoLISP
foreach  (foreach name lst [expr …]) Evaluates expressions for all members of a list
progn  (progn [expr …]) Evaluates each expression sequentially, and returns the value of the last expression
command  (command [arguments] …) Executes an AutoCAD command
defun  (defun sym ([arguments] [/variables …]) expr … ) Defines a function
setq  (setq sym1 expr1 [sym2 expr2 …]) Sets the value of a symbol or symbols to associated expressions
getvar  (getvar “varname”) Retrieves the value of an AutoCAD system variable
setvar  (setvar “varname” value) Sets an AutoCAD system variable to a specified value
load  (load filename [onfailure]) Evaluates the AutoLISP expressions in a file
*error*  (*error* string) A user-definable error-handling function
list  (list [expr …]) Takes any number of expressions and combines them into one list
length  (length lst) Returns an integer indicating the number of elements in a list
last  (last lst) Returns the last element in a list
nth  (nth n lst) Returns the nth element of a list
reverse  (reverse lst) Returns a list with its elements reversed
car  (car lst) Returns the first element of a list
cdr  (cdr lst) Returns the specified list, except for the first element of the list
caddr 
cadr 
cons  (cons new-first-element lst) The basic list constructor
append  (append lst …) Takes any number of lists and runs them together as one list
member  (member expr lst) Searches a list for an occurrence of an expression and returns the remainder of the list, starting with the first occurrence of the expression
assoc  (assoc item alist) Searches an association list for an element and returns that association list entry
apply  (apply function lst) Passes a list of arguments to a specified function
mapcar  (mapcar function list1 … listn) Returns a list of the result of executing a function with the individual elements of a list or lists supplied as arguments to the function
lambda  (lambda arguments expr …) Defines an anonymous function

 

Strings and File I/O are pretty straighforward

read  (read [string]) Returns the first list or atom obtained from a string
strcat  (strcat [string1 [string2 …]) Returns a string that is the concatenation of multiple strings
strlen  (strlen [string …]) Returns an integer that is the number of characters in a string
substr  (substr string start [length]) Returns a substring of a string
vl-string-subst  (vl-string-subst new-str pattern string [start-pos]) Substitutes one string for another, within a string
open  (open filename mode) Opens a file for access by the AutoLISP I/O functions
read-char  (read-char [file-desc]) Returns the decimal ASCII code representing the character read from the keyboard input buffer or from an open file
read-line  (read-line [file-desc]) Reads a string from the keyboard or from an open file
write-char  (write-char num [file-desc]) Writes one character to the screen or to an open file
write-line  (write-line string [file-desc]) Writes a string to the screen or to an open file
close  (close file-desc) Closes an open file

 

The last category is Autocad graphic interfacing commands. ( I am leaving out a few things I think may be less useful or obsolete or inadvertently)

angle  (angle pt1 pt2) Returns an angle in radians of a line defined by two endpoints
distance  (distance pt1 pt2) Returns the 3D distance between two points
inters  (inters pt1 pt2 pt3 pt4 [onseg]) Finds the intersection of two lines
osnap  (osnap pt mode) Returns a 3D point that is the result of applying an Object Snap mode to a specified point
polar  (polar pt ang dist) Returns the UCS 3D point at a specified angle and distance from a point
getangle  (getangle [pt] [msg]) Pauses for user input of an angle, and returns that angle in radians
getdist  (getdist [pt] [msg]) Pauses for user input of a distance
getint  (getint [msg]) Pauses for user input of an integer, and returns that integer
getorient  (getorient [pt] [msg]) Pauses for user input of an angle, and returns that angle in radians
getpoint  (getpoint [pt] [msg]) Pauses for user input of a point, and returns that point
getreal  (getreal [msg]) Pauses for user input of a real number, and returns that real number
getstring  (getstring [cr] [msg]) Pauses for user input of a string, and returns that string
entsel  (entsel [msg]) Prompts the user to select a single object (entity) by specifying a point
entdel  (entdel ename) Deletes objects (entities) or restores previously deleted objects
entget  (entget ename [applist]) Retrieves an object’s definition data
entlast  (entlast) Returns the name of the last non-deleted main object in the drawing
entmod  (entmod elist) Modifies the definition data of an object
entnext  (entnext [ename]) Returns the name of the next object in the drawing
entupd  (entupd ename) Updates the screen image of an object
ssadd  (ssadd [ename [ss]]) Adds an object (entity) to a selection set, or creates a new selection set
ssdel  (ssdel ename ss) Deletes an object (entity) from a selection set
ssget  (ssget [mode] [pt1 [pt2]] [pt-list] [filter-list]) Prompts the user to select objects (entities), and returns a selection set
sslength  (sslength ss) Returns an integer containing the number of objects (entities) in a selection set
ssmemb  (ssmemb ename ss) Tests whether an object (entity) is a member of a selection set
ssname  (ssname ss index) Returns the object (entity) name of the indexed element of a selection set
grread  (grread [track] [allkeys [curtype]]) Reads values from any of the AutoCAD input devices
grclear 
graphscr  (graphscr) Displays the AutoCAD graphics screen
grdraw  (grdraw from to color [highlight]) Draws a vector between two points, in the current viewport
grtext  (grtext [box text [highlight]]) Writes text to the status line or to screen menu areas
menucmd  (menucmd string) Issues menu commands, or sets and retrieves menu item status
prin1  (prin1 [expr [file-desc]]) Prints an expression to the command line or writes an expression to an open file
princ  (princ [expr [file-desc]]) Prints an expression to the command line, or writes an expression to an open file
print  (print [expr [file-desc]]) Prints an expression to the command line, or writes an expression to an open file
prompt  (prompt msg) Displays a string on your screen’s prompt area
redraw  (redraw [ename [mode]]) Redraws the current viewport or a specified object (entity) in the current viewport
terpri  (terpri) Prints a newline to the Command line

 

Autocad Help System for Lisp and VBA (ActiveX)

I have found the front end pages for Autocad programming languages VBA (ActiveX) and Lisp (Visual Lisp). Here is my big suggestion. You can copy and paste an entire page of links into Excel and the links transfer. Use Excel to collate and organize Autodesk help bookmarks.

Autodesk splits both subjects into two groups – what they call a Guide which would be teaching text and a Reference which is a page by page Index. Visual Lisp is traditional Autocad Lisp plus ActiveX. So if you are looking for Visual Lisp help, you need to include the ActiveX references in your reading list.

As of 2017, Autodesk has returned “Developer Documentation” to its front end for Autocad 2017 help,
http://help.autodesk.com/view/ACD/2017/ENU/

Following that link brings you to this page to be bookmarked,
http://help.autodesk.com/view/ACD/2017/ENU/?home=homepage_dev

If you copy and paste that page into excel, the links all transfer without any additional work. Here i have marked with asterisk the 5 critical pages.
2017-02-22_2

you can then make tabs for guide and reference for both lisp and activeX. In a few minutes you have an upper level table of contents in a single file. as you explore the pages using the live links you can make notes or mark as read. you can make a reference to the entire page at the top of your excel sheet. Pages come in formatted with good links, you might have to reset column width and row height for entire sheet.

2017-02-22_3

If you are looking for Visual Lisp code, it is in the ActiveX reference. Both groups ActiveX and Lisp have an Object Model page, but the Lisp page is not live, just a picture. The Object Model page for ActiveX has live links. You do not need to paste that page into Excel, but it also pastes with live links, and you never have to go looking for it. You can have the Object Model with links in your spread sheet. Regardless how you access it, it is a very valuable tool.

As an example of its usefulness, say you want to know how to draw a circle with Visual Lisp.

2017-02-22_4

Click on the Circle object. It takes you to Circle Object ActiveX help page. Which has the properties and methods of the object that is a circle, but it does not have the tool to draw a circle. The Addcircle is a method of ModelSpace, PaperSpace and Block. Click on ModelSpace, scroll down to the methods, and click on AddCircle. there you find the code to draw a circle in both VBA and Lisp. Code that you can paste into your VBA module or Lisp editor.

http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-18ADF171-166F-4FF0-8ED6-5F83153A5649#GUID-18ADF171-166F-4FF0-8ED6-5F83153A5649

http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-837C702F-91A7-445B-8713-3099B94664BE

the object model –

http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-A809CD71-4655-44E2-B674-1FE200B9FE30

2017-02-22_6

* EDIT – unfortunately the ActiveX Reference page links did NOT copy from www into Excel. *
The other pages, lisp guide and reference, activex guide, and activex model links do work in excel.

and finally, autocad 2017 still installs two activex chm files on your hard drive with installation, the Guide and the Reference. You can also link to those.

2017-02-22_7