Pixel Graphics, Inc. - Litigation & Court Graphics
LITIGATION GRAPHICS - COMPUTER ANIMATION - TECHNICAL ILLUSTRATION - CAD DRAFTING - AUTOLISP PROGRAMMING
3423 Rivers Edge Trail
Houston, Texas 77339
281.359.1187
Copyright 2008 - Pixel Graphics, Inc. All rights reserved.
AutoLisp Tutorial: Getting and Using Data from Entities
What are Entities?

AutoCAD entities are the basic objects we use to draw with in AutoCAD. They include lines, circles, arcs,
blocks, text, etc. When you are programming in Autolisp, it's important to understand that
all of the entities
and the parameters that define them in your drawing are listed in a database in the drawing
that you have
access to using Autolisp. That's really all that an AutoCAD drawing file is: one big database list of the
drawing entities contained in the drawing.

Here’s an example of what a "LINE" entity looks like from the database when using Autolisp. First draw a
line in AutoCAD, then at the command prompt, type:
Command: (entget (entlast))
Here's what Autolisp returns:
Jeff Winship - Computer Graphics Consultant                                                                                                                                                    April 22, 2008
Some Common Autolisp Group Codes
HOME  |  3D ANIMATION  |  DIGITAL IMAGES  |  AUTOCAD DRAFTING  |  AUTOLISP PROGRAMMING  |  CONTACT & OTHER INFO  |  F.A.Q.
((-1 . <Entity name: 7efa28f0>) (0 . "LINE") (330 . <Entity name:
7ef5bcf8>) (5
. "57E") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0")
(100 .
"AcDbLine") (10 -1.68423 46.3172 0.0) (11 5.40053 48.6858 0.0)
(210 0.0 0.0
1.0))
At first glance, this appears to be a complete mess. If you look a little closer, you'll see that the entity data
Autolisp returns for the "LINE" entity is, like all other things in Autolisp, simply a list. If we break it down into
it's list items as follows, we can start to tell what each part of the list represents.
(
    (-1 . <Entity name: 7efa28f0>)
    (0 . "LINE")
    (330 . <Entity name: 7ef5bcf8>)
    (5 . "57E")
    (100 . "AcDbEntity")
    (67 . 0)
    (410 . "Model")
    (8 . "0")
    (100 . "AcDbLine")
    (10 -1.68423 46.3172 0.0)
    (11 5.40053 48.6858 0.0)
    (210 0.0 0.0 1.0)
)
Each of the numbers that start the list are referred to as "Group Codes". They are simply codes telling
Autolisp what the text string or number following each group code represent. In the previous example the
line with the "0" group code indicates what type of entity we are looking at, in this case a "LINE". You don't
need to memorize all of the group codes, but a few of them are pretty common and you should be familiar
with them.
Group Code
Description
0
The entity type (i.e. "LINE", "CIRCLE", "ARC", "PLINE", etc.)
8
The layer name that the entity is currently on
10
For almost all (if not all) entity types, this represents a point list
For our "LINE" example, this is the starting point of the line (x y z)
11
Again a point list, for the "LINE" this is the end point coordinates of the line (x y z)
That's about all the ones I have memorized, but if you need a more comprehensive listing, look in the
"Developers Help" file in AutoCAD.

Selecting Entities Using Autolisp

Now that we know how to decipher the group codes, we need to be able to access that information. This
first thing we need to do is to figure out how we want to choose the entities (pick them on screen in
AutoCAD, query the AutoCAD database directly, etc.) Once we've done that, we'll assign the entity data to
a variable and then we'll be able to get access to the data contained within each entity listing.

Going back to our last example, we can get the entity data from the last item drawn in AutoCAD using the
entlast function. At the command prompt, type:
Which returns: <Entity name: 7efa28f0> or something similar.

This is the entity code that AutoCAD assigned to the line, and not much use to us in this form. What we
really need to do is assign that entity to a variable we can work with. Type the following at the command
prompt:
Command: (setq ent (entlast))
Command: (entlast)
Which again returns: <Entity name: 7efa28f0>

This also doesn't do us much good as it is, so we use the entget Autolisp function to show us what data is
inside the entity. Use the
entget function as follows:
Which returns all of the data we saw at the beginning of this tutorial. At this point we have the AutoCAD's
entity code for that specific line assigned to the variable "ent", and the data inside that entity assigned to
the variable "entdata".

Let's say we want to know what layer the line is on.

Getting Data from Entities

To pull out the layer info from the entity data, we use the assoc Autolisp function. You need to pass the
entity name, and the group code you're interested in to the
assoc function as follows:
Command: (setq entdata (entget ent))
Command: (assoc 8 entdata)
Which returns: (8 . "0")

To remove of the group code and just get the actual layer name we use the cdr function to strip off the
"8" group code, so we add that to what we previously typed:
Command: (cdr (assoc 8 entdata))
Returns: "0"

Success! Now we just assign that to a variable that we choose to represent the layer as follows:
Command: (setq lay_name (cdr (assoc 8 entdata)))
Now our variable "lay_name" contains the layer name that the line exists on.

Extending this concept to retrieve the starting point of the line, type:
Command: (setq st_point (cdr (assoc 10 entdata)))
Returns: (-1.68423 46.3172 0.0)

You're data will be different because we obviously couldn't have lucked out and initially drawn our line from
the exact same starting point.

Follow the same procedure to get the end point of the line:
Command: (setq end_point (cdr (assoc 11 entdata)))
Will return the endpoint of the line.

At this point you have the know how to get any piece of information from any entity in AutoCAD.

Putting it All Together

So far, we've been entering single lines of Autolisp program code at the AutoCAD command prompt,
which can sometimes be handy, but isn't very useful when you're programming more than line of code.
Let's write a simple program that calculates the midpoint of the line we've drawn. The following example
should give you a little insight into how AutoCAD might find the "midpoint" of a line when you "snap" to it.

First things first, we've got to come up with a mathematical way of calculating the midpoint of a line given
that you know the two endpoints of the line. This isn't the actual coding stage, it's development of the
algorithm. Most of the time, development of the algorithm is the most difficult and important part of the
program creation process. This is where good math skills and really creative thinking pay off.

No direct formula I can think of off the top of my head solves for the midpoint of a line. So, like I was taught
in engineering, if you don't understand the problem, break it down into smaller pieces. If we take the X of
the starting point and the X of the ending point, and average those two numbers together, that will give us
the average X (or midpoint in the X axis). Following suit with the Y and Z coordinates, we'll get the average
Y and average Z. Combine those three into a list and we've got the 3D midpoint. Now we begin the coding:
(defun c:3d_midpt ()

    <Calculation of midpoint code goes here>

);-End of 3d_midpt command
TIP: I learned pretty quickly that when writing Autolisp programs, to write them "outside-in" as shown in the
code sample above. It really helps you keep the parentheses in the proper places it frankly just makes
more sense to me to do it this way. If you test run the code in AutoCAD at each stage, it will make it a lot
easier to find and correct the syntax and coding errors as well.

First, get the entity data as we did in the previous example:
(defun c:3d_midpt ()
    ;-Get the entity data for the last entity (will crash if not a
    ;- line)
    (setq ent (entlast))
    (setq entdata (entget ent))


);-End of 3d_midpt command
Next, get the X, Y, and Z data for the starting point and ending point.
(defun c:3d_midpt ()
    ;-Get the entity data for the last entity (will crash if not a
    ;- line)
    (setq ent (entlast))
    (setq entdata (entget ent))

    ;-Get start and end point data for the line
    (setq st_pt (cdr (assoc 10 entdata)))
    (setq end_pt (cdr (assoc 11 entdata)))


);-End of 3d_midpt command
Now, calculate the X, Y and Z averages.
(defun c:3d_midpt ()
    ;-Get the entity data for the last entity (will crash if not a
    ;- line)
    (setq ent (entlast))
    (setq entdata (entget ent))

    ;-Get start and end point data for the line
    (setq st_pt (cdr (assoc 10 entdata)))
    (setq end_pt (cdr (assoc 11 entdata)))

    ;-Calculate the X, Y and Z averages
    (setq Xavg (/
    (+ (car st_pt) (car end_pt))
    2.0
    ))
    (setq Yavg (/
    (+ (cadr st_pt) (cadr end_pt))
    2.0
    ))
    (setq Zavg (/
    (+ (caddr st_pt) (caddr end_pt))
    2.0
    ))

);-End of 3d_midpt command
To finish it off, combine the averages into a list and draw a point at that coordinate.
(defun c:3d_midpt ()
    ;-Get the entity data for the last entity (will crash if not a
    ;- line)
    (setq ent (entlast))
    (setq entdata (entget ent))

    ;-Get start and end point data for the line
    (setq st_pt (cdr (assoc 10 entdata)))
    (setq end_pt (cdr (assoc 11 entdata)))

    ;-Calculate the X, Y and Z averages
    (setq Xavg (/
    (+ (car st_pt) (car end_pt))
    2.0
    ))
    (setq Yavg (/
    (+ (cadr st_pt) (cadr end_pt))
    2.0
    ))
    (setq Zavg (/
    (+ (caddr st_pt) (caddr end_pt))
    2.0
    ))

    ;-Combine the averages into a list
    (setq midpt (list Xavg Yavg Zavg))

    ;-Draw a point at the calculated midpoint
    (command "point" midpt)

);-End of 3d_midpt command
And we are finished. I hope you learned a lot from this tutorial and can now start to see how easy it is to
get and use data using Autolisp. In a future tutorial, we'll take a look at how to navigate polylines using
Autolisp, because they are slightly more complex than most entities.

If you have any comments or questions regarding this technique or code, feel free to e-mail me at:
support@pixelgraphicsinc.com