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".