- •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
Mapcar takes the list of points ptlst and, one at a time, applies each element of the list to the variable rand in the lambda expression until all the elements of the list have been applied. The if conditional expression is added to the lambda expression to check for the end of ptlst.
Mapcar can apply more than one lists to a function as shown in the following expression:
(mapcar 'setvar
'("cmdecho" "blipmode" "osnap" "expert")
'(0 0 512 1)
)
Here mapcar applies several AutoCAD system variables to the setvar function. One element is taken from each list and applied to setvar. "Cmdecho" is set to 0, "blipmode is set to 1, "osmode" is set to 512, the nearest mode, and "expert" is set to 1.
Evaluating Data from an Entire List at Once
Apply is similar to mapcar in that it allows you to supply a list as an argument to a function. But rather than metering out each item in the list one by one, apply gives the entire contents of a list as an argument all at once. As an example, you could use apply in the Mdist function to add distances.
;Program |
to measure non-sequential distances |
|
(defun MDIST (/ dstlst dst) |
|
|
;while |
loop to obtain list of points-------------------------------------- |
|
(while |
(setq dst (getdist "\nPick distance or Return to exit: ")) |
|
|
(Setq dstlst (append dstlst (list dst))) |
;append new point to list |
|
(princ (apply '+ dstlst)) |
;print current total |
);end while;--------------------------------------------------------------
);end MDIST
Figure 9.3: The Mdist function using the apply function.
In this example, apply is given the list of distances dstlst which it applies to the plus function. If you load and run this program, it works no differently from the earlier version of MDIST.
191
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
Using Complex Lists to Store Data
In chapter 8, you created an error function that reset the osmode system variable when an error occurred. The problem with that error function was that it was too specific. It only worked for certain conditions namely, to restore the osmode system variable to its previous setting. But you can create a function that will help you handle system variable settings in a more general way using the length function.
The length function allows you to find the length of a list. This function is often used in conjunction with the repeat function to process a list. The following function converts a list of system variables to a list containing both the variable and its current setting:
(defun GETMODE (mod1) (setq *mod2 '())
(repeat (length mod1) (setq *mod2
(append *mod2
(list (list (car mod1) (getvar (car mod1))))
)
)
(setq mod1 (cdr mod1)))
)
Using this function, you can store the current system variable settings in a list. Figure 9.4 shows the C:BREAK2 program from chapter 8 with modifications to add the getmode function.
192
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
;function to save system variable settings---------------------------------- |
|
|
|||
(defun GETMODE (mod1) |
|
|
|
||
(setq *mod2 '()) |
|
;create global variable to store settings |
|||
(repeat (length mod1) |
;find length of variable list and repeat |
||||
(setq *mod2 |
|
|
;build *mod2 list |
|
|
(append *mod2 |
|
|
|
||
(list (list (car mod1) (getvar (car mod1)))) |
|||||
) |
|
|
|
|
|
) |
|
|
|
|
|
(setq mod1 (cdr mod1)) |
;go to next element in list |
||||
);end repeat |
|
|
|
|
|
) |
|
|
|
|
|
;function to restore system variable settings------------------------------- |
|
||||
(defun SETMODE (mod1) |
|
|
|
||
(repeat (length mod1) |
|
;find length of list and repeat |
|||
(setvar (caar mod1) (cadar mod1)) |
;extract setting info and reset |
||||
(setq mod1 (cdr mod1)) |
|
;go to next element in list |
|||
);end repeat |
|
|
|
|
|
) |
|
|
|
|
|
;function for error trap --------------------------------------------------- |
|
|
|
||
(defun *error* (msg) |
|
|
|
||
(setmode *mod2) |
|
|
|
;reset system variables |
|
(princ msg) |
|
|
|
;print error message |
|
(princ) |
|
|
|
|
|
) |
|
|
|
|
|
;program to break circle into two arcs-------------------------------------- |
|
|
|||
(defun C:BREAK2 (/ pt1 pt2 pt3 pt4 pt0 ang1 dst1) |
|
||||
(getmode '("osmode" "orthomode" "cmdecho")) |
;saves system vars. |
||||
(mapcar 'setvar '("osmode" "orthomode" "cmdecho") |
;set vars. for funct. |
||||
'(512 |
0 |
0) |
|
|
|
) |
|
|
|
|
|
(setq pt1 (getpoint "\nSelect object: ")) |
|
;get first break point |
|||
(setq pt2 (getpoint pt1 "\nEnter second point: ")) |
;get second break point |
||||
(setvar "osmode" 128) |
|
|
;perpend osnap mode |
||
(Setq pt3 (getpoint pt1 "\nSelect parallel line: "));get 2nd line |
|||||
(setq ang1 (angle pt1 pt3)) |
|
|
;find angle btwn lines |
||
(setq dst1 (distance pt1 pt3)) |
|
|
;find dist. btwn lines |
||
(setq pt4 (polar pt2 ang1 dst1)) |
|
|
;derive pt4 on 2nd line |
||
(command |
|
|
|
|
|
"break" pt1 pt2 |
|
|
;break 1st line |
||
"break" pt3 pt4 |
|
|
;break 2nd line |
||
"line" pt1 pt3 "" |
|
|
;close ends of lines |
||
"line" pt2 pt4 "" |
|
|
|
||
) |
|
|
|
|
|
(setmode *mod2) |
|
|
|
;reset system vars. |
|
) |
|
|
|
|
|
|
|
|
|
|
|
Figure 9.4: Revised BREAK2 program
193
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
The following expression has been added to the BREAK2 program:
(getmode '("osmode" "orthomode" "cmdecho"))
Here, a list of system variables is supplied as an argument to the getmode function. The following explains what getmode does with this list.
The first expression in getmod creates a list to be appended to. The second expression is a recursive one using the repeat function:
(setq *mod2 '())
(repeat (length mod1)
Repeat uses an integer argument to determine the number of time it is to repeat the evaluation of its other arguments. Here, length is used to find the length of mod1 which is a local variable that has the list of system variables passed to it. Length finds the number of elements in the list mod1, which in our example is 3, and passes that value to the repeat function (see Figure 9.5).
Figure 9.5: Using length and repeat in the getmode function
Repeat then processes the following set of expressions 3 times:
(setq *mod2
(append *mod2 (list (list (car mod1) (getvar (car mod1)))))
)
(setq mod1 (cdr mod1)))
194
Copyright © 2001 George Omura,,World rights reserved
The ABC’s of AutoLISP by George Omura
This set of expressions takes an element of the list mod1 and finds the current setting for that element.
(getvar (car mod1))
Then the setting value is combined with the setting name to form a two element list:
(list (car mod1) (getvar (car mod1)))
This new list is then appended to the list *mod2 and *mod2 is assigned the value of the new appended list:
(setq *mod2
(append *mod2 (list (list (car mod1)(getvar car mod1)))))
)
Finally the first element of mod1 is removed in preparation for the next iteration:
(setq mod1 (cdr mod1)))
Remember that cdr returns a copy of a list with its first element removed. The whole process is then repeated again.
When the getmode is done, a global variable called *mod2 is created. Mod2 might look like this:
(("osmode" 0)("orthomode" 1)("cmdecho" 1))
In this list, each element is another list that contains the mode as its first element and its current setting as its second element.
Once the desired settings are saved, you can go on to change the settings to suite your program. In the case of the C:BREAK2 program, "osmode" is changed to 512, the nearest setting, "orthomode" is set to 0, which turns off the orthomode, and "cmdecho" is set to 0 which controls command echoing to the prompt line.
When BREAK2 has done its work, you need a way to restore your saved settings. The setmode function in figure
9.4will restore the settings saved by the Getmodes function:
(Defun setmode (mod1) (repeat (length mod1)
(setvar (caar mod1)(cadar mod1)) (setq mod1 (cdr mod1))
)
)
195
Copyright © 2001 George Omura,,World rights reserved