Adjust Lisp to include block on zero layer

Adjust Lisp to include block on zero layer

mattv4F4AG
Explorer Explorer
828 Views
13 Replies
Message 1 of 14

Adjust Lisp to include block on zero layer

mattv4F4AG
Explorer
Explorer

Hi, I came across this very helpful lisp on here that allows changing layer colors quickly in xrefs or live in a drawings. It doesnt appear to work on blocks where the linework within the block is on the 0 layer. Any idea how to fix this? I think its changing the 0 layer color itself but not the color of the layer the block is on. Is there way to make it so if it sees a 0 layer, it goes one level up to the block instead?

 

(defun c:clc (/ c d e l)
;; RJP » 2018-08-17
;; Set layer color by pick
(or (getenv "clc") (setenv "clc" "(62 . 1)"))
(cond ((setq c (acad_truecolordlg (read (getenv "clc"))))
(setenv "clc" (vl-prin1-to-string (last c)))
(setq d (vla-get-activedocument (vlax-get-acad-object)))
(while (and (setq e (car (nentsel "\nSelect entity to change layer color: ")))
(setq l (tblobjname "layer" (cdr (assoc 8 (entget e)))))
)
(entmod (append (entget l) c))
(vla-regen d acactiveviewport)
)
)
)
(princ)
)
(vl-load-com)

0 Likes
Accepted solutions (1)
829 Views
13 Replies
Replies (13)
Message 2 of 14

Moshe-A
Mentor
Mentor

@mattv4F4AG ,

 

the lisp is ok. the reason it does not changes the colors of zero layer objects is because the block is inserted in another layer, all its internal objects originally build on layer 0 are 'moving' properties actually inheriting the color + ltype (and other) of the layer the block is in.

 

if you change the block layer to 0, you will get what you want but this may change the properties of the block that you do not want - dilemma - Ha?!

 

Moshe

 

0 Likes
Message 3 of 14

Kent1Cooper
Consultant
Consultant

@mattv4F4AG wrote:

... this very helpful lisp ... that allows changing layer colors quickly in xrefs or live in a drawings ... doesnt appear to work on blocks where the linework within the block is on the 0 layer. .... its changing the 0 layer color itself but not the color of the layer the block is on. Is there way to make it so if it sees a 0 layer, it goes one level up to the block instead?

....


Yes, (nentsel) "sees" the most-deeply-nested Layer of the sub-object you select, which will be 0 if it was drawn there in the Block definition.   You can find the deepest non-0 Layer on which a nested entity resides [where it "appears"] with code that's part of LayerQuellPick.lsp, >here<.  Look at the code starting with:

....

    (if (= (cdr (assoc 8 edata)) "0"); on Layer 0

....

It "steps up" the Layers of nesting until it finds one that is not 0, and works with that Layer name.  That routine turns it off or freezes it, but the same can be used to change its color.

Kent Cooper, AIA
0 Likes
Message 4 of 14

Moshe-A
Mentor
Mentor

@mattv4F4AG 

 

got up this morning on my right side 😀

try this fix

 

moshe

 

 

(defun c:clc (/ c d e l)
 ;; RJP » 2018-08-17
 ;; Set layer color by pick
 (or (getenv "clc") (setenv "clc" "(62 . 1)"))
  
 (cond
  ((setq c (acad_truecolordlg (read (getenv "clc"))))
   (setenv "clc" (vl-prin1-to-string (last c)))
   (setq d (vla-get-activedocument (vlax-get-acad-object)))

   (while (setq pick (nentsel "\nSelect entity to change layer color: "))
    (if (not (eq (type (setq e (last pick))) 'ENAME))
     (setq e (car pick))
    )
     
    (setq l (tblobjname "layer" (cdr (assoc 8 (entget e)))))
    (entmod (append (entget l) c))
    (vla-regen d acactiveviewport)
   ); while
  ); case
 ); cond
 (princ)
)

 

0 Likes
Message 5 of 14

mattv4F4AG
Explorer
Explorer

@Moshe-A  I gave this a try and it doesn't appear to work on blocks where linework is on 0 layer live in the file or in xref. Does it work for you? For me its functioning the same as the original. I appreciate you working with me on this.

0 Likes
Message 6 of 14

mattv4F4AG
Explorer
Explorer

@Kent1Cooper That sounds like exactly what I need. I tried brining in the section of code you mentioned, but I'm getting some errors.Can you possibly show me what the lisp will look like after you insert that code section? 

0 Likes
Message 7 of 14

Kent1Cooper
Consultant
Consultant
Accepted solution

Try this [minimally tested]:

 

(defun c:clc (/ c d esel edata layc nestlist nlayc)
;; RJP » 2018-08-17; enhanced by Kent Cooper 4 Nov 2022 for nested Layer 0
;; Set layer color by pick
  (or (getenv "clc") (setenv "clc" "(62 . 1)"))
  (cond
    ((setq c (acad_truecolordlg (read (getenv "clc"))))
      (setenv "clc" (vl-prin1-to-string (last c)))
      (setq d (vla-get-activedocument (vlax-get-acad-object)))
      (while
        (and
          (setq esel (nentsel "\nSelect entity to change layer color: "))
          (setq edata (entget (car esel)))
        ); and
        (setq layc ; = LAYer to change Color of
          (if (= (cdr (assoc 8 edata)) "0"); on Layer 0
            (cond ; then
              ((> (length esel) 2); nested entity [other than Attribute] in Block/Xref
                (setq nestlist (last (nentselp (cadr esel)))); stack of references it's nested in
                (while
                  (and
                    nestlist ; still nesting level(s) remaining
                    (= (setq nlayc (cdr (assoc 8 (entget (car nestlist))))) "0"); = Nested [non-0] LAYer to change Color of
                  ); and
                  (setq nestlist (cdr nestlist)); if was 0, move up a level if present
                ); while
                nlayc
                  ; lowest-level non-0 Layer of nested or containing reference(s); 0 if that all the way up
              ); non-Attribute nested entity on Layer 0 condition
              ((= (cdr (assoc 0 edata)) "ATTRIB"); Attribute in Block
                (cdr (assoc 8 (entget (cdr (assoc 330 edata))))); Block's Layer
              ); Attribute on Layer 0 condition
              ("0"); none-of-the-above condition
            ); cond - then
            (cdr (assoc 8 edata)); else - non-0 Layer of entity/nested entity
          ); if & layc
        ); setq
        (entmod (append (entget (tblobjname "layer" layc)) c))
        (vla-regen d acactiveviewport)
      ); while
    ); or
  ); cond
  (princ)
)
(vl-load-com)

 

The main thing is the (setq layc ... part, with slight adjustments to parts of your surrounding code to line up variables to work with that, and add all variables to the localized list.

Kent Cooper, AIA
0 Likes
Message 8 of 14

mattv4F4AG
Explorer
Explorer

@Kent1Cooper Works perfectly! Thank you.

0 Likes
Message 9 of 14

Moshe-A
Mentor
Mentor

@mattv4F4AG ,

 

yes you are right , check this

 

(defun c:clc (/ c d e l)
 ;; RJP » 2018-08-17
 ;; Set layer color by pick
 (or (getenv "clc") (setenv "clc" "(62 . 1)"))
  
 (cond
  ((setq c (acad_truecolordlg (read (getenv "clc"))))
   (setenv "clc" (vl-prin1-to-string (last c)))
   (setq d (vla-get-activedocument (vlax-get-acad-object)))

   (while (and
            (setq pick (nentsel "\nSelect entity to change layer color: "))
            (setq l (tblobjname "layer" (cdr (assoc 8 (entget (car pick))))))
          )
    (if (and
          (eq (cdr (assoc '8 l)) "0")
          (eq (type (last pick)) 'ENAME)
        )
     (setq l (tblobjname "layer" (cdr (assoc 8 (entget (last pick))))))
    )  
    
    (entmod (append (entget l) c))
    (vla-regen d acactiveviewport)
   ); while
  ); case
 ); cond
 (princ)
)
0 Likes
Message 10 of 14

Kent1Cooper
Consultant
Consultant


I don't think it's there yet.  If a selected sub-object is nested more than one level deep, then

(last pick)

will be not an entity but a list of the entity names of the Blocks it's nested in, and since that's not an ENAME, it will leave its Layer alone.  It looks like it will not look for the lowest-level nesting Block's Layer to change its color [if it's not 0], but will change only the top-most Block's Layer, no matter how many nesting levels there are.

Kent Cooper, AIA
0 Likes
Message 11 of 14

mattv4F4AG
Explorer
Explorer

Understood. I think for my purpose, this is more than adequate though. Most of the blocks I am working with in my drawings don't have nested blocks. Is there a way to get the undo function to work with this? I notice that I can't ctrl-z to undo if I select the wrong linework. 

0 Likes
Message 12 of 14

mattv4F4AG
Explorer
Explorer

@Kent1Cooper If its not too much trouble, could you help me to include the ctrl-z command during the routine to undo a color change if I accidently click a wrong line or block during the routine?

0 Likes
Message 13 of 14

Kent1Cooper
Consultant
Consultant

@mattv4F4AG wrote:

@Kent1Cooper If its not too much trouble, could you help me to include the ctrl-z command during the routine to undo a color change if I accidently click a wrong line or block during the routine?


I stole and adjusted that functionality from my ReverseDirection.lsp routine, >here<.  It seems to work here, in very limited testing:

;|Change Layer Color by picking object / nested object, but if nested
    object's Layer is 0, lowest-level non-0 nesting Layer up from there.
  RJP » 2018-08-17, enhanced by Kent Cooper 4 Nov 2022
    to prevent of change to nested Layer 0, add individual Undo within.
|;

(defun C:CLC (/ c d n done esel ent edata elay layc nestlist nlayc)
  (or (getenv "clc") (setenv "clc" "(62 . 1)")); red first-use default
  (cond
    ((setq c (acad_truecolordlg (read (getenv "clc")))); get color
      (setenv "clc" (vl-prin1-to-string (last c)))
      (setq
        d (vla-get-activedocument (vlax-get-acad-object))
        n 0 ; internal Undo counter
      ); setq
      (while (not done)
        (setvar 'errno 0)
        (if (> n 0) (initget "Undo")); Undo option only if things to undo
        (setq esel
          (nentsel
            (strcat
              "\nSelect object to change Layer color, or "
              (if (> n 0) "[Undo] " ""); Undo option only if things to undo
              "<exit>: "
            ); strcat
          ); entsel
        ); setq
        (cond ; overall object-selection or Undo option
          ((= esel "Undo")
            (setq n (1- n))
            (command "_.undo" "_back"); revert last color change
          ); Undo condition
          ( ; test for selection, unlocked Layer
            (and
              (= (getvar 'errno) 0); picked something
              (setq
                ent (car esel)
                edata (entget ent)
                elay (cdr (assoc 8 edata))
              ); setq
              (= (logand 4 (cdr (assoc 70 (tblsearch "layer" elay)))) 0)
                ; 0 = unlocked, 4 = locked
            ); and
            (command "_.undo" "_mark")
            (setq layc ; = LAYer to change Color of
              (if (= elay "0"); on Layer 0
                (cond ; then
                  ((> (length esel) 2); nested entity [other than Attribute] in Block/Xref
                    (setq nestlist (last (nentselp (cadr esel)))); stack of references it's nested in
                    (while
                      (and
                        nestlist ; still nesting level(s) remaining
                        (= (setq nlayc (cdr (assoc 8 (entget (car nestlist))))) "0"); = Nested [non-0] LAYer to change Color of
                      ); and
                      (setq nestlist (cdr nestlist)); if was 0, move up a level if present
                    ); while
                    nlayc
                      ; lowest-level non-0 Layer of nested or containing reference(s); 0 if that all the way up
                  ); non-Attribute nested entity on Layer 0 condition
                  ((= (cdr (assoc 0 edata)) "ATTRIB"); Attribute in Block
                    (cdr (assoc 8 (entget (cdr (assoc 330 edata))))); Block's Layer
                  ); Attribute on Layer 0 condition
                  ("0"); none-of-the-above condition
                ); cond - then
                elay; else - non-0 Layer of entity/nested entity
              ); if & layc
            ); setq
            (if (= (logand 4 (cdr (assoc 70 (tblsearch "layer" layc)))) 0); unlocked
              (progn ; then
                (entmod (append (entget (tblobjname "layer" layc)) c))
                (vla-regen d acactiveviewport)
                (setq n (1+ n)); for Undo option
              ); progn
              (alert "\nObject's lowest-nested non-0 Layer is locked."); else
            ); if
          ); picked-something condition
          ((= (getvar 'errno) 0); picked something, but ....
            (prompt "\nThat object is on a locked Layer --")
          ); non-qualifying condition
          ((= (getvar 'errno) 7) (prompt "\nNothing selected --"))
          ((setq done T)); Enter/space at Select-object prompt [errno = 52]; stop (while) loop
        ); cond -- selection or U or <exit>
      ); while
    ); got-color condition
  ); cond
  (princ)
); defun
(vl-load-com)

 

Kent Cooper, AIA
0 Likes
Message 14 of 14

Kent1Cooper
Consultant
Consultant

Here's an upgrade that also includes a Newcolor option, to change the color that is to be assigned to the Layers of selected objects/nested objects, within the running of the command so you don't need to end it and restart it to get a new color.

Kent Cooper, AIA
0 Likes