Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Autocad 2005 And Autocad LT 2005 Bible (2004).pdf
Скачиваний:
92
Добавлен:
17.08.2013
Размер:
32.22 Mб
Скачать

1022 Part VII Programming AutoCAD

Figure 35-7: One possible result of the listsset routine.

Here’s how this routine works:

Line 1 creates a function and declares two variables, mysset and counter.

Line 2 sets the mysset variable equal to the selection set that the user provides using

SSGET.

Line 3 sets the counter variable to 0, because selection sets work on a zero-based index (the first item is 0).

Line 4 starts a WHILE loop. Working from the innermost set of parentheses, first you obtain the number of objects in the mysset selection set, using SSLENGTH. Then you specify that the WHILE loop will continue as long as the counter is less than the number of objects in the mysset selection set. In other words, when the routine has cycled through all the objects in the selection set, it stops.

Line 5 uses TERPRI to start a new line before printing out the list of objects.

Line 6 prints the list. Working from the innermost set of parentheses, first the routine obtains the name of the object in the mysset selection set whose number is equal to the variable counter. Then the routine gets that object using ENTGET. Then the routine gets the name of that object using ASSOC with the 0 group code. The result is a dotted pair list whose second item is the name of the object. The CDR function eliminates the first item in the dotted pair list, leaving just the name of the object, which is what you want. The routine then prints the result.

Line 7 sets the counter up one to repeat the WHILE loop for the next object.

Line 8 closes the WHILE loop.

Line 9 exits the routine quietly. (I discuss exiting quietly later in the chapter.)

Line 10 closes the entire function.

Getting Input from the User

The course of your AutoLISP routines may often depend on user input. To satisfy this need, AutoCAD has a family of functions prefaced with the word GET. You have seen GETVAR for obtaining system variable information. Table 35-4 shows some other useful GET functions.

Chapter 35 Exploring AutoLISP Further 1023

 

Table 35-4: Basic User-Input Functions

 

 

Function

Description

 

 

GETDIST

Returns the distance between two points

GETINT

Returns an integer

GETREAL

Returns a real number (which can be a non-integer, negative, and so on)

GETSTRING

Returns a text string

 

 

Within the COMMAND function, you can use the PAUSE function to pause the operation of the routine and enable user input, such as picking a point or typing a value. For example, the expression (command “circle” pause “3”) pauses to let the user specify a center point and then creates a circle with a radius of 3.

Notice the function ENTSEL in the next exercise. This is a type of shorthand for SSGET. Use it when you want to limit the user to selecting a single object. ENTSEL returns an entity name and the coordinates of your pick point in a dotted-pair list. Therefore, you can use CAR before ENTSEL to get the entity name for ENTGET.

There is also a new argument for getstring, T. If you use this argument and it isn’t nil, users can place spaces in the input. Using this argument enables users to type a text value that includes more than one word. Without the T, AutoLISP would interpret a space as equivalent to pressing Enter.

STEP-BY-STEP: Getting User Input

1.Start a new drawing using the acad.dwt template.

2.Start Visual LISP, open a new file, and enter the following routine. Save it as ab35-05. lsp in AutoCAD2005\Support or a folder that you’ve added to the support-file search path.

(defun c:chgmytext (/ src_object new_ht new_str) (setq src_object (entget (car (entsel))))

(setq new_ht (getreal “\nWhat is the new height? “))

(setq new_str (getstring T “\nWhat is the new text value? “))

(setq src_object

 

 

(subst

(cons 40

new_ht)

(assoc 40 src_object ) src_object)

)

 

 

 

(setq src_object

 

 

(subst

(cons 1 new_str)

(assoc 1 src_object) src_object)

)

 

 

 

(entmod src_object) (princ)

)

3. Choose Format Edit Window from the Tools toolbar.

1024 Part VII Programming AutoCAD

4.Load ab35-05.lsp.

5.Create some text using either the DTEXT or the TEXT command and run chgmytext on it. AutoCAD changes the text object’s height and content to the values you input in response to the prompts.

Don’t save your drawing.

Here’s how the routine works:

Line 1 defines the function and declares the three variables.

Line 2 uses ENTSEL to let the user select one object. As explained earlier, CAR enables you to get just the entity name. ENTGET gets this entity name so that you can modify it. Finally, this line sets the resulting entity name equal to the variable src_object.

Line 3 prompts the user for a new height for the text and sets the entered number equal to the new_ht variable.

Line 4 prompts the user for a new text value (a new string) and sets the entered text value equal to the new_str variable.

Line 5 starts the process of substituting the new values for the old values. Here the routine starts to set the new value for src_object.

Line 6 uses SUBST to substitute the new text height for the old text height for the object src_object. (Group code 40 represents text height.)

Line 7 closes the SETQ function.

Line 8 is the same as line 5. You’ll be repeating the process of lines 5 through 7 for the new text (string) value.

Line 9 uses SUBST to substitute the new text value for the old text value. (Group code 1 represents the text value.)

Line 10 closes the SETQ function.

Line 11 uses ENTMOD on src_object to make the change in the drawing database.

Line 12 exits quietly.

Line 13 closes the entire function.

Putting on the Finishing Touches

You have a number of finishing touches that you should add to a routine before you can call it complete. All AutoLISP expressions return a value, and the last expression returns its value on the command line. You’ve noticed the PRINC function at the end of several routines. PRINC returns a blank line and, therefore, ensures that no extraneous evaluation return values are echoed on the command line. Using the PRINC function in this way is called exiting cleanly or exiting quietly.

Most of the AutoLISP applications covered thus far do not include much in the way of error handling. A new function called EQUAL is used on line 4 of the final routine in the next Step-by- Step exercise. EQUAL is different than = in that EQUAL returns true only if two expressions are equal (each of the two objects tested for equality are evaluated before checking if they’re equal). A simple rule of thumb is to use EQUAL for list comparisons and = for numeric comparisons.

Chapter 35 Exploring AutoLISP Further 1025

In the routine in the next Step-by-Step exercise, if you select an object that is not a text object, the program jumps to line 18 and prints the error message You must select a text object.

A similar type of error handling is to enclose the selection of objects in an IF function. The IF function’s test condition has to exist in order for the IF function to work. Therefore, if your user doesn’t select an object, the test evaluates as false. You can place an error message as the if-false part of the IF function to catch this type of error.

This type of error handling is crucial to making your AutoLISP programs look finished and function properly.

Another way to finish off your routine is to add comments. Start with a comment at the beginning that states the purpose and function of the routine. This helps others understand what the routine does and can help you as well when you look at the routine again a few months later! Comments are prefaced with a semicolon.

Then continue to make comments throughout your code. A lack of comments can make even the most useful code useless. Most professional programmers fully comment and document a function’s purpose and behavior by placing comments within the code.

Visual LISP supports several commenting styles. When you click Format Edit Window on the Tools toolbar, Visual LISP uses these styles to automatically format your code. Here’s how they work:

;;; Triple semicolon: When you type a comment with three semicolons, Visual LISP places the comment at the left margin. A triple semicolon comment is good for the beginning of your routine to describe its overall purpose and what it does.

;; Double semicolon: Visual LISP indents a comment with two semicolons at the current nesting level, flush with the next level of parentheses. Use this type of comment to explain the next line or lines of code.

; Single semicolon: Visual LISP indents a comment with one semicolon by 40 spaces, by default. Choose Tools Environment Options Visual LISP Format Options to open the Format Options dialog box, shown in Figure 35-8, and change this value if you want. Use this type of comment for running comments at the right side of your code. Because they’re indented, they stand out from the body of your code.

;| |; Inline comment: Place an inline comment within any line of code so that it has code both before and after it. An inline comment is formatted as shown here: ;|This is a comment|;. You use the pipe symbol (usually over the backslash) along with the semicolon. Use an inline comment to explain a small section of code within a line or to span comments over several lines without adding a semicolon before each line.

;_ End-of-line comment: Place an end-of-line comment at the end of any line of code. An end-of-line comment is formatted as shown here: ;_ This is an end-of-line comment. You use the underscore symbol along with the semicolon. Use an end-of-line comment to explain which function to which the closing parenthesis is matched. This is especially useful for conditional functions where one closing parenthesis can be several lines from the opening parenthesis.

See the “Using AutoLISP to match properties” sidebar for several examples of comment styles.

1026 Part VII Programming AutoCAD

Figure 35-8: Use the Format Options dialog box to format margins and indentation in the Visual LISP editor.

STEP-BY-STEP: Putting on the Finishing Touches

1.Load the application completed in the previous Step-by-Step exercise. If you didn’t do the previous exercise, enter it from that exercise in Visual LISP’s edit window and save it as ab35-05.lsp in AutoCAD 2005\Support or a folder that you’ve added to the support-file search path. Then load it with any drawing open in AutoCAD.

2.Now run chgmytext and choose an object that is not a text object (such as a circle) in response to the Select object: prompt. Answer the prompts for new height and new text value.

If you’ve done this to a circle, you see its radius change to match the value you specified to be the new text height. This is definitely not what you intended when writing this program.

3.Modify the program so that it reads this way and save it as ab35-06.lsp:

;;;modifies text height and content (value) (defun c:chgmytext (/ src_object new_ht new_str)

(terpri)

(setq src_object (entget (car (entsel))))

(if (equal (assoc 0 src_object) ‘(0 . “TEXT”)) (progn

(princ “What is the new height for the text? “) (setq new_ht (getreal))

(princ “What is the new text value? “)

Chapter 35 Exploring AutoLISP Further 1027

Using AutoLISP to match properties

This routine modifies the layer of objects to match the layer of one other object. This powerful routine was a mainstay of many AutoCAD users before the advent of the MATCHPROP command introduced in AutoCAD R14. The general method used here for matching layers can be used to change any properties you wish on any AutoCAD object.

;;;Matches the layer of one selected source object in any number of destination objects.

(defun c:matchlayer (/ src_object mysset counter cur_ent_ent_layer)

(princ “\n*** Select Source object to match ***”)

; prompt the user

(if (setq src_object (car (entsel)))

; select the object

(progn

 

 

 

 

(setq src_layer (assoc 8 (entget

src_object)))

; get the object’s

layer

 

 

 

 

;; prompt the user

 

 

 

(princ “\n*** Select Destination

objects to match layer ***”)

;; collect some objects using ssget

 

(if (setq mysset (ssget))

; verify

the user selected something

(progn

; if the user selected some items do the following

(setq counter 0)

(while (< counter (sslength mysset))

(setq cur_ent (entget (ssname mysset counter))) (setq ent_layer (assoc 8 cur_ent))

(entmod (subst src_layer ent_layer cur_ent)) (setq counter (+ counter 1))

)

)

(princ “\nYou did not select any items”) ; prompt the user

);_end of if verification

);_end of progn for the selection of object to match

;;prompt the user they did not select a source object (princ “\nSorry you did not select an Object”)

) ;_end of if

(princ)

);_end of function c:matchlayer

This routine first gets the name of the selected object with (car (entsel)). It determines its layer by using ENTGET on the object name and using ASSOC with the 8 group code. Then it gets a selection set of the Destination objects. It creates a loop that cycles through these objects, gets their layers (the ent_layer variable), and uses ENTMOD and SUBST to change the object’s current layer to the source object’s layer.

Each selection of objects (the source object and the destination objects) is enclosed in an IF function whose if-false statement prints an error message telling users that they did not select an object (or objects).