Drawing by the Rules (Harry's Code Class Newsletter)27 Nov, 2007
Drawing by the Rules
This month, Harry provides a lesson in parametric programming in VBA that applies to Visual LISP as well.
Several decades ago, the term parametric programming was applied as a description for programs that created drawings by following rules given a set of parameters. This type of programming can have the greatest impact on your productivity. But it can also be the most costly to create. This month we will be taking a look at the basic concepts behind parametric programming for AutoCAD using a simple example written in VBA (Visual Basic for Applications). Download the parametric programming source code (ZIP file) to accompany the text in this article. All the files I reference here are included in the download.
The simplest form of parametric programming is a block. The parameters are the scale factors and rotation. The programming is a graphic description of the object. The mini-application example we will be creating is a bit more complex than a block. The application involves a fictional power source that is rectangular in nature (like photovoltaic cells) to be filled into a rectangular area. The twist is that we want the program to make the selection of which power cells to use based on a minimum power requirement at the cheapest price, but still fill up a rectangular area as best we can. Simply put, we are asking for a small bit of artificial intelligence based on a set of data with some rules.
The input into this function is pretty straightforward. The operator is to supply a rectangular area and a minimum power requirement. The program is expected to know about the available power cells and will select the power cells that can deliver enough power to meet the minimum requirement at the lowest cost.
To program such an application, the best place to start is with a text editor of your choice. I tend to use a programming text editor to outline a description of the program as comments. The program description includes basic information about how the program will work and which data it will be using. For this example, I happened to start by using VBA's independent developer environment (VBAIDE) inside AutoCAD to write a description of the program. You could accomplish the same thing using Visual LISP's independent developer environment (VLIDE) if we were writing the routine in Visual LISP. (For more about the distinction between VBA and Visual LISP and their associated IDEs, check out the Harry's Code Class archives.)
Program descriptions are divided into two parts. The first part is the data. The second part is the procedure or process. In this simple example, the power units known to the program have four basic parameters: x-size, y-size, power output, and cost. The procedure is a bit more complex to describe, but essentially we will accept a corner point and minimum power value. The program will then search the known panels to find one suitable and at the lowest total cost. Last, the program will render the panels in the rectangular area.
Because I selected VBA as the tool, the first question is where to house the panel information set. This program involves the manipulation of data; hence, we need to get that tied down. The program will know about a variety of panel sizes, each with unique power and cost variables. This type of data lends itself to a custom object stored in what is known as a collection. In VBA, a custom object is a class module in your project. Class modules contain public and private variables along with functions and subroutines. Anything defined as public in a class can be seen and used by modules outside the class. The best part about classes in VBA is that they can be grouped together to form collections. A collection is an array or list of objects such as a custom class. Collections are used frequently in AutoCAD VBA for things such as tables and block definitions. In the case of a table, all the elements in a table are the same basic type, such as layers or linetypes. For block definitions, everything is an AutoCAD database object, such as line and arc entities. When you program in VBA, you will use collections, and this example shows how to create your own custom collection of custom objects.
The parametric example program, POWERPANELS.DVB, contained in the ZIP file download, has two modules. These modules are also saved as text files with a CLS (class) file extension. One module is a class named Panel. This is where you will find the basic parameters of a panel defined as public variables along with an initialize routine to establish default values. The other module, POWERPANELS.CLS (or thisDrawing in the DVB), is where the main program can be found.
The main program, located in the POWERPANELS.CLS code, consists of a series of subroutine calls. This basic program structure will work for most parametric programs. There is an input section, a processing section, and an output section. All you need to do is supply the details!
In most parametric programs, the input comes from two sources. One is the user. The user will provide some input into the system that may be used to search the other input source, a set of data or a database. The data set consists of lists or collections of data containing the remaining parameters needed to perform the process and generate the output.
Our parametric example has two user input items. We want to know about a rectangular area and the minimum power requirements. Basic AutoCAD style input in VBA is accomplished with the methods of Utility object inside the AutoCAD drawing object. When programming in VBA, the object "thisDrawing" is the current drawing. You can access the utility object, then drill down further into the methods to provide Command line input for your programs.
vp1 = ThisDrawing.Utility.GetCorner(vp0, "Rectangle size: ") PowerReq = ThisDrawing.Utility.GetReal("Minimum power required: ")
The two lines of code above demonstrate the Utility object methods in action. The first line requests a corner input. The corner input utility method uses a base point supplied as a variant pointing to an array of numbers (a point) along with a prompt string. To set up the variant pointing to an array, first define the array (three numbers), then set them equal. In the source code, look for the subroutine named getInput to see where the variant pointing to the array is established.
So, what is returned from these input functions, assuming the operator does as asked? In the case of the GetReal method, the answer is a double. It is the point data that often will trip up new programmers to VBA. When using VBA, data points are generally sent to and from AutoCAD using variants pointing to arrays. Thus, the returning value "vp1" from the corner input method is actually a variant. In VBA, variants are powerful variable-variables. In other words, they can be anything, and during run time VBA does its best to work with them as such. As is true with LISP, it is up to the programmer to be aware of what is going on! When you have a variant pointing to an array, you can treat it like an array to get the data out. You can see this in action in the subroutine findBestOne, where the VP1 (variant pointer one) is accessed like an array using an index as in rX = vp1(0) to get the x value of the point.
Variant pointers to arrays are not always used in the VBA methods when talking directly to the AutoCAD objects, as seen in the subroutine named drawPanel. This subroutine uses the AddLightWeightPolyline method to draw the panel outline, given an array of numbers representing the x,y sequence. The array must be dimensioned to hold just the points needed. Because lightweight polylines use 2D points, the array should be dimensioned as twice the number of points. The first element in the array will contain the first x ordinate value, the second will hold the first y ordinate, the third the second x ordinate value, and so forth for all the x,y pairs.
For those of you who prefer a Visual LISP solution, one is included the ZIP file download. This Visual LISP solution follows the exact structure of the VBA example and can be used to learn more about how these two tools compare. I opted to write this month's example in VBA; however, Visual LISP would have worked just as well as an original authoring tool. In this case, the selection of programming language is entirely up to you. The key to success in either case: Keep on programmin'.
Following are some other examples and references related to parametric programming:
Example LISP Routines for Parametric Programming
A few parametric LISP routines are included in Cadalyst's Get the Code! database. Go to the Get the Code! Advanced Search and enter "parametric" in the Description field.
Cadalyst article by Bill Kramer provides an overview of parametric programming for AutoCAD. Read more >>
Spreadsheet-Driven Parametric Bookcase
A tutorial from the Instructables Web site. Read more >>