- •Introduction
- •Who should read this book
- •How This Book Is Organized
- •How to Use This Book
- •Where to Find the LISP Programs
- •CHAPTER 1: Introducing AutoLISP
- •Understanding the Interpreter and Evaluation
- •The Components of an Expression
- •Using Arguments and Expressions
- •Using Variables
- •Understanding Data Types
- •Integers and Real Numbers
- •Strings
- •Lists
- •File Descriptors
- •Object Names
- •Selection Sets
- •Symbols
- •Subrs
- •Atoms
- •Assigning Values to Variables with Setq
- •Preventing Evaluation of Arguments
- •Applying Variables
- •Functions for Assigning Values to Variables
- •Adding Prompts
- •CHAPTER 2: Storing and Running Programs
- •Creating an AutoLISP Program
- •What you Need
- •Creating an AutoLISP File
- •Loading an AutoLISP file
- •Running a Loaded Program
- •Understanding How a Program Works
- •Using AutoCAD Commands in AutoLISP
- •How to Create a Program
- •Local and Global Variables
- •Automatic Loading of Programs
- •Managing Large Acad.lsp files
- •Using AutoLISP in a Menu
- •Using Script Files
- •CHAPTER 3: Organizing a Program
- •Looking at a Programs Design
- •Outlining Your Programming Project
- •Using Functions
- •Adding a Function
- •Reusing Functions
- •Creating an 3D Box program
- •Creating a 3D Wedge Program
- •Making Your Code More Readable
- •Using Prettyprint
- •Using Comments
- •Using Capitals and Lower Case Letters
- •Dynamic Scoping
- •CHAPTER 4: Interacting with the Drawing Editor
- •A Sample Program Using Getdist
- •How to Get Angle Values
- •Using Getangle and Getorient
- •How to Get Text Input
- •Using Getstring
- •Using Getkword
- •How to Get Numeric Values
- •Using Getreal and Getint
- •How to Control User Input
- •Using Initget
- •Prompting for Dissimilar Variable Types
- •Using Multiple Keywords
- •How to Select Groups of Objects
- •Using Ssget
- •A Sample Program Using Ssget
- •CHAPTER 5: Making Decisions with AutoLISP
- •Making Decisions
- •How to Test for Conditions
- •Using the If function
- •How to Make Several Expressions Act like One
- •How to Test Multiple Conditions
- •Using the Cond function
- •How to Repeat parts of a Program
- •Using the While Function
- •Using the Repeat Function
- •Using Test Expressions
- •CHAPTER 6: Working With Geometry
- •How to find Angles and Distances
- •Understanding the Angle, Distance, and Polar Functions
- •Using Trigonometry to Solve a Problem
- •Gathering Information
- •Finding Points Using Trigonometry
- •Functions Useful in Geometric Transformations
- •Trans
- •Atan
- •Inters
- •CHAPTER 7: Working with Text
- •Working With String Data Types
- •Searching for Strings
- •Converting a Number to a String
- •How to read ASCII text files
- •Using a File Import Program
- •Writing ASCII Files to Disk
- •Using a Text Export Program
- •CHAPTER 8: Interacting with AutoLISP
- •Reading and Writing to the Screen
- •Reading the Cursor Dynamically
- •Writing Text to the Status and Menu Areas
- •Calling Menus from AutoLISP
- •Drawing Temporary Images on the Drawing Area
- •Using Defaults in a Program
- •Adding Default Responses to your Program
- •Dealing with Aborted Functions
- •Using the *error* Function
- •Organizing Code to Reduce Errors
- •Debugging Programs
- •Common Programming Errors
- •Using Variables as Debugging Tools
- •CHAPTER 9: Using Lists to store data
- •Getting Data from a List
- •Using Simple Lists for Data Storage
- •Evaluating Data from an Entire List at Once
- •Using Complex Lists to Store Data
- •Using Lists for Comparisons
- •Locating Elements in a List
- •Searching Through Lists
- •Finding the Properties of AutoCAD Objects
- •Using Selection Sets and Object Names
- •Understanding the structure of Property Lists
- •Changing the properties of AutoCAD objects
- •Getting an Object Name and Coordinate Together
- •CHAPTER 10: Editing AutoCAD objects
- •Editing Multiple objects
- •Improving Processing Speed
- •Using Cmdecho to Speed up Your Program
- •Improving Speed Through Direct Database Access
- •Filtering Objects for Specific Properties
- •Filtering a Selection Set
- •Selecting Objects Based on Properties
- •Accessing AutoCAD's System Tables
- •CHAPTER 11: Accessing Complex Objects
- •Accessing Polyline Vertices
- •Defining a New Polyline
- •Drawing the new Polyline
- •Testing for Polyline Types
- •How Arcs are Described in Polylines
- •Accessing Object Handles and Block Attributes
- •Using Object Handles
- •Using Object Handles
- •Extracting Attribute Data
- •Appendix A: Menu Primer
- •Appendix B: Error Messages
- •Appendix C: Group Codes
The ABC’s of AutoLISP by George Omura
How to Create a Program
The box program is like a collection of expressions working together to perform a single task. Each individual expression performs some operation who's resulting value is passed to the next expression through the use of variables (see figure 2.8).
Figure 2.8: Arguments are assigned to variables in the function
The first line in the box program:
(defun c:BOX (/ pt1 pt2 pt3 pt4)
ties the collection of expressions that follow into a command called Box. Defun is a special function that allows you to define other functions. The arguments to defun are first the function name, in this case, C:BOX, followed by the argument list. The Quote function is automatically applied to the first argument. The c: in the name tells AutoLISP that this function is to act like an AutoCAD command. This means that if the function name is entered at the
37
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
AutoCAD command prompt, the function will be executed as an AutoCAD command. The name following the C: should entered in upper case letters. Care should be take not to give your functions names reserved for AutoLISP's built in functions and atoms. If, for example, you were to give the box function the name setq, then the setq function would be replaced by the box function and would not work properly.
Table 1.1 shows a list of AutoLISP function names that can easily be mistaken for user defined variable names.
abs |
if |
or |
and |
length |
pi |
angle |
list |
read |
apply |
load |
repeat |
atom |
member |
reverse |
distan |
nil |
set |
ce |
|
|
eq |
not |
t |
equal |
nth |
type |
fix |
null |
while |
float |
open |
|
Table 1.1 AutoLISP function names
The list that follows the name Box is an argument list. An argument list is used for two purposes. First, it is used where the function is called from another function to evaluate a set of values. For example, you could define a function that adds the square of two variables. Try entering the following function directly into the AutoLISP interpreter.
(defun ADSQUARE (x y)
(+ (* x x) (* y y))
)
1. Carefully enter the first line. Pay special attention to the parentheses and spaces.
(defun ADSQUARE (x y)
2. Once you are sure everything is correct, press Return. You will see the following prompt:
38
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
(>
This tells you that your expressing is missing one closing parenthesis.
3. Enter the rest of the function at the 1> prompt again checking your typing before pressing Return.
In this example, the c: is left out of the Defun line. By doing this, you create a function that can be used in other functions like a subprogram or during an AutoCAD command. We'll discuss this item in more detail later. Note that the variables X and Y are included in the parentheses after the name of the function, ADSQUARE. This is the argument list. To use this function, enter the following at the command prompt:
(adsquare 2 4)
AutoLISP returns 20. The variables X and Y in the ADDSQUARE function take on the arguments 2 and 4 in the order they are listed. X takes on the value of 2, and Y takes on the value of 4 (see figure 2.9).
Figure 2.9: Arguments are evaluated before they are assigned to variables in the function
39
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
Variables can also be used to pass values to the function. For example, if you have a variable called A whose value is 2 and a variable B whose value is 4, you could use A and B in place of the 2 and 4. Enter the following:
(setq a 2)
(setq b 4)
(adsquare a b)
AutoLISP returns 20. Remember that AutoLISP evaluates the arguments before applying them to the function. This rule applies even to functions that you create yourself. In this case, the A is evaluated to 2 before it is passed to the X variable B is evaluated to 4 before it is passed to the Y variable.
Local and Global Variables
The second use for the argument list is to determine global and local variables. Global variables maintain their value even after a function has finished executing. In chapter 1, when you assign the value 1.618 to the variable Golden, Golden holds that value no matter where it is used. Any function can evaluate Golden to get its value, 1.618. Enter the following:
(setq golden 1.618)
(adsquare 2 golden)
The value of 6.61792 is returned. A local variable, on the other hand, holds its value only within the function it is found in. For example, the variable X in the Adsquare function above holds the value 2 only while the Square function is evaluated. Once the function is finished running, X's value of 2 is discarded. Enter the following:
!x
Nil is returned. The variables A, B, and Golden, however, are global and will return a value. Enter the following:
!golden
The value 1.618 is returned. This temporary assigning of a value to a variable with a function is called binding. This term should not be confused with the term bound which often refers to the general assignment of a value to a variable. In the example of X above, we say that a binding is created for the value X within the function Adsquare. In order for binding to take place, a variable must be used within a function that includes that variable in its argument list. Global variables cannot have bindings since they are not by their very definition confined to individual functions (see figure 2.10).
40
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
Figure 2.10: Local and Global variables
Since an argument list is used for two purposes, the forward slash symbol is used to separate variables used locally from function arguments to which values are passed when the function is called. The variables used to hold the value of arguments are listed first. Then a slash is entered, then the list of local variables as in the following example:
(defun square2 (x y / dx dy)
(setq dx (* x x))
(setq dy (* y y))
(+ dx dy)
)
X and Y are variables that will be assigned values when the function is called initially, as in the Square function given earlier. Dx and Dy, on the other hand, are variables assigned values within the function, so they follow the slash sign. In either case, the variables are local. Arguments left out of the list become global. If, for example, Dy is left out of the argument list, it's value will remain in the AutoLISP system memory for as long as the current editing
41
Copyright © 2001 George Omura,,World rights reserved