Author Topic: LayerStates  (Read 11679 times)

0 Members and 1 Guest are viewing this topic.

mpeterson79

  • Guest
Re: LayerStates
« Reply #15 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!


T.Willey

  • Needs a day job
  • Posts: 5251
Re: LayerStates
« Reply #16 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.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #17 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)
)
« Last Edit: February 27, 2008, 04:09:20 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

mpeterson79

  • Guest
Re: LayerStates
« Reply #18 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?

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #19 on: February 27, 2008, 04:28:56 PM »
Are you running (relockfreezelayers) at the end? I cannot duplicate what you are describing.

Ron

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

mpeterson79

  • Guest
Re: LayerStates
« Reply #20 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.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #21 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.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

mpeterson79

  • Guest
Re: LayerStates
« Reply #22 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.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: LayerStates
« Reply #23 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))
    )
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

mpeterson79

  • Guest
Re: LayerStates
« Reply #24 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)

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #25 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) :?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #26 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)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

T.Willey

  • Needs a day job
  • Posts: 5251
Re: LayerStates
« Reply #27 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.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: LayerStates
« Reply #28 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)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

mpeterson79

  • Guest
Re: LayerStates
« Reply #29 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....