June 02, 2007

ACA/ADT Layer LISP Functions

10/30/2014 - Updated to include ACA 2015
06/30/2013 - Updated to include ACA 2013 and 2014.
04/03/2011 - Updated to include ACA 2012.
01/27/2010 - Updated to include ACA 2008 - 2011!

AutoCAD® Architecture (ACA) and Autodesk® Architectural Desktop (ADT) ship with an ARX file that contains LISP functions that work with Layer Standards and Layer Keys. Mark Webb of Autodesk posted a synopsis of the LISP functions that were available in the AecLMgrLISP40.arx file that accompanied ADT 2004; you can obtain that synopsis in this thread in the AutoCAD Architecture Customization Discussion Group. Look for my repost on May 8, 2007.

Note that the name of the ARX file changes, depending upon the version you are using.
ADT 2004 - AecLMgrLisp40.arx
ADT 2005 - AecLMgrLisp45.arx
ADT 2006 - AecLMgrLisp47.arx
ADT 2007 - AecLMgrLisp50.arx
ACA 2008 through ACA 2015 - AecLMgrLisp.arx

ADT 3.3 included an ARX file called aeclayermanagerui30.arx; if memory serves, not all of the LISP functions listed in the synopsis noted above are present in that version.

Here is some sample code for loading the proper ARX function, based on the value of the ACADVER system variable. It supports ADT3.3 through ACA 2015.
(setq sacdvr (getvar "ACADVER"))
;; ARXload proper ARX function:
(cond ; cond A.
((= "15.06" sacdvr)
;; ARXload ADT3.3 function:
(if (not (member "aeclayermanagerui30.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclayermanagerui30.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclayermanagerui30.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A1.
((= "16.0" sacdvr)
;; ARXload ADT2004 function:
(if (not (member "aeclmgrlisp40.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclmgrlisp40.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclmgrlisp40.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A2.
((= 16.1 (atof sacdvr))
;; ARXload ADT2005 function:
(if (not (member "aeclmgrlisp45.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclmgrlisp45.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclmgrlisp45.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A3.
((= 16.2 (atof sacdvr))
;; ARXload ADT2006 function:
(if (not (member "aeclmgrlisp47.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclmgrlisp47.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclmgrlisp47.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A4.
((= 17.0 (atof sacdvr))
;; ARXload ADT2007 function:
(if (not (member "aeclmgrlisp50.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclmgrlisp50.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclmgrlisp50.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A5.
((or
(= 17.1 (atof sacdvr))
(= 17.2 (atof sacdvr))
(= 18.0 (atof sacdvr))
(= 18.1 (atof sacdvr))
(= 18.2 (atof sacdvr))
(= 19.0 (atof sacdvr))
(= 19.1 (atof sacdvr))
(= 20.0 (atof sacdvr))
) ;_ End or.
;; ARXload ACA 2008 through 2015 function:
(if (not (member "aeclmgrlisp.arx" (arx)))
; If the ARX file is not currently loaded...
(progn ; ...do the following:
(prompt "\nARXloading \"aeclmgrlisp.arx\". ")
; Display prompt noting file to be loaded.
(if (arxload "aeclmgrlisp.arx" nil)
; If ARX file loads successfully...
(setq flag T) ; ...set flag to T.
(prompt "\n; error: ARXLOAD failed")
; ...else display prompt and return nil.
) ;_ End if.
) ;_ End progn.
(setq flag T) ; ...else already loaded, set flag to T.
) ;_ End if.
) ;_ End condition A6.
(T
(alert
(strcat
"Unsupported version of AutoCAD is running."
"\nACADVER = " sacdvr "."
"\n\nPlease notify Computer Services."
) ;_ End strcat.
) ;_ End alert.
nil ; Return nil.
) ;_ End condition A7.
) ;_ End cond A.

Note that after running that code, the LISP variable flag will be set to T (true) if the ARX file was already loaded or was successfully loaded and will be set to nil if the ARX file failed to load. Your subsequent code may want to test that value before trying to use one of the LISP routines defined by the ARX file.

One function that many users will find useful is AecGenerateLayerKey function, which takes one argument, the name of a Layer Key as a quoted string. If a layer of that name does not exist in the drawing file, it will be created, using the parameters specified in the current Layer Key Style, and the layer name returned. If a layer of that name already exists, the layer name is returned, but no changes are made to the layer's properties (color, linetype, etc.), even if they do not agree with those set in the Layer Key Style. That is consistent with the way a Layer Key works when called by an ACA/ADT object create command, or by AEC Content. If the specified Layer Key does not exist in the current Layer Key Style, the Layer Key name is returned as a quoted string. No other action is taken, if you want that layer set current, trap the return value, test to see if it is nil and, if not, use the CLAYER system variable or the LAYER command in your routine to set that layer current. This function allows you to add Layer Keying to any custom LISP routines you may have for things that AEC Content alone can not do easily, or which you wrote long before using ADT/ACA.

A pair of functions I found useful when customizing a Layer Standard for my firm were the AecLayerSaveStdAsText and AecLayerLoadStdAsText functions. This allows you to export the contents of a Layer Standard as a formatted text file, open the text file in a text editor, like Notepad, carefully make edits - preserving the proper formatting, then reload the edited file as a Layer Standard in a drawing file. My firm's Layer Standard is based on the U.S. National CAD Standard, and I wanted to have all of the Minor fields available in both Minor1 and Minor2. Rather than enter each field twice in the editor available inside ADT or ACA, I was able to export the Layer Standard to a text file, copy all the Minor1 field values to Minor2 and then reload the text file. I believe I may have tweaked some of the other field values before reloading the file, as well. Much more efficient, and it avoided the possibility of typos when doing the same thing twice.

There are a number of other layer-related functions in the ARX file, for setting Layer Key Overrides, toggling Layer Key Overrides on and off, generating a list of Layer Keys and working with layer snapshots. Take a look at what is available, and make use of those that fit your needs.

2 comments:

Anonymous said...

onfused about how to use "AecLayerSaveStdAsText and AecLayerLoadStdAsText"

How do i determine the LayerStd name to use for the 1st argument... ??

David Koch said...

There are several places where you can check:

The Layering tab of the Drawing Setup dialog will list the current Layer Key Style and the Layer Standard on which it is based. One way to get here is through the pulldown menus: Format > Layer Management > Select Layer Standard....

The Layer Key Overrides dialog also displays the name of the current Layer Standard. Open this dialog by selecting Format > Layer Management > Layer Key Overrides... from the pulldown menus.

None of the above options allows you to select a Layer Standard, only to determine the current standard's name. In fact, you really do not select a Layer Standard directly, instead, a Layer Standard is associated with a Layer Key Style, you set a Layer Key Style current, and the Layer Standard associated with it comes along for the ride.

To associate a Layer Standard with a Layer Key Style (and a third place to determine the current Layer Standard, provided that you know the name of the current Layer Key Style), is to open the Style Manager, go to the Layer Key Styles node (under Multi-Purpose Objects), edit the current Layer Key Style, and then select the Keys tab. At the bottom there is a dropdown list that will display the Layer Standard that is currently associated with that Layer Key Style, and allow you to change it to any other Layer Standard that is defined in that drawing file.