Merging Layers List

Discussion in 'AutoCAD' started by Sam Manzella, Jan 12, 2004.

  1. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 12, 2004
    #1
  2. Sam Manzella

    Jeff Mishler Guest

    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)
    )
     
    Jeff Mishler, Jan 12, 2004
    #2
  3. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 12, 2004
    #3
  4. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 12, 2004
    #4
  5. Do you have the express tools? LAYMRG is the
    command you want.
     
    Jason Piercey, Jan 12, 2004
    #5
  6. ah... although I don't know if it will handle linetypes
    in the way you want...
     
    Jason Piercey, Jan 12, 2004
    #6
  7. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 12, 2004
    #7
  8. Sam Manzella

    Jeff Mishler Guest

    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 Mishler, Jan 13, 2004
    #8
  9. Sam Manzella

    James Buzbee Guest

    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)))))))
     
    James Buzbee, Jan 13, 2004
    #9
  10. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 14, 2004
    #10
  11. Sam Manzella

    Sam Manzella Guest

    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 Manzella, Jan 14, 2004
    #11
  12. Sam Manzella

    James Buzbee Guest

    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)))))))
     
    James Buzbee, Jan 14, 2004
    #12
  13. Sam Manzella

    Sam Manzella Guest

    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
     
    Sam Manzella, Jan 14, 2004
    #13
  14. Sam Manzella

    James Buzbee Guest

    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
     
    James Buzbee, Jan 14, 2004
    #14
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.