Fast Polyline Widths (pwid.lsp)

Ever had to change the width of a number of polylines and been frustrated by the PEDIT command's insistence on changing them one at a time? If you only have three or four polylines to change, the frustration is minimal but increase the number to anything more than half a dozen or so and an AutoLISP program that lets you change them in one hit can be a godsend.

PWID.LSP may be that godsend. It will ask the user to select some polylines, prompt for a new width for all the polylines, or allow entering a halfwidth or even supplying a width (or halfwidth) to individual polylines, offering the previous supplied width as a default.

The Listing

After a few lines of comment describing the program, the DEFUN statement gives the program it's name, PWID, and localizes the variable names used by the program. Localizing variable names prevents clashes with variables of the same name in other programs and ensures that their value is always nil when the program is started. Localizing is usually done after the program has been completed and debugged.

The next step is to save the value of the CMDECHO setvar for restoration later as the program will be changing it. Variable CTR2, which will be used as a counter, is initialized to zero at this point. The CMDECHO setvar is then set to zero to prevent the command sequences from being echoed to the screen. CMDECHO may already have a value of zero but to perform a check and change it conditional to its value will add unnecessary code and slow the program down.

Since the SSGET function can only display a generic "Select objects:"" prompt, it is preceded with a "Select polyline:" prompt to give users a better idea of what is expected of them. The SSGET function has only a filter list as an argument, which enables users to select objects by any method they prefer but only polylines will be passed on to selection set SS2.

Most of the remainder of the program is then nested in an IF function which tests for a value in SS2. The PROGN function on the line following the IF groups into one expression all the expressions nested in it. This is required because the IF function expects to be followed by a test-expression, a then-expression and, optionally, an else-expression. The then-expression will be processed if the test-expression returns T (is true) and the else-expression will be processed if the test-expression returns nil (is false). If multiple then-expressions and/or else-expressions need to be run, they must firstly be grouped by a simple PROGN function.

The first function in the PROGN is INITGET which has two arguments: an integer '5', which prevents either [ENTER] or a negative number from being valid responses for the following GETDIST function and a string containing two keywords, "Halfwidth" and "Individual". Capitalizing the first character of each keyword enables the user to key in only that one character for a valid entry, or type in more characters, up to the full word. Typing in a positive number, or picking two points, are also valid responses. The response is then stored in variable WID2.

If the response was "Halfwidth", the IF function immediately following would process it's then-expression which is also grouped in a PROGN. Please note the case of the characters of the keyword in the IF test. It must match the case of the keyword in the INITGET function.

The INITGET's '5' will allow the following GETDIST to accept only a positive number (or two points on the screen). This value is then passed back through the mathematical 'multiply' operator, being multiplied by two to provide the width which is then stored in variable WID2, overwriting the previous value. By nesting functions in this way, we can avoid creating and setting variables that will only be needed for a few microseconds. The IF function then ends.

A new IF function is then started, its then-expression being a REPEAT function that is evaluated if the value in WID2 is not the string Individually". It will run the code nested within it by the number of objects in the selection set stored in SS2. This code extracts the name of a polyline from the selection set, storing it in variable OBJN2, increments counter CTR2 by one and calls the PEDIT command which changes the width of the polyline to the value in WID2.

Note that "PEDIT" is prefixed with a dot and underscore. This ensures that the command will still work if its been undefined or a non-English language version of AutoCAD is being used. CTR2 controls which object name is extracted by the value stored in it. Initially CTR2 is zero, which extracts the name of the first polyline. Incrementing it's value to one makes SSNAME extract the name of the second polyline, if there was one.

This REPEAT is closed and a new REPEAT started, which is the else-expression of this particular IF. This is run if the value in WID2 is the string "Individually". REPEAT also repeats for each object in the selection set but runs differently.

After extracting the object name, storing it in variable OBJN2 and incrementing CTR2, the polyline is highlighted on screen. An IF will check whether the value in WID2 is a REAL (a real number) and if so, will run the then-expression. This will initialise the "Halfwidth" keyword for the next GETDIST function, which in turn will prompt for a width or the Halfwidth keyword with the last entered width appended, acting as a default.

This INITGET has a '4' integer argument, allowing [RETURN] which would represent accepting the default but not allowing a negative number. The then-expression of this IF will never run for the first 'Individual' polyline as WID2 will not contain a REAL until a polyline has been edited. The else-expression will run only for the first polyline, initializing the keyword for the GETDIST which will prompt for a width, or the Halfwidth keyword, and not have a default value. This IF is then closed.

The IF function following will have its then-expression processed if the response was the "Halfwidth" keyword to the preceding prompt. This is a duplicate of an earlier IF, requesting a distance and doubling it. After closing this IF, another one is started which, if there is no value in WID2 (the default value was accepted), will set WID2 to the value in WID3. Otherwise it will set the value of WID3 to the value in WID2, storing the width value for use as the default next time around.

The then -expression of this IF can only run after a polyline has been edited and WID3 would have a value at this point. The else-expression will run for the first polyline and will also run for subsequent polylines if the default width was not accepted. WID3 is used to store the default width for subsequent polylines as WID2's value can change. The PEDIT command is then called which will simply change the width of the polyline.

The REPEAT function is then closed, as is the PROGN for the first IF, which was started near the beginning of the program. The else-expression of this IF is then run, which simply informs the user that no polylines were selected. The IF is then closed.

The original value of CMDECHO is then restored and the PRINC function prevents the value of CMDECHO being echoed to screen as the program exits.
 

©1996-2001 ZOTO Technologies