In AutoCAD 2009, Autodesk introduced the concept of command versioning. This functionality was added was to help ensure reliable playback from Action Macros by providing a method for the Action Recorder to initialize a specific version of a command on playback. When I refer to the version of a command I’m usually referring to the difference between how a command responds when invoked manually, e.g., typing, menu pick, etc., versus how the same command responds when invoked from automation like AutoLISP or scripts. For example: typing the COLOR command launches the “Select Color” dialog, whereas running (command “.color”) automatically runs the command-line version of the COLOR command. In that example, the automation method is considered the oldest version – version 1 – because it preceded the addition of a Color dialog. When entered manually, it is considered the latest version of the COLOR command, or version 2. The ability for you to request a specific version of a command is available through a new AutoLISP function and, to a more limited degree, through a new menu control code.
(initcommandversion)
The (initcommandversion) function can be used to initialize a version to be used by the next command that is run. It is similar to the (initdia) function in that it only applies to the command that is run immediately after calling (initcommandversion). Running (initcommandversion #) initializes a specific version of the command that follows (1 or 2). Running (initcommandversion -1) initializes the default version of the command (typically, the most recent version).
For example, running the COLOR command normally displays the Select Color dialog but the following will force the command-line version of the COLOR command even though it is being run manually:
Another example is the EXPLODE command. When run manually, EXPLODE allows for multiple selections before exploding the selection set (version 2). When run from automation, EXPLODE runs immediately after a single pick (version 1). You can force EXPLODE to use one behavior or the other by initializing the command version right before running the command. To force EXPLODE to run after a single pick, you could do the following:
Menu Macros
Command versioning for menu macros was a slightly different approach. Single-token menu macros automatically run the latest version of a command, e.g., ^C^C^P_3dconfig, in a menu macro, launches the “Adaptive Degradation and Performance Tuning” dialog. On the other hand, multiple-token menu macros automatically run a command as though it was driven by automation. For example: ^C^C^P_3dconfig ^P runs the command-line version of the same command because of the ^P at the end (this makes it a multiple-token macro). Preceding a command with the new ^R control code will force the command to run the latest version instead. For example: ^C^C^P^R_3dconfig ^P will cause the 3DCONFIG command to launch the dialog instead of running at the command line.
What commands support command versioning?
To date, there is only a small subset of AutoCAD commands that have been updated to support versioning:
-ARCHIVE, -COLOR, -ETRANSMIT, -GROUP, -IMAGE, -INSERT, -LAYER, -STYLE, -TABLE, -VIEW, 3DCONFIG, 3DMOVE, 3DROTATE, ABOUT, ARCHIVE, ARRAY, ATTDEF, ATTEDIT, ATTEXT, BCLOSE, BEDIT, BHATCH, BLOCK, BOUNDARY, BOX, BPARAMETER, BPOLY, BSAVEAS, BVSTATE, BWBLOCKAS, CHAMFER, CLASSICIMAGE, CLASSICXREF, COLOR, CONVERT, CONVERTCTB, CONVERTPSTYLES, COPY, COPYTOLAYER, CUILOAD, CUIUNLOAD, DDEDIT, DIM, DIMEDIT, DIMSTYLE, DTEXT, DWGCONVERT, DXFIN, DXFOUT, ETRANSMIT, EXECUTETOOL, EXPLODE, EXTRUDE, FILLET, GROUP, HATCH, HATCHEDIT, HELIX, HIDE, IMAGE, IMAGEADJUST, INSERT, LAYDEL, LAYER, LAYISO, LAYMCH, LAYMRG, LAYOUT, LINETYPE, LOFT, LWEIGHT, MASSPROP, MENULOAD, MENUUNLOAD, MLEADER, MLEDIT, MOVE, MTEXT, MVIEW, OPENDWFMARKUP, OSNAP, PAN, PLOTSTAMP, PSETUPIN, PSOUT, PURGE, QUICKCALC, RENAME, RENDER, REVOLVE, SCALE, SHADE, SHADEMODE, SOLIDEDIT, STRETCH, STYLE, TABLE, TABLEDIT, TABLESTYLE, TOOLBAR, UNITS, VBALOAD, VBARUN, VIEWPORTS, VPLAYER, VPORTS, WBLOCK, WSSAVE, XBIND, XREF
These are the commands that needed to be updated in order to get reliable recording and playback with the Action Recorder. In many cases, it was only one or two aspects of a command that actually needed updating. For example, SOLIDEDIT only checks for a version when changing the color of an edge or face, and only to decide between displaying the Select Color dialog or requesting a color from the command line. For some commands, the version is checked to determine keyword options. For many commands, issuing (initcommandversion 1) before the command will simply cause it to run from the command line instead of using the dialog version, e.g., LAYER, BLOCK, INSERT. There is no official list of what will change in these commands if you explicitly initialize a version – you’ll just have to experiment.
How does (initcommandversion) affect commands that don't have versions?
Commands that don't use versioning are unaffected. The command itself has to have been updated to support retrieving an initialized version in the first place. Issuing (initcommandversion) prior to a command that doesn't check for versions is harmless and does nothing.
Why Should You Care About This?
As I said, command versioning was added specifically to support the Action Recorder and it should be mostly transparent in normal usage, however there are times when understanding it could be beneficial.
I recently received the following question from a customer, “Why does the fillet command end out of the fillet command after entering a radius? Shouldn't it continue back to the fillet prompt?" After asking for more information (since, yes, it should go back to the prompt after setting the radius), I found that he was invoking the FILLET command from within an AutoLISP function, like so:
(command ".fillet")
His objective was to simply start the FILLET command and then he would set the radius and pick the objects to be filleted, at which point the command would finish and the rest of the LISP would continue on. This worked for him prior to AutoCAD 2009 but when he ran it now, the FILLET command would start and as soon as he entered a radius value, it would exit the command. The reason it was failing now was that FILLET had been updated to support command versioning and it was affecting how FILLET responded when called in this manner.
The fix for this customer was to add one line to his existing LISP code to initialize the latest version of the FILLET command prior to calling it:
(initcommandversion 2)
(command ".fillet")
Here is an example of how that bit of LISP code behaves with and without the call to (initcommandversion):
This instructs FILLET to use the newest version of the command instead of the oldest version, which it would default to since it was being called from LISP (as I recall, we changed the “exit after radius” behavior back in 2000 for manual operations but retained the original behavior for script compatibility).
Understanding a little about command versioning and the (initcommandversion) function can help when trouble-shooting issues like this one and can give you a little more control over those commands that support versioning. For example, LISP and other automation tools now have a mechanism for accessing new behavior, like being able to invoke the Select Color dialog from a (command “.color”) LISP statement.
Comments