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.
I someone who can help me?
Jo
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by Lee_Mac. Go to Solution.
I wouldn't say that... found the problem. I revised the code, simplified the new subroutine and it should work now...
;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.
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 🙂
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!
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))
...
)
@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.
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)
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.
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!
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.
@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)
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"
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.
Thank you!
@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]:
@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.
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
@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.