Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 133 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
133
Dung lượng
19,85 MB
Nội dung
1146 Part VII ✦ Programming AutoCAD 6. Type (cdr endpt) ↵. AutoLISP returns (2.0 1.4). 7. Type (nth 1 endpt) ↵. AutoLISP returns 2.0. Do not save your drawing. Setting Conditions Often you want to execute a procedure based on a certain condition. One way of doing this is with the IF statement, which does one thing if a statement is true and another thing if it is false. In other words, the operation is conditioned on the truth of a certain statement. Looping is an important part of programming. Frequently you want to execute a procedure over and over until the routine has finished operating on all the target objects or items. Looping sets up the condition that determines when the operation starts, the number of objects upon which the routine operates, and when the opera- tion ends. Conditional structures Conditional structures enable program flow to be determined based on the out- come of a given decision. These decisions result in the return of either T, meaning true, or nil, meaning false. To try out the following statements, type them in the Visual LISP Console window. For instance, for the statement (< 3 5) T AutoLISP returns T for true, having determined that 3 is less than 5. For the statement (> 3 5) nil AutoLISP returns nil for false, having determined that 3 is not greater than 5. For the statement (= 3 5) nil AutoLISP returns nil. Here we have determined that 3 is not equal to 5. Because these statements return either T or nil, you can use the IF statement. The general syntax of the IF statement is (if conditional-test if-true if-false). Say you want to find circles whose radius is less than 0.25. Here’s a sample IF state- ment. In this example, radius is a variable that has been previously set. 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1146 1147 Chapter 35 ✦ Exploring AutoLISP Further (if (< radius .25) (princ “The radius is less than .25”) (princ “The radius is not less than .25”) ) The conditional test is (< radius .25). The if-true statement is (princ “The radius is less than .25”). The if-false statement is (princ “The radius is not less than .25”) . This IF statement is equivalent to saying, “If the radius is less than .25, print ‘The radius is less than .25’ but if not, print ‘The radius is not less than .25.’” You can leave out the if-false statement. Then AutoLISP executes the if-true state- ment if the conditional statement is true and does nothing if it is false, and contin- ues to the rest of the program. In the following exercise, you see both types of IF statements, one nested inside the other. Step-by-Step: Using the IF Statement 1. Start a new drawing in AutoCAD using the acad.dwt template. 2. Open Visual LISP, start a new file, and type the following: (defun c:compare2three (/ entered_num) (setq entered_num (getint “\nEnter an integer: “)) (if (< entered_num 3) (princ “\nThe entered number is less than 3.”) (if (= entered_num 3) (princ “\nThe entered number is equal to 3.”) (princ “\nThe entered number is greater than 3.”) ) ) (princ) ) The GETINT function gets an integer from the user and is covered later in this chapter. The \n before the Enter an integer: prompt starts a new line; it is similar to using (terpri). Using (princ) at the end of a routine is also cov- ered later in this chapter. 3. Choose Check Edit Window. If you see any error message in the Build Output window, check your typing, make any necessary correction, and try again. 4. Save the file as ab35-02.lsp in a folder that is in the support file search path, or in AutoCAD 2004\Support\. 5. Choose Load active edit window and then choose Activate AutoCAD. 6. To try out the IF statement, type compare2three ↵. At the Enter an inte- ger: prompt, type 5 ↵. AutoCAD displays: The entered number is greater than 3. 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1147 1148 Part VII ✦ Programming AutoCAD 7. Repeat the COMPARE2THREE command. At the Enter an integer: prompt, type 3 ↵. AutoCAD displays: The entered number is equal to 3. 8. Repeat the COMPARE2THREE command. At the Enter an integer: com- mand, type 2 ↵. AutoCAD displays: The entered number is less than 3. Do not save your drawing. Loop structures Looping provides the capability to execute a step or a number of steps a given number of times based on an evaluation you make in your application. One way to do this is with the WHILE function. The format of the WHILE function is: (while conditional-test-if-true then-perform-the-following-code-until-the condition-is- false) One method that can be useful with a WHILE conditional-test-if-true is to include a counter for the WHILE expression. A counter counts how many times an operation is executed. You can then end the operation when the counter reaches a certain num- ber. To create a counter, set a variable (perhaps named “counter”) to the number at which you want to start. Then write the code for one pass through the operation. Then set the counter to the next higher number using an expression, such as the following: (setq counter (+ 1 counter)) The routine then loops back over the operation until the counter reaches the value you set. Here’s a simple example: (defun c:process (/ counter) (setq counter 1) (while (< counter 6) (princ “Processing number “) (princ counter) (terpri) (setq counter (+ 1 counter)) ) ) In this example, the process function starts by setting the variable counter to 1. Then you start the WHILE statement and specify that the counter must be less than 6. Within the WHILE statement, you print the text string “Processing number” and 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1148 1149 Chapter 35 ✦ Exploring AutoLISP Further then the value of the counter variable. You use (terpri) so that each text string starts on a new line. Then you set the counter to the next higher number. Each time through the WHILE loop, the value of the counter is incremented by 1. Without the increment statement, line 3 would always evaluate to true and the WHILE loop would never exit because the counter would always be 1. If you accidentally program an infinite loop like this, you can stop the execution of your AutoLISP routine by pressing Esc, Ctrl+Break, or from the Visual LISP menu, choose Debug ➪ Abort Evaluation. In the preceding example, the WHILE loop continues as long as the counter is less than 6. When the counter reaches 6, the routine stops. The WHILE statement returns the last value of the routine, so AutoCAD prints 6 on the last line. Figure 35-3 shows the result. Figure 35-3: The result of the process function When using WHILE, you may want to combine several operations under the condi- tion. The IF function normally evaluates one then expression if the test expression is true. Suppose you want an IF expression that processes various tasks if the test condition is true. An IF expression, as previously mentioned, processes a “do-if-true” and “do-if-false.” Therefore, to process more than one “do-if true” expression, you need to separate the “do-if-true” processes from the “do-if-false” processes. To accomplish this, use PROGN (PROGram Nest) to include (or nest) all items you want executed when the test is true. In general, PROGN evaluates all the statements within its parentheses and returns the last evaluation as if it were one statement, as the following example demonstrates. In the next example, you see the same IF statements used in an earlier example. However, after the second IF statement, you want your routine to print two lines if the entered number equals 3. You can do this by enclosing the two lines of code (plus a terpri) within a PROGN statement: (defun c:compare2three (/ entered_num) (setq entered_num (getint “\nEnter an integer: “)) (if (< entered_num 3) (princ “\nThe entered number is less than 3.”) (if (= entered_num 3) (progn (princ “\nThe entered number is equal to 3.”) (terpri) 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1149 1150 Part VII ✦ Programming AutoCAD (princ “\nThis is the one we are looking for.”) ) (princ “\nThe entered number is greater than 3.”) ) ) (princ) ) The file used in the following Step-by-Step exercise on using WHILE, IF, PROGN, and a counter, ab35-b.lsp, is in the Drawings folder of the AutoCAD 2004 Bible CD-ROM. Step-by-Step: Using WHILE, IF, PROGN, and a Counter 1. Open AutoCAD with any new drawing. 2. Open Visual LISP. 3. Click Open File on the Visual LISP Standard toolbar and open ab35-b.lsp from the AutoCAD 2004 Bible CD-ROM. 4. Save the file as ab35-03.lsp in \AutoCAD 2004\Support or any folder in the support file search path. Figure 35-4 shows this routine. Figure 35-4: The print0to10 routine 5. Load ab35-03.lsp. Return to AutoCAD. 6. Type print0to10 ↵. Press F2 to open the AutoCAD Text Window and see the result, shown in Figure 35-5. Do not save your drawing. On the CD-ROM 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1150 1151 Chapter 35 ✦ Exploring AutoLISP Further Figure 35-5: The result of the print0to10 function Managing Drawing Objects The real power of AutoLISP is in manipulating drawing objects. This section reveals how many of the AutoLISP routines perform their magic. You can get information about an object and then use that information to change the object. You can also create selection sets of objects. Getting information about an object Every object in the AutoCAD database has an entity name. This name enables you to reference that object anywhere in your AutoLISP application. To see an example of an entity name, type the following after starting a new drawing: (command “_line” “3,3” “5,5” “”) (entlast) AutoLISP responds with an Entity name such as <Entity name: 2ed0520>. The numbers will probably differ on your system, but using the information returned from ENTLAST enables you to programmatically get or set a variety of options on any given database object by referencing its entity name. The ENTGET (ENTity GET) function is the key to making modifications to the draw- ing database. The ENTGET function takes an entity name as its one and only argu- ment. After drawing the line in the preceding steps, type the following: (setq myline (entget (entlast))) AutoLISP responds with: 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1151 1152 Part VII ✦ Programming AutoCAD ((-1 . <Entity name: 15ac558>) (0 . “LINE”) (330 . <Entity name: 15ac4f8>)(5 . “2B”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”) (8 . “0”)(100 . “AcDbLine”) (10 3.0 3.0 0.0) (11 5.0 5.0 0.0) (210 0.0 0.0 1.0)) This is a representation of how the line is stored in the AutoCAD drawing database. AutoLISP returned one large list that contains 12 smaller lists. Each of the smaller lists is referred to as a group indexed by the first element. The entity name is in group –1. Each of the initial numbers in the small lists represents a different quality of the line. These numbers are called object group codes. The object group codes used most often are listed in Table 35-2. Table 35-2 Commonly Used AutoCAD Object Group Codes Group Code Description –1 Entity name 0 Entity type 1 Text value 8 Layer 10 Start point (or center) 11 Endpoint (or alignment point) 38 Elevation 39 Thickness 40 Radius (or height of text) 62 Color 67 Paper space flag As you can see from the 10, 11, and 40 codes, the meaning of the group codes can change depending on the type of object it is used for. You can also use Visual LISP to examine an AutoCAD object. Begin by choosing View➪ Browse Drawing Database ➪ Browse Selection. At this point, Visual LISP will display a pickbox in your drawing so that you can select an object. After you end object selection, you are returned to Visual LISP where you see the Inspect dialog box. Select the name of the entity and, while the cursor is over the selected text, right-click. Choose Inspect to see information about the object. Figure 35-6 shows information about an arc. Note 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1152 1153 Chapter 35 ✦ Exploring AutoLISP Further Figure 35-6: Getting information about a drawing object from Visual LISP Not all these group codes are present in the line you drew. For instance, group 62 (color) is absent in the list returned by AutoLISP. Every time you draw a line, you do not explicitly set its color. As a result, it defaults to the current color. In the same way, AutoLISP does not explicitly set every attribute of every group. In this case, the color is ByLayer and the current layer is 0. AutoLISP returned (8. “0”) in the preceding list to signify the line is on layer 0. There are many other group codes than the ones listed in Table 35-2, and they can be found in the Visual LISP Help system. From Visual LISP, choose Help ➪ Visual LISP Help Topics. From the Contents tab, double-click DXF Reference. (Because the group codes are also used for DXF files, they are found in the DXF Reference.) Double-click ENTITIES Section. You can then either choose Common Group Codes for Entities or choose the specific entity you want to look up. In many cases, one group code can have different meanings depending on the entity in which it appears. For example, in the list representing the line you drew, group 10 is repre- sented by (10 3.0 3.0 0.0), which means the start point of the line is at X=3.0, Y=3.0, Z=0.0. If group 0 were a circle instead, the coordinates of group 10 would specify the center point of the circle. To manipulate a given attribute of an object, two important functions are ASSOC and SUBST: ✦ ASSOC returns a list that finds the entry associated with an item in a list. It takes two arguments, the item in the list and the list itself. For example, if you specify the group code (such as 10) as the first argument, it returns the code’s value (which would be the start point of a line). If a list named myobject con- tains three groups, as in ((0 . “group 0”) (1 1.0 2.0) (3 4.2 1.5 6.75)) , then (assoc 1 myobject) would return (1 1.0 2.0). ✦ SUBST substitutes a value for every occurrence in a list. The SUBST function takes three arguments. To make the substitution, the first argument specifies what to substitute with, the second argument specifies what to substitute for, and the third argument specifies on what list to perform this operation. 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1153 1154 Part VII ✦ Programming AutoCAD To manipulate the start point of your line, first get the start point: (setq startpt (assoc 10 myline)) AutoLISP responds: (10 3.0 3.0 0.0) To modify the start point of your line, use: (setq new_startpt ‘(10 6.5 1.0 0.0)) (setq myline (subst new_startpt startpt myline)) AutoLISP responds: ((-1 . <Entity name: 15ac558>) (0 . “LINE”) (330 . <Entity name: 15ac4f8>)(5 . “2B”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”) (8 . “0”)(100 . “AcDbLine”) (10 6.5 1.0 0.0) (11 5.0 5.0 0.0) (210 0.0 0.0 1.0)) In this case, the new_startpt is substituted for the existing startpt in the object myline. No changes to the line are yet apparent. To commit the change, you need the ENTMOD function. Modifying objects The key to modifying objects is the ENTMOD (ENTity MODify) function. The list returned by AutoLISP can be modified and then passed to ENTMOD as an argument to update the AutoCAD database. Continuing with the example, if you enter: (entmod myline) AutoLISP responds: ((-1 . <Entity name: 15ac558>) (0 . “LINE”) (330 . <Entity name: 15ac4f8>) (5 .”2B”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”) (8 . “0”) (100.”AcDbLine”) (10 6.5 1.0 0.0) (11 5.0 5.0 0.0) (210 0.0 0.0 1.0)) The AutoCAD database is changed as well, and the start point of your line is now at X=6.5, Y=1.0, Z=0.0. Creating selection sets A selection set is created with the SSGET (Selection Set GET) function. This prompts the user with the familiar Select objects: prompt. Table 35-3 shows the commonly used selection set functions. 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1154 1155 Chapter 35 ✦ Exploring AutoLISP Further Table 35-3 Common AutoCAD Selection Set Functions Function Description SSGET Obtains a selection set from the user. SSLENGTH Returns the number of objects in a selection set. It takes one argument, the selection set. ssname Returns the entity name of a given object in a selection set. It takes two arguments: the selection set and the number of the object in the selection set. The first item number is 0, the second is 1, and so on. You can use a maximum of 256 selection sets at any given time. To release a selec- tion set back to AutoLISP so that it can be used again, set the selection set to nil — for example, (setq ss nil). For example, you can enter the following in a new drawing: (command “_circle” “3,3” “2”) nil (command “_circle” “4,4” “3”) nil (command “_line” “7,2” “6,6” “3,4” “5,5” “”) nil (setq mysset (ssget)) Select objects: all ↵ 5 found Select objects: ↵ <Selection set 1> Now mysset is set to the selection set specified by all, which includes the three lines segments and the two circles. To see what you have in your selection set, type the following either on the command line or in the Visual LISP Console: (sslength mysset) 5 You now know that you have five objects in your selection set. The first object is number 0, and the fifth object is number 4. To see what the first object is, enter the following: (ssname mysset 0) <Entity name: 3fe0550> To get the database data on the object, enter: (entget (ssname mysset 0)) 43 539922 Ch35.qxd 5/2/03 9:44 AM Page 1155 [...]... working with break points, ab36-a.lsp, is in the Drawings folder of the AutoCAD 2004 Bible CD-ROM Step-by-Step: Working with Break Points 1 Open AutoCAD and start a drawing using any template 2 Start the Visual LISP Editor Open ab36-a.lsp from the AutoCAD 2004 Bible CD-ROM Choose File ➪ Save As and save it as ab36-01.lsp in the \AutoCAD 2004\ Support folder or in another folder you have added to the support... name: 1456cf8>) (5 “2C”) (100 “AcDbEntity”) (67 0) ( 410 “Model”) (8 “0”) (100 “AcDbLine”) (10 0 0 0) (11 15.0 5.0 0.0) ( 210 0.0 0.0 1.0)) To reflect the modification of this line in AutoCAD, as explained in Chapter 35, you can now use the function ENTMOD, as follows, by typing it in the Console This code actually changes the start point of the line (You can return to AutoCAD to check it out.)...43 539922 Ch35.qxd 1156 5/2/03 9:44 AM Page 1156 Part VII ✦ Programming AutoCAD Visual LISP responds: ((-1 ) (0 “LINE”) (330 )(5 “30”) (100 “AcDbEntity”) (67 0) ( 410 “Model”) (8 “0”) (100 “AcDbLine”) (10 3.0 4.0 0.0) (11 5.0 5.0 0.0) ( 210 0.0 0.0 1.0)) By stepping through each of the entity names returned by SSNAME from 0 to 4,... window: (setq NewStartPoint (cons 10 ‘( 0 0 0 ))) ↵ Visual LISP returns the following: (10 0 0 0) Using the variables NewStartPoint and LinePropertyList, you can now substitute the newly created group 10 code You do this using the SUBST function explained in Chapter 35 The following code substitutes the new group 10 code represented by the variable NewStartPoint for the 10 association in LinePropertyList... Here is an example of a property list, formatted for readability ((-1 ) (0 “LINE”) (330 ) (5 “2C”) (100 “AcDbEntity”) (67 0) ( 410 “Model”) (8 “0”) (100 “AcDbLine”) (10 5.0 5.0 0.0) (11 15.0 5.0 0.0) ( 210 0.0 0.0 1.0)) 44 539922 Ch36.qxd 5/2/03 9:44 AM Page 1169 Chapter 36 ✦ Exploring Advanced AutoLISP Topics As you can see, ENTGET returns an entity’s... Page 1170 Part VII ✦ Programming AutoCAD After you create this function and load it, you can test it out in the Console as follows, using the LineEntity variable previously defined: (Get-A-Group-Code LineEntity 10) ↵ (5.0 5.0 0.0) As you can see, the function returns only the value of the 10 group code You can refine this small interface by defining a separate 10 group 10 function, such as the following... modifier function You can do the same for any group code (defun Put-Group -10- Code (EntityName Value) (Put-Group-Code-Value EntityName 10 Value) ) After entering and loading this function, type the following at the Console to change the start point of the line to 15,–5,0 (Put-Group -10- Code LineEntity ‘( 15 -5 0 )) ↵ Activate AutoCAD to check that the line has been changed Using ActiveX with Visual LISP... any AutoCAD object using AutoCAD s ActiveX interface That is to say, AutoCAD exposes all of its objects to ActiveXenabled applications This includes Visual LISP as ActiveX objects, all of which expose their properties, including put (modify) and get (retrieve) functions 44 539922 Ch36.qxd 5/2/03 9:44 AM Page 1173 Chapter 36 ✦ Exploring Advanced AutoLISP Topics Using Visual LISP to communicate with AutoCAD. .. IAcadLine: AutoCAD Line Interface ; Property values: ; Angle (RO) = 1.5708 ; Application (RO) = # ; Delta (RO) = (0.0 10. 0 0.0) ; Document (RO) = # ; EndPoint = (15.0 5.0 0.0) ; Handle (RO) = “89” ; HasExtensionDictionary (RO) = 0 ; Hyperlinks (RO) = # ; Layer = “0” ; Length (RO) = 10. 0 ; Linetype... Part VII ✦ Programming AutoCAD 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 AutoCAD 2004 Bible CD-ROM. 4. Save the file as ab35-03.lsp in AutoCAD 2004 Support or any folder in the support file search path. Figure 35-4 shows this routine. Figure 35-4: The print0to10. <Entity name: 15ac4f8>) (5 .”2B”) (100 . “AcDbEntity”) (67 . 0) ( 410 . “Model”) (8 . “0”) (100 .”AcDbLine”) (10 6.5 1.0 0.0) (11 5.0 5.0 0.0) ( 210 0.0 0.0 1.0)) The AutoCAD database is changed as. Programming AutoCAD ((-1 . <Entity name: 15ac558>) (0 . “LINE”) (330 . <Entity name: 15ac4f8>)(5 . “2B”) (100 . “AcDbEntity”) (67 . 0) ( 410 . “Model”) (8 . “0”) (100 . “AcDbLine”) (10 3.0