Author Topic: Improved Layer-off command  (Read 2730 times)

0 Members and 1 Guest are viewing this topic.

matthewj

  • Newt
  • Posts: 42
  • Vanilla
Improved Layer-off command
« on: April 08, 2010, 11:06:41 PM »
I've been working on an improved layer-off command.  The improvements are an undo specific to this layer off command and the ability to turn off multiple layers at once.  Not super complicated; but I am rather proud of it (I'm still learning).  :-D  If anyone has any ideas, thoughts or criticisms I'd love to hear them.

usage:
LO - layer off
OL - layer off undo

(Notice there is a distinct lack of error handling right now. I'll get to that later... scout's honor.)

-cheers

Code: [Select]
;setvar cmdecho shortcut
(if (= echo nil)(defun echo( temp / )(setq old_cmdecho (getvar "cmdecho"))(setvar "cmdecho" temp)))

;set undo shortcut
(if (= undo nil)(defun undo( temp / )(command "undo" temp)))


;#####################
;###   Layer Off   ###
;#####################
;version 2.6

;Improved Layer Off command. (shortcuts: "LO" & "OL")
; This silly command provides:
; 1. The ablility to turn off multiple layers at once.
; 2. The ability to turn those layers back on by entering "OL".  Works
;    like a layer-off specific undo.

; Error handling not implimented yet.


(defun c:lo( / i eset layName splat table_list layer_off_list)

(setq eset (ssget))
(echo 0)(undo "begin")
  ;get selected entity layer names
    (if eset
      (progn
        (setq i 0)
        (while (< i (sslength eset))
          ;get layer names
 (setq layName(cdr(assoc 8 (entget (ssname eset i)))))
  ;build list of layers to turn off - get rid of duplicate layer names
  (if (not (member layName layer_off_list))
    (setq layer_off_list (cons layName layer_off_list))
  )
          (setq i(+ i 1))
        ) ;while

;turn off layers in list
        (foreach i layer_off_list
          ;set layer_off_sets to layer name from each in list
  (setq table_list (entget (tblobjname "layer" i)))
  (setq splat (- (cdr(assoc 62 table_list))))
  (setq table_list (subst (cons 62 splat) (assoc 62 table_list) table_list))
  (entmod table_list)
) ;foreach
      ) ;progn
      (princ "\n Nothing Selected!")
    ) ;if

    ;append this list of layers (this "set") to a list of sets
    ;this allows us to turn the layers back on (stores up to 7 sets)
    (if (= layer_off_sets nil)
      (setq layer_off_sets (cons layer_off_list nil))
      (progn
        (setq layer_off_sets (cons layer_off_list layer_off_sets))
        (while (< 7 (length layer_off_sets))
          (setq layer_off_sets (reverse (cdr (reverse layer_off_sets))))
        ) ;while
      ) ;progn
    ) ;if

    (undo "end")(echo old_cmdecho)
    (princ)
) ;defun


;The "ol" (on layer) command will turn on the previous layer set
(defun c:ol ( / i splat table_list)
  (echo 0)(undo "begin")

  ;turn on previous set of layers
  (foreach i (car layer_off_sets)
    (setq table_list (entget(tblobjname "layer" i)))
    (setq splat (abs (cdr (assoc 62 table_list))))
    (setq table_list (subst (cons 62 splat) (assoc 62 table_list) table_list))
    (entmod table_list)
  );foreach

  ;remove this layer set from storage
  (setq layer_off_sets (cdr layer_off_sets))

  (undo "end")(echo old_cmdecho)
  (princ)
)
« Last Edit: April 09, 2010, 11:13:01 AM by matthewj »

matthewj

  • Newt
  • Posts: 42
  • Vanilla
Re: Improved Layer-off command
« Reply #1 on: April 09, 2010, 07:48:43 PM »
I probably should have been clearer: are there any things you would have done differently?  Are there any mistakes or oversights that anyone can point out?  I've learned a lot by lurking about on the board, but much like chess I find it valuable to interact with people who are more skilled; the learning quotient jumps a metric ton.

- thanks (& enjoy your weekend!)

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Improved Layer-off command
« Reply #2 on: April 09, 2010, 08:01:25 PM »
Pretty good program, well done.  :-)

1 thing I would change:

Code: [Select]
    ;append this list of layers (this "set") to a list of sets
    ;this allows us to turn the layers back on (stores up to 7 sets)
    (if (= layer_off_sets nil)
      (setq layer_off_sets (cons layer_off_list nil))
      (progn
        (setq layer_off_sets (cons layer_off_list layer_off_sets))
        (while (< 7 (length layer_off_sets))
          (setq layer_off_sets (reverse (cdr (reverse layer_off_sets))))
        ) ;while
      ) ;progn
    ) ;if

Could be just:

Code: [Select]
(setq layer_off_sets (cons layer_off_list layer_off_sets))

I don't see the relevance of a limit of 7?

Lee

matthewj

  • Newt
  • Posts: 42
  • Vanilla
Re: Improved Layer-off command
« Reply #3 on: April 09, 2010, 10:42:34 PM »
Quote
Could be just:

Code:
Code: [Select]
(setq layer_off_sets (cons layer_off_list layer_off_sets))

I don't see the relevance of a limit of 7?

Thanks, the thought was to keep the list of deletions from growing super large.  I figure a user is unlikley to undo a layer-off more than three or four times at any given time.  Most of the time I only use it only once before moving on.  But I added a few more just in case; seven's just where it ended up.

Perhaps I shouldn't be so stingy, in the grand scheme of things getting rid of the limit won't cause any problems.  The sheer amount of data that autocad is dealing with makes this look like a drop in a pond.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Improved Layer-off command
« Reply #4 on: April 10, 2010, 07:53:19 AM »
Yeah, don't worry about the list getting too large - it will never get to the stage of using up too much memory (especially on the computers nowadays). And the variable is wiped from the document namespace when you close the drawing anyway.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Improved Layer-off command
« Reply #5 on: April 10, 2010, 08:15:16 AM »
For that kind of work, I still prefer the layer command:

Code: [Select]
(defun c:lo (/ i ss en el)
  (if (setq i -1
           ss (ssget))
      (progn
         (while (setq en (ssname ss (setq i (1+ i))))
                (setq el (strcase (cdr (assoc 8 (entget en)))))
                (if (not (member el LayOffList))
                    (setq LayOffList (cons el LayOffList))))
         (command "_.LAYER")
         (foreach l LayOffList
            (command "_Off" l))
         (command "")))
   (prin1))

(defun c:ol ()
  (if LayOffList
      (progn
        (command "_.LAYER")
        (foreach l LayOffList
           (command "_On" l))
        (command "")))
  (prin1))

No matter which, dealing with turning the current layer off probably should be addressed.  -David
R12 Dos - A2K

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Improved Layer-off command
« Reply #6 on: April 10, 2010, 12:58:07 PM »
For that kind of work, I still prefer the layer command:

Just out of curiosity, what do you do about trying to turn off the current layer, or do you keep the expert level higher than 0?
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Improved Layer-off command
« Reply #7 on: April 11, 2010, 06:10:49 AM »
My personal preference is to thaw and set layer 0.  I can't think of a scenario in my setup where I would turn 0 off.  I do freeze it sometimes, but not off.  -David
R12 Dos - A2K

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Improved Layer-off command
« Reply #8 on: April 11, 2010, 08:16:05 AM »
That seems the standard consensus. I guess I was just concerned since the above post does not account for that. I was just curious.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Improved Layer-off command
« Reply #9 on: April 11, 2010, 08:44:07 AM »
Another fun one, using a toggle  :-)

Code: [Select]
(defun c:lo (/ itemp MakeSelSet ss layers l tmp)
  (vl-load-com)
  ;; Lee Mac  ~  11.04.10

  (defun itemp (item coll / result)
    (if (not (vl-catch-all-error-p
               (setq result (vl-catch-all-apply
                              (function vla-item) (list coll item))))) result))
 
  (defun MakeSelSet (ref / SelSet SelSets)
    (if (setq SelSet (itemp ref (setq SelSets (vla-get-SelectionSets
                                                (vla-get-ActiveDocument
                                                  (vlax-get-acad-object))))))
      (vla-delete SelSet))
    (vla-Add SelSets ref))

  (or (progn (setq tmp *layeroff* *layeroff* nil) tmp)
      (progn
        (vla-SelectOnScreen (setq ss (MakeSelSet "LayerOff")))

        (if (< 0 (vla-get-count ss))
          (progn
            (vlax-for obj ss
              (or (vl-position (setq l (vla-get-Layer obj)) *layeroff*)
                  (setq *layeroff* (cons l *layeroff*))))
            (vla-delete ss)))))

  (setq layers (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
 
  (mapcar
    (function
      (lambda (layer) (setq l (itemp layer layers))
        (vlax-put l 'LayerOn (~ (vlax-get l 'LayerOn))))) (cond (*layeroff*) (tmp)))

  (princ))

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Improved Layer-off command
« Reply #10 on: April 11, 2010, 08:52:42 AM »
HaHa, nice. I wrote a Layer Isolate one a while back that works the same way.

Another fun one, using a toggle  :-)

Code: [Select]
(defun c:lo (/ itemp MakeSelSet ss layers l tmp)
  (vl-load-com)
  ;; Lee Mac  ~  11.04.10

  (defun itemp (item coll / result)
    (if (not (vl-catch-all-error-p
               (setq result (vl-catch-all-apply
                              (function vla-item) (list coll item))))) result))
 
  (defun MakeSelSet (ref / SelSet SelSets)
    (if (setq SelSet (itemp ref (setq SelSets (vla-get-SelectionSets
                                                (vla-get-ActiveDocument
                                                  (vlax-get-acad-object))))))
      (vla-delete SelSet))
    (vla-Add SelSets ref))

  (or (progn (setq tmp *layeroff* *layeroff* nil) tmp)
      (progn
        (vla-SelectOnScreen (setq ss (MakeSelSet "LayerOff")))

        (if (< 0 (vla-get-count ss))
          (progn
            (vlax-for obj ss
              (or (vl-position (setq l (vla-get-Layer obj)) *layeroff*)
                  (setq *layeroff* (cons l *layeroff*))))
            (vla-delete ss)))))

  (setq layers (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
 
  (mapcar
    (function
      (lambda (layer) (setq l (itemp layer layers))
        (vlax-put l 'LayerOn (~ (vlax-get l 'LayerOn))))) (cond (*layeroff*) (tmp)))

  (princ))
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

myloveflyer

  • Newt
  • Posts: 152
Re: Improved Layer-off command
« Reply #11 on: April 12, 2010, 03:12:22 AM »
NICE! Lee
Never give up !

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Improved Layer-off command
« Reply #12 on: April 12, 2010, 07:07:50 AM »