Visual LISP Sample
This document supplements the
code comments contained in the sample files that are included in Visual LISP.
It details the uses for these files and the concepts they demonstrate.
This document expands on the code comments
already included in the sample files that ship with Visual LISP. The
following sections explain the important concepts that these sample files are
meant to demonstrate.
Before reading further, please note that this document assumes you are
already familiar with the Visual LISP Integrated Development Environment (IDE)
and the AutoLISP programming language.
Visual LISP Sample Files
If for some reason you do not have the Visual Lisp Sample
files, you can download them from here.
Visual LISP contains a collection of sample LISP
files that are located in <your Visual LISP directory>\Sample.
These files range in complexity from basic AutoLISP to advanced techniques in
implementing the Visual LISP connection to the AutoCAD ActiveX Object Model. You
will also encounter examples that use the special ActiveX Extension functions
included in the Visual LISP function library.
You should be able to find the following files in your \SAMPLE directory:
<your Visual LISP directory>\Sample
<your Visual LISP directory>\Sample\ActiveX
<your Visual LISP directory>\Sample\Reactors
Each of the following explanations includes a list of the functions in the
sample files as well as the syntax you should use to call them from the Visual
LISP Console prompt. However, function names preceded by a c: can be called from
the AutoCAD command line as well. All other functions must be called from the
Visual LISP Console prompt unless you explicitly export them to AutoCAD as
native AutoLISP functions, at which point you could call them from the AutoCAD
The executable function lists that accompany the sample file explanations
follow the syntax as described here:
Example of a non-exported function:
Example of an exported function:
(c:functionB) (from the Visual LISP Console or AutoCAD command
functionB (from the AutoCAD Command Line
only) This syntax
will not be included later in this document; it should be understood as a
feature of preceding function names with a "c:".
Visual LISP Samples
This file defines two functions that use recursion to factorize an integer.
Each function requires one argument which should be an integer between 1 and 31.
For example, (fact1 5) returns 120 by calling fact2 which in turn calls
fact1, each time decreasing the value of the argument by 1 and multiplying it by
the product from the previous functions return value.
The range of 1 to 31 is based on a limitation of the ability of AutoLISP and
Visual LISP to process any value outside of its Integer data type range, a
32-bit signed value. The range is between -2,147,483,648 and 2,147,483,647 or
-231 ณ X ณ (231 - 1).
However, with regard to the practice of recursion, the limitation on the
depth of recursion for this routine is far more lenient. In the AutoLISP
environment, these functions can reach a depth of 144; in the Visual LISP
environment, these functions can reach a depth of 983. The maximum attainable
depth varies by the complexity of the routine.
The argument n is an integer between 1 and
The argument n is an integer between 1 and
This sample file is used throughout the documentation to demonstrate Visual
LISP concepts and features. It is the corrected version of the drawline-with-errors.lsp file which this document describes next.
This routine defines a simple function that draws a line with the AutoCAD
LINE command using the AutoLISP command function after it asks the user to
specify a start point and end point. If the user does not pass valid coordinate
values for the start point and end point prompts, the routine will return a
predefined error message.
This file is the same as drawline.lsp, however, it contains deliberate
errors. The focus of this routine is to provide the user with the opportunity to
become familiar with Visual LISP debugging tools. This sample file is referenced
in your online Help in:
Developing Programs With Visual LISP
Checking for Syntax Errors
Balance of Parentheses
Using Color Coding to
Detect Syntax Errors
As explained earlier, this routine draws a line with the AutoCAD LINE command
using the AutoLISP command function after it asks the user to specify a
start point and end point. The user will first need to debug the program to make
it functional. See Chapter 6 of your on-line Help documentation for information
on Visual LISPs debugging tools.
This file contains two main functions that can be used to compare the speed
of calling AutoCAD commands with the AutoLISP command function verses
implementation of ActiveX methods. Both programs create a 3D mesh and return the
time required to complete the task. The al-gf function uses AutoCAD commands to
create the 3D mesh, and the vla-gf function uses ActiveX methods to create the
You will need to make sure that the User Elapsed Timer is on (see the TIME
command in your AutoCAD on-line Help).
c:vla-gf (ActiveX methods)
c:al-gf (AutoCAD commands)
Note: The first time an ActiveX function is executed, you may
notice less of a speed improvement than expected because the environment may
need to be initialized or AutoCAD may need to reclaim memory. Subsequent calls
using that connection will be significantly faster than calling AutoCAD
commands using the AutoLISP command function.
This sample file demonstrates the difference between implicitly and
explicitly exporting functions to AutoCAD and AutoLISP from the Visual LISP
The c:hello command is a Command defined function ("c:") and is
therefore implicitly exported to AutoLISP and can be called from the AutoCAD
command line when loaded in Visual LISP.
The HELLO function passes an argument to a princ expression as the second
part of a string that is printed at the command line. It is called by the
hello-autocad function which is explicitly exported to AutoLISP using the
vl-acad-defun function when loaded in Visual LISP.
A significant point that this routine demonstrates is that functions which
are exported to AutoCAD or AutoLISP from Visual LISP are not functions at all.
They are simply references to functions which exist as USUBR routines in the
Visual LISP environment. For example, if you open and load hello.lsp in
Visual LISP and then enter (type hello-autocad) at the AutoCAD command
line, it will return EXRXSUBR. This signifies that hello-autocad is contained in
an external ARX subroutine (in this case, vlide.arx). Therefore, when you
call the hello-autocad function, it is not being executed in the AutoLISP
environment; it is being executed in the Visual LISP environment.
The s argument is the string the user passes
to the function.
The s argument is the string the user passes
directly when calling the hello function or indirectly when calling the
hello-autocad function. Note that (hello s) is only available from Visual LISP
and not AutoLISP since it was neither implicitly or explicitly exported to
This sample file demonstrates a workaround for a limitation involving the
AutoCAD IMAGE command where you are not allowed to pass additional arguments
when calling it with the AutoLISP command function within Visual LISP. As an
alternative, this file demonstrates how a user can insert an image using ActiveX
methods. A suggested example of executable syntax is included at the end of the image.lsp file.
(insert-image image_file_name insertion_point scale rotation)
(insert-image ".\\Textures\\3ds.tga" '(0.0 0.0 0.0) 1 0.0)
This sample file demonstrates two examples of the ability of Visual LISP to
add and remove non-graphical data in a drawing using Visual LISP vlax-ldata-xxx
extension functions. These functions are advanced solutions to the standard
procedures for adding and removing dictionary data.
Upon executing the function, the routine runs through two examples using the
vlax-ldata-xxx functions. The first example creates and stores data to key
"KEY1" in the named object dictionary that it also creates called "MY-DICT". It
then lists the data contained in the key and finishes by removing the key, but
it does not remove the dictionary entry.
The second example creates a Circle object, associates it with key "KEY2"
which the routine stores in the AutoCAD extension Dictionary (ACAD_XDICTIONARY),
and lists the extension data which it stored in that key using the
vlax-ldata-put function. It then proceeds to remove the key and finally deletes
the Circle object.
Similar to the second section of LispData1.lsp, this sample file
demonstrates the use of non-graphical data in a drawing by allowing the user to
add or change the value of key "LDT" associated with a graphical object and
located in the AutoCAD extension dictionary, using the vlax-ldata-xxx functions.
The "LDT" key value is not set on a selected object until you run the routine
once. Afterwards, you can use the routine to change the value associated with
key "LDT" for that object.
Please note that this description supplements the extensive comments
contained in the Regarx.lsp file. Furthermore, it supersedes the comments in the
source code on the function arguments which are incorrect.
The regarx.lsp sample file demonstrates how to register the Visual
LISP IDE ARX application for demand loading by designated commands. It also
provides a thorough explanation of the information necessary to implement this
mechanism since the wrong information in any location of the registry can
completely disable AutoCAD and possibly your operating system. Please back up
your registry before running any commands that edit and change your registry
Regarx.lsp also suggests code on how to unregister command demand
loading. The register-VL-app function defined in this routine is a replica of
Visual LISPs vlax-reg-app function. With either of these functions, you will be
able to register the Visual LISP IDE ARX application by designating the correct
parameters for instructing AutoCAD to load the application on demand. The
vlax-reg-app function is more general and can be used to register any
application. Please see the Visual LISP documentation for a description of that
The register-VL-app function requires three arguments:
1. app-rp - The application name: a key to be entered in the
Registry. It will need to look like this: "SOFTWARE\\your_application_name"
2. cmds - A quoted list of the commands which you designate for the
demand loading of Vlide.arx when invoked (demand loading requires at least the
4 bit-code value to be set in the loadctrls parameter below).
3. loadctrls - An integer flag that is equal to the sum of any
combination of the following possibilities (from the ObjectARX Developers
0 No action taken (do not load the application).
1 Load the application upon detection of proxy object.
2 Load the application upon AutoCAD start-up.
4 Load the application upon invocation of a command (defined in your
8 Load the application upon request by the user or another application.
16 Do not load the application.
At the end of the file, you will find sample code that passes correct
parameters to the register-VL-app function.
'("[command name]" "[command name]" etc
For example to register Visual Lisp for demand loading:
register-vl-app (strcat "SOFTWARE\\Autodesk\\VisualLISP\\"
This sample file provides an example of what can be accomplished with Visual
LISP registry functions. The dump-registered-apps function prints out a registry
database subtree for every application that is registered for demand loading in
your AutoCAD Release 14 configuration.
One particular expression worth mentioning in the registry-tree-dump function
(called by dump-registered-apps) is the second occurrence of the foreach
function which contains a recursive call to registry-tree-dump. For each
application that is registered for demand loading, there are three subkeys: Commands,
Loader, and Name. This particular foreach
expression applies the registry-tree-dump function to the string concatenation
of each these three subkeys with the key for each of the registered applications
to build and print out its subtree.
This sample file defines two functions and uses the Visual LISP vl-acad-defun
function to explicitly export them to the AutoLISP environment. Each of these
two functions contain only one expression: a call to one Visual LISP symbol
function. These symbol functions, vlisp-import-symbol and vlisp-export-symbol,
are used to copy variables between the Visual LISP environment and the AutoLISP
It is important to recognize that vl-acad-defun does not actually copy the
function to AutoLISP. What it does is insert a reference to a function which
exists as a USUBR routine in the Visual LISP environment. Therefore, although
you call the function in AutoLISP, it is still executed in Visual LISP.
It is also important to notice that the vl-acad-defun expressions appear
outside of the defined functions. If they were inside a non-command line
function (no "c:"), it would be impossible to call either of the two functions
in sym-exp.lsp if you compiled it as an ARX routine because the
vl-acad-defun expressions could never be evaluated. Therefore, there are two
rules to follow for explicitly exporting functions from an ARX routine without
using a command line function to evaluate vl-acad-defun expressions:
1. The vl-acad-defun expressions must be contained outside of the defined
2. You must select "Initialize in load time" in step 7 of the
Code is included at the end of the sample file which can be used to test
these functions from the AutoCAD command line.
This program utilizes Editor Reactors to update a "time-stamp" text entity
each time the user completes an instance of the PLOT command. Between the user
pressing OK to begin the plotting procedure and AutoCAD spooling to the plotter,
the Editor Reactor fires off the callback function which adds or updates a
time-stamp text entity at a base point of 0,0,0.
This routine ties together several major concepts that other sample files
The LDATA functions: Using vlax-ldata-put, it creates a global dictionary
named "TIME-STAMP". This dictionary contains a key named "TEXT-OBJECT" whose
value is the "time-stamp" text entity in the form of a Visual LISP ActiveX
The REGISTRY functions: Using vlax-reg-app, entries are made in the
Registry that associates vlide.arx (the primary Visual LISP module) or
whichever ARX application from which you first ran the Register-Timestamp
function in the AutoCAD application. The result is that until you run the
Unregister-Timestamp function, the associated ARX application will
automatically be launched the next time you start AutoCAD regardless of the
drawing file that you open.
Furthermore, if you open the drawing in which you registered the Time-Stamp
routine without the associated ARX loaded, you will receive a notification
dialog informing you that the required ARX application is missing.
Please note that if you have already registered other commands to demand
load the Visual LISP IDE, once Register-TimeStamp is run, those commands will
no longer demand load the Visual LISP IDE. To return to other commands for
demand loading of vlide.arx, you will have to re-register your command
since the UnRegister-TimeStamp function merely turns off demand loading but
leaves the registered application pointing to TimeStamp.
There is a workaround contained in this sample file which solves an "Object
Open for Read" error which you may receive in connection with associating a
callback function with the PLOT command to modify a graphical entity. The
workaround is to add an additional graphical object to the drawing after
creating the object which the callback function modifies. This behavior is
documented and explained in the Visual LISP Readme file.
Upon loading this sample file, it uses ActiveX function calls to draw a line.
It then passes the line as a VLA Object along with a 4 x 4 transformation matrix
to the vla-TransformBy function in order to rotate the line by 90 degrees. The
file provides a total of five different matrices which can be used to rotate,
move, or scale the line. To switch to a different matrix, change the variable
called in the vla-TransformBy expression.
The use of matrices can be an excellent shortcut for manipulating graphical
objects. Once created, the code for a matrix can easily be reapplied in other
functions. The following documentation can be found in the Visual LISP online
Help in the AutoLISP Function Reference under "nentselp":
The first three columns of the matrix specify scaling and rotation. The
fourth column is a translation vector.
The functions that use a matrix of this type treat a point as a column vector
of dimension 4. The point is expressed in homogeneous coordinates, where the
fourth element of the point vector is a scale factor that is normally set to
1.0. The final row of the matrix, the vector [M30 M31 M32 M33], has the nominal
value of [0 0 0 1]; it is currently ignored by the functions that use this
matrix format. In this convention, applying a transformation to a point is a
matrix multiplication that appears as follows:
This multiplication gives us the individual coordinates of the point as
As these equations show, the scale factor and the last row of the matrix have
no effect and are ignored.
It is also noteworthy to mention a Visual LISP function called vlax-tmatrix
which will accept a list of four lists representing a 4 x 4 transformation
matrix (each sub-list contains four numbers). Specifically, it will process the
lists, converting each number to a real and then returns the list in a format
that is compatible with ActiveX requirements. The return can then be passed to
the vla-TransformBy function.
When run from the AutoCAD command line, this program ends your Visual LISP
session by unloading the vlide.arx module. Using Visual LISP functions
not available in native AutoLISP, it creates a script file in the Windows System
Temp directory with the Visual LISP application path and name (vlide.arx)
along with the ARXUNLOAD command. It then uses the AutoCAD SCRIPT command to run
This sample file is referenced throughout the Visual LISP online
documentation. It is used as an example for debugging in Chapter 6, building
applications in Chapter 7, and defining some functions in the Visual LISP AutoLISP Function Reference.
The routine asks for user input and draws a "Yin-Yang" symbol with basic
AutoCAD geometry commands. Using the vl-acad-defun function, it explicitly
exports the yinyang function as a native AutoLISP function so it can be called
from within the AutoLISP environment in addition to the Visual LISP environment.
Please see the section on sym-exp.lsp for more information on the use of
the vl-acad-defun function.
Visual LISP ActiveX Sample
The ActiveX enabled sample programs demonstrate and test the speed
enhancements with using the Visual LISP "vla-" function connections to the
ActiveX Object Model versus the conventional AutoLISP function library. The
al-tst function draws 2000 circles and changes their properties by means of the
native AutoLISP functions. The vla-tst function completes the same test using
Visual LISP VLAX functions and ActiveX methods and properties. You will need to
make sure that the User Elapsed Timer is on (see the TIME command in your
AutoCAD online Help).
To Run the test:
Note: Because the contents of MKP files are dependent on the
directory structure of the system on which they originated, using the
vla-tst.mkp file may generate error messages. It is recommended you select the
"New Application Wizard" option under File > Make Application to create a
new MKP file for your system.
There are several options for running the test command functions:
Load the resulting vla-tst.arx file in AutoCAD.
Run the ActiveX test using the vla-tst command.
Run the AutoLISP test using the al-tst command.
Run the native AutoLISP (uncompiled) test by unloading
vla-tst.arx, loadingal-tst.lsp in AutoCAD and using the al-tst
Load the vla-tst.prj files into Visual LISP, run the uncompiled
vla-tst or al-tst functions from the AutoCAD Command Line (or (c:vla-tst) and
(c:al-tst) from the Visual LISP Console).
Each test prints the elapsed time for the procedure.
Visual LISP Reactor Samples
Both of these reactor projects build upon Visual LISP code that is covered
the preceding sample files. However, these two sample projects implement
LISPs reactor functions. At this time, the only other way to accomplish
AutoCAD drawings is to write ObjectARX C++ applications.
If you are planning on implementing reactors
within your Visual LISP code,
there is important documentation you will need to review in addition to the
sample code in these projects. Please carefully study Lessons 6 and 7 of the
Visual LISP Garden Path Tutorial as well as Chapter 9 in the Visual LISP
online Help documentation.
This project demonstrates how to create
circles of equal radii which lie on a given curve,
have an equal step in distance along the curve, and maintain these relationships
some of the objects are modified. The project also gives you examples of
files in your compiled applications, registration of LISP defined commands, and
registration of an application or command.
Note: Before loading the Rctr-tst project into
Visual LISP, you may need to set the Project properties Build Options for the
FAS directory and TMP directories for the appropriate directory location on
your hard drive. Otherwise you may receive this error when attempting to load
the project: ; *** ERROR: in project RCTR-TST: the FAS Directory does not
There is one minor change which you will need to make in order for
this sample code to work.
Please modify the following line in the
Getparm.lsp file from:
(setq radius (get-radius (vlax-curve-getStartPoint aCurve)))
(setq radius (get-radius-from-point (vlax-curve-getStartPoint aCurve)))
After loading the source files using the project file rctr-tst.prj, you can
start the program using the RCTR-TST command. This command will prompt you to
choose between dialog or prompt mode. In both cases, you will first select a
circle that you have previously drawn before running this command. Next, you
will be asked to determine the circles initial radius, their number and color,
and finally if the reactors will be persistent. If you choose the persistent
option, all reactors will be restored automatically in subsequent drawing
sessions (persistent reactors are saved with the drawing, transient reactors are
not). After the command ends, you can change the radii of the circles, the
parameters of the curve, and move the circles or curve all in a dynamic
relationship to each other.
The Rctr-tst project contains no c:RCTR-TST function defined in any of the
source files. Instead, it uses the vlax-add-cmd function and registers this
command in the registry.
Note: If you wish to compile this as an
application, it is important to note that because the contents of MKP files
are dependent on the directory structure of the system on which they
originated, using the Rctr-tst.mkp file may generate error messages. It is
recommended you select the "New Application Wizard" option under
File ฎ Make Application to create a new MKP file for your system.
(rctr-tst) (from the Visual LISP console only)
rctr-tst (from the AutoCAD command line only)
This project comprises of a host of different functions which provide
examples of what can be accomplished using Reactors. These examples cover each
of the four types of Reactors: Linker, Editor, Database, and Object. For more
information on the different reactor types, see Attaching Reactors to AutoCAD
Drawings in Chapter 9 of your Visual LISP online Help.
After opening the reac-tst.prj project, choose the "Load Source Files"
button. This process will print out the associated functions to the AutoCAD Text
Window due to the contents of toplevel.lsp. As you will see in the text
window output after loading the source files (which is included below), each
function is associated with another function that will provide information on
how it works. Text Window contents:
|To test: SAME-RCL-TST
||For information: SAME-RCL-INFO
|To test: RTRANSL-TST
||For information: RTRANSL-INFO
|To test: ROLLS-TST
||For information: ROLLS-INFO
|To test: PIPE-TST
||For information: PIPE-INFO
|To test: OBJEX-TST
||For information: OBJEX-INFO
|To test: LINKEX-TST
||For information: LINKEX-INFO
||To stop: STOP-LINKEX-TST|
|To test: EDITEX-TST
||For information: EDITEX-INFO
||To stop: STOP-EDITEX-TST|
|To test: DUMBELLS-TST
||For information: DUMBELLS-INFO
|To test: DIMEX-TST
||For information: DIMEX-INFO
|To test: COPYSELF-TEST
||For information: COPYSELF-INFO
|To test: ACDBEX-TST
||For information: ACDBEX-INFO
||To stop: STOP-ACDBEX-TST|
|To test: A-MTEXT-TEST
||For information: A-MTEXT-INFO|
It is important to load the entire project rather than individual source
files because some of the routines call functions that are defined in other
files. Review the following table to see where you can find examples of specific