In this Article...
In the last AutoLISP tutorial, we have tried to place block and change the attribute value. We also use conditional IF. Using AutoCAD block in AutoLISP is a great benefit. We can use our reusable content to make AutLISP programming less complex, and we can maintain our drawing standard in AutoCAD. This time we will try to use another conditional, using COND. We will also touch AutoCAD system variables, one of the most important thing in AutoLISP.
The program we will make in this AutoLISP tutorial will draw grid line, and automatically place label at the end of line.
Before you start, you need to download this file first. The zip file has 4 AutoCAD DWG files, each file is a grid label for each direction. We will use conditional COND to choose which AutoCAD block we should use. This AutoLISP tutorial requires you to understand what we did previously. So if you haven’t read it or want to refresh your memory, read the AutoLISP tutorial here. Or if you completely new to AutoLISP, follow the tutorial from beginning here.
Using Conditional COND
COND is a bit different with IF. When using IF, you can tell AutoCAD to do A when condition is met. Or else, do B. COND will only do things when the condition is met.
The basic of using COND is:
(cond
((condition a) (things to do when condition a is met)
((condition b) (things to do when condition b is met)
((condition c) (things to do when condition c is met)
and so on…
)
Let’s see what can we do with COND in our case.
(cond
((AND (= pt1x pt2x) (> pt1y pt2y)) (setq gridblockname "vgridbottom")) ;change block name when meet the condition
((AND (= pt1x pt2x) (< pt1y pt2y)) (setq gridblockname "vgridtop"))
((AND (> pt1x pt2x) (= pt1y pt2y)) (setq gridblockname "hgridleft"))
)
First, we set the block name to HGRIDRIGHT. We will use this block when we draw grid line to the right. But when we draw it to bottom, we need to use block VGRIDBOTTOM.
When we draw a grid to bottom, there are two conditions are met:
- X1 and X2 are the same.
- Y2 is larger than Y1.
X1, Y1 is the first picked point, and X2, Y2 is the 2nd point picked by user. We define the three conditions in our program. For right direction, we don’t have to define it because we already set it as default block name.
Changing AutoCAD system variable
Another thing we need to do is change an AutoCAD system variable temporarily. We can do it in AutoLISP using SETVAR. We want to create the grid horizontal or vertical. To achieve that, we need to draw line with ortho mode is on.
This behavior is controlled by system variable ORTHOMODE. We need to change it to 1 to make ortho mode active. But before we change it, it is a good thing to restore the system variable after the program ends. We don’t want the program to change our AutoCAD behavior and we need to change option every time we use the program.
We need to save the current ortho mode first to a temporary variable. We can get the system variable and save it to user variable in AutoLISP using GETVAR.
(setq CurrentOrthomode (getvar "orthomode"))
(setvar "orthomode" 1)
The first line will get the system variable and save it to variable CurrentOrthomode. OK, if you feel the variable name is ridiculously long, you can choose your own name :)
The second line, we set ORTHOMODE system variable to 1.
After our AutoLISP program ends, we can restore the system variable to the original value.
(setvar "orthomode" CurrentOrthomode)
The complete AutoLISP program
Now we have everything we need. The AutoLISP program will run like this:
- It will check the drawing scale. Refer to previous tutorial to see how it works.
- It will save the current orthomode and change orthomode to 1.
- It will ask user to place two points for the grid.
- It will check which it should use.
- It will draw grid line and insert the block.
- It will restore the orthomode.
The complete AutoLISP code is like this:
(defun c:cngrid (/ pt1)
(if (= cnglobalscale nil)
(c:cnannoscale)
) ; end if
(setq CurrentOrthomode (getvar "orthomode"))
(setvar "orthomode" 1)
(setq pt1 (getpoint "
Pick Grid Start Point: "))
(setq pt2 (getpoint pt1 "nPick Grid Last Point: "))
(setq pt1x (car pt1))(setq pt1y (cadr pt1))
(setq pt2x (car pt2))(setq pt2y (cadr pt2))
(setq gridblockname "hgridright") ;set default grid name
(cond
((AND (= pt1x pt2x) (> pt1y pt2y)) (setq gridblockname "vgridbottom")) ;change grid name when meet the condition
((AND (= pt1x pt2x) (< pt1y pt2y)) (setq gridblockname "vgridtop")) ((AND (> pt1x pt2x) (= pt1y pt2y)) (setq gridblockname "hgridleft"))
)
(setq gridnumber (getstring "
Enter Grid Number: "))
(command "_line" pt1 pt2 "")
(command "_-insert" gridblockname pt2 cnglobalscale cnglobalscale 0 gridnumber)
(setvar "orthomode" CurrentOrthomode)
(princ)
)
(defun c:cnannoscale () ; this another function defined to enable user to change scale later
(setq cnglobalscale (getreal "
Set Global Scale for CN Annotation <1/1>: "))
(if (= cnglobalscale nil) ; this will check if the user choose default value
(setq cnglobalscale 1)
) ; end if
)
Error trapping
To complete this AutoLISP program, it is a good thing that you create an error trapping. We change an AutoCAD system variable: ORTHOMODE. We do set it back to original value. The problem is, when an error occur and the program ends prematurely, the system variable is not restored. The variable will not be restored when you press esc key!
This is what happen in this selection issue and the missing dialog box. Many problem can happen if you don’t set error trapping in an AutoLISP program!
hopefully you can give me a hand..
I’m creating a pull down menu, but I want to specify the lineweights and linetype, so far this is what I have.
(defun c:layA-SEC-LIH-005()
(command “layer” “m” “A-SEC-LIH-005” “C” “magenta” “” “l” “DASHED2” “” “”)
In order to add lineweight I added the “_LW”, but I’m not able to specify the linetype… any advise?
(defun c:layA-SEC-LIH-005()
(command “layer” “m” “A-SEC-LIH-005” “C” “magenta” “” “_LW” 0.10 “” “”)
regards
regards