In three-plus years of blogging as “Controlling the Machine” on the Autodesk MSD site, we posted nearly a hundred AutoCAD Electrical-related utilities. Now we’ve moved. This marks our first posting in our new home, “AutoCAD Electrical Etcetera”.
Lots to do. Let’s get moving…
How to change an existing utility from Single operation to Drawing-wide
In this example we’ll take an existing single-pick, single-operation utility and modify it to work automatically drawing wide. No user prompt to pick what to operate on… just apply the example utility to the whole drawing… process the whole drawing without any prompts.
The example utility generates specially-formatted wire number. It was posted about three years ago. Here is the original posting and here is the original version of the “single operation” version the utility.
Only a small part of the original version of the program changes, the bulk of it remains untouched.
This old utility prompts you to pick a single wire segment…
… and then it then looks for component connections at the ends of the wire network (i.e. one or more interconnected wire line segments). If only two components found on the wire network, it builds up a special “fixed” wire number and pops it in. This special wire number is a concatenation of the tag-ID and wire connection pin number of each of the two interconnected components.
The problem is that the command is currently set up for one pick at a time. Pick wire – wire number goes in, pick wire – wire number goes in, … You’d like to just launch the tool and have it process all valid 2-component wire networks on the active drawing.
Starting with the Old utility – single pick operation
Open up the milnum_plc.lsp AutoLISP file (download from the link above) with an ascii text editor or with AutoCAD Electrical’s built-in Visual Lisp editor. Go down about 40 lines. Here is the key part of the program that controls the wire pick operation:
; -- main routine starts here -- (while (setq x (entsel "\nSelect wire for special MIL wire number format:")) (setq en (car x)) (setq ed (entget en)) (if (= (cdr (assoc 0 ed)) "LINE") (progn ; okay to continue (if (setq netlst (c:wd_get_wire_netlst en 1)) (progn
The “entsel” function above prompts the user for a single entity pick. The pick is evaluated and, if it is a LINE entity, it is processed to find any/all other wires and components that tie in to it.
The “while” function forms the beginning of a “loop” so that the command repeats after each individual wire segment pick until the user escapes out of the command or picks in blank space.
Creating a modified version for drawing-wide operation
Let’s modify the above so that it will process the whole drawing without user prompt.
We need to do several adjustments to the old utility’s code.
1. The first is to get rid of the “while” loop with its “entsel” call. Replace it with a generic selection set call ssget across the whole drawing, “_X” . Find all LINE entities on the drawing and process them one at a time by processing the selection set in a while loop.
; -- main routine starts here -- (setq ss (ssget"_X" '((0 . "LINE")))) ; automatically process all wires on active dwg (if (/= ss nil) (progn (setq slen (sslength ss)) ; number of LINE entities selected (setq lines_processed_entlist nil) ; used to track what has been processed (setq ix 0) ; used to index through the selection set (while (< ix slen) ; Get next LINE entity candidate (setq en (ssname ss ix)) (setq ix (1+ ix)) ; increment counter for next time ; Check to see if this LINE entity is already in the "processed" list (if (not (member en lines_processed_entlist)) (progn ; not yet processed, okay to continue (setq ed (entget en)) (if (setq netlst (c:wd_get_wire_netlst en 0)) (progn
2. The second issue we need to deal with is this… when we process ALL line segments on the active drawing, we may end up processing the same segment two or more times. This is because processing one LINE segment may include others (via the (c:wd_get_wire_netlst en…) call) that tie into it as a wire network. Then, later on, we process one of these other network wires and end up processing the first one again. So, we need to keep track of what wire LINE segments have been processed along the way and skip processing any repeats. Our modified utility will keep a list of processed LINE entity name is a temporary variable called lines_processed_entlist .
This is done with the lines shown in red here:
(while (< ix slen) ; Get next LINE entity candidate (setq en (ssname ss ix)) (setq ix (1+ ix)) ; increment counter for next time ; Check to see if this LINE entity is already in the "processed" list (if (not (member en lines_processed_entlist)) (progn ; not yet processed, okay to continue (setq ed (entget en)) (if (setq netlst (c:wd_get_wire_netlst en 0)) ; 2nd arg 0=read through ; terminals that do not ; change the wire number (progn ; Add list of this wire network's wire entities to the running ; list of "processed" wire line segments... so that won't repeat ; later. ; netlst = (list wlst en1st xmin ymax s_sig d_sig trmlst xtermlst ; cmplst cmpconlst fan_inout_lst nil) (setq lines_processed_entlist (append (car netlst) lines_processed_entlist))
That’s about it. You can download this modified version of the utility here (pick on “Click here to start download…” in middle of left-hand column. Should only take a second or two.) You should end up with a file named milnum_alldwg.lsp.
…Then, to run it, APPLOAD the file and type milnum_alldwg [Enter] at the AutoCAD command prompt.