AutoLISP Solutions: Plant Lists in AutoCAD
6 Jul, 2006 By: Tony HotchkissUse this AutoLISP solution to extract plant lists and quantities for contractors.
Ms. Kirsten Jones of Vancouver, BC, Canada, requested a routine that calculates plant quantities from landscape architecture drawings to produce a plant list for contractors. Kirsten uses a block KEY-PLANT that has two attributes, PLANTTYPE and QUANTITY. The Eattext command doesn't add up the total quantities for each species of plant named in the PLANTTYPE attribute, so it's cumbersome to get the totals after extracting the attribute values.
The AutoLISP solution is PLANT-LIST.LSP, which creates a text file with total quantities separated by plant species.
Figure 1. A typical landscape drawing that contains a variety of plants. |
I wrote the code in AutoCAD 2006 and have tested it in both 2006 and 2007, although it also should run in earlier versions such as 2004 and 2005. The program's execution speed depends on the complexity of the drawing. The example drawing that Kirsten Jones sent me took about five seconds to extract the results.
Get the Code
Download the PLANT-LIST.LSP file from Cadalyst's CAD Tips site. Save the file in AutoCAD's Support directory. Use the Appload facility by selecting Tools / Load Application, and then use the browser to select the file.
How to Use PLANT-LIST Code
To start the program, enter PL and the Results File dialog box displays. You can browse to save the results file in any folder, with any name you choose. The file type is TEXT as shown below.
Figure 2. The Results File dialog box. |
If you enter the name of a an existing file, a warning displays. You can overwrite the existing file.
The text file is automatically created with no further prompts, and you may open the file with any text editor such as Notepad. The file has headings for PLANT TYPE and QUANTITY.
Figure 3. The Results File shown in the Notepad editor. |
Programming Notes
The program was written in AutoCAD 2006, and I have tested it in both AutoCAD 2006 and AutoCAD2007.
The program starts with my error handler and system variable management functions. The main program function is PLANT-LIST, and it opens the results file in write mode before collecting a list of the objects that have KEY-PLANT as a block name and also has the tags PLANTTYPE and QUANTITY. The attribute tags and their associated values are obtained using the following:
(setq tag (vla-get-TagString attrefobj))
(setq val (vla-get-TextString attrefobj))
A list of pairs of values for Plant type and Quantity is collected in the variable TypeQuantityList for each occurrence of a KEY-PLANT block. That list is then passed to the function DO-TOTALS to produce another list, KeyPlantList, of plant-type and total quantity pairs.
Finally, the KeyPlantList list is written to the open external text file, and the file is then closed. The last lines of code of PLANT-LIST that accomplish this task are:
(setq KeyPlantList (do-totals TypeQuantityList))
(print-out KeyPlantList f1)
(setq f1 (close f1))
The function DO-TOTALS sorts the TypeQuantityList using the VL-SORT visual LISP function:
(setq SortedList
(vl-sort TypeQuantityList
(function (lambda (e1 e2)
(< (car e1) (car e2))
) ;_ end of lambda
) ;_ end of function
) ;_ end of vl-sort
) ;_ end of setq
This sort is in the order of the first item of each pair of values (the plant-type). The routine uses a repeat loop to sum the totals for each plant type. The method here is to compare the plant type of the two consecutive elements of the sorted list. If they are the same, the quantity numbers are added together, and the next element in the sorted list is then compared with the current value of plant-type and so on. The total value is only added to the new plant list if the plant type differs from that of the previous element. The logic to do this step is shown here:
(if (= ptype2 ptype1)
(progn
(setq number (+ number1 number2))
(setq number1 number)
(setq check 0)
) ;_ end of progn
(progn
(setq number number1)
(setq ptype ptype1)
(setq keylist (list (cons ptype (list number))))
(setq element1 element2
ptype1 (car element1)
number1 (atoi (cadr element1))
) ;_ end of setq
(setq keyplist (append keyplist keylist))
(setq check nil)
) ;_ end of progn
) ;_ end of if
The PRINT-OUT function is simple and is shown here:
(defun print-out (KList f1 / str)
(repeat (length KList)
(setq
str (strcat " "
(caar KList)
" "
(itoa (cadar KList))
) ;_ end of strcat
) ;_ end of setq
(write-line str f1)
(setq KList (cdr KList))
) ;_ end of repeat
) ;_ end of print-out
The spaces in the string to be printed match the format of the heading that was made at the start of the PLANT-LIST function, and figure 3 shows the result as viewed in the Notepad text editor.
As always, I look forward to receiving your comments and requests for AutoLISP Solutions. Contact me using the links below.
For Mold Designers! Cadalyst has an area of our site focused on technologies and resources specific to the mold design professional. Sponsored by Siemens NX. Visit the Equipped Mold Designer here!
For Architects! Cadalyst has an area of our site focused on technologies and resources specific to the building design professional. Sponsored by HP. Visit the Equipped Architect here!