Filling Up (AutoLISP Solutions AutoCAD Tutorial)1 Jul, 2007 By: Tony Hotchkiss
Advanced array fills a variety of area shapes with user-selected blocks.
Bilal Issa e-mailed a request for a routine to fill an arbitrary area such as a circle, polygon, rectangle, triangle or closed polyline with an array of symbols or blocks. The routine should offer a choice of row and column spacing and should present a list of available blocks from which to choose in the current drawing. The blocks should appear as individual objects so they can be selected and adjusted later. Some typical areas to fill are shown below.
A variety of area shapes.
The AutoLISP Solution is ADARRAY.LSP, a routine that allows users to select a block from a pop-up list, choose the row and column spacing and pick a point inside the area to be filled.
Get the Code
Download the ADARRAY.LSP and ADARRAY.DCL files from Cadalyst's CAD Tips site and save the files in AutoCAD's Support directory. Use the Appload facility by selecting Tools/Load Application and then select ADARRAY.LSP as shown below.
Loading the ADARRAY.LSP program into the current drawing.
How to Use the ADARRAY.LSP Code
To start the program, enter AD, and you will see the dialog box shown below.
The Adarray dialog box.
You may select a block from the list of names in the pop-up list as well as the row and column distances. The Pick Point button allows you to select anywhere inside a predefined area in the drawing. Any enclosed space is acceptable, as shown below.
Picking a point inside an area.
The dialog box returns to the screen so that you can select any item in any order. When the dialog box selections have been made, click OK to see the area filled with an array of the selected block as shown below.
A typical area filled with an array of blocks.
The results for a variety of shapes are shown below. The resulting array depends on the shape of the area selected. The rectangular area produces a rectangular array of blocks, and the other shapes produce a series of equally spaced blocks adjusted to the left side of the area shape.
Results for a variety of area shapes.
The program essentially creates a pattern of horizontal lines, along each of which the AutoCAD Measure command places a block at equal intervals. The function of the program that does this task is Do-Array, shown below.
(defun do-array ()
(setq lyr "arr-hatch")
(vl-cmdf "Layer" "M" lyr "C" "green" "" "")
(vl-cmdf "-Hatch" *point0* "P" "U" "0.0" *rowdist* "N" "")
(vl-cmdf "Explode" (entlast))
(setq ss (ssget "X"
(list '(0 . "LINE")
(cons 8 lyr)
) ;_ end of list
) ;_ end of ssget
num (sslength ss)
) ;_ end of setq
(setq en (ssname ss (setq i (1+ i))))
(vl-cmdf "Measure" en "B" *bname* "Y" *coldist*)
) ;_ end of repeat
) ;_ end of do-array
The AutoCAD Hatch command is put to good use to define the set of horizontal lines at a spacing provided by the ROWDIST variable, denoting the distance between rows. The hatch pattern is created on a layer ARR-HATCH to contain the individual lines created by exploding the hatched area. These lines are collected in a selection set, which is used inside a repeat loop. The Measure command is used to insert the chosen block on each line at equal intervals given by the COLDIST (column distance) variable. The lines are then deleted one by one after the blocks have been placed so the end result is an array of individual blocks.
The most significant part of the program is where it requests user data via the dialog box. It's interesting to note that DCL (dialog control language) and the Help documentation for DCL haven't changed since Release 12 of AutoCAD in 1992. I keep wondering whether AutoLISP will ever become truly visual in the same way as Visual Basic, with interactive forms that incorporate drag-and-drop components and their corresponding program templates. What has changed in the meantime is the ability to preview the dialog boxes in Visual LISP, so the layout is somewhat easier to develop.
The dialog box driver function, Adarray, controls the individual tiles within the box. Of interest here is the introduction of the While loop to control hiding the dialog box so users can select a picked point from the graphic screen. The loop is shown below, and its structure echoes that of the available AutoCAD customization documents.
(setq doit 4)
(setq ad_id (load_dialog "adarray.dcl"))
(while (>= doit 2)
(if (not (new_dialog "adarray" ad_id))
) ;_ end of if
(action_tile "bname" "(setq bnameindex (atoi $value))")
(action_tile "row" "(setq *rowdist* (atof $value))")
(action_tile "col" "(setq *coldist* (atof $value))")
(action_tile "pick" "(done_dialog 3)")
"(get-adarray-data) (done_dialog 1)"
) ;_ end of action_tile
(setq doit (start_dialog))
((= doit 1)
((= doit 3)
(setq *point0* (getpoint "\nPick a point: "))
) ;_ end of cond
) ;_ end of while
The essential feature is that the (start_dialog) function returns the argument passed to the (done_dialog) function. In the above, that argument is captured by the variable DoIt, so that a decision can be made as to when the dialog box can be hidden to let a point be picked from the screen.
As always, I look forward to receiving your comments and requests for "AutoLISP Solutions." Contact me using the links below.