Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

change all to 0 layer, by layer, including block and block in block

40 REPLIES 40
SOLVED
Reply
Message 1 of 41
Anonymous
18948 Views, 40 Replies

change all to 0 layer, by layer, including block and block in block

Hi

I have a lot of block that consist hundred block in block in block, in some specyfic layer and they are colored (not by layer).

It is killing me go inside every block and change, by 0, color by layer. Is it possible to ask about that lisp?

What I need is simpely all in 0, even it is block in block in block.

I have tryed lisp from here, but it does not menat to change color-by layer, and does not go deep inside block in block.

http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/change-all-block-element-to-layer-0-w...

I someone who can help me?

Jo

 
 
 
40 REPLIES 40
Message 21 of 41
ВeekeeCZ
in reply to: Anonymous

I wouldn't say that... found the problem. I revised the code, simplified the new subroutine and it should work now... 

 

Spoiler
;Modified by BeekeeCZ
;Original by Lee Mac
;http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/change-all-to-0-layer-by-layer-including-block-and-block-in/td-p/5376995/page/2

(defun c:CBV	(/ block->0 subst-append subst-append-06 subst-lt2gray
		   idx lst sel )  
  
  (defun block->0 (blk / ent enx)
    (cond
      ((member blk lst))
      ((setq ent (tblobjname "block" blk))
       (while (setq ent (entnext ent))
	 (entmod (subst-append 8 "0"
		   (subst-lt2gray
		     (subst-append 62 256
		       (subst-append-06 6
			 (setq enx (entget ent)))))))
	 (if (= "INSERT" (cdr (assoc 0 enx)))
	   (block->0 (cdr (assoc 2 enx))))
	 
	 )
       (setq lst (cons blk lst))
       )
      )
    )
  
  (defun subst-append (key val lst / itm)
    (if (setq itm (assoc key lst))
      (subst (cons key val) itm lst)
      (append lst (list (cons key val)))
      )
    )

  (defun subst-lt2gray (lst /)
    (if (wcmatch (strcase (cdr (assoc 6 lst))) "CENTER,DASHED2,PHANTOM2")
      (subst '(62 . 9)
	     (assoc 62 lst)
	     lst)
      lst)
    )
  
  (defun subst-append-06 (key lst / itm str val)
    (if (setq itm (assoc key lst))
      (progn
	(setq str (strcase (cdr itm))
	      val (cond ((wcmatch str "CONTIN*S")
			 "ByBlock")
			((wcmatch str "CENTER2,BORDER*,DASHDOT*,DIVIDE,ACAD_ISO0[45689]W100,ACAD_ISO1[012345]W100,JIS_08_11,JIS_08_15,JIS_08_25,JIS_08_37,JIS_08_50,JIS_09_08,JIS_09_15,JIS_09_29,JIS_09_50,DOTTED_DASHED7")
			 "CENTER")
			((wcmatch str "DASHED,DOT,HIDDEN*,ACAD_ISO0[237]W100,JIS_02_0.7,JIS_02_1.0,JIS_02_1.2,JIS_02_2.0,JIS_02_4.0,SHORT_DASHED[56]")
			 "DASHED2")
			((cdr itm))))
	(subst (cons key val) itm lst))
      (append lst (list (cons key "ByBlock")))
      )
    )

  (if (setq sel (ssget '((0 . "INSERT"))))
    (progn
      (or (tblsearch "LTYPE" "CENTER")
	  (command "_.-LINETYPE" "_L" "CENTER" "" ""))
      (or (tblsearch "LTYPE" "DASHED2")
	  (command "_.-LINETYPE" "_L" "DASHED2" "" ""))
      (repeat (setq idx (sslength sel))
	(block->0 (cdr (assoc 2 (entget (ssname sel (setq idx (1- idx))))))))))
  (command "_.REGEN")
  (princ) 
)

PS. Since we are off-topic, next time create a new one with link to the old one.

Message 22 of 41
Anonymous
in reply to: ВeekeeCZ

Perfect! it works like a charm. Many thanks friend! I'll learn more about Lisp. It's so interesting.

Message 23 of 41
Anonymous
in reply to: Anonymous

Hi Lee,

 

With your blkto0 code, how would I make it convert the entities within the block to 'colour by block' rather than 'colour by layer'? After a bit of trial and error at trying to do it I came up empty handed.

 

Thanks 🙂

Message 24 of 41
Anonymous
in reply to: Anonymous

I figured it out in the end; turns out it was simpler than I thought 🙂

 

Change

(entmod (subst-append 8 "0" (subst-append 62 256 (setq enx (entget ent)))))

to

(entmod (subst-append 8 "0" (subst-append 62 0 (setq enx (entget ent)))))

to make the inside block entities colour be set to 'by block' rather than 'by layer'.

 

Thanks for the excellent lisp!

Message 25 of 41
Anonymous
in reply to: Lee_Mac

Hi,

 

Can you explain why variable lst is defined there?  It isn't used in that function, it isn't passed to functions as a parameter, it is used in other functions though.

 

 

(defun c:blkto0 ( / idx lst sel ent)

...

)

 

 

(defun block->0 ( blk / ent enx obj)

...

  ( (member blk lst))

...

)

Message 26 of 41
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

.... 

Can you explain why variable lst is defined there?  It isn't used in that function, it isn't passed to functions as a parameter, it is used in other functions though.

....


This line:

 

        (setq lst (cons blk lst))

 

after processing a Block, adds its Block name to the list of those already processed, so that if it gets to another of the same Block, this first (cond)ition:

    (cond
        (   (member blk lst))

 

will have the routine skip that one, since it's already been done.

Kent Cooper, AIA
Message 27 of 41
Anonymous
in reply to: Kent1Cooper

Thanks, but let me rephrase my question ...

 

It's about scope. 

 

lst is a local variable of c:blkto0 .  Is lst automatically available to block->0 because c:blkto0  calls block->0 ?

 

If I were writing this, I would be thinking of either

- decrlaring lst as a global var

- define block->0 inside c:blkto0.  Then inside block->0 I can use any variable that was declared in c:blkto0

- pass lst as a parameter.  Works fine, even for recursive functions (those do create a big stack if one is not careful).

 

What am I missing?

 

 

(EDIT: I come from other programming languages; every language has a different system of scope; I seem to be misunderstanding how LIPS scope exactly works)

 

 

 

Message 28 of 41
Kent1Cooper
in reply to: Anonymous

The lst variable is created and added to inside the block->0 routine.  If it were localized within that routine, then it would be gone when that routine is called again to process the next Block, so it wouldn't know what it had already dealt with, and would re-process Block names already processed.  That's why it's localized one level up, in the C:blkto0 command, so that the (repeat) function within that, while going through the Blocks and applying the routine, can skip re-processing.

 

If it were not localized at all [i.e. made global], it would "hang around" after the whole thing is done, but there's no reason for it to remain.

 

Defining the function inside the command looks [without analyzing too deeply] viable -- another way to do it [there are usually multiple ways to accomplish just about anything].

 

I don't see passing it as a parameter.  Presumably that would have to already exist when the function starts in order to be passed to it, but it needs to be at first nothing [so the first Block processed can't already be in it], and then created and added to within, to keep track of what it's already done.  It can't be a parameter passed as an empty list  to start, because unlike a text string or a selection set [which you can start empty and add to], a list can't start out empty -- a list with nothing in it is just nil.

Kent Cooper, AIA
Message 29 of 41
Anonymous
in reply to: Kent1Cooper

Thank you

Message 30 of 41
AIR_123
in reply to: Lee_Mac

Hi Lee, Thanks for great work.

Would it be possible to include little control options of what attributes are changed?
Say [Color:By_Block; Ltype: By_Layer; Lthk: By_Layer]

This way script it more flexible I think. I dont understand why Autodesk still did not included such functionality so far...

I'm aware of (SETBYLAYER) but its limited...

Thanks again!

Message 31 of 41
aruckerY7D6L
in reply to: Kent1Cooper

Blast from the past post here. Trent - thank you so much for your LISP! Is there a way to through in setting elevations to 0" and then run an overkill inside each block? This of course would only be for things needing to be 2D and not 3D objects. I have been using it to help clean up Revit to DWG background exports and just updated it to your 4 November version. I have tried to add

(vla-put-elevation obj "0") ; elevation to 0
(command "-overkill" "p" "" "")

to a couple of places but with no luck of it working even though the commands alone (while in block editor) do work as desired. Doing a few blocks by hand isn't an issue, but I have about 12000 blocks for the structure alone.

Message 32 of 41
Kent1Cooper
in reply to: aruckerY7D6L


@aruckerY7D6L wrote:

.... I have tried to add

(vla-put-elevation obj "0") ; elevation to 0....


"0" is a text string.  Try giving it zero as a number:

(vla-put-elevation obj 0)

Kent Cooper, AIA
Message 33 of 41
aruckerY7D6L
in reply to: Kent1Cooper

Thanks! where should I insert it into the code for best results you think? I am getting an  "Error: ActiveX Server returned the error: unknown name: Elevation"

Message 34 of 41
japplebach
in reply to: Kent1Cooper

Hello all,

This LISP is almost the exact thing I need. My organization controls ALL block properties on their layer in model space (linetype, lineweight and color). I am very LISP challenged. Is there anyway I could get a version that included all block properties being placed to ByLayer? If this already exists, please point me in that direction I have been searching for quite a while. 

 

japplebach_0-1650299199685.png

 

Thank you!

Message 35 of 41
Kent1Cooper
in reply to: japplebach


@japplebach wrote:

.... My organization controls ALL block properties on their layer in model space (linetype, lineweight and color). .... Is there anyway I could get a version that included all block properties being placed to ByLayer? ....


You should be able to just add a couple of lines to the code at Message 7 [untested]:

....

          (setq obj (vlax-ename->vla-object ent))
          (vla-put-layer obj "0"); to Layer 0
          (vla-put-color obj 256); color ByLayer

         (vla-put-linetype obj "ByLayer")

         (vla-put-lineweight obj -1)

          (if (wcmatch (vla-get-ObjectName obj) "*Dimension,*Leader")

....

 

EDIT:  There are more Properties you could consider adding, that you didn't mention [here for a Line -- could vary with object type]:

Kent1Cooper_1-1650305918976.png

Kent Cooper, AIA
Message 36 of 41
phartwell
in reply to: Lee_Mac

Brilliant! This has just solved my problem too. Many thanks.

Message 37 of 41
dsulz
in reply to: Lee_Mac

@Lee_Mac, I was wondering if you could help me.  Your block to zero code works great but I was wondering if you could edit it so that all layer colors are set to "bylayer" and exclude layers that are set to "noplot" from being set to layer "0"?  I have been trying to get this to work for days and have been unsuccessful.  Granted I am no good at coding and I just can't wrap my brain around how to make it work.  I would greatly appreciate your help.  

Message 38 of 41
Kent1Cooper
in reply to: dsulz


@dsulz wrote:

.... all layer colors are set to "bylayer" ....  


What do you really mean by that part?  A Layer's color cannot be set to "ByLayer" -- only an object's color can [including sub-objects like parts of Dimensions].

Kent Cooper, AIA
Message 39 of 41
john.uhden
in reply to: ВeekeeCZ

@Anonymous,

I use a different approach from the others.  It will attack every block, nested or not.  But I am confused.  Are those layer names or what look to be linetypes?

So, f'rinstance, an entity with linetype CENTER2 should be hardwired to color 9?

But if it's being changed to layer 0, then its linetype, if ByLayer, will be that of layer 0, which may not be CENTER2.

So, do you mean set the color 9 only if the entity is hardwired to linetype CENTER2, etc?

John F. Uhden

Message 40 of 41
dsulz
in reply to: Kent1Cooper

@Kent1Cooper, I need every object in the block to be set to color "bylayer" and every object set to the "0" layer except for objects that are already set to "noplot".  The "noplot" objects need to keep their layer name but the color changed to "bylayer" like everything else.  

 

Lee's code changes everything to layer zero but I need it to ignore the "noplot" layers.  I have been able to integrate the option to change the color to "bylayer" but can't get the code to skip the "noplot" layers. 

 

I've tried to add this plottable property from the autodesk help files with no success. 

(setq acadObj (vlax-get-acad-object))

(setq doc (vla-get-ActiveDocument acadObj))

 (vlax-for tempLayer (vla-get-Layers doc)

(if (= (vla-get-Plottable tempLayer) :vlax-true)

 

Any help incorporating this "noplot" check is much appreciated. 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report