Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
George Omura. Lisp programing tutorial for AutoCAD customization / 620.0.The ABC's of AutoLISP - Omura, George.pdf
Скачиваний:
146
Добавлен:
02.05.2014
Размер:
1.55 Mб
Скачать

The ABC’s of AutoLISP by George Omura

Chapter 11: Accessing Complex Objects

Introduction

Accessing polyline vertices

Defining a new polyline

Drawing the new polyline

Testing for polyline types

How arcs are described in polylines

Accessing object handles and block attributes

Extracting attribute data

Conclusion

Introduction

In this the final chapter, you will look at several programs that not only introduce you to some new AutoLISP functions, but also review many of the functions you learned about from earlier chapters. In the process, you will learn how to access complex object types. You will also look at ways to store data as a permanent record within a drawing.

Accessing Polyline Vertices

Polylines are complex objects that are a composite of many objects. There are a variety of polylines from straight lines, to three dimensional Bezier-spline polylines. But even the most complex polyline can be broken into three basic components, Vertices, lines and arcs. AutoCAD stores polylines as a kind of compound object made up of several layers of information. To help you get a grasp of this idea, you can think this storage structure as an onion; as you peal off one layer, another layer is revealed. The first layer, the one accessed by entget, gives general information about the polyline. In this section, you will look at ways to access deeper layers of information using AutoLISP.

237

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

It will help our investigation if we first take a look at typical polyline property list first hand.

Figure 11.1: Test drawing for exercise

Open a drawing file called Chapt11 and draw the polyline rectangle shown in figure 11.1. Use the coordinates shown in the figure to locate the corners.

1. Enter the following expression at the command prompt:

(entget (car (entsel)))

2. The selection cursor box appears and you get the select object prompt. Pick the polyline you just drew. The following listing appears.

((-1 . <Object name: 60000120>)

(0 . "POLYLINE")

(8 . "TEXT")

(66 . 1) (10 0.0 0.0 0.0)

238

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

(70 . 1) (40 . 0)

(41 . 0)

(210 0.0 0.0 1.0)

(71 . 0)

(72 . 0)

(73 . 0)

(74 . 0)

(75 . 0))

We have list the polyline property list vertically for clarity though you will see the list shown as a continuous string on your text screen. We see the object name, object type and layer listed but where the point group code 10 should indicate some coordinate location, only zeros are shown. Also, we would expect to see a list of at least four coordinate values. Instead, we see some somewhat unfamiliar codes from the 40 and 70 group codes, all showing zeros.

This doesn't mean that we are unable to access more specific information about polylines. We just need to dig a little deeper. The tool we use for digging is the entnext function.

We mentioned that it helps to think of the polyline data as being stored in layers like those of a onion. The listing above represents the outermost layer. To get to the next layer, you need to use the entnext function.

1. Enter the next expression:

(entget (entnext (car (entsel))))

2. You will get a listing like the following:

((-1 . <Object name: 60000120>) (0 . "VERTEX")

(8 . "0")

(10 1.0 1.0 0.0)

(40 . 0)

(41 . 0)

(42 . 0)

239

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

(70 . 0)

(50 . 0))

This new property list gives us some new information. The object name is different from the previous list. Also, instead of showing "POLYLINE" as an object type, we get "VERTEX". The layer information is nearly the same but for the first point value, group code 10, we see the coordinate for the first corner of the box, 1.0 1.0 0.0. For purposes of our discussion, we'll call this vertex object a polyline sub-object or just sub-object.

Now, we know how to get more detailed information about a polyline by introducing entnext into our expression to extract an object's sub-object information. We have "peeled off" the first layer of our onion to reveal the next layer of information. But we only got the first vertex of the polyline. To get the others, you just continue adding more entnext functions.

1. Enter the following:

(entget (entnext (entnext (car (entsel)))))

2. When the Select object prompt appears, pick the polyline box. Another new property list appears.

((-1 . <Object name: 60000120>) (0 . "VERTEX")

(8 . "0")

(10 10.0 1.0 0.0)

(40 . 0)

(41 . 0)

(42 . 0)

(70 . 4)

(50 . 0))

Now we see a list that describes the second vertex of the polyline. Note the group code 10 value shows a coordinate 10.0 1.0 0.0 which is the next vertex in the polyline.

It would be rather awkward to have to keep expanding our expression by adding more entnext functions to extract each sub-object's property lists. If we have a polyline that has 40 vertices or more, we would end up with a enormous program in order to extract all the vertices. Fortunately, we can use a recursive function to get the property list of each vertex. By using the same variable name to which we assign each vertex object name, we eliminate the need to add continual nests of the entnext function. Figure 11.2 shows a diagram of how this recursive function works and figure 11.3: shows a function that uses this recursion to extract a list of polyline vectors. The Function at the top of the figure, Getvec, is the one we will look at first.

240

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

Figure 11.2: Using recursion to extract subobject information

241

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

;Function to create list of polyline vertices----------------------------------

 

(defun getver (EntNme / SubEnt VerLst vertex)

 

(setq SubEnt (entnext EntNme))

;get first vertex

(setq VerLst '())

;setup vertex list

(while SubEnt

 

(setq vertex (cdr (assoc 10 (entget SubEnt))))

;get first vertex point

(setq VerLst (append VerLst (list vertex)))

;add vertex to verlst

(setq SubEnt (entnext SubEnt))

;go to next vertex

)

 

VerLst

;return vertex list

)

 

;Function to check if point lies between endpoints of line---------------------

(defun btwn (a b c)

 

(setq ang1 (angle a b))

;find vertex to point ang.

(setq ang2 (angle a c))

;find vertex to vertex ang.

(if (EQUAL (RTOS ang1 2 2) (RTOS ang2 2 2)) b)

;if equal return point.

)

 

;Program to insert Vertex in simple polyline ;------------------------------------------------------------------------------

(defun C:ADDVERT (/ pEnt VerLst Newpt int NewVer ptyp)

(setq pEnt (entsel "Pick vertex location: "))

;Get new vertex and pline

(setq VerLst (getver (car pEnt)))

;extract vertices

(setq ptyp (assoc 70 (entget (car pEnt))))

 

(setq Newpt (osnap (cadr pEnt) "nearest"))

;Get new vertex location

(while (cadr VerLst)

 

(setq NewVer

;add vertex to new NewVer

(append NewVer (list (car VerLst)))

 

)

 

(setq int

;Check for between-ness

(btwn (car VerLst) newpt (Cadr VerLst))

 

)

 

(if int

;if between, add to NewVer

(setq NewVer (append NewVer (list int)))

 

)

 

(setq VerLst (cdr VerLst))

;Remove vertx. from list

);end while

(setq NewVer (append NewVer (list (car VerLst)))) ;add last vertx. to NewVer

(command "erase" (car pEnt) "")

;erase old pline

(command "pline")

;start pline command

(foreach n NewVer (command n))

;insert points from NewVer

(if (= (cdr ptyp) 1)

 

(command "close")

 

(command "")

 

)

;end pline command

)

 

 

 

Figure 11.3: Function that implements diagram in figure 11.2

242

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

Lets examine this function in detail.

The function takes an object name as an argument. Presumably the object in question is a polyline. It proceeds to obtain the first vertex object name from that object.

(defun getvec (EntNme / SubEnt VecLst vector)

(setq SubEnt (entnext EntNme))

This vertex object name is assigned to the symbol subEnt. Next, a list is created to hold the vector coordinates:

(setq VecLst '())

The following while expression then goes to each vector property list and extracts the coordinate value. It first extract the coordinate from the current vertex object:

(while SubEnt

(setq vector (cdr (assoc 10 (entget SubEnt))))

Next, it appends that coordinate value to the vertex list VecLst.

(setq VecLst (append VecLst (list vector)))

finally, the variable SubEnt is assigned the vertex object name of the next vertex and the process is repeated:

(setq SubEnt (entnext SubEnt))

)

When all the vertices have been obtained, the list of vertices is returned:

VecLst

)

Now that we know what entnext is capable of, lets look at a practical application. Figure 11.3 includes a program called Addvect that adds a vertex to a polyline. If you have ever had to add a vertex to a polyline using the AutoCAD pedit command, you know it can be a trying effort. This program simplifies the operation to one step. Figure 11.4 gives a graphic description of how this program works.

243

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

Figure 11.4: How Addvect work conceptually

Lets see first hand how it works.

1.Save and exit the Chapt11 file.

2.Open an AutoLISP file called Addvert.lsp then copy figure 11.3 into the file. Save and exit Addvert.lsp

3.Return to the Chapt11 drawing file and load addvert.lsp.

4.Enter Addvert at the command prompt. At the prompt:

244

Copyright © 2001 George Omura,,World rights reserved