I did this for AutoCAD 2000-2004. Now with 2006 it's obsolete... . The way I did it was to set up a command reactor to watch for the OFFSET command, and then a database reactor to count the additions to the database after the first reactor fires. That way you get a selection set of new objects that get changed to the current layer. This works great BUT it didn't allow you to use OFFSET the "old" way, placing objects on the layer of the source object. Since one of my test users wanted to do that, I added a conditional flag to the reactor routine so it would only fire if the flag was true. That way, "OCL" would offset to the current layer and "O" or "OFFSET" worked the standard way. The reactor code looks like this:
Code:
;;; OffsetChangeLayerFlag.lsp
;;; Was ReactorOffsetChangeLayer.lsp
;;; Changes entities created by OFFSET to the current layer
;;; Added OFFSETFLAG to allow 2 versions of OFFSET
;;; Copyright 2005 Lance Gordon Custom Software
(vl-load-com)
;;; Define routine to strip reactors away before calling it
(defun remove (Name / ReactorsinDwg ReactorGrp ReactorObj)
(setq ReactorsinDwg (vlr-reactors))
(foreach ReactorGrp ReactorsinDwg
(foreach ReactorObj (cdr ReactorGrp)
(if (= (vlr-data ReactorObj) Name)
(vlr-remove ReactorObj)
)
)
)
)
;;; Before starting, remove any current OFFSET reactors
(remove "off-rctEnded")
(remove "off-rctWillStart")
;;; Manually empty running total in case we're loaded twice
(setq entlist nil)
;;; First, set up CommandWillStart and CommandEnded reactors
;;; to watch for OFFSET command and to call our Change routine
(setq off-rctWillStart
(vlr-command-reactor
"off-rctWillStart"
'((:VLR-CommandWillStart . off-CmdStarted))
)
off-rctEnded
(vlr-command-reactor
"off-rctEnded"
'((:VLR-CommandEnded . off-CmdEnded))
)
)
;;; This routine runs right after OFFSET has started, assuming the flag is set.
;;; It sets up the Appended reactor to fire for anything added to the database.
(defun off-CmdStarted (off-rctWillStart str)
(if (and (= (strcase (car str)) "OFFSET") offsetflag)
; Fire only if OFFSET is running
(progn ; and flag is set.
(setq off-rctAppended ; If so, set up the reactor
(vlr-AcDb-reactor
nil
'((:VLR-ObjectAppended . off-ObjAdded))
)
)
)
)
)
;;; This routine runs after each object is added to the database
;;; by the reactor conditional on "OFFSET" running
(defun off-ObjAdded (off-rctAppended str / ent cl)
(setq cl (getvar "CLAYER"))
(if (vlr-added-p off-rctAppended)
(progn ; avoid double reactor action
(vlr-remove off-rctAppended)
;;(princ "\n*** Reactor Active *** ") ; FOR TESTING
)
)
(if (= (type (cadr str)) 'EName)
(progn ; Keep a running list of new objects appended
(setq ent (entlast))
(if (not (= cl (cdr (assoc 8 (entget ent)))))
(progn ; if they're not on the current layer.
(if entlist ; Make sure they aren't duplicates
(if (not (member ent entlist))
(setq entlist (append (list ent) entlist))
)
(setq entlist (list ent))
)
(princ "\nChange to current layer pending...")
)
)
)
)
(if (and (vlr-added-p off-rctWillStart)
(not (vlr-added-p off-rctAppended))
) ; Reset the Appended reactor
(vlr-add off-rctAppended)
) ; if something was appended
)
;;; This runs after OFFSET has finished
;;; so that objects can be modified
(defun off-CmdEnded (off-rctEnded str / ent el cl)
(if (= (strcase (car str)) "OFFSET")
(progn
(foreach ent entlist
(setq
el (entget ent)
cl (getvar "CLAYER")
)
(setq el (subst (cons 8 cl) (assoc 8 el) el))
(entmod el)
) ; Move appended stuff to current layer
(if off-rctAppended ; Check to be sure it's defined (NOT if flag is nil)
(vlr-remove off-rctAppended) ; Remove last Appended reactor now
)
(if entlist
(progn ; Notify about changed objects
(princ (strcat "\n"
(itoa (length entlist))
" objects changed to current layer."
)
)
(setq entlist nil) ; and manually delete the list.
(setq offsetflag nil) ; Kill the flag, if any
)
)
)
)
(princ)
)
(princ "\nOffset ChangeLayer utility loaded.\n")
(princ)
and the OCL program is simply
Code:
;;; OCL Function
(defun c:ocl()
(setvar "CMDECHO" 0)
(setq offsetflag T)
(command "_OFFSET")
(setvar "CMDECHO" 1)
(princ)
)
(princ "\nOffsetChangeLayer loaded. (C)LGCS 2005.\n")
(princ)
Note that offsetflag is a GLOBAL variable so it persists until the reactor code turns it off. To use this code, you load the reactor code with ACADDOC.LSP, and then just load/run OCL.LSP when you want it.