Merging Layers List

Sam Manzella

Usenet Archive
Joined
Jan 12, 2004
Messages
25
Reaction score
0
Hello Everyone, I'm trying to figure out if there is an easy way (lisp maybe) to merge multiple layers into one layer, while retaining the linetype of the original layers, and maybe the colors too, but the retaining the colors is not as important as maintaining the linetype. Most of the entities drawn are bylayer, thus the problem with the linetypes. I know, I know... Why would we want to merge all our layers? It has to do with some legality stuff when we are working with certain contractors.

If anyone know of any tips and trick on how to do this, that would be greatly appreciated.

Thanks in advance for you help.

Sam
 
This will do it for most entities. You can enter just 1 ("layname"), or a few ("lay1, lay2, lay*"), or all ("*") layers to include to place on 1 layer. It does not do any checking of entities contained in blocks.

Jeff

; laymerge - Get all entities on specified layers, match entities' ; color & linetype to that of the parent layer if the ent's color ; and/or linetype were bylayer. ; Place objects on a specified, new or existing, layer ; format - (laymerge old_layers new_layer) ; example: (laymerge "FLR*,ELEC*" "FLOOR") ; standard wildcards are allowed in the old_ layers argument ; Jeff Mishler, January 2004

(defun laymerge (oldlays newlay / count ent lay layObj ss) (setq layObj (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) lay (vla-add layobj newlay) ) (if (setq ss (ssget "x" (list (cons 8 oldlays)))) (progn (setq count -1) (while (< (setq count (1+ count)) (sslength ss)) (setq ent (vlax-ename->vla-object (ssname ss count))) (if (eq (vla-get-color ent) 256) (vla-put-color ent (vla-get-color (vla-item layObj (vla-get-layer ent)))) ) (if (eq (strcase (vla-get-linetype ent)) "BYLAYER") (vla-put-linetype ent (vla-get-linetype (vla-item layObj (vla-get-layer ent)))) ) (vla-put-layer ent newlay) ) ) ) (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))) (princ)
)
 
Chip:
I do use AutoCAD 2002, and the Layer Translate command (laytrans) is great, but it changes the linetypes I want to retain from the old layer to the new layer definition. I Think Jeff has what I'm looking for, but for some reason, it's not working.

Jeff:
Thanks for the list, but it's not working. After I successfully load the lisp (load"laymerge.lsp"), and I type in LAYMERGE, I get the Unknown Command message at the command line. Am I doing something wrong here? (I copied and pasted your list into notepad just as you have it shown below, and saved the files as laymerge.lsp)

Thanks again,
Sam
 
Nevermind... I saw your example.... (ok, I'm slooowww!)

Works like a charm! Too bad it doesn't get into the blocks, otherwise it would be perfect!

Thank you,
Sam
 
ah... although I don't know if it will handle linetypes in the way you want...
 
Jason, you are right, LAYMRG moves the linotypes as well. The lisp that Jeff wrote works exactly the way I wanted the properties to move. Now if he could only manage to get into the blocks...(hint, hint..)

Thanks again,
Sam
 
Well, this works almost perfectly. If a block has entities on layers other than "0", the entities will change but the layers they were on can't be purged. I'm still not sure why this happens, but if I explode all inserted blocks and then purge, they go away. I know that we don't want to do that, so I will continue to search the Why? until I can find some reasonable answer.

Jeff

; laymerge - Get all entities on specified layers, match entities' ; color & linetype to that of the parent layer if the ent's color ; and/or linetype were bylayer. ; Place objects on a specified, new or existing, layer ; format - (laymerge old_layers new_layer) ; example: (laymerge "FLR*,ELEC*" "FLOOR") ; standard wildcards are allowed in the old_ layers argument ; Jeff Mishler, January 2004

(defun laymerge (oldlays newlay / count ent lay layObj ss) (setq layObj (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) lay (vla-add layobj newlay) blks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) ) (vlax-for blk blks (if (= (vla-get-isxref blk) :vlax-false) (progn (vlax-for x blk (if (not (= "AcDbBlockReference" (vla-get-objectname x))) (progn (if (eq (vla-get-color x) 256) ;;(vla-put-color x 8);for testing (vla-put-color x (vla-get-color (vla-item layObj (vla-get-layer x)))) ) (if (eq (strcase (vla-get-linetype x)) "BYLAYER") (vla-put-linetype x (vla-get-linetype (vla-item layObj (vla-get-layer x)))) ) (vla-put-layer x newlay) ) (vla-put-layer x newlay) ) ) ) ) ) (if (setq ss (ssget "x" (list (cons 8 oldlays)))) (progn (setq count -1) (while (< (setq count (1+ count)) (sslength ss)) (setq ent (vlax-ename->vla-object (ssname ss count))) (if (eq (vla-get-color ent) 256) ;;(vla-put-color ent 40);for testing (vla-put-color ent (vla-get-color (vla-item layObj (vla-get-layer ent)))) ) (if (eq (strcase (vla-get-linetype ent)) "BYLAYER") (vla-put-linetype ent (vla-get-linetype (vla-item layObj (vla-get-layer ent)))) ) (vla-put-layer ent newlay) ) ) ) (setvar "clayer" newlay) (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))) (princ)
)
 
Jeff,
Just a thought - instead of ssget, try iterating through the blocks collection. Remember that modelspace and paperspace are blocks! Therefore you'll get all objects including those in all of the block references. The only issue is the property of blocks that entities on layer "0" inside a block definition take on the properties of the block references' layer. In the code below you can comment out the line that excludes all objects on layer "0" - it just depends on how one creates their blocks.

jb

;;;
;;; Use - (jb:putlayer "A-Detl-Lite"(list "0" "A-Detl-Hevy" "A-Detl-Hdn2" "A-Detl-Fine")) ;;; ;;; (defun jb:putlayer (newlay oldlay / doc blocks) (setq doc (vlax-get (vlax-get-acad-object) "activedocument") blocks (vlax-get doc "blocks") layers (vlax-get doc "layers")) (vlax-for i blocks (vlax-for b i (if (vlax-property-available-p b "layer") (if (and (not (= (vlax-get b "layer") newlay)) (member (vlax-get b "layer") oldlay) (not (= (vlax-get b "layer")"0")) ;<-- comment this line out if you don't want to ignore objects on layer "0" ) (progn ;set the linetype to the object first (vlax-put b "linetype" (vlax-get (vlax-invoke layers "item" (vlax-get b "layer")) "linetype")) (vlax-put b "layer" newlay)))))))
 
Jeff:
I tried the new code, and it works, but you are right about the block issue. The hopes is to not explode blocks.

James:
I tried your code, and for some reason it didn't work. Does it work in conjunction with Jeff's routine? (I'm dumb about this stuff, so please excuse my ignorance...)

Thanks again for all your help. What you have now works great already.

Sam
 
Hi James,

I'm not exactly sure where to call the (vl-load-com) function, but the routine shown below seems to not make any changes at all, and I'm not sure why.

I load the routine through a putlayer.lsp where I pasted the information below. Once it loads, I get the JB:PUTLAYER prompt, so I follow the instructions you put in the lisp ;;; Use - (jb:putlayer "A-Detl-Lite"(list "0" "A-Detl-Hevy" "A-Detl-Hdn2" "A-Detl-Fine"))

I create a new layer and called it HAWA

At the command prompt, In my case, I tried the following two statements, but neither one of them made any changes:

1) Command: (jb:putlayer "HAWA"(list "*"))
nil

2) Command: (jb:putlayer "HAWA"(list "DEV" "CIR" "EQP-HID" "LTG"))
nil

The only message returned, was the "nil". Again, pardon my ignorance, but I also tried:

Command: (vl-load-com)(jb:putlayer "HAWA"(list "*"))

and that didn't work either.

I hope I explained clear enough.

Thanks again,
Sam
 
Sam,

Just some thoughts:
You might need to call (vl-load-com) before running mine. I do this is a menu and often forget about it.

If that doesn't do it could you be a little more specific about the errors you recieve and perhaps how exactly you call it, etc. More iformation will help in formulating a solution.

jb

;;;
;;; Use - (jb:putlayer "A-Detl-Lite"(list "0" "A-Detl-Hevy" "A-Detl-Hdn2" "A-Detl-Fine")) ;;; ;;; (defun jb:putlayer (newlay oldlay / doc blocks) (vl-load-com);<<<< added to load com services (setq doc (vlax-get (vlax-get-acad-object) "activedocument") blocks (vlax-get doc "blocks") layers (vlax-get doc "layers")) (vlax-for i blocks (vlax-for b i (if (vlax-property-available-p b "layer") (if (and (not (= (vlax-get b "layer") newlay)) (member (vlax-get b "layer") oldlay) (not (= (vlax-get b "layer")"0")) ;<-- comment this line out if you don't want to ignore objects on layer "0" ) (progn ;set the linetype to the object first (vlax-put b "linetype" (vlax-get (vlax-invoke layers "item" (vlax-get b "layer")) "linetype")) (vlax-put b "layer" newlay)))))))
 
Hi James,

I've tried it on different drawings, and it doesn't switch the layers over.

What I am trying to accomplish is this:

1) I have a normal MEP drawing with several layers (so a wild card would definitely be a plus). The layers in the drawing have bylayer defined colors and linetypes.

2) Ultimately, the goal is to create just 1 layer, and move all (50 or so) layers to the new single layer, while retaining the linetypes and colors from the layers those entities are being changed from. Example: I have M-HVAC on color 5 and Dashed Linetype and M-HVAC EQPM on color 3 with Dash-Dot Linetype. The new layer created would be called COMBINED (for example) and would be created with any color and let's say continuous linetype. Once the routine is executed, all entities would go on layer COMBINED, but the entities that were on M-HVAC will still have color 5 and Dashed linetype, and entities that were on M-HVAC-EQPM would still be on color 3 with a Dash-Dot linetype (but they would all be on COMBINED layer).

Jeff's routine works very well, and does exactly what I was hoping for. It has a flaw when blocks are created on Layer 0, because it will cause the block to inherit all the properties of the COMBINED layer. On the other hand, if the blocks are created on a certain layer (let's say M-HVAC), then it works correctly. The problem is that the layers that were used for the blocks that do convert properly (let's use M-HVAC as an example again) will somehow be retained in the drawing, meaning, even though the block changed to the new layer in its entirety, the M-HVAC layer cannot be purged.

I'm not sure why the routine you sent me is not working. Maybe I'm not executing it properly. I'm not sure. I've tried everything I could think of.

I hope that clarifies the issue, and thanks again for your help.

Sam
 
Your second option should have worked. The routine does't use the command function so it wouldn't recognize the wildcard "*"
2) Command: (jb:putlayer "HAWA"(list "DEV" "CIR" "EQP-HID" "LTG"))
nil

It would only return nil - but your saying that it didn't chage the entities in the drawing? The way I understood your request was to merge entities in a drawing from one layer to another applying the layer defined linetype to the entity. Is this not happening?

jb
 

Latest threads

Back
Top