TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: daron on February 03, 2004, 12:03:01 PM

Title: LayerStates
Post by: daron on February 03, 2004, 12:03:01 PM
Has anybody had any luck with exporting a layer state? Here's the script.
Code: [Select]
(setq laystatenam (substr (getvar 'dwgname) 5 4)
  stateprefix (getvar 'dwgprefix))
     (command ".layer" "a" "s" laystatenam "" "ex" laystatenam stateprefix "" "")

Under normal circumstances that should work, but in export all that is exported is .las. The layer state name is not there. The laystatenam variable should contain A000 and does create a state with that name, it just doesn't use it when it exports it. Is there a way to tell it to use it, without selecting it or typing it in?
Title: LayerStates
Post by: Keith™ on February 03, 2004, 12:14:59 PM
Will have to look into that one ....
Title: LayerStates
Post by: daron on February 03, 2004, 12:23:24 PM
Let's see if I can add to it. By adding a pause to the export so I can manually type the name in, works, but when I go to the specified folder to import it later, it is a .las file as I stated before, but when it imports in, it has the originally given name:? That's odd.
Title: LayerStates
Post by: JohnK on February 03, 2004, 01:03:19 PM
i messed with layerstates a bit. (It aint easy) --This was on 02 but-- i couldnt acess the layerstates as a group perse, i did however access the manager thru lisp. eventualy i gave up, cause it was getting a bit to mich for my taste.  I'll look for the code i did endup with, but most likely i left it on my former job's computer along with 90% of my code.
Title: LayerStates
Post by: daron on February 03, 2004, 01:31:48 PM
Quote
most likely i left it on my former job's computer along with 90% of my code.

That sucks. Why didn't you take it with you?
Title: LayerStates
Post by: JohnK on February 03, 2004, 02:00:43 PM
Cause i didnt really care. (I thought i could just re-wite what i needed; ya know? )
Title: LayerStates
Post by: JohnK on February 03, 2004, 02:05:22 PM
Daron, here is a small snipit of code i did find. (I aint got much more then this but) Give this a whirl with a saved layer state called "test"

(vla-export (vla-Getinterfaceobject (vlax-get-object "AutoCAD.Application") "AutoCAD.AcadLayerStateManager") "test" "c:\test.las")
Title: LayerStates
Post by: CAB on February 03, 2004, 03:13:57 PM
Not sure what you are doing Daron,
but does this do anything for you?

Code: [Select]
;;
;; By R. ROBERT BELL
;;
(defun C:LayerFiltersDelete ()
 (vl-Load-Com)
 (vl-Catch-All-Apply '(lambda ()
                       (vla-Remove
                        (vla-GetExtensionDictionary
                         (vla-Get-Layers
                          (vla-Get-ActiveDocument
                           (vlax-Get-Acad-Object)))) "ACAD_LAYERFILTERS")))
 (princ "\nAll layer filters have been deleted.")
 (princ)
)
Title: LayerStates
Post by: JohnK on February 03, 2004, 03:27:57 PM
CAB, Daron is hunting Layerstates. (That code is for the Layerfilters. )
Title: LayerStates
Post by: daron on February 03, 2004, 03:29:51 PM
No, I don't want to delete filters. Are you familiar with the eNotThatKindofClass thread I started in General Autocad? Well, that works with some tweaking. First, it needs to select all graphical objects on the drawing, not the entire database. The problem is in the database. I'd love to be able to delete the dictionary, but this is starting to work. Anyway, the other problem is this: xref'ed objects don't retain their previous layer settings when they've been wblock'ed, so, the trick is to save and export the layer states before wblocking, wblock the drawing objects and drawing to itself, close the drawing without saving and reopen the drawing. Then I need to import the previously saved state. Does that help?

Nice code though. That Robert Bell, he's a nice guy. If you ever get the chance to meet him, take it. Se7en's code is closest yet, but I can't get it working.
Title: LayerStates
Post by: JohnK on February 03, 2004, 03:43:40 PM
Daron i just noticed something. (I am using 2000 right now and there isnt a layer state mgr in that version --besides in the express tools-- but give this line a try and see if it returns something.

(vla-Getinterfaceobject (vlax-get-object "AutoCAD.Application") "AcadLayerStateManager")
Title: LayerStates
Post by: daron on February 03, 2004, 03:50:47 PM
No return, but this returns:
(vla-Getinterfaceobject (vlax-get-object "AutoCAD.Application") "AutoCAD.AcadLayerStateManager.16")
Your first one with a .16 at the end. From that it's the export that's messed up. I get Automatin Error. Not initialized yet.
Title: LayerStates
Post by: CAB on February 03, 2004, 04:01:40 PM
Don't mean to but it, but her is some more info.
I'll have to do some homework as i I don't understand it.


Code: [Select]
; Setup some pointers
(setq app (vlax-get-acad-object)
      doc (vla-get-activedocument app); this can be replaced with an
axdbdocument pointer
      lobj(vla-GetExtensionDictionary(vla-get-layers doc)))

; Now lets be safe because there may not be any layerstates
(setq lstdict (vl-catch-all-apply
      'vla-item(list lobj "ACAD_LAYERSTATES")))

(if (vl-catch-all-error-p lstdict)
  (princ "\nThere are no saved Layer States!")
; Now iterate through the dictionary collection
; and collect the layerstate names
(vlax-for l lstdict
  (setq lstates(append lstates (list(vla-get-name l))))))


; Return the list of names
lstates



;;;/////////////////////////////////////////////
;;;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

(vl-load-com)

(defun get-acadobject  ()
  (setq *acad*
  (cond
    (*acad*)
    ((vlax-get-acadobject))
    (T nil))))

(defun get-activedocument  ()
  (setq *doc*
  (cond
    (*doc*)
    ((vla-get-activedocument (get-acadobject)))
    (T nil))))

(defun delete-layerstate  (obj name)
  (if (vl-catch-all-error-p
 (vl-catch-all-apply
   'vla-delete
   (list obj name)))
    nil
    T))

(defun save-layerstate (obj name mask)
  (if (vl-catch-all-error-p
 (vl-catch-all-apply
   'vla-save
   (list obj name mask)))
    nil
    T))

(defun set-layerstate  (name mask)
  (setq state
  (vlax-create-object
    "AutoCAD.AcadLayerStateManager"))
  (vla-setdatabase
    state
    (vla-get-database (get-activedocument)))
  (delete-layerstate state name)
  (save-layerstate
    state
    name
    ;; acLsAll
    mask))

(defun get-statenames  (/ collection names)
  (if (not
 (vl-catch-all-error-p
   (setq collection
   (vl-catch-all-apply
     (function (lambda ()
          (vla-item (vla-getextensiondictionary
        (vla-get-layers
          (vla-get-activedocument
            (vlax-get-acadobject))))
      "ACAD_LAYERSTATES")))))))
    (vlax-for item  collection
      (setq names (cons (strcase (vla-get-name item)) names)))))

(defun restore-layerstate  (name)
  (if (and state
    (vl-position
      (strcase name)
      (get-statenames)))
    (progn (vla-restore state name)
    (delete-layerstate state name)
    (vlax-release-object state)
    (setq state nil))))
Title: LayerStates
Post by: Mark on February 18, 2004, 07:56:00 PM
Half the credit goes to Se7en.
Code: [Select]

;;; return the LayerStateManager object ready to use
;;; tested on 2004
;;; for earlier versions change the '16' below to '15'
(defun return-lsm (/ db lsm)
  (vl-load-com)
  (setq db (vlax-get-property
             (vla-get-activedocument (vlax-get-acad-object))
             'Database
             )
        )
  (setq lsm
     (vl-catch-all-apply
        'vla-Getinterfaceobject
          (list (vlax-get-object "AutoCAD.Application")
             "AutoCAD.AcadLayerStateManager.16");< or 15
           )
        )
  (if (not (vl-catch-all-error-p lsm))
    (progn (vla-SetDatabase lsm db) lsm)
    )
  )

; Methods supported:
;   Delete (1)
;   Export (2)
;   Import (1)
;   Rename (2)
;   Restore (1)
;   Save (2)
;   SetDatabase (1)

; now do some testing
; save the current state
(if (setq lsm (return-lsm))
  (vlax-invoke-method lsm 'Save "new-state" acLsAll)
  )

; export it
(if lsm
  (vlax-invoke-method lsm 'Export "new-state" "c:/new-state.las")
  )

; change your layers so we can restore them
(if lsm
  (vlax-invoke-method lsm 'Restore "new-state")
  )

(vlax-release-object lsm)
Title: LayerStates
Post by: daron on February 19, 2004, 12:14:48 AM
Thanks. I'll have to look at that soon.
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 03:50:15 PM
We have a LISP routine here that sets up our layers automatically. The problem we have is that the routine essentially errors out if the user has any layers that are frozen or locked.

My thought was to use the code found in this thread to create a temporary layer state, unlock all the layers on, thaw them, then revert to the temporary layer state.

I was able to save, restore & delete the layer state using simple syntax in the LISP routine, but for some reason it invokes the AutoCAD text window when the code is run this way. Here's a sample of the code I was using:

Code: [Select]
(vl-load-com)
(defun C:MakeLAYER ()
  (setvar "cmdecho" 0)
  (command ".undo" "begin")
  (setq ccl (getvar "clayer"))
;
;
(command "-layer" "state" "save" "PreMakelayer" "" "" "") 
(command "-layer" "on" "*" "thaw" "*" "unlock" "*" "")   
;
;
  (setq curlayer "BASEPLATE")
  (command "-layer" "m" curlayer "c" "GREEN" curlayer "")
  (SetLayerDescription curlayer "Baseplate Outline and Mounting Holes")
  (setq curlayer "END")
;
;
(command "-layer" "state" "restore" "PreMakelayer" "" "")   
(command "-layer" "state" "delete" "PreMakeLayer" "" "")   
;
;
  (setq curlayer "END")
  (setvar "clayer" ccl)
  (command ".undo" "end")
  (princ)
)

My problem is this: I'm not sure how to use the code in this thread (though it seems to be what I'm looking for) in order to save a layer state, restore it later on, then delete it.

For example, from the code that CAB last posted, I see this:
Code: [Select]
(defun save-layerstate (obj name mask)
  (if (vl-catch-all-error-p
 (vl-catch-all-apply
   'vla-save
   (list obj name mask)))
    nil
    T))

So, if I were to want to save a layer state called "PreMakeLayer", what syntax would I use? My assumption was:
Code: [Select]
(save-layerstate "PreMakeLayer"), but that returns error: too few arguments.

Can someone help a newb along here & clue me in as to how this code is supposed to work? I'd really appreciate it!

Title: Re: LayerStates
Post by: T.Willey on February 27, 2008, 03:59:04 PM
You don't need a layer state.  You just need a lisp that will unlock any locked layers, and return the list of unlocked layers so that you can lock them again after you make your changes.  So something like this should work:

Code: [Select]
(defun UnlockLayers (Doc / LayList)
   
    (vlax-for lay (vla-get-Layers Doc)
        (if (equal (vla-get-Lock lay) :vlax-true)
            (progn
                (setq LayList (cons lay LayList))
                (vla-put-Lock lay :vlax-false)
            )
        )
    )
    LayList
)
Called like (for the current drawing)
Code: [Select]
(setq LayList (UnlockLayers (vla-get-ActiveDocument (vlax-get-Acad-Object))))

Then you would do your thing, and after that call the portion below.
Code: [Select]
(foreach lay LayList
    (vla-put-Lock lay :vlax-true)
)

Hope that helps.
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 04:05:10 PM
What Tim said....you don't need a layerstate. Here is a lisp to unlock and thaw all layers then restore:
Code: [Select]
;;;to use (unlockthawlayers)

;;; do your stuff

;;;(relockfreezelayers)


(defun unlockthawlayers (/)
  (vlax-map-collection
    (vla-get-layers
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (cond ((eq (vla-get-lock x) :vlax-true)
      (setq lock (cons x lock))
      (vla-put-lock x :vlax-false)
     )
       )
       (cond ((eq (vla-get-freeze x) :vlax-true)
      (setq freeze (cons x freeze))
      (vla-put-freeze x :vlax-false)
     )
       )
     )
  )
  (princ)
)

(defun relockfreezelayers (/)
  (if lock
    (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    lock
    )
  )
  (if freeze
    (mapcar '(lambda (x)
       (vl-catch-all-apply 'vla-put-freeze (list x :vlax-true))
     )
    freeze
    )
  )
  (setq lock nil)
  (setq freeze nil)
  (princ)
)
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 04:22:10 PM
Wow, how you guys make this stuff so 'easy' is beyond me. Thanks!

One catch I noticed was that the code I've now asssembled turns all layers on after is has been run. Is there a way to store whether a layer is on or off as well as if it's frozen or locked?
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 04:28:56 PM
Are you running (relockfreezelayers) at the end? I cannot duplicate what you are describing.

Ron
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 04:36:42 PM
Yes, I'm running relockthawlayers at the end.

Could it be due to the way I'm creating the layers?

Code: [Select]
  (setq curlayer "BLDGS FOOTPRINT")
  (command "-layer" "m" curlayer "c" "14" curlayer "")
  (SetLayerDescription curlayer "Footprint on non-test buildings")
  (setq curlayer "END")

SetLayerDescription is the code I got from Peter. I can post that back up if it would help.
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 04:46:10 PM
You might have grabbed the code above before I updated it. I had a typo in the lower portion. Copy the code again and let me know if it works.
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 04:51:24 PM
Weird - still does it.

I have three layers I turn off as a test. When I run the code, those three layers turn back on, everytime.  :?

If a layer is off before I run the code, it's on afterwards.
Title: Re: LayerStates
Post by: T.Willey on February 27, 2008, 05:01:38 PM
You can try this then.

Code: [Select]
(defun UnlockThawOnLayers (Doc / LayList cLayer)
   
    (setq cLayer (getvar 'CLayer))
    (vlax-for lay (vla-get-Layers Doc)
        (setq LayList
            (cons
                (cons
                    lay
                    (list
                        (vla-get-LayerOn lay)
                        (vla-get-Freeze lay)
                        (vla-get-Lock lay)
                    )
                )
                LayList
            )
        )
        (vla-put-LayerOn lay :vlax-true)
        (vla-put-Lock lay :vlax-false)
        (if (/= (vla-get-Name lay) cLayer)
            (vla-put-Freeze lay :vlax-false)
        )
    )
    LayList
)
Called like (for the current drawing)
Code: [Select]
(setq LayList (UnlockLayers (vla-get-ActiveDocument (vlax-get-Acad-Object))))
Do your thing here, then call what is below.
Code: [Select]
(setq cLayer (getvar 'CLayer))
(foreach lst LayList
    (setq tempObj (car lst))
    (vla-put-LayerOn tempObj (cadr lst))
    (vla-put-Lock tempObj (caddr lst))
    (if (/= cLayer (vla-get-Name tempObj))
        (vla-put-Freeze tempObj (cadddr lst))
    )
)
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 05:13:16 PM
Even with that, it still turns all layers on after executing - I must be using the code incorrectly.

Here's my code currentlY:
Code: [Select]
; -mlayer.lsp
;Written by Mark Peterson, August 08, 2007
;Revised February 27th, 2008 to include the ability to maintain layer states of drawing
;DESCRIPTION
;This program was written to automate the creation & repair of
;standard layer scheme in AutoCAD
;--------------------------------------------------------------------------------------------
;
;ERROR HANDLER
(defun err (s)
(if (/= s "Function cancelled")
  (princ (strcat "\nError: " s))
)
(if ech (setvar "cmdecho" ech))
(setq *error* olderr)
(princ)
)

; Written By: Peter Jamtgaard copr 2005
; Set the layer description of a specified layer
; Syntax (setlayerdescription "layername" "layerdescription")
; Function returns T if successful nil if not
(defun SetLayerDescription (strLayer strDescription)
(vl-load-com)
 (if (and (= (type strLayer) 'STR)
  (tblsearch "layer" strLayer)
  (= (type strDescription) 'STR)
)
  (progn
   (vla-put-description
(vla-item
(vla-get-layers
  (vla-get-activedocument
   (vlax-get-acad-object)
  )
)
strLayer
)
strDescription
   )
   T
  )
 )
)
;----------------------------------------------------------------------------------------------
(defun UnlockThawOnLayers (Doc / LayList cLayer)
   
    (setq cLayer (getvar 'CLayer))
    (vlax-for lay (vla-get-Layers Doc)
        (setq LayList
            (cons
                (cons
                    lay
                    (list
                        (vla-get-LayerOn lay)
                        (vla-get-Freeze lay)
                        (vla-get-Lock lay)
                    )
                )
                LayList
            )
        )
     )
)
;--------------------------------------------------------------------------------------------
;MAKE LAYER ROUTINE
;
;
;
(defun C:MakeLAYER ()
  (setq LayList (UnlockLayers (vla-get-ActiveDocument (vlax-get-Acad-Object))))
  (setvar "cmdecho" 0)
  (command ".undo" "begin")
  (setq ccl (getvar "clayer"))
;
  (setq curlayer "BASEPLATE")
  (command "-layer" "m" curlayer "c" "GREEN" curlayer "")
  (SetLayerDescription curlayer "Baseplate Outline and Mounting Holes")
  (setq curlayer "END")
;
  (setq curlayer "BLDGS")
  (command "-layer" "m" curlayer "c" "RED" curlayer "")
  (SetLayerDescription curlayer "Non-test Buldings (foam)")
  (setq curlayer "END")
;
  (setq curlayer "BLDGS DATUM")
  (command "-layer" "m" curlayer "c" "51" curlayer "")
  (SetLayerDescription curlayer "Base elevation datum of non-test buildings")
  (setq curlayer "END")
;
  (setvar "clayer" ccl)
  (command ".undo" "end")
  (setq cLayer (getvar 'CLayer))
  (foreach lst LayList
    (setq tempObj (car lst))
    (vla-put-LayerOn tempObj (cadr lst))
    (vla-put-Lock tempObj (caddr lst))
    (if (/= cLayer (vla-get-Name tempObj))
        (vla-put-Freeze tempObj (cadddr lst))
    )
  )
  (princ)
  (princ)
)
  (prompt "\nLayer Standards 2007 loaded - type MAKELAYER to begin.")
  (prompt "\n-------------------TEST PHASE--------------------------")
  (princ)
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 05:14:20 PM
The only thing I can think of is your code is bonking out before it hits the (relockfreezelayers) :?
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 05:20:05 PM
This works for me:

Code: [Select]
; -mlayer.lsp
;Written by Mark Peterson, August 08, 2007
;Revised February 27th, 2008 to include the ability to maintain layer states of drawing
;DESCRIPTION
;This program was written to automate the creation & repair of
;standard layer scheme in AutoCAD
;--------------------------------------------------------------------------------------------
;
;ERROR HANDLER
(defun err (s)
  (if (/= s "Function cancelled")
    (princ (strcat "\nError: " s))
  )
  (if ech
    (setvar "cmdecho" ech)
  )
  (setq *error* olderr)
  (princ)
)

; Written By: Peter Jamtgaard copr 2005
; Set the layer description of a specified layer
; Syntax (setlayerdescription "layername" "layerdescription")
; Function returns T if successful nil if not
(defun SetLayerDescription (strLayer strDescription)
  (vl-load-com)
  (if (and (= (type strLayer) 'STR)
   (tblsearch "layer" strLayer)
   (= (type strDescription) 'STR)
      )
    (progn
      (vla-put-description
(vla-item
  (vla-get-layers
    (vla-get-activedocument
      (vlax-get-acad-object)
    )
  )
  strLayer
)
strDescription
      )
      T
    )
  )
)
;----------------------------------------------------------------------------------------------
(defun unlockthawlayers (/)
  (vlax-map-collection
    (vla-get-layers
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (cond ((eq (vla-get-lock x) :vlax-true)
      (setq lock (cons x lock))
      (vla-put-lock x :vlax-false)
     )
       )
       (cond ((eq (vla-get-freeze x) :vlax-true)
      (setq freeze (cons x freeze))
      (vla-put-freeze x :vlax-false)
     )
       )
     )
  )
  (princ)
)

(defun relockfreezelayers (/)
  (if lock
    (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    lock
    )
  )
  (if freeze
    (mapcar '(lambda (x)
       (vl-catch-all-apply 'vla-put-freeze (list x :vlax-true))
     )
    freeze
    )
  )
  (setq lock nil)
  (setq freeze nil)
  (princ)
) ;--------------------------------------------------------------------------------------------
;MAKE LAYER ROUTINE
;
;
;
(defun C:MakeLAYER ()
  (unlockthawlayers)
  (setvar "cmdecho" 0)
  (command ".undo" "begin")
  (setq ccl (getvar "clayer"))
;
  (setq curlayer "BASEPLATE")
  (command "-layer" "m" curlayer "c" "GREEN" curlayer "")
  (SetLayerDescription
    curlayer
    "Baseplate Outline and Mounting Holes"
  )
  (setq curlayer "END")
;
  (setq curlayer "BLDGS")
  (command "-layer" "m" curlayer "c" "RED" curlayer "")
  (SetLayerDescription curlayer "Non-test Buldings (foam)")
  (setq curlayer "END")
;
  (setq curlayer "BLDGS DATUM")
  (command "-layer" "m" curlayer "c" "51" curlayer "")
  (SetLayerDescription
    curlayer
    "Base elevation datum of non-test buildings"
  )
  (setq curlayer "END")
;
  (setvar "clayer" ccl)
  (command ".undo" "end")
  (setq cLayer (getvar 'CLayer))
  (relockfreezelayers)
  (princ)
)
(prompt
  "\nLayer Standards 2007 loaded - type MAKELAYER to begin."
)
(prompt
  "\n-------------------TEST PHASE--------------------------"
)
(princ)
Title: Re: LayerStates
Post by: T.Willey on February 27, 2008, 05:21:21 PM
The only thing I can think of is your code is bonking out before it hits the (relockfreezelayers) :?
Agreed.  Maybe you can post the command line prompt from when you call the routine.
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 05:34:57 PM
Here's something to look at. Different approach putting layername, color, and description in a list then using a foreach loop:

Code: [Select]
(defun C:MakeLAYER (/ CCL CLAYER LAYLIST)
  (unlockthawlayers)
  (setvar "cmdecho" 0)
  (command ".undo" "begin")
  (setq ccl (getvar "clayer"))
  (setq laylist '(("BASEPLATE"
   "GREEN"
   "Baseplate Outline and Mounting Holes"
  )
  ("BLDGS"
   "RED"
   "Non-test Buldings (foam)"
  )
  ("BLDGS DATUM"
   "51"
   "Base elevation datum of non-test buildings"
  )
)
  )
  (foreach lyr laylist
    (command "-layer" "m" (car lyr) "c" (cadr lyr) (car lyr) "")
    (SetLayerDescription (car lyr) (caddr lyr))
  )
  (setvar "clayer" ccl)
  (command ".undo" "end")
  (setq cLayer (getvar 'CLayer))
  (relockfreezelayers)
  (princ)
)
(prompt
  "\nLayer Standards 2007 loaded - type MAKELAYER to begin."
)
(prompt
  "\n-------------------TEST PHASE--------------------------"
)
(princ)
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 05:45:59 PM
Ronjonp - I'll give your list method a shot next.

Best I can tell, the layers all turning on (unless they were frozen) is a factor of the "-layer" "make" system I was using to create/repair the layers.

From the AutoCAD help menu:

Quote
Make

Creates a layer and makes it current. New objects are drawn on the current layer.

Enter name for new layer (becomes the current layer) <current>: Enter a name or press ENTER

If no layer exists for the name you enter, a new layer with that name is created. The new layer is on and assumes the following properties by default: color number 7, the CONTINUOUS linetype, and a lineweight of DEFAULT.

If the layer exists but is turned off, it is turned on.

How it was working for you guys, I have no idea....
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 05:55:44 PM
Sooo....

About those layer states.    :-)

Am I thinking about this the wrong way - I mean, this system doesn't seem to be working, what would be wrong with doing it with layer states?
Title: Re: LayerStates
Post by: ronjonp on February 27, 2008, 06:10:50 PM
I'm out of ideas...sorry.
Title: Re: LayerStates
Post by: mjfarrell on February 27, 2008, 06:16:16 PM
Why not put your layers in your DWT?

Then when you need layers, they are already there.  And or, if they have been purged from the working drawing they are easily re-imported using design center (CTRL+2) to drag the layers back into the working file.
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 06:26:23 PM
We do initiate all our drawing files with a DWT that contains all our standard layers. Through the process of working with the files, which often inclues purging them, many layers are often lost or changed by users. The lisp routine we have is a quick & easy way to reinstate any missing layers, as well as repair existing ones to the company standard (colors, linetypes, etc). Going through design center to recreate layers is long & cumbersome for the number of times our users perform this function.

Also, the way we have our CUI's setup, I can quickly edit the LISP routine to either alter an existing layer's properties, or create an entirely new layer with all the appropriate properties. The next time a user invokes the LISP routine, the new layer settings are produced in their drawing.
Title: Re: LayerStates
Post by: T.Willey on February 27, 2008, 06:26:56 PM
If they are new layers, they will be on and thawed and unlocked because they were not in the drawing when the first piece of code was ran.  If you want the new layers be off or frozen or locked, then you will need to create a new way to create the layers, which wouldn't be that had to do.
Title: Re: LayerStates
Post by: T.Willey on February 27, 2008, 06:30:34 PM
There are some good routines to create layers, or import them from an other drawing in this thread.

http://www.theswamp.org/index.php?topic=12845.0
Title: Re: LayerStates
Post by: mjfarrell on February 27, 2008, 06:36:49 PM
We do initiate all our drawing files with a DWT that contains all our standard layers. Through the process of working with the files, which often inclues purging them, many layers are often lost or changed by users. The lisp routine we have is a quick & easy way to reinstate any missing layers, as well as repair existing ones to the company standard (colors, linetypes, etc). Going through design center to recreate layers is long & cumbersome for the number of times our users perform this function.

Also, the way we have our CUI's setup, I can quickly edit the LISP routine to either alter an existing layer's properties, or create an entirely new layer with all the appropriate properties. The next time a user invokes the LISP routine, the new layer settings are produced in their drawing.

From this end it sounds like the solution IS the problem.  Or you wouldn't need to invest in a lisp file to solve it. Perhaps the users should be trained to NOT purge out your layers, and or follow the standards more closely, nor changed so frequently that they aren't really standards at all. IMHO
Title: Re: LayerStates
Post by: mpeterson79 on February 27, 2008, 06:53:48 PM
Arguements as to the 'right way' we create & repair our layers aside, can anyone explain to me how the following code might be used?

Half the credit goes to Se7en.
Code: [Select]
;;; return the LayerStateManager object ready to use
;;; tested on 2004
;;; for earlier versions change the '16' below to '15'
(defun return-lsm (/ db lsm)
  (vl-load-com)
  (setq db (vlax-get-property
             (vla-get-activedocument (vlax-get-acad-object))
             'Database
             )
        )
  (setq lsm
     (vl-catch-all-apply
        'vla-Getinterfaceobject
          (list (vlax-get-object "AutoCAD.Application")
             "AutoCAD.AcadLayerStateManager.16");< or 15
           )
        )
  (if (not (vl-catch-all-error-p lsm))
    (progn (vla-SetDatabase lsm db) lsm)
    )
  )

; Methods supported:
;   Delete (1)
;   Export (2)
;   Import (1)
;   Rename (2)
;   Restore (1)
;   Save (2)
;   SetDatabase (1)

; now do some testing
; save the current state
(if (setq lsm (return-lsm))
  (vlax-invoke-method lsm 'Save "new-state" acLsAll)
  )

; export it
(if lsm
  (vlax-invoke-method lsm 'Export "new-state" "c:/new-state.las")
  )

; change your layers so we can restore them
(if lsm
  (vlax-invoke-method lsm 'Restore "new-state")
  )

(vlax-release-object lsm)
Title: Re: LayerStates
Post by: daron on February 28, 2008, 10:18:30 AM
It depends on what version of acad you're using. I'm testing it on ACA2008 and this line: "AutoCAD.AcadLayerStateManager.16" needs to be "AutoCAD.AcadLayerStateManager.17" in in 2008, possibly 2007. As for using it, open the vlide, select (double click the parenthesis behind the defun to highlight the function) and load the  function using the partial load button on the editor. Then highlight
Code: [Select]
(if (setq lsm (return-lsm))
  (vlax-invoke-method lsm 'Save "new-state" acLsAll)
  )
and hit the inspect button, (the microscope on the toolbar). As well, inspect this:
Code: [Select]
(if lsm
  (vlax-invoke-method lsm 'Export "new-state" "c:/new-state.las")
  )
That will save your layer state. You can now proceed to make changes. After you're done and want to revert to the old layerstate, inspect:
Code: [Select]
(if lsm
  (vlax-invoke-method lsm 'Restore "new-state")
  )
and
Code: [Select]
(vlax-release-object lsm)
Title: Re: LayerStates
Post by: ronjonp on February 28, 2008, 10:50:45 AM
Maybe getting away from using command to make the layers will fix your problem......give this a try:

Code: [Select]
(defun unlockthawlayers (/)
  (vlax-map-collection
    (vla-get-layers
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (cond ((eq (vla-get-lock x) :vlax-true)
      (setq lock (cons x lock))
      (vla-put-lock x :vlax-false)
     )
       )
       (cond ((eq (vla-get-freeze x) :vlax-true)
      (setq freeze (cons x freeze))
      (vla-put-freeze x :vlax-false)
     )
       )
     )
  )
  (princ)
)

(defun relockfreezelayers (/)
  (if lock
    (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    lock
    )
  )
  (if freeze
    (mapcar '(lambda (x)
       (vl-catch-all-apply 'vla-put-freeze (list x :vlax-true))
     )
    freeze
    )
  )
  (setq lock nil)
  (setq freeze nil)
  (princ)
)

(defun layercreate (layname color linetype desc / lyr)
  (if (not (tblobjname "ltype" linetype))
    (setq linetype "continuous")
  )
  (if (tblsearch "layer" layname)
    (progn
      (setq lyr (vlax-ename->vla-object (tblobjname "layer" layname)))
      (vla-put-color lyr color)
      (vla-put-linetype lyr linetype)
    )
    (setq lyr (vlax-ename->vla-object
(entmakex
  (list (cons 0 "LAYER")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbLayerTableRecord")
(cons 70 0)
(cons 2 layname)
(cons 62 color)
(cons 6 linetype)
  )
)
      )
    )
  )
  (vla-put-description lyr desc)
  (princ)
)


(defun C:MakeLAYER (/ CCL LAYLIST)
  (unlockthawlayers)
  (setvar "cmdecho" 0)
  (setq ccl (getvar "clayer"))
  (setq laylist '(("BASEPLATE"
   3
   "continous"
   "Baseplate Outline and Mounting Holes"
  )
  ("BLDGS"
   1
   "continous"
   "Non-test Buldings (foam)"
  )
  ("BLDGS DATUM"
   51
   "continous"
   "Base elevation datum of non-test buildings"
  )
)
  )
  (foreach lyr laylist
    (layercreate (car lyr) (cadr lyr) (caddr lyr) (cadddr lyr))
    (princ (strcat "\n Layer - " (car lyr) " created..."))
  )
  (setvar "clayer" ccl)
  (relockfreezelayers)
  (princ)
)
Title: Re: LayerStates
Post by: mpeterson79 on February 28, 2008, 12:52:46 PM
First off, thanks again to you guys for helping. I'm really trying to understand what is happening in the code being presented here so I can learn more about LISP & vba.

Ronjonp, one thing I noticed in the code you last posted, was that there wasn't a 'switch' (feel free to correct me if I'm using incorrect terms here) for whether or not the layer you created in the C:makelayer list was set to plot. I thought it would be good practice for me to try & add this in order to gain some more knowledge about how all this works.

Doing some research, I found that the DXF code for the plotting flag was 290. (I found this from HERE (http://www.autodesk.com/techpubs/autocad/acad2000/dxf/)). By working my way through your code, I simply added a (cons 290 plotflag) to the list you make in layercreate. Then, down in the laylist for c:makelayer, I added either a 1 or a 0 (assuming the plot flag is a binary switch - I couldn't confirm this) to represent whether I wanted the layer to plot or not.

Then, where you are actually creating each layer in the laylist, I see where you have your car's, cadr's, caddr's and cadddr. And you lost me. I can't seem to find out/figure out how to add the fourth object in the laylist to the layer creation.

Can you give me some hints as to how I might add the fourth (maybe even fifth - lineweights) object type?

Here's where I'm at so far:
Code: [Select]
;-------------------------------------------------------------------------------------------------
(defun unlockthawlayers (/)
  (vlax-map-collection
    (vla-get-layers
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (cond ((eq (vla-get-lock x) :vlax-true)
      (setq lock (cons x lock))
      (vla-put-lock x :vlax-false)
     )
       )
       (cond ((eq (vla-get-freeze x) :vlax-true)
      (setq freeze (cons x freeze))
      (vla-put-freeze x :vlax-false)
     )
       )
     )
  )
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun relockfreezelayers (/)
  (if lock
    (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    lock
    )
  )
  (if freeze
    (mapcar '(lambda (x)
       (vl-catch-all-apply 'vla-put-freeze (list x :vlax-true))
     )
    freeze
    )
  )
  (setq lock nil)
  (setq freeze nil)
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun layercreate (layname color linetype desc / lyr)
  (if (not (tblobjname "ltype" linetype))
    (setq linetype "continuous")
  )
  (if (tblsearch "layer" layname)
    (progn
      (setq lyr (vlax-ename->vla-object (tblobjname "layer" layname)))
      (vla-put-color lyr color)
      (vla-put-linetype lyr linetype)
    )
    (setq lyr (vlax-ename->vla-object
(entmakex
  (list (cons 0 "LAYER")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbLayerTableRecord")
(cons 70 0)
(cons 2 layname)
(cons 62 color)
(cons 6 linetype)
(cons 290 plotflag)
  )
)
      )
    )
  )
  (vla-put-description lyr desc)
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun C:MakeLAYER (/ CCL LAYLIST)
  (unlockthawlayers)
  (setvar "cmdecho" 0)
  (setq ccl (getvar "clayer"))
  (setq laylist '(("TEST LAYER 01"
   3
   "continous"
   "TESTING LAYER 01"
   1
  )
  ("TEST LAYER 02"
   1
   "DASHED"
   "TEST LAYER 02"
   0
  )
  ("TEST LAYER 03"
   51
   "CENTER"
   "Testing layer 03"
   0
  )
)
  )
  (foreach lyr laylist
    (layercreate (car lyr) (cadr lyr) (caddr lyr) (cadddr lyr) (cadadr lyr))
    (princ (strcat "\n Layer - " (car lyr) " created..."))
  )
  (setvar "clayer" ccl)
  (relockfreezelayers)
  (princ)
)
;-------------------------------------------------------------------------------------------------
Title: Re: LayerStates
Post by: ronjonp on February 28, 2008, 01:38:22 PM
Have a look at this:

I only made changes to two lines...

You have to add the argument of plot status to the function.
(defun layercreate (layname color linetype desc plotflag / lyr)

Nth may be easier to visualize (0 is the first element, 1 is the second.....)
(layercreate (nth 0 lyr) (nth 1 lyr) (nth 2 lyr) (nth 3 lyr) (nth 4 lyr))

HTH :)

Code: [Select]
;-------------------------------------------------------------------------------------------------
(defun unlockthawlayers (/)
  (vlax-map-collection
    (vla-get-layers
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (cond ((eq (vla-get-lock x) :vlax-true)
      (setq lock (cons x lock))
      (vla-put-lock x :vlax-false)
     )
       )
       (cond ((eq (vla-get-freeze x) :vlax-true)
      (setq freeze (cons x freeze))
      (vla-put-freeze x :vlax-false)
     )
       )
     )
  )
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun relockfreezelayers (/)
  (if lock
    (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    lock
    )
  )
  (if freeze
    (mapcar '(lambda (x)
       (vl-catch-all-apply 'vla-put-freeze (list x :vlax-true))
     )
    freeze
    )
  )
  (setq lock nil)
  (setq freeze nil)
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun layercreate (layname color linetype desc plotflag / lyr)
  (if (not (tblobjname "ltype" linetype))
    (setq linetype "continuous")
  )
  (if (tblsearch "layer" layname)
    (progn
      (setq lyr (vlax-ename->vla-object (tblobjname "layer" layname)))
      (vla-put-color lyr color)
      (vla-put-linetype lyr linetype)
    )
    (setq lyr (vlax-ename->vla-object
(entmakex
  (list (cons 0 "LAYER")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbLayerTableRecord")
(cons 70 0)
(cons 2 layname)
(cons 62 color)
(cons 6 linetype)
(cons 290 plotflag)
  )
)
      )
    )
  )
  (vla-put-description lyr desc)
  (princ)
)
;-------------------------------------------------------------------------------------------------
(defun C:MakeLAYER (/ CCL LAYLIST)
  (unlockthawlayers)
  (setvar "cmdecho" 0)
  (setq ccl (getvar "clayer"))
  (setq laylist '(("TEST LAYER 01"
   3
   "continous"
   "TESTING LAYER 01"
   1
  )
  ("TEST LAYER 02"
   1
   "DASHED"
   "TEST LAYER 02"
   0
  )
  ("TEST LAYER 03"
   51
   "CENTER"
   "Testing layer 03"
   0
  )
)
  )
  (foreach lyr laylist
    (layercreate (nth 0 lyr) (nth 1 lyr) (nth 2 lyr) (nth 3 lyr) (nth 4 lyr))
    (princ (strcat "\n Layer - " (car lyr) " created..."))
  )
  (setvar "clayer" ccl)
  (relockfreezelayers)
  (princ)
)
;-------------------------------------------------------------------------------------------------
Title: Re: LayerStates
Post by: mpeterson79 on February 28, 2008, 02:06:20 PM
Ah yes - fantastic! I find the nth argument to be much easier to follow. I really have a hard time with car's, cdr's & such.


Thanks for your help!
Title: Re: LayerStates
Post by: ronjonp on February 28, 2008, 02:28:04 PM
Glad we got it figured out :)
Title: Re: LayerStates
Post by: KewlToyZ on March 03, 2008, 02:53:58 PM
I have an issue using the following:
Code: [Select]
;==========================================================================================================================================
(command "._-layer" "state" "save" "KTA-Scripted" "color" "" "" "unlock" "*" "thaw" "*" "on" "*" "")  ;===================Save Layer Settings
(prompt "\nLayer State Saved!!!")
;==========================================================================================================================================

;run some layer color settings and routines

;==========================================================================================================================================
(command "._-layer" "state" "restore" "KTA-Scripted" "" "" "")    ;===================Restore Layer Settings
(command "._-layer" "state" "delete" "KTA-Scripted" "" "" "")
(prompt "\nLayer State Restored and Deleted !!!")
;==========================================================================================================================================


The problem is that the Color is a toggle so some drawings toggle it back to Yes instead of No and make the routine pretty much a null.