 Sequential Numbering Systems (AutoLISP Solutions AutoCAD Tutorial)

28 Feb, 2007

Add circles and sequence numbers to semiconductor chip schematics.

Rohaya Shaffini of Stats ChipPAC Ltd. requested a routine to add circles and sequence numbers to a schematic of a rectangular integrated circuit chip drawing (see a typical schematic below). Rohaya requested that the circles be offset by an amount selected by the user. Plus, he wanted to indicate the start location for numbering, the circle radius and a choice of clockwise or counterclockwise numbering direction. A typical schematic diagram.

The solution is TIP-NUM.LSP that lets you select all of the tips surrounding the main rectangle by using a window. You select the upper-left point first and then choose the lower-right point. The prompt for the upper-left point of the selection window. The selection window lower-right point.

The program then asks for the start point for the number sequence, the number direction (clockwise or counterclockwise), the offset distance from the tip to the circle and the circle radius. Additional user input prompts.

Get the Code

How to Use the TIP-NUM.LSP Code
To start the program, enter TN and the prompts appear. The tips should have three line entities (not polylines), and you should select them by indicating the upper-left and lower-right locations. The tips should be on a layer that is reserved for them alone. The start point for numbering expects that you select an endpoint of a tip, and this will be one of the corner tips, as numbering should start at any of the four corners. The number direction prompt as displayed as Number direction: <Cw>/ccW:, where the default is clockwise. For counterclockwise numbering, only enter the W point. The other prompts are for offset distance and circle radius. The program then automatically draws the circles and numbers on the current layer of the drawing with no further input (see below for a typical result). The schematic diagram with circles and sequence numbers shown.

Programming Notes
The program starts with my usual error handler and system-variable management functions. If an error occurs during the program for any reason, such as a cancellation by the user, any system variables that have been changed are reset to their previous values by calling the Resetting function.

Program major functions
TIP-NUM begins with some standard code so that AutoCAD recognizes Visual LISP functions and sets global variables for the current drawing, model space and utility functions. TIP-NUM calls the function GET-INPUT, GET-CIRCLE-DATA and DO-CIRCLE-AND-NUMBER, as shown here:

(defun tip-num ()
(setq *thisdrawing* (vla-get-activedocument
) ;_ end of vla-get-activedocument
*modelspace* (vla-get-ModelSpace *thisdrawing*)
*utility* (vla-get-Utility *thisdrawing*)
) ;_ end of setq
(setq input-data (get-input))
(setq circle-data (get-circle-data input-data))
(do-circle-and-number circle-data)
) ;_ end of tip-num

GET-INPUT, as its name suggests, is the function that asks for user input. The utility methods in Visual LISP are used throughout. As an example, a point is input as an object using the GetCorner method as follows:

(setq	p2 (vla-GetCorner
*utility*
p1
(vlax-make-variant "\nLower right point: ")
) ;_ end of vla-getcorner
) ;_ end of setq
(vla-select ssobj acSelectionSetCrossing p1 p2)

Here, the points p1 and p2 are objects rather than entities and are used with the subsequent select method as shown in the last line of this code fragment.

At the end of GET-INPUT, a start location is created as a global variable *startloc* to indicate whether you selected the start point at the upper-left, upper-right, lower-left or lower-right of the schematic. Later in the program, this determines the sort order of the tip line objects. To keep track of the numbering, I decided to collect the horizontal and vertical parts of the tip lines into left, right, top and bottom groups.

The GET-CIRCLE-DATA function performs this grouping after filtering the selected objects by using the layer of the tip that was selected at the start-point prompt. The code for this is:

(vla-SelectAtPoint ssobj2 startpt)
(setq lyr (vla-get-Layer (vla-item ssobj2 0)))
(repeat (vla-get-count ssobj)
(setq item (vla-item ssobj (setq j (1+ j))))
(if (= (vla-get-Layer item) lyr)
(setq line-objlist (append line-objlist (list item)))
) ;_ end of if
) ;_ end of repeat

The horizontal and vertical lines are then grouped into a list, and the rest of the selected lines (the sloping lines) are collected into another list. The lists are sorted via a call to the SORT-LISTS function. There are four lists of lines to sort representing the top, bottom, left and right horizontal and vertical lines. Each of them is sorted depending on whether you select a clockwise or counterclockwise direction. For each of the clockwise or counterclockwise sets of lines, the order of appearance in a list of all lines changes. The conditional function to do this for the clockwise option is as follows:

(cond
((= *startloc* "UL")
(setq plst (append cwtlist cwrlist cwblist cwllist))
)
((= *startloc* "UR")
(setq plst (append cwrlist cwblist cwllist cwtlist))
)
((= *startloc* "LR")
(setq plst (append cwblist cwllist cwtlist cwrlist))
)
((= *startloc* "LL")
(setq plst (append cwllist cwtlist cwrlist cwblist))
)
) ;_ end of cond

The data is now in the form of a list of points representing each end of the sequence of horizontal and vertical lines. That list of points is subsequently compared with the x and y coordinates of the remainder of the lines to collect them into a larger list of trios of lines for each tip. The tips were then categorized into four types representing the top, left, bottom and right rows of tips, and the circles and text were added for each type as shown in the following code fragment for the type 4 lines:

(if (and (= xmid1 xmid2) (or (> xlin11 xmid1) (> xlin12 xmid1)))
;; type 4
(progn
(setq p1 (polar p3 0 *offset*)
p2 (polar p5 0 *offset*)
) ;_ end of setq
(if (= (car p4) (car p3))
(setq p4 p31)
) ;_ end of if
(if (= (car p6) (car p5))
(setq p6 p51)
) ;_ end of if
(setq p8 (inters p1 p2 p3 p4 nil))
(setq p7 (inters p1 p2 p5 p6 nil))
(setq cen (polar p7 (angle p5 p3) (/ (distance p7 p8) 2)))
(setq ipt (polar cen (angle p5 p6) (* *rad* 3))
ipt (polar ipt (* pi 1.5) *rad*)
) ;_ end of setq
(do-text ipt)
) ;_ end of progn
) ;_ end of if

The text insertion point is set in the above code and differs depending on the orientation of the tip lines. In the above, the text insertion point IPT was at a sloping distance of 3X the circle radius and shifted downward by the value of the circle radius as shown, before the call to DO-TEXT is made.

The text height is set at 1.5X the circle radius and the text string was added as follows from the DO-TEXT function.

(defun do-text (inspt)