LAYMRG by Layer COLOR

LAYMRG by Layer COLOR

4co2op0
Contributor Contributor
5,118 Views
25 Replies
Message 1 of 26

LAYMRG by Layer COLOR

4co2op0
Contributor
Contributor

Hello All,

 

I have a base file from the CIVIL and I must convert all of the CIVIL's layers to different layer names/colors to meet another companies layer standards. All of the CIVIL layers have been assigned colors that are typical for all of drawing plot settings

 

Example: Civil file has layers such as Curb (color 150), Curb-back (color 150), Curb-face (color 150), Curb-Gutter (color 8), Curb-Drain (color 113)...

 

I need to merge all the "color 150" layers to a generic "CURB" layer, the "color 8" layers need to change to a generic "GUTTER" layer, and the "color 113" layers need to change to a generic "DRAIN" layer.

 

When using the LAYERMANAGER I can sort by color and select all "color 150" layers, right click and merge the layers to the new desired layer name. Then select all "color 8" layers and merge to the desired layer, then select all "color 113" layers and merge to that desired layer. This process does work very well, but when doing this to 100's of drawing files it is very redundant and time consuming. 

 

If it is possible to setup a LISP routine that will automate this process by changing all desired layers that are on a specific COLOR to a different specified layer it would save me hours of time per week and make the learning curve for new drafters quite a bit easier.

 

I have tried the LAYTRANS command and it almost works except for the layer name problems such as *CURB* would also select the "CURB-DRAIN" layer and "CURB-GUTTER" layer which will not work for my use.

 

Any suggestions are greatly appreciated. TYIA

 

NOTE: I am not very good at creating LISP routines. I have adjusted pre-made LISP routines to fit my needs in the past and also created VERY VERY Basic LISP routines as well but this is beyond my ability. I also read that the LAYMRG command doesnt quite work right in LISP routines but I am hoping someone can point me in the right direction for a solution to my "desires"

 

-Matt

 

 

0 Likes
Accepted solutions (2)
5,119 Views
25 Replies
Replies (25)
Message 2 of 26

john.vellek
Alumni
Alumni

HI @4co2op0,

 

I can move this thread to the customization forum for you where you can get help on LISP routines but I wonder why the LAYTRANS is not working for you. I know it will take time to map individual CURB- layers instead of using a wildcard but it should pretty much be a one time operation. Can you attach some sample files of what you are working with and perhaps I can make other suggestions?

 

 

Please select the Accept as Solution button if my post solves your issue or answers your question.


John Vellek


Join the Autodesk Customer Council - Interact with developers, provide feedback on current and future software releases, and beta test the latest software!

Autodesk Knowledge Network | Autodesk Account | Product Feedback
0 Likes
Message 3 of 26

Kent1Cooper
Consultant
Consultant

This seems to do that [very lightly tested]:

 

(defun C:LCC ; = Layer Consolidation by Color
  (/ LCClist ss n obj)
  (setq LCClist
    '(
      (1 . "RedLayers")
      (2 . "YellowLayers")
      (3 . "GreenLayers")
      (8 . "GUTTER")
      (113 . "DRAIN")
      (150 . "CURB")
    ); list
  ); setq
  (setq ss (ssget "_X")); everything
  (repeat (setq n (sslength ss))
    (vla-put-Layer
      (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n)))))
      (cdr (assoc (vla-get-Color (vlax-ename->vla-object (tblobjname "layer" (vla-get-Layer obj)))) LCClist))
    ); ...put-Layer
  ); repeat
  (princ)
); defun

 

NOTE a few things....

 

It does everything in the drawing, but could be made to do the transfer only to objects that you select.

 

It assumes the Layer names already exist in the drawing, and that everything in the drawing will be on some Layer whose color is one of those in the list, but it could be made to leave alone anything that's on some Layer with a color that isn't in the list, or put such things on some none-of-the-above Layer.

 

It changes the Layer of each object based on the color assigned to its current Layer, ignoring any override color that may be assigned to the object itself, so override colors will remain.  It could be made, instead, to force everything to be ByLayer in color in the process, or if you prefer, to change the Layer of objects with override colors to a Layer whose color matches the color override, not to the Layer whose color matches that of the object's Layer.

Kent Cooper, AIA
Message 4 of 26

4co2op0
Contributor
Contributor

Sorry about the post location, I figured this was where it should be posted. Feel free to move it! Thank you.

 

As for LAYTRANS, it will not work because we actually receive files from many different CIVIL/ARCH/SURVEY firms and their Layer descriptions very a great deal and it would be impossible to set up every instance (A large portion could be addressed but it is never very consistent and so it just isn't going to work for our needs) and when a new instance arrives it will create its own set of problems as well (and there are always new description variation coming through).

 

We actually adjust the layers in each BASE file we receive to be on OUR layer colors standards first thing so that our plotting (CTB) looks as it should. That is a process we must do for each drawing when adding our design work to it. Down the line we convert all layers to the generic/simple layer standards of a company we must send the file to with all xref's bound and exploded (I dont like their requirements but that is out of my control). Its that final process that is eating up more time than I think it should. If there is a way to LAYMRG based on designated colors, then it will not matter what the LAYER NAMES are, only what color that Layer is set to. 

 

I don't NEED to use LAYMRG, I am mainly just using that as an example of the process we currently use and explaining how it works very well, but automating the fairly simple process would be ideal, even if using an entirely different command all together.

0 Likes
Message 5 of 26

john.vellek
Alumni
Alumni

HI @4co2op0,

 

No worries! You picked a good starting spot for this query. I have moved your thread but suggest that you also take a look at the Autodesk App Store to see if there are any tools there that might help.

 

 

Please select the Accept as Solution button if my post solves your issue or answers your question.


John Vellek


Join the Autodesk Customer Council - Interact with developers, provide feedback on current and future software releases, and beta test the latest software!

Autodesk Knowledge Network | Autodesk Account | Product Feedback
Message 6 of 26

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

.... 

NOTE a few things.....


Another one:  It does not get rid of the original Layers as LAYMRG would.  I suppose it could be made to, but it sounds like your process could use a general PURGE when you've taken care of everything anyway, which can cover more than just Layers.

Kent Cooper, AIA
0 Likes
Message 7 of 26

4co2op0
Contributor
Contributor

I will give this a shot and report back (an overload of work right now prevents me from testing it now but it sounds like it may work). Thank you!

0 Likes
Message 8 of 26

DannyNL
Advisor
Advisor
Accepted solution

Try this one. It makes use of the LAYMGR as mentioned by Kent.

 

The color of a layer is leading for the merging, so it doesn't matter what the original name of the layer is. If the layer color is 8 it will be merged to layer GUTTER, if it's 113 to layer DRAIN, etc.. You can expand the T_LayMatrix as needed, as long as each color is a unique value in the list.

 

Code could probably be a bit more optimized but it does the job.

 

(defun c:Test (/ T_LayMatrix T_LayConfig)
   (setvar "CMDECHO" 0)
   (setvar "CLAYER" "0")
   (setq T_LayMatrix
      '(
          (8   . "GUTTER")
          (113 . "DRAIN")
          (150 . "CURB")
       )
   )
   (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
   (foreach T_Item (GetLayers)
      (if
         (setq T_LayConfig (assoc (car T_Item) T_LayMatrix))
         (progn
            (if
               (not (tblsearch "LAYER" (cdr T_LayConfig)))
               (command "-LAYER" "N" (cdr T_LayConfig) "C" (car T_LayConfig) (cdr T_LayConfig) "")
            )
            (command "-LAYMRG")
            (foreach T_Lay (cadr T_Item)
               (if
                  (/= T_Lay (cdr T_LayConfig))
                  (command "N" T_Lay)
               )
            )
            (command "" "N" (cdr T_LayConfig) "Y")
         )
      )
   )
   (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
   (setvar "CMDECHO" 1)
   (princ)
)

(defun GetLayers (/ GL_Layer GL_Color GL_Name GL_Return)
   (setq GL_Layer (tblnext "Layer" T))
   (while
      GL_Layer
      (if
         (/= (setq GL_Name (cdr (assoc 2 GL_Layer))) "0")
         (if
            (not (assoc (setq GL_Color (cdr (assoc 62 GL_Layer))) GL_Return))
            (setq GL_Return (append GL_Return (list (list GL_Color (list GL_Name)))))
            (setq GL_Return (subst (list GL_Color (append (cadr (assoc GL_Color GL_Return)) (list GL_Name))) (assoc GL_Color GL_Return) GL_Return))
         )
      )
      (setq GL_Layer (tblnext "Layer"))
   )
   GL_Return
)
   

 

Message 9 of 26

john.uhden
Mentor
Mentor

That's very good, Danny, but I have a very strong suspicion that there are plenty of other layers that are color 113, or 8, or 150, that are for a large variety of site improvements or conditions.  Changing gas pipes to curb lines (or vice versa) will wreak havoc on the designer trying to figure out where to place his new storm drains.

 

I am afraid he will have to have a (oldcolor . newcolor) matrix instead, retaining the original layer names.  This is especially true when dealing with the Port Authority of New York / New Jersey.  We were lucky to have had a civil tech who knew the Authority's requirements thoroughly.  We just budgeted his time to scroll through the layer dialog and change colors and linetypes by eye.

 

This to me is a clear cut case of where the contract with the surveyor must require that the surveyor adhere to his superiors' standards in names and colors and linetypes, or they must budget for a tech to perform the conversions.

John F. Uhden

0 Likes
Message 10 of 26

DannyNL
Advisor
Advisor

You are probably right John, but I thought to get started with something that matches the description of the OP.

It shouldn't be to hard to expand the code and include some wildcard matching for the layer names as well, but that depends on the respons of Matt Smiley Wink

0 Likes
Message 11 of 26

john.uhden
Mentor
Mentor

Whadayamean "probably?"  Of course I'm right.  Smiley Wink

John F. Uhden

0 Likes
Message 12 of 26

DannyNL
Advisor
Advisor

LOL Smiley Very Happy

0 Likes
Message 13 of 26

4co2op0
Contributor
Contributor

John, I do understand your point but for my situation I would prefer that everything on the specified color is switched to the specified layer name, and the old layer name will be purged out completely. There are definitely colors that I will not be adding to the list because of the results you mentioned but knocking out the color specific layers will save me a ton of time.

 

If it is possible to add wildcard matches as well, that would be so GREAT! for instance, all of the wet utilities are actually on color 113 based on our standards, and so water, sewer, storm drain will all need to be separated accordingly and adding 113 to the list as is would certainly create the nightmare you mention. I was using the colors as an example but there are some variations. 8 is only and always gutter, 150 is only and always curb, etc.. and so those colors will be solved quickly and I like that.

 

I have been very busy so havn't had time to mess with it but i am going to test it in a few minutes.

 

 

0 Likes
Message 14 of 26

4co2op0
Contributor
Contributor

Thank you Danny! I tested it and it works as described and does exactly what i needed it to do with the color based code. 

 

I also tried Kents code but I got an error:

 

"Command: LCC
; error: ActiveX Server returned an error: Parameter not optional"

 

Now I am curious how I would go about adding in the wildcard string.

 

For instance, 113 has water, storm drain, and sewer, as well as Fire Hydrants and Catch basins which also need to be on a different FINAL layer and  different civil's use different naming. (we place all on 113 manually and I may change our standards to have them on unique colors in order to utilize this lisp and save time unless the wildcard can be pretty specific)

 

Water can be spelled out or labled as WTR, or WAT, or FIRE, Reclaimed... etc...

Sewer could be spelled out or labeled as SWR, SEW... etc...

Storm Drain could be spelled out or labeled as SD, STRM, Drain... etc...

Hydrants = FH, HYD... etc...

 

One issue I see that may prevent the wildcard use in some situations is (example) the Hydrants have a prefix (or suffix) of Water a lot of the times, so an  layer named "water_FH" on color 113 would be changed to the water layer when i really need it to be on an FH layer in the end.

 

Honestly, the code as provided is excellent and I am beyond appreciative for your assistance (all of you!). If adding wildcard info is going to be too intense and have too many issues please ignore that request. but if you have a simple solution that you can suggest then I am all ears. Also note that I am still curious how the wildcard would be added because that will be very useful on other colors that are a bit more simple.

 

All in all if the wildcard is not possible as I requested then I may just adjust out color standards to have a few more color specific objects and use the code as is.

 

Again, Thank you so much for all your help.

 

(AND SORRY IF THIS RESPONSE WAS A LITTLE CRAZY AND HECTIC. I am heading out for vacation and will be back next week. Have a great Thanksgiving all)

0 Likes
Message 15 of 26

DannyNL
Advisor
Advisor
Accepted solution

You're welcome.

 

And here is the code enabling wildcard matching as well.

Again the code could be probably a bit more optimized, so if anyone else has the time to dig in and can keep the code human readable (!) be my guest.

 

The T_LayMatrix variable enables you to give none, one or more wildcards for layer name filtering.

In all cases the current color of the layer is leading, so in the example code a layer with the name Water_FH and color 113 will end up on layer FH, while a layer with the name Name1_FH and color 1 will not.

 

If you configure the T_LayMatrix please keep in mind the order of filtering. In the current order a layer with the name Water_FH and color 113 will be merged onto layer FH. But if you turn around the filtering so i.e. (113 "DRAIN") is put before (113 "FH" ("*"FH")), all layers with color 113 will be merged onto layer DRAIN first and there will be no layers left to put on FH or WATER. So the first match will be leading.

 

(defun c:Test (/ T_LayMatrix T_VarName T_LayerSetList T_MergeList T_WildcardList T_ProcessList)
   (setvar "CMDECHO" 0)
   (setvar "CLAYER" "0")
   (setq T_LayMatrix
      '(
          (8   "GUTTER")
          (113 "FH"    ("*FH"))
          (113 "WATER" ("*WTR" "*WAT" "*FIRE" "*RECLAIMED"))
          (113 "DRAIN")
          (150 "CURB")
       )
   )   
   (foreach T_Item (GetLayers (mapcar 'cadr T_LayMatrix))
      (set (read (setq T_VarName (strcat "T_LayerSet_" (itoa (car T_Item))))) (cadr T_Item))
      (setq T_LayerSetList (append T_LayerSetList (list T_VarName)))
   )
   (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
   (foreach T_Item T_LayMatrix
      (setq T_MergeList nil)
      (cond
         (
            (and
                (setq T_WildcardList (nth 2 T_Item))
                (setq T_ProcessList (eval (read (strcat "T_LayerSet_" (itoa (car T_Item))))))
            )
            (foreach T_Layer T_ProcessList
               (foreach T_Wildcard T_WildcardList
                  (if
                     (and
                        (not (member T_Layer T_MergeList))
                        (wcmatch (strcase T_Layer) (strcase T_Wildcard))
                     )
                     (progn
                        (setq T_MergeList (append T_MergeList (list T_Layer)))
                        (set (read (strcat "T_LayerSet_" (itoa (car T_Item)))) (vl-remove T_Layer (eval (read (strcat "T_LayerSet_" (itoa (car T_Item)))))))
                     )
                  )
               )
            )
         )
         (
            (and
                (not (nth 2 T_Item))
                (setq T_ProcessList (eval (read (strcat "T_LayerSet_" (itoa (car T_Item))))))
            )
            (foreach T_Layer T_ProcessList                                  
               (setq T_MergeList (append T_MergeList (list T_Layer)))
               (set (read (strcat "T_LayerSet_" (itoa (car T_Item)))) (vl-remove T_Layer (eval (read (strcat "T_LayerSet_" (itoa (car T_Item)))))))
            )
         )
         (
            T
            nil
         )
      )
      (if
         T_MergeList
         (progn
            (if
               (not (tblsearch "LAYER" (nth 1 T_Item)))
               (command "-LAYER" "N" (nth 1 T_Item) "C" (nth 0 T_Item) (nth 1 T_Item) "")
               (command "-LAYER"                    "C" (nth 0 T_Item) (nth 1 T_Item) "")
            )
            (command "-LAYMRG")
            (foreach T_Lay T_MergeList
               (command "N" T_Lay)               
            )
            (command "" "N" (nth 1 T_Item) "Y")
         )
      )      
   )                        
   (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
   (foreach T_Item T_LayerSetList
      (set (read T_Item) nil)
   )   
   (setvar "CMDECHO" 1)
   (princ)
)

(defun GetLayers (GL_IgnoreList / GL_Layer GL_Color GL_Name GL_Return)
   (setq GL_Layer (tblnext "Layer" T))
   (while
      GL_Layer
      (if
         (and
            (/= (setq GL_Name (cdr (assoc 2 GL_Layer))) "0")
            (not (member GL_Name GL_IgnoreList))
         )
         (if
            (not (assoc (setq GL_Color (cdr (assoc 62 GL_Layer))) GL_Return))
            (setq GL_Return (append GL_Return (list (list GL_Color (list GL_Name)))))
            (setq GL_Return (subst (list GL_Color (append (cadr (assoc GL_Color GL_Return)) (list GL_Name))) (assoc GL_Color GL_Return) GL_Return))
         )
      )
      (setq GL_Layer (tblnext "Layer"))
   )
   GL_Return
)

 

 

Message 16 of 26

4co2op0
Contributor
Contributor
Amazing! This is so great. I will be spending some time refining these wildcards to work with our current standards. Looks like it will be exactly what we needed. I really do appreciate all the help. I think I'm going to take a class or 2 for writing lisp routines like this so I can pay it forward as well. So thankful!
0 Likes
Message 17 of 26

Kent1Cooper
Consultant
Consultant

@4co2op0 wrote:

.... 

I also tried Kents code but I got an error:

 

"Command: LCC
; error: ActiveX Server returned an error: Parameter not optional"

....


It may not matter if you have something that works, but....

 

Since it sounds from other posts as though you have Layers of colors that are not  among your conversion needs, the problem could be in my "example" other-color entries in the list.  It may work if you take those out, that is, eliminate these lines:

 

      (1 . "RedLayers")
      (2 . "YellowLayers")
      (3 . "GreenLayers")

 

I tested it in a drawing that had only Layers with your 8 / 113 / 150 colors assigned, and it worked.  I put those others in the list only to illustrate that you can include more than just the colors you mentioned, but it would  require you to have Layers in the drawing to move appropriate things to, and I would assume those Layer names I used as examples are highly unlikely.

Kent Cooper, AIA
Message 18 of 26

john.uhden
Mentor
Mentor

I've been thinking about your layer name problem.

I think you need a 4-coulumn Excel or easier a CSV file containing

Old Color, Old Names, New Name, New Color

150,CURB*,CURB,8

etc.

etc.

etc.

 

The program reads the file and puts each line into a list, e.g. ((150 "CURB*" "CURB" 8) etc.)

Then you roll though all the layers in your drawing and compare the color and name using wcmatch, and create any new layers as required.

Then you roll through each object in every block checking for color and name matches and change the object's layer accordingly.

In the same iteration, build a list of all the layers that are being converted.

At the end, vla-delete each layer in the list, or you could skip the list and just purge all layers ("*").

 

Over time, you keep adding any new layers with colors to the CSV.  Notice I used "CURB*" in the example to enable wildcard matches to keep the file size and processing down.

 

John F. Uhden

0 Likes
Message 19 of 26

4co2op0
Contributor
Contributor

Danny, Just to clarify.

 

when this is first 

          (113 "WATER" ("*WTR" "*WAT" "*FIRE" "*RECLAIMED")

does it completely ignore all other items on color 113 that do not fit into the wildcard search?

 

or another way of wording that, If each line has a wildcard specified, will it leave the ones that do not match that wildcard alone so that I can go back through anything that is still on 113 and manually change them if needed? If so then I will not insert a line without wildcards and that would protect me from losing anything that hasnt been addressed.

0 Likes
Message 20 of 26

4co2op0
Contributor
Contributor

Hello Danny, I am having a bit of an issue with the second code you uploaded. When I run the command it is changing the color of my predefined layers. I have the NEW CURB layer on color 10, the OLD CURB colors are 150, When I run the command it changes the NEW CURB layer to color 150. I am able to restore the layer state and correct this but perhaps you can point in the right direction for what controls that in the code so I can make the adjustment. I beleive the first one you posted without the wildcards was not changing the NEW CURB layer color.

0 Likes