Visual LISP & Polylines - Part 1
- See also:
- Visual LISP & Polylines - Part 2
Dealing with polylines using straight forward AutoLISP can be quite a pain. But, believe it or not, using Visual LISP they are a breeze to modify and manipulate. Let's have a look shall we?
Manipulating Polylines
First of all, fire up AutoCAD and draw a polyline but do not close it :

Now, type the following in the Visual LISP editor :
_$ (vl-load-com) _$ (setq theobj (car (entsel "\nSelect a Polyline: "))) <Entity name: 14e35f8> _$ (setq theobj (vlax-ename->vla-object theobj)) #<VLA-OBJECT IAcadLWPolyline 01ea16d4> _$ (vlax-dump-object theobj T) ; IAcadLWPolyline: AutoCAD Lightweight Polyline Interface ; Property values: ; Application (RO) = #<VLA-OBJECT IAcadApplication 00ac8928> ; Area (RO) = 16178.7 ; Closed = 0 ; Color = 256 ; ConstantWidth = 0.0 ; Coordinate = ...Indexed contents not shown... ; Coordinates = (540.98 557.623 640.815 449.587 453.624 403.879 ... ) ; Document (RO) = #<VLA-OBJECT IAcadDocument 00ec89b4> ; Elevation = 0.0 ; Handle (RO) = "957" ; HasExtensionDictionary (RO) = 0 ; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 01ea1ec4> ; Layer = "7" ; Linetype = "BYLAYER" ; LinetypeGeneration = 0 ; LinetypeScale = 1.0 ; Lineweight = -1 ; Normal = (0.0 0.0 1.0) ; ObjectID (RO) = 21902840 ; ObjectName (RO) = "AcDbPolyline" ; OwnerID (RO) = 21901504 ; PlotStyleName = "ByLayer" ; Thickness = 0.0 ; Visible = -1 ; Methods supported: ; AddVertex (2) ; ArrayPolar (3) ; ArrayRectangular (6) ; Copy () ; Delete () ; Explode () ; GetBoundingBox (2) ; GetBulge (1) ; GetExtensionDictionary () ; GetWidth (3) ; GetXData (3) ; Highlight (1) ; IntersectWith (2) ; Mirror (2) ; Mirror3D (3) ; Move (2) ; Offset (1) ; Rotate (2) ; Rotate3D (3) ; ScaleEntity (2) ; SetBulge (2) ; SetWidth (3) ; SetXData (2) ; TransformBy (1) ; Update () T
This is a listing of all the Properties and Methods belonging to our polyline object. Let's close the polyline:
_$ (vla-put-closed theobj :vlax-true)
nil

Now let's change the width of all the segments :
_$ (vla-put-ConstantWidth theobj 2.0)
nil

Let's "bulge" the third segment :
_$ (vla-setbulge theobj 2 0.5)
nil

Let's change the starting and ending width of the fourth segment :
_$ (vla-setwidth theobj 3 10.0 0.0)
nil

Let's get the area :
_$ (vla-get-area theobj)
14505.9
Now, we'll make it invisible :
_$ (vla-put-visible theobj :vlax-false)
nil
See it's gone. Let's bring it back :
_$ (vla-put-visible theobj :vlax-true)
nil
Now we'll explode it :
_$ (vla-explode theobj)
#<variant 8201 ...>
And delete the original :
_$ (vla-delete theobj)
nil
We are left with an exploded copy of our polyline :

A practical example
Right, let's have a look at extracting some information from a polyline. This program will extract the X and Y coordinates from any polyline.
(prompt "\nType \"VL-POLY\" to run........")
(defun c:vl-poly ( / theobj thelist n xval yval fname fn)
;load the visual lisp extensions
(vl-load-com)
;get the entity and entity name
(setq theobj (car (entsel "\nSelect a Polyline: ")))
;convert to vl object
(setq theobj (vlax-ename->vla-object theobj))
;check if it's a polyline
(if (= (vlax-get-property theobj 'ObjectName) "AcDbPolyline")
;if it is, do the following
(progn
;retrieve the coordinates
(setq thelist (vlax-get-property theobj 'coordinates))
;convert to a list
(setq thelist (vlax-safearray->list (variant-value thelist)))
;zero the counter
(setq n 0)
;create a text file
(setq fname "coord.txt")
;open it to write
(setq fn (open fname "w"))
;write the header
(write-line "PolyLine X and Y Coordinates" fn)
;underline the header
(write-line "*****************************************" fn)
;start the loop
(repeat (/ (length thelist) 2)
;get the x coordinate
(setq xval (rtos (nth n thelist)))
;increase the counter
(setq n (1+ n))
;get the y coordinate
(setq yval (rtos (nth n thelist)))
;write the x coordinate to the file
(write-line (strcat "X-Value : " xval) fn)
;write the x coordinate to the file
(write-line (strcat "Y-Value : " yval) fn)
;add a seperator
(write-line "-----------------------------" fn)
;increase the counter
(setq n (1+ n))
);repeat
;close the file
(close fn)
);progn
;it's not a polyline, inform the user
(alert "This is not a Polyline! - Please try again.")
);if
(princ)
);defun
;------------------------
;clean loading
(princ)
;---------------------------
;End of VL-POLY.LSP
;---------------------------
Save this as "VL-Poly.lsp" and then load and run it. Select any polyline.
The X and Y coordinates of each vertex will be output and written to a file named "Coord.txt" It should look something like this :
PolyLine X and Y Coordinates ***************************************** X-Value : 478.6 Y-Value : 622 ----------------------------- X-Value : 815.5 Y-Value : 349.9 ----------------------------- X-Value : 636.7 Y-Value : 291.7 ----------------------------- X-Value : 586.7 Y-Value : 437.1 ----------------------------- X-Value : 516 Y-Value : 310.4 ----------------------------- X-Value : 349.6 Y-Value : 304.2 -----------------------------
In Part 2 we'll have a look at creating polylines and adding one or two "bulges".
