Nate Holt's Blog

July 5, 2009

Nate’s Simple AutoLisp – Lesson 004

Filed under: Tutorials — nateholt @ 11:31 am

(note: first appeared October 2008 on old blog)

Geeze, it’s been over two years since lesson “003”. Busy times. Anyway, we’re back. If you have 10 minutes to kill and want to take a chance with an exciting, hands-on experience, then read on.

Warning/Disclaimer: I’m neither a professional teacher nor am I well versed in the theory behind AutoLisp programming. But even beginners can come up with something useful and… best of all, have fun at the same time!

Here’s what we’ll do in the next 10 minutes. We will build up, step-by-step, a useful program consisting of just one line of code. Then we’ll add it as a button on the AutoCAD menu. Note: We’re using AutoCAD Electrical as our example application but this applies to AutoCAD in general.

Step-by-Step… A Really Simple “Wire Layer” Lister

We just want to have a lead-pipe simple tool to quickly list the layer name of the picked object, let’s say a series of AutoCAD Electrical wire segments, one at a time, boom…boom…boom. We don’t want a screen-full of data about the object, we don’t want some kind of property dialog to display, we just want this one piece of info and we want it fast.
Just for fun, let’s start develop this little tool with nothing more than the “Command:” window. With your AutoCAD schematic drawing active on screen, let’s start here:
Command: (entsel) [Enter]
Select object: [pick on wire segment, return=] (<Entity name: 7ef05f60> (19.5858 16.9905 0.0))
 
The (entsel) function returns a two-element list: the first element is the entity name of the picked line segment and the second element is the XY coordinate of the mouse pick point. We just want the entity name, the first element of this returned list. Use the AutoLISP “car” function to extract the first element. So let’s next try this:
 
Command: (car (entsel)) [Enter]
Select object: [pick on wire segment, return=] <Entity name: 7ef05f60>
 
Remember, gotta keep those “(” and “)” balanced out. For each “(” you add, you need to balance it with a “)”. Okay, good so far. Now let’s modify our “program” to open up the selected line segment with a call to “entget”
 
Command: (entget (car (entsel))) [Enter]
Select object: [pick on wire segment, return=] ((-1 . <Entity name: 7ef05f60>) (0 . “LINE”) (330 . <Entity name: 7ef05c10>) (5 . “6C”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”) (8 . “RED_18AWG”) (100 . “AcDbLine”) (10 20.0 17.0 0.0) (11 18.5625 17.0 0.0) (210 0.0 0.0 1.0))
 
Wow, got a lot more information than we really need. The part we want to focus in on is the “8” subrecord which is used to carry the entity’s layer assignment. We’ll use the “assoc” call to filter out all but the first instance of the target subrecord… 
Command: (assoc 8 (entget (car (entsel)))) [Enter]
Select object: [pick on wire segment, return=] (8 . “RED_18AWG”)
 
Really close. The layer name is in the second part of this return. We can use the “cdr” function to strip off the first part of this list of data…
 
Command: (cdr (assoc 8 (entget (car (entsel))))) [Enter]
Select object: [pick on wire segment, return=] “RED_18AWG”
 
Okay, we did it. Pick entity, get layer name instantly. But it only does one at a time. Let’s add a “while” loop around our little program like this:
 
Command: (while (princ (cdr (assoc 8 (entget (car (entsel))))))) [Enter]
Select object: RED_18AWG
Select object: RED_18AWG
Select object: BLK_14AWG
Select object: BLK_14AWG
Select object:
; error: bad argument type: lentityp nil
Command: *Cancel*
 
Nice. We could stop now. We’re can pick,pick,pick and get instant gratification with each pick. It doesn’t look too pretty when we decide to kick out with [ESC] or pick in empty space. Let’s do just a tiny clean-up so that it exits nicely when we just pick in empty space to finish. We will store the return from (entsel) in variable “x”. If valid, then we go ahead and dig out the layer name of “x” and “princ” it out to the command window. The extra “(princ)” at the very end also helps give a clean return.
 
Command: (while (setq x (entsel))(princ (cdr (assoc 8 (entget (car x))))))(princ) [Enter]
Select object: BLK_14AWG
Select object: RED_18AWG
Select object: RED_18AWG
Select object: BLK_14AWG
Select object:

Nifty.

Now let’s add our cool tool to the pull-down menu so we don’t have to type it in each time. Type CUI to bring up the standard “Customize User Interface” dialog. Select “ELECTRICAL” and “Menus” for the pull-down menu customization. Let’s put our new tool under the “Wires” pull-down. So expand “Wires” as shown here.

lisp004_01

  Highlight an existing command, let’s say “Insert Wire” and right-click. Pick “Duplicate”. Now you’ll end up with two “Insert Wire” entries, one above the other. Click on the new, lower one and begin to edit it.
 lisp004_02

Change the Display name, description. Carefully enter in your new program in the “Macro” line as shown here. The “^C^C^P” prefix is not absolutely necessary but does serve a useful purpose. If you are in some existing command and then pick on this new menu item, the ^C^C part will cancel out of the previous command before starting your new command. Be careful about NOT adding in extra spaces. These can sometimes be interpreted as an [Enter] keystroke when the “Macro” string is executed.

lisp004_03

Save the CUI changes. Now, go to your “Wires” pull-down menu.

WOW! There it is! Give it a try!

lisp004_04

 

BUT… this cool utility is encoded right into my current version of the menu. Could be easy to lose and a hassle to remember it and to type it back in 100% correctly. Let’s make it a bit safer – put the one-line program into an ASCII text file, call the file “cool.lsp”, and just reference this file from our new menu entry instead of having to encode the program itself into the menu entry.

The key here is to create the cool.lsp ASCII text file and save to some folder that is one of the support paths defined for AutoCAD (or a new support path you add for your cool utilities). This way, a simple call to the AutoLISP function “findfile” will find it.
After you create the one-line ASCII text file called “cool.lsp”, do this: test at command line to make sure it works. Type this string:
Command: (if (setq x (findfile “cool.lsp”))(load x)) [Enter]
Select object: BLK_10AWG
Select object: BLK_10AWG
Select object:
 

Okay, the above test worked. It found, loaded, and executed the one line of code. It worked! Now edit the menu button and encode this “findfile” command string into it. To do this, type CUI and find your “Cool layer lister” entry. Change the macro string to match below. OK out of CUI command and test the menu button.

lisp004_05

 

Time’s up! Was that fun or what… ? ! ! !

Advertisements

2 Comments »

  1. […] previous postings: Lesson 001, Lesson 002, Lesson 003, Lesson 004, and Lesson […]

    Pingback by Nate’s Simple AutoLISP – Lesson 006 « AutoCAD Electrical Etcetera — September 26, 2009 @ 5:03 pm

  2. Can you place the text into Autocad instead of the command line? and if so how would i do that
    Thank you so much
    Sherry

    Comment by Sherry — November 30, 2009 @ 3:39 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: