Autocad and Lisp
Autocad and Lisp
Autocad and Lisp
Let us learn AutoLISP in plain English. You will be guided slowly to create your own AutoLISP program!
1. Your First AutoLISP Program: Zoom to Origin 2. Using AutoLISP Variable and Asking User Input 3. Using AutoLISP Program to label point coordinate 4. Labeling Coordinate with Easting and Northing in AutoCAD 5. AutoLISP Exercise : Create Regular Polygon by Defining Area 6. AutoLISP exercise: creating program to label coordinate 7. AutoLISP Exercise: Using Block and Conditional If 8. AutoLISP tutorial: system variable and conditional COND 9. Adding New Line in Multiline text 10.AutoLISP tutorial: Working with layers 11.Creating layer and styles with AutoLISP 12.Modifying objects: working with selection 13.Filter selection with selection set 14.Saving, using and managing your AutoLISP program 15.How to load AutoLISP program 16.Automatically execute command when open/create new file 17.Set default system variables in acaddoc.lsp 18.Adding AIA standard layers with LISP 19.How to: Create polygon in isometric drawing
AutoCAD will open visual lisp window. This window might not look fancy, and and the icons remind me of good old Windows 3.1 icons. However, it has many specific AutoLISP programming tools that can help us.
AutoLISP Structure
Before we start, let us see the common program structure below.
(defun c:YourProgramCommand () WhateverYouWantAutoCADtoDo (princ) ) Define a Function (defun ()) AutoLISP will start with (defun c:ProgramCommand ()). Defun stands for define for a function. If you find this: (defun c:ZO ()) It means that we are defining ZO as a command. AutoCAD will run your program when you type ZO then enter at command line. Most programmer will put the close parenthesis below, parallel to open parenthesis. This will be easier for us to find the parenthesis pair. Most programming language will not care where is the close parenthesis, as long as they can find it. So make sure it will be EASY FOR YOU to find it. Inside the parenthesis, you define whatever you want AutoCAD to do. That is the tricky part. We will do a simple exercise here, to see how it works.
4. The last thing AutoCAD will ask is the magnification. Type the distance you want to see on your screen. I use 2000. It means AutoCAD will show 1000 to the left, and 1000 to the right. With 0,0 at the screen center. If you use imperial, you may want to change it to smaller number. Each time we give the input, we press enter. So we type _zoom [enter] _c [enter] 0,0 [enter] 2000 [enter]. Now in your Visual LISP editor, try to type like below. Type it, do not copy and then paste it. It will not work. (defun c:ZO () (command _ZOOM _C 0,0 2000) (princ) ) You know whats written in red means right? Command will load internal AutoCAD command, then you give the parameters. Each input in quote. This time, you can use (princ) or not using it. Adding (princ) will end the program gracefully, but without it, it will also work. Now save this program.
Now move to AutoCAD window, and try to type ZO then [enter]. Does it work? Congratulations! You have just created your first program! We will modify this program further. So save it and dont loose it.
We have started the AutoLISP tutorial by creating a very simple program: zoom to origin. That program works, but it is very limited to zoom to 0,0,0 coordinate only. We will add more functionalities so users can pick other point to zoom to. Because we will enable users to pick their own point, zoom to origin may not appropriate name anymore. So I changed the name to Zoom to Point (ZP). Remember to type ZP then [enter] to run it after this.
If you want to learn more about it, you can read visual lisp tutorial on AfraLISP, which is very good. I will not cover about it, at least now, and focus more on how you can write the routines.
Using Variables
In programming, we use variables to save our values. In our previous sample, we havent use it.
(command "_ZOOM" "_C" "0,0" "2000")
Lets say we save the coordinate to ZPT (zoom point) and save the magnification to MRAT (magnification ratio), then our program will be like this.
(command "_ZOOM" "_C" ZPT MRAT)
Remember, the program name and user variables have to be unique and not using AutoCAD system variables. You can use any other names that can be easily recognized. So how to tell AutoCAD the variables value? You can assign the value to variables using setq function. To set the ZPT value and MRAT value, we add these following lines before our command.
(setq ZPT '(0 0)) (setq MRAT 2000)
Now lets put it all together in our program. Now our program become like this.
(defun c:ZP () (setq ZPT '(0 0)) (setq MRAT 2000) (command "_ZOOM" "_C" ZPT MRAT) (princ) )
Try to type it in your visual LISP editor and try it. Load the program, and run it. Does it work? Asking for User Input Now we are going to ask the user to define their point. Change the 0,0 coordinate to this code:
(setq ZPT (getpoint))
Now load the application again, then try to activate it again. It works, doesnt it? But there is one thing left. We both know that the program want us to click a point, but there is no instruction what should we do. If we give the program to other people, they will be confused! So lets fix the code.
Now load your program. After you run it, type !ZPT or !MRAT to see the variable value. Now they should say nil. Now AutoCAD doesnt keep the variable in your computer memory after the program has finished running.
Giving Comments
Most AutoLISP program have comments. The idea is to give information when other people open the program, what it does, who create it, and you can also add some information what the codes in a line does. Comments will be ignored by AutoCAD, and will not be processed. Let us complete it so it would looks like a real program. You can give comments to your AutoLISP program using semicolon character. I added some comments like below. Now you can see how the pretty colors can easily distinguish the codes right? See what the colors mean in this AfraLISP tutorial.
If you have a problem with the code, try to copy the completed code below, and paste in your Visual LISP editor.
;Zoom to Point ;This program will quickly zoom to a specific point ;Created by: Edwin Prakoso ;website: http://cad-notes.com (defun c:ZP (/ ZPT MRAT) (setq ZPT (getpoint " Pick a point or type coordinate: ")) ;this will ask for user input (setq MRAT 2000) (command "_ZOOM" "_C" ZPT MRAT) ; this will run the zoom command (princ) )
I have posted an AutoCAD tip how you can create your own label coordinate in AutoCAD using block attributes. It is nice that you can create your own block, create your own block shapes, and customize it to look anything you want to. But there is a limitation. It will only recognize the point position from global coordinate. If you move the UCS, it will still use global coordinate. It makes sense, because if we want to label our coordinate, then usually we do use global coordinate. But what if you want to label the coordinate from UCS? Because Im currently learning AutoLISP, then I decided to take it as a challenge to create a program to do that. You can download the file in link youll find below this post.
4. You need to click twice: the point you want to label and label location. 5. It will use leader command. So if its too large, too small, or you want to customize it, change your style. 6. It is also use file UNITS settings. If you want to change the format to decimal or architecture format, change it in UNITS settings. 7. The program will continue to ask you for points until you press [esc] or [enter]. I decide to make it this way because mostly we want to create several labels at once. So you dont need to reactivate it after you have labeled one point. If you are following AutoLISP tutorial in CAD Notes, be patience! We will get there. Here is the code.
; ; ; ; ; ; ; Automatic coordinate labeling Edwin Prakoso http://cad-notes.com Limitation ---------Will use current leader style and current units setting
(defun c:lb (/ p x y ptcoord textloc) (while (setq p (getpoint " Pick Point: ")) (setq textloc (getpoint " Pick Label Location: ")) (setq x (rtos (car p))) (setq y (rtos (cadr p))) (setq z (rtos (caddr p))) (setq ptcoord (strcat x ", " y ", " z)) (command "_LEADER" p textloc "" ptcoord "") ) )
And if you want to simply download and use it, download this file. There are two files in the zip file. 1. LB.lsp is for Labeling Coordinate (X and Y only) 2. LBZ.lsp is for Labeling Coordinate (X, Y, and Z) Enjoy the LISP, and share it to your friends! Notes: After I wrote this, I realize that Shawki abo zeed have published similar code in labeling coordinate tips. It looks it has more features. If this one doesnt work fine, you may want to try his code too. Thank you to Shawki!
After I provided AutoLISP program to label coordinate automatically, I had some questions if it can show N, E, and elevation instead of just the coordinate text. So I made minor adjustment to the code. This automatic labeling will create three lines of texts instead of just one line of xyz coordinate.
You can open notepad, copy and paste the code below, then save it as lb.lsp (type it with double quote when saving in notepad). If you want to show only Easting and Northing, you can delete the marked lines. Or replace East with E or X=, and so on.
You can read our tip on how to load AutoLISP program. I hope this is useful.
; ; ; ; ; ; ; ; Automatic coordinate labeling Edwin Prakoso http://cad-notes.com Limitation ---------Will use current leader style and current units setting If you don't want to show elevation, then modify lines marked *
(defun c:lb (/ p x y z ptcoord textloc) (while (setq p (getpoint " Pick Point: ")) (setq textloc (getpoint " Pick Label Location: ")) (setq x (rtos (car p))) (setq y (rtos (cadr p))) (setq z (rtos (caddr p))) ;*you may delete this line (setq x (strcat "East " x)) (setq y (strcat "North " y)) (setq z (strcat "Elev. " z)) ;*you may delete this line (command "_LEADER" p textloc "" x y z "") ;*you may delete z ) )
Want to create this program by your own? You can also adjust it to your needs. Try this AutoLISP exercise to create labeling coordinate program here.
Now lets try another one. Type each line then press [enter].
(setq a 2) (setq b 5) (+ a b)
This one means c = a + b. Not so difficult, isnt it? Refer to other calculation function in AfraLISP site here. Now let us see the polygon formula.
source: Math Open Reference page. If we know the area and number of sides, we can calculate the apothem. What is apothem? See image below.
How can we draw a polygon when we know the apothem and number of sides? Using polygon tool of course. We create it using circumscribed method.
Functions in Our Formula We will use these function in our formula. 1. 2. 3. 4. 5. square root can be written as (sqrt a), multiplication as (* a b), division as (/ a b), cosine of an angle as (cos ang), sine of an angle as (sin ang).
With a, b, and ang are variables. The bad news is AutoLISP doesnt have tan function. But there is work around. Tangen is sin/cos. Tan (pi/N) can be written as:
(setq ang (/ pi N)) (/ (sin ang) (cos ang))
Pi is built in variable, so we will just use it. Besides the sequence, you should be familiar with the command. If you want to try writing the equation by yourself, go ahead. It can be a good exercise to get familiar with mathematical function in AutoLISP. You can find the equation below later. The complete equation can be written. I use variable a for area and n for number of sides. I also use apt to keep the equation value (the apothem length), and ang to keep (pi/n).
(setq ang (/ pi n)) (setq apt (sqrt (/ (/ a (/ (sin ang) (cos ang))) n)))
We already use getpoint to ask user to pick a point. Or they can type the coordinate. Now we need three user input: number of sides, area, and center point. 1. Number of sides is an integer. You dont accept 2.5 as number of sides, dont you? We can use GETINT to ask for integer. 2. Area can have decimal numbers, so it is a real number. We can use GETREAL for this purpose. 3. You already use GETPOINT to ask for a point right? Let us try. In AutoCAD command line, type (GETINT) type integer number. It should return the number you entered. Try again. This time type a decimal number.Lets say 3.2. What will AutoCAD say? Command: (getint) 3.2 Requires an integer value. Using the right user input function will also reduce probability of errors.
Now we have complete data, what we will put in our program. I strongly suggest you to try writing the program first. You can check and compare the code later. Below is the complete code I created. If you have problem, you can copy the code below.
; This LISP will create regular polygon by defining polygon area and number of sides ; Created by Edwin Prakoso ; Website: http://cad-notes.com (defun c:pba (/ a n apt ptloc) (setq n (getint " Number of Polygon Sides: ")) (setq a (getreal " Expected Polygon Area: ")) (setq ang (/ pi n))
(setq apt (sqrt (/ (/ a (/ (sin ang) (cos ang))) n))) ;calculating apothem for circumscribed polygon (setq ptloc (getpoint " Pick Location: ")) (command "_POLYGON" n ptloc "C" apt) )
How are you doing so far? I would like to know what do you think after you have done the exercises. Next, we are going to create an AutoLISP program to label coordinate.
Program Basic
We are going to use leader tool to label it. It will require us to define two points: point to label, and where we want to place the label. We already learned how to ask for user input for a point. So you should already familiar with this code:
(defun c:\cnlabel () (setq p (getpoint " Pick Point to Label: ")) ; asking user to click point to label and save it (setq textloc (getpoint " Pick Text Location")) ; asking user to click text location
In visual LISP editor, you can copy or type it (I suggest you to type it for your exercise) then click load active edit window.
What if you dont want to use leader, but would like to use Multileader? Simple, use this line:
(command "_mleader" p textloc p)
Try to use it first if you want to know how mleader works, pay attention on each step what you should do. The program can be used, but the result is not good enough. We cant control the text appearance, the label will be shown similar like below.
We already get the x and y value, but they are still in real number. If we want to add more text, like x=, y= then we need to convert them to string. We can convert them to string using rtos function. Let us add it to our code. (setq x (rtos (car p))) (setq y (rtos (cadr p))) Now x and y are strings. We can add more texts to those strings. In calculating real or integer, we can use mathematic function like + or . But in strings, we use strcat to add more text to the variable. Let say I want it to look like this: x = 100, y = 50 I can create it by combining x and y like this: (setq ptcoord (strcat x= x ; y= y)) Dont forget to save it to a variable! I use ptcoord. You may change the text inside the double quotes. You may want to use E=, N=, el= etc. Now lets put it all together:
(defun c:cnlabel () (setq p (getpoint " Pick Point to Label: ")) (setq textloc (getpoint " Pick Text Location")) (setq x (rtos (car p))) (setq y (rtos (cadr p))) (setq ptcoord (strcat "x=" x ", " "y=" y)) (command "_leader" p textloc "" ptcoord "") (princ) )
To add the dynamic line, we simply add the variable of the first point when we ask the second point. The variable is p, so now the line become: (setq textloc (getpoint p Pick Text Location)) Add it and try it again.
We will cover more about loop, but now this will do. Now try it. Im amazed how many thing I can do with a basic knowledge of AutoLISP, and I believe many more things can be done. I would like to know what program have you made until this point? Please share with us! Next, we are going to modify it a bit further: You will create AutoLISP program to label coordinate showing Northing, Easting and elevation in multiple lines.
This time we are going to work with AutoCAD block. We had a good time when creating label for coordinate. Now we are going to create a similar AutoLISP program. We will create a program to label elevation. But this time we will also use block. Using block has several advantages. We can have more geometries without having to draw them and also can place the text to block attributes.
Before we start, you need to download this AutoCAD file. This is the block we are going to use as elevation label.
Save the file to your library folder. I save it to D:\acadlib. You may have different location if you want to. Now we need to set the location as AutoCAD support file search path. Open AutoCAD option. Add the folder location here.
Insert block will insert a block with the name we defined in our AutoLISP program. If it cant find it, then it will search and load DWG name with the same name as the block. Then insert the DWG as block. That is why we define the file location in default search path. AutoCAD will load the file from that location. The rest is easy. Like in previous tutorial, we can get the elevation value from the coordinate list and insert it to the block attribute. So our basic program can be like this:
(defun c:cnannolevel (/ labelposition y) (setq labelposition (getpoint " Pick Label Position: ")) (setq y (cadr labelposition)) (setq y (rtos y)) (command "_-insert" "annolevel" labelposition 1 1 0 y) )
More Consideration
If you already tried it, you can see it works nicely. But you may want to consider to allow AutoCAD users to change the block scale. We will do it later in this AutoLISP tutorial. The next thing is change the label value when its at 0 elevation. In my country, many people like to use + 0.00 when its at zero elevation. We will add an if conditional to change the value. Add Ability to Change Scale If you examine the block, you will soon know that it was created in full scale 1:1. When you need to place it to a drawing with 1:100 scale, then you need to scale it after placing it. We dont want that, dont we? So now we will add one more variable. This time we will let the variable become global variable. So AutoCAD will still recognize the variable after the application ends. And we can use it for other LISP application. Because we dont want the program to ask user for scale every time they use it, then we will use conditional IF. The structure of conditional IF is (IF (statement) (things to do if true) (else, things to do if false)) I added conditional IF twice:
(if (= cnglobalscale nil) (setq cnglobalscale (getreal " Set Global Scale for CN Annotation <1/1>: "))
The code in plain English 1. The first conditional will check if the globalscale is not set (the value is NIL). If its true it will ask the user for input. 2. The second conditional will check if the user dont give any input and simply press *enter+. Because the user dont provide value, then the scale still NIL.We assume that they want to use default scale 1:1. Thats why we provide 1/1 in the bracket. We tell user that if they dont give any value, it will use full scale. This is common in AutoCAD tools to offer user to use default value.
I added one more function at the bottom so users can change the scale anytime. Remember, we only ask for scale one time, when the global scale is NIL. So we need to provide them a way to change the scale manually later. Change Text in Zero Elevation As I mentioned before, we here would like to have + 0.00 than just 0 at zero level. This is simple. Just like before, we use conditional IF. Instead of using
(setq y (rtos y))
We use
(if (= y 0) (setq y "%%p 0.00") (setq y (rtos y)))
The code will check if Y value is zero, and replace it with + 0.00. If its not, it will use the original value.
Final Code
After we added those features, then this is the complete code:
; CAD-Notes.com annotation utilities ; by: Edwin Prakoso (defun c:cnannolevel (/ labelposition y) (if (= cnglobalscale nil) ; this will check if user already has defined the drawing scale (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) ) (setq labelposition (getpoint " Pick Label Position: ")) (setq y (cadr labelposition)) (if (= y 0) (setq y "%%p 0.00") (setq y (rtos y))) ; this will change text when in zero elevation (command "_-insert" "annolevel" labelposition cnglobalscale cnglobalscale 0 y) (princ) ) (defun c:cnannoscale () ; this another function defined to enable user to change scale later (setq cnglobalscale (getreal " Set Global Scale for CN Annotation: ")) )
This program works nice. But the problem is the label cant be updated automatically. Not like using fields. We will cover how to update the value later when we cover entity selection.
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 havent 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.
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:
1. X1 and X2 are the same. 2. 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 dont have to define it because we already set it as default block name.
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)
3. 4. 5. 6.
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.
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 dont set error trapping in an AutoLISP program! You can read it in AfraLISP about error trapping here.
We created an AutoLISP program to create leader to label coordinate before. It will be very useful for surveyors who use vanilla AutoCAD. But you may want to use multileader instead of leader in your AutoLISP program. MLEADER is neat, and you can have more control and flexibility with it. The problem is it uses multiline text, not single line text in leader. When working with multiline text, we press [enter] when we want to add another text line. But using in AutoLISP to simulate pressing enter, it will not work. When we use AutoCAD thinks we want to end the command. But not adding new line.
I posted a reply in the comment section, but just in case you miss it I write it as a post. To solve this, we need to use ANSI character to add a new line. chr 10 will add new line (or line feed) to our variable. Lets take an example. We add that character to our string variable:
(setq ptcoordN (strcat "N=" y)) (setq ptcoordE (strcat "E=" x)) (setq ptcoordN (strcat ptcoordN (chr 10) ptcoordE))
The first and second line will get x and y value, then add prefix. The 3rd line will combine them both. That AutoLISP code will combine N coordinate, new line, then place E coordinate there. The complete AutoLISP code will be:
(defun c:cnlabel (/ p x y ptcoordN ptcoordE textloc oldprec) (setq oldprec (getvar "LUPREC")) (setvar "LUPREC" 4) (while ; start while loop (setq p (getpoint " Pick Point to Label:")) ; asking user to click point to label and save it (setq textloc (getpoint p " Pick Text Location:")) ;asking user to click text location (setq x (rtos (car p))) (setq y (rtos (cadr p))) (setq ptcoordN (strcat "N=" y)) (setq ptcoordE (strcat "E=" x)) (setq ptcoordN (strcat ptcoordN (chr 10) ptcoordE)) (command "mleader" p textloc ptcoordN) ;ativate label command and use the input (setvar "LUPREC" oldprec) (princ) ) )
I dont know if there is other solution for this. If you know the other way, please share it here! Filed Under: AutoLISP
An AutoLISP program doesnt have to be difficult. We can create simple LISP program and get many benefits from it. Its not just about speed up the drawing creation, but also to maintain our standard. In system variable and COND conditional, we discussed how we can use block to create grids. This will ensure the users (or you) to use the same block for every drawing. Now lets see how to control the other properties you need to control: layers and styles. Lets explore the possibility to use it to control our drawing standard.
Layers are the most important thing to manage our drawings. If youre not familiar with layer standard, CADD manager has a short article about the concept.
(setq textcontent (getstring " Type Text: ")) (setq textloc (getpoint " Text Position: ")) (command "_TEXT" textloc "" "" textcontent) ;create the text (setvar "CLAYER" oldlayer) ;restore active layer )
We have discussed about using conditional IF in AutoLISP before. The problem is IF only allows you to run one statement. So we need to add (progn GROUP OF STATEMENTS) to run several statements. Lets see the complete code below:
(defun c:cntext () (setq flag (tblsearch "LAYER" "A-Anno")) ;looking for A-Anno layer ;then do this if exist (if flag (progn ;grouping statement (setq oldlayer (getvar "CLAYER")) (setvar "CLAYER" "A-Anno") (setq textcontent (getstring " Type Text: ")) (setq textloc (getpoint " Text Position: ")) (command "_TEXT" textloc "" "" textcontent) (setvar "CLAYER" oldlayer) ) ;end statement group
;else - and give warning if it doesn't exist (alert "No A-Anno layer. Create it first to maintain standard.") ) ; end if )
Now AutoCAD will try to find the layer first before executing our command. If it doesnt exist, then it will give a warning.
If the layer exists, then it will run our program. There are several possibilities to handle this situation. We will see in the next tutorial, other alternatives to deal with non-exist layers. credit: this article was written based on this AfraLISP tutorial.
We learned how we can work with layers when we create objects in our AutoLISP program. By changing current layer or style in the program, it will make sure our objects to use specific properties. For example, we want when we place the grid label, we place it on annotation layer. This is a good way to be implemented with your company standard. But what we did before is simply change it. If it doesnt find it in name list, it simply gives a warning. Ask the user to create it first. Thats not cool.
The more logical thing to do is, when it doesnt find it, it creates a new one.
-Layer is the command. M will create new one, it will ask you for its name and then make it current. This command will keep asking you to enter an option. So we press [enter] to end the command.
Easy, right? This will create new layer named NEWLAYER (if there is no newlayer in the list) and make it current. The good thing about it is, if there is existing layer with that name, it will accept it and set make it current. So we dont have to add code to check if it already exist. We can replace this code we made before:
(defun c:cntext () (setq flag (tblsearch "LAYER" "A-Anno")) ;looking for existing ;then do this if exist (if flag (progn ;grouping statement (setq oldlayer (getvar "CLAYER")) (setvar "CLAYER" "A-Anno") (setq textcontent (getstring " Type Text: ")) (setq textloc (getpoint " Text Position: ")) (command "_TEXT" textloc "" "" textcontent) (setvar "CLAYER" oldlayer) ) ;end statement group ;else - and give warning if it doesn't exist (alert "No A-Anno layer. Create it first to maintain standard.") ) ; end if )
Text Styles
What about text styles? We can use style command. It also can create new style and use it as current. Let examine in command line how the sequence is.
Command: -STYLE Enter name of text style or [?] <Standard>: newstyle New style. Specify full font name or font filename (TTF or SHX) <txt>: arial Specify height of text or [Annotative] <0.0000>: Specify width factor <1.0000>: Specify obliquing angle <0>: Display text backwards? [Yes/No] <No>: Display text upside-down? [Yes/No] <No>: newstyle is now the current text style. There are 7 options AutoCAD will ask you. Lets see this sample. You can use this line to create text styles
(command "-style" "newstyle" "arial" "" "" "" "" "")
That code will create a new text style with name newstyle and using arial.ttf as its font. It ignores the other questions and accept default values. Another example, this will create a style with height 2.5 and width factor 0.85.
(command "-style" "newstyle" "arial" 2.5 0.85 0 "N" "N")
* Note: if you use shx font, you need to press [enter] one more time. SHX fonts support vertical alignment, and AutoCAD will ask one more question, if you want to make it vertical.
Dimension Styles
Unfortunately when working with dimstyle, we need to use conditional IF.
1. We need to use save option in dimstyle to create a new one. 2. Or if it doesnt exist, we need to use restore to change the current dimension style.
The problem is when we use save dimstyle, and AutoCAD find it already exist, it will ask one more question. It asks us to confirm if we want to redefine the existing. So we use this code:
(defun c:tst () (setq flag (tblsearch "dimstyle" "newdimstyle")) ;looking for dimstyle ;then do this if exist (if flag (command "-dimstyle" "R" "NEWDIMSTYLE") (command "-dimstyle" "S" "NEWDIMSTYLE" "")
); end if )
We covered several topics on how we can draw more efficiently using AutoLISP. Now its time to move on. We are going to learn how we can modify existing objects in our drawing. The most important thing about editing objects is to select them. As we know, After we activate an AutoCAD modification command (like move, copy, etc) AutoCAD will ask us to select object.
SSGET will save your selection to sel1 variable. Then you can add it to move command. Remember, you need to add to end selection. If you dont add it, AutoCAD will continue to ask you to select object.
That code will select all objects inside rectangular window from 0,0 to 10,10. Other code that we can use are:
setq sel1 (ssget "c" '(0 0) '(10 10))
to select last objects created. to select objects in previous selection. all objects in the drawing.
If youre not familiar with the selection mode above, read using AutoCAD selection below. For window and crossing polygon selection, we can also ask for users input. For example:
(setq pt1 (getpoint " Pick first point: ")) (setq pt2 (getpoint " Pick other corner point: ")) (setq sel1 (ssget "c" pt1 pt2))
If you have a simple example that we can use in this exercise, please let me know. I will add your code here, and you will be credited.
Further readings:
1. Selection sets. Good explanation by Kenny Ramage on AfraLISP. 2. Using AutoCAD selection. Here are the list how you can select objects in AutoCAD. 3. AutoLISP function list. See all LISP function that you can use to expand your LISP program.
In the last tutorial, we learned how to use object selection in AutoLISP. This time we will extend the object selection by using selection filter. Using filter in AutoLISP is very similar with using AutoCAD filter. We can define which kind of object we want to select. We can define objects with specific properties to select.
For example, we can create a program to run and select dimensions in drawing, and move it to annotation layer. We will create this program in this tutorial. This kind of program probably very simple, but can help you to maintain drawing standard. As we did before, we can select all object using this line.
(setq sel1 (ssget "x"))
With that simple code, you can quickly find and move all dimensions to desired layer. Very useful, right? You can also modify it to allow user to check the selection visually before move dimensions to other layer.
DXF code
One more thing that you might want to know is the DXF code.
(0 . "DIMENSION") - Using DXF code 0 allows you to define object to select by objects type. This code will only allows you to select dimensions.
Using DXF code 8 allows you to define object to select by their layers. This code will only allows you to select objects on layer ANNO-DIMENSION.
(8 . "ANNO-DIMENSION") -
We use DXF codes with selection filters in AutoLISP. See the complete dxf associative code here.
Andres Rodriguez Fotolia.com We covered several basic AutoLISP tutorial already. You should be able to use the programs. Now its time to manage them in AutoCAD. This is not only for you who want to learn AutoLISP, but also for you who want to simply use AutoLISP program. We know that we can find many AutoLISP program on internet now.
You can use visual lisp editor to save it as a program. Or notepad will work. But dont use Microsoft Word or other Word Processing program.
Paste your code there. Save it as LISP program. If you use Visual LISP editor, then by default it will save your code as .lsp file. But if you use notepad, then you must define the .lsp extension when saving your file. Type YourProgramName.lsp (with double quote to force notepad save it as it is). Of course, change the blue text with your program name.
Save your file to a location that allow people easily access it.
hint: AutoCAD veterans use APPLOAD in command line In load/unload applications dialog, browse and find your AutoLISP file you saved before. Select it and click load.
The less cool way to do it is by clicking contents button below startup suite briefcase. Here you can add or remove LISP from startup suite. Just in case one day you dont want a LISP program to load automatically anymore, you know where to remove it now, right?
Again, if you copy it from internet, you can see on top of the program like this.
DEFUN is defining the function. In this sample, the function can be loaded by typing DIMLA in command line then press [enter]. As simple as that. What you should do next, depends on your AutoLISP program.
In ribbon panel/toolbar/menu
Type CUI then press [enter] to load Customize User Interface dialog. Or click User Interface in customization panel.
If youre not familiar how to create a command here, read this tutorial first. You have to make a command, change the command name and macro. The macro should be ^C^CDIMLA. Or whatever command you want to activate using this macro. ^C^C means you press esc twice to cancel all running command. After youve done, drag the command to ribbon panel, toolbar, or menu as you like.
In tool palettes
What about tool palettes? Can we place the command there? Sure you can. You can use palettes to activate AutoLISP command too. The process is similar with adding action recorder command in this tutorial.
What we learned
Now you know how to save a LISP code, load it to AutoCAD, and use it. You also know how to use AutoLISP command from ribbon/toolbar. And even using from tool palette. So how do you use AutoLISP? Do you load it automatically? And do you use command line or place it to ribbon?
Do you want to load an AutoLISP program? Here is a basic guide how to do it.
To load application
If you have an AutoLISP program, you can load it by using load application in manage tab.
Or you can type APPLOAD then press [enter]. You will see load/unload applications dialog opened. Find your AutoLISP program then click load. Double-clicking the file will also load the application. This method will load your application in current session only. It means that when you close AutoCAD, then restart it, the application is no longer loaded. You have to load it again. If you use the application frequently, then you can consider to load it automatically in every AutoCAD session. You can do it by adding it to startup suite.
Drag and drop thing to add application is cool. If you notice the add button here, yes, its the other method to add application to startup suite. Click it, find your application and click open.
There are some more advance technique, but I find this is the most convenient way for people who dont know much about customization like me. There are more methods like described in AfraLISP here, if you are interested :)
Last week we covered about loading AutoLISP file. You learned how to load, and optionally put your LISP to startup suite. Startup suite will load LISP automatically every time you start AutoCAD. In this post, you will learn how to load AutoLISP program using acaddoc.lsp. We also had another post about excel datalink. The problem with datalink is, its not updated automatically. We have to update it manually. It means we may send or plot files that use old value. In this post, you will also learn how to make AutoCAD automatically update datalink when we save or plot our files. We will define our own plot and save command.
What is ACADDOC.LSP?
In short, its also an AutoLISP file. The difference is, AutoCAD will execute it every time we create or open a drawing file. If you want further explanation, Jimmy Bergmark explain about ACADDOC.LSP in details here.
Creating acaddoc.lsp
Create a new LISP file. You may use text editor or visual LISP editor to do it. Save it to a support file path. You may choose any existing path, or create your own support path. I would recommend you to do the later, and you can also save all your LISP file there.
Loading AutoLISP command is something quite basic we can do with acaddoc.lsp. Next, we will try to define our own command here.
Now try type .PLOT [enter]. Notice the dot before PLOT command. Plot command should work. The dot means we use AutoCAD built in command. After we finished, PLOT and .PLOT will give different result. The first one will use plot we define in acaddoc.lsp. The last one use AutoCAD built-in plot command. You can activate PLOT command back using REDEFINE [enter] PLOT [enter]
We use INITDIA to load AutoCAD plot dialog. If we dont use INITDIA before plot, then you will not see the dialog box. You will need to setup the plot using command line.
Save this AutoLISP file. Create or open a new file then activate plot. You will see after I create a new file, our code will undefine plot. Then when we use PLOT command, it updates datalink first, then activate plot. Nice, isnt it?
Regenerating model. AutoCAD menu utilities loaded.undefine Enter command name: plot Command: Command:
Command: PLOT _DATALINKUPDATE Select an option [Update data link/Write data link] <Update data link>: Command: .plot
We covered about acaddoc.lsp in AutoLISP tutorial. Acaddoc.lsp will execute commands defined in it, every time AutoCAD open a file.
In this article, we are going to focus to the last one. I found that there are many users confused why their AutoCAD doesnt work as usual. And they become regular questions. These are some samples of changed system variables.
There is a debate why they changed. Most people think that it was because routines in AutoLISP or other 3rd party applications. I used to be agree with it, until I saw this problem also happens in AutoCAD LT. So it remains a mystery to me.
Feel free to add more lines or change system variables and values as you preferred. If you want to learn how to use Visual LISP editor, see this basic AutoLISP tutorial.
Standard layers is one popular topic when we talk about CAD standards. There are several standard layers available like BS 1192, AIA, ISO 12567. If you asked me, I would suggest you to keep your standard layers in AutoCAD template and standards file. However, if youve never created standard the layers before, it would take times to add them in your template manually. There is a bundle of AutoLISP programs that you can download and run to build the layers. You can run it, it will create the layers and you can save your template. You can download the AutoLISP program in this cadalyst tip. There are four LISPs, one linetype, and one ctb plot style. You must load demo.lin linetype, before you run AIALAYERSDEMO. If you dont, you will get error when running the LISP program.
If you are planning to adopt AIA standard layers, now you have a good tool to start using it!
We can create isometric drawing by changing the snap style. Its really helpful. However, what if you need to draw polygon in isometric drawing? Lee Mac has an AutoLISP program to do this. As you can see below, you can quickly draw polygon in your isometric drawing. Its not a 3D drawing, its a 2D drawing. If you are interested, you can download the isopoly program here.
Using Isopoly
To use isopoly, you need to load the program to AutoCAD first. Refer to Lees guide to load AutoLISP program here. After you load the program, change SNAPSTYL system variable to 1. Type SNAPSTYL then [enter]. Type 1 then [enter] again to accept the value.
You can cycle between isoplane by pressing F5 or type ISOPLANE on command line. Lee also includes a short code to allow you quickly change SNAPSTYL using command line. Find it at the bottom of the download page. If you are not familiar how to save that code to an AutoLISP program, read this guide saving: using and managing your AutoLISP program. Lee has many great free AutoLISP program. If you never visit his site, check all these programs that you can download.