Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
George Omura. Lisp programing tutorial for AutoCAD customization / 620.0.The ABC's of AutoLISP - Omura, George.pdf
Скачиваний:
74
Добавлен:
02.05.2014
Размер:
1.55 Mб
Скачать

The ABC’s of AutoLISP by George Omura

This function also uses length and repeat to perform a recursion. In this case, the recursive function consist of two expressions:

(setq mod1 (cdr mod1))

The first of these expressions takes the first element of the list of saved settings then applies its two elements to setvar. In our example, the result of this combination looks like this:

(setvar (caar mod1)(cadar mod1)) = (setvar "osmode" 0)

The result is an expression that sets "osmode" to 0. The next expression removes the first element from the list of settings then the processes is repeated.

The setmode function is placed at the end of the C:BREAK2 program to reset the variables. It is also placed in the *error* function. As long as getmode is used in a function to save system variables, The *error* function shown in figure 9.4 will work to restore system variables in the event of a canceled AutoLISP program. With the addition of the getmode and setmode functions, you have a general system for maintaining system variables.

# Using Lists for Comparisons

Like mapcar, foreach applies individual elements of a list to a function. But foreach only accepts one list. Foreach is often used to test elements of a list for a particular condition. For example, you could test a list of coordinates to sort out those above another datum point:

(foreach n

'((4.00 1.00) (10.09 1.01) (11.96 6.80) (7.03 10.38) (2.11 6.79) (4.00 1.00))

(if (> (cadr n) 2)(Setq newlist (append newlist (list n))))

)

This function simply checks the y value of each coordinate against the value 2. If y is greater than 2, the coordinate is added to a new list that contains only coordinates whose y value is greater than 2.

## Locating Elements in a List

You won't always want to use all the elements of a list in your programs. In many instances, you will want to obtain a specific element from a list. There are two functions, member and nth, that can help you find specific elements in a list.

196

;set up counter
;if item is a file ;close the file
;redefine atomlist ;without symbols ;previous to C:CLEAN ;and print DONE

The ABC’s of AutoLISP by George Omura

Note:

In the following discussion, an obsolete component of AutoLISP called Atomlist will be discussed. You can think of Atomlist as a very big list. Just think of Atomlist as any list in which you want to place a marker that you can later refer to..

## Searching Through Lists

To see how these two functions work, look at a program called Clean. Clean is an older program intended for earlier versions of AutoCAD that had limited memory resources. The purpose of Clean was to remove unused user-defined functions in order to free-up memory.

;program to clean symbols and functions from atomlist and close open files ;-----------------------------------------------------------------------------

(defun C:CLEAN (/ i item) (setq i 0)

;while not at the end of atomlist do...

(while (not (equal (setq item (nth i atomlist)) nil)) (if (= (type (eval item)) 'FILE)

(close (eval item)) );end IF

(setq i (1+ i) ) );end WHILE

(setq atomlist (member 'C:CLEAN atomlist)) 'DONE

)

Figure 9.6: The CLEAN program.

Before we analyze this program, we must first discuss the atomlist. Atomlist was a special list used to store data in earlier versions of AutoCAD. It contains the names all of the built-in AutoLISP functions. It was also used to store any user defined functions and symbols. If you are using Release 11 or earlier, you can view its contents by first flipping the screen to text mode, then entering:

!atomlist

You will get a listing of all the user defined and built in AutoLISP functions currently loaded into AutoCAD.

The list contains all of the AutoLISP functions we have discussed so far plus a few we have not. If you are using

197

The ABC’s of AutoLISP by George Omura

Acad.lsp to load some of your own functions, they will also appear at the top of the list. Whenever you create a new function or symbol, it is added to the beginning of atomlist. If you have an older version of AutoCAD, try entering the following:

(setq myfunc "mufunc")

If you enter !atomlist. you will see that myfunc is added to the list. The more functions you add, the larger atomlist gets and more memory is used to store symbols and functions.

If the C:CLEAN function is included in your Acad.lsp file, it is also added to the atomlist at startup time. C:CLEAN's purpose is twofold. First, it closes any files that may have been opened and inadvertently left open. This might occur if the open function was used to open an ASCII file and due to a function being canceled, the file was never closed. As we mentioned, this can cause loss of data to the open file. Second, C:CLEAN clears the atomlist of any function that is added after it thereby recapturing memory space.

In order to find and close any open files, C:CLEAN uses the while function in conjunction with the if and type functions. First, a counter is set to 0. the symbol i is used as a counting device:

(setq i 0)

Next, a while expression checks to see if an item of the atomlist is equal to nil. The nth function is used to read each element of atomlist.

(nth i atomlist)

Nths syntax is:

(nth [integer][list])

where integer is the numeric position of an element in list. In C:CLEAN, nth returns the element whose position within atomlist is represented by i. The variable i is a counter to which 1 is added each time the while function loops through the expressions it contains. The net result is that each element of the list atomlist is compared to nil. While continues to loop through its expressions until such a condition is met (see Figure 9.7).

Figure 9.7: The while loop in C:CLEAN

198

The ABC’s of AutoLISP by George Omura

Notice that the element returned by nth is assigned to the variable item. This allows the next if conditional function to test the element to see if it is a file descriptor:

(if (= (type (eval item)) 'FILE)

The eval function is used to force an evaluation of the variable item to extract its value. Eval can be used to find the value of a nested symbol, that is, a symbol whose value is also a symbol. Eval is the basic mechanism by which AutoLISP evaluates expressions. It is always being applied to expressions by AutoLISP. You could think of eval as the opposite of quote.

The type function above returns the data type of the value of item. If eval is not used, type would return the data type of the symbol item rather than the data type of items value (see figure 9.8).

Figure 9.8: Using eval to force one level of evaluation

199

The ABC’s of AutoLISP by George Omura

The following table gives a list of the values returned by type and their meaning:

 Value Meaning REAL real number FILE file descriptor STR string INT integer SYM symbol LIST list and user defined functions SUBR AutoLISP function PICKSET selection set ENAME object name PAGETB function paging table

If item turns out to be equal to a file descriptor or FILE, then the next line closes that file:

(close (eval item))

Using an Element of a List as a Marker

Once C:CLEAN has finished closing any open files, then it proceeds to redefine atomlist:

(setq atomlist (member 'C:CLEAN atomlist)

Here, the function member is used to find a list whose elements are all the elements of atomlist beginning with C:CLEAN. The expression then assigns that list to atomlist. The symbol C:CLEAN acts like a marker within the list telling the member function where to begin the list. The net affect is that of clearing atomlist of all the symbols and functions that were added to atomlist after C:CLEAN.

Members syntax is:

(member [element][list])

Member returns a list whose elements are the same as those of list starting with element.

200