Jump to content

Change colour of all objects within blocks in a drawing file using a batch process


Recommended Posts

Posted

I created an action macro to do the following:

 

1) Select all objects

2) Change the colour to "140"

 

I saved it as "ActMacro001"

 

I needed to apply this macro to heaps of files, and used the following batch process lisp (It applies ActMacro001 to files A.DWG, B.DWG, C.DWG etc):

 

[color=#ff0000]([/color][color=#0000ff]defun[/color] C:BATCH[color=#ff0000]([/color][color=#0000ff]/[/color] dwgs scr-name lsp-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]setq[/color] dwgs '[color=#ff0000]([/color][color=#ff00ff]"C:/A.DWG" "C:/B.DWG" "C:/C.DWG" "C:/D.DWG"[/color][color=#ff0000])[/color]
       scr-name [color=#ff00ff]"c:/tmp.scr"[/color]
       lsp-name [color=#ff00ff]"c:/batch.lsp"[/color]
 [color=#ff0000])[/color]
 (create-script scr-name dwgs lsp-name [color=#ff00ff]"(ChangeColour)"[/color] [color=#0000ff]T[/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]command[/color] [color=#ff00ff]"_.SCRIPT"[/color] scr-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]vl-file-delete[/color] scr-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]princ[/color][color=#ff0000])[/color]
[color=#ff0000])[/color]

[color=#ff0000]([/color][color=#0000ff]defun[/color] ChangeColour[color=#ff0000]([/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]command[/color] [color=#ff00ff]"ActMacro001"[/color][color=#ff0000])[/color]
[color=#ff0000])[/color]

[color=#ff0000]([/color][color=#0000ff]defun[/color] create-script[color=#ff0000]([/color]scr dwgs lsp cmd save [color=#0000ff]/[/color] f dwg[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]setq[/color] f [color=#ff0000]([/color][color=#0000ff]open[/color] scr [color=#ff00ff]"w"[/color][color=#ff0000])[/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]foreach[/color] dwg dwgs
   [color=#ff0000]([/color][color=#0000ff]progn[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color]
       [color=#ff0000]([/color][color=#0000ff]strcat[/color] [color=#ff00ff]"_.OPEN \""[/color] dwg [color=#ff00ff]"\""[/color][color=#ff0000])[/color] f
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color]
       [color=#ff0000]([/color][color=#0000ff]strcat[/color] [color=#ff00ff]"(load \""[/color] lsp [color=#ff00ff]"\")"[/color][color=#ff0000])[/color] f
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color] cmd f[color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]if[/color] save
       [color=#ff0000]([/color][color=#0000ff]write-line[/color] [color=#ff00ff]"_.QSAVE"[/color] f[color=#ff0000])[/color]
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color] [color=#ff00ff]"_.CLOSE"[/color] f[color=#ff0000])[/color]
   [color=#ff0000])[/color]
 [color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]close[/color] f[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]princ[/color][color=#ff0000])[/color]
[color=#ff0000])[/color]

 

 

I have discovered now that some of the drawings which had the macro applied had blocks. All elements aside from the blocks were changed to colour 140. Now I want to improve my macro, or lisp routine, such that all elements within blocks are changed to colour 140, along with non block elements. Is there a way to automate the changing of block definitions with repect to nested object colour??

 

Would greatly appreciate some insight on this problem.

Posted

Search for here for block routines all you need to do is cut out the bit you want and add it to your code or just add another "load" command in your script.

 

heres a change linetype in all blocks

(vl-load-com) 
 (setq adoc (vla-get-activedocument (vlax-get-acad-object))) 
 (vla-startundomark adoc) 
 (vlax-for block (vla-get-blocks adoc) 
   (if   (not (wcmatch (strcase (vla-get-name block) t) "*_space*")) 
     (vlax-for   ent block 

(if  (= (vla-get-linetype ent ) "solid" ) 
(progn
(vla-put-linetype ent "Continuous")
(princ (vla-get-name block))
)
);_ end of if
   
  ) ;_ end of vlax-for 
     ) ;_ end of if 
   ) ;_ end of vlax-for 
 (vla-regen adoc acactiveviewport) 
 (vla-endundomark adoc) 
 (princ) 

 

pretty sure I have seen change colour here or just edit the code to reflect color rather than linetype

Posted

Just a bit extra if you have a lot of files to do why not look into using Start CMD dir *.dwg >mylist this creates a text file you can edit so your script does not have to have a list coded into it. You can create the list from it. There was pasted here a directory lisp/batch generator making the task of selecting dwgs easier. Can not remember what it was called.

Posted (edited)

BIGAL!!!! I have totally figured this out!!! I am convinced that I am extremely smart.

 

1) Use Visual Studio to Create a .dll file using this C# code by Kean Walmsley:

 

[color=#0000ff]using[/color] Autodesk.AutoCAD.ApplicationServices;
[color=blue]using[/color] Autodesk.AutoCAD.DatabaseServices;
[color=blue]using[/color] Autodesk.AutoCAD.EditorInput;
[color=blue]using[/color] Autodesk.AutoCAD.Runtime;
[color=blue]using[/color] Autodesk.AutoCAD.Colors;


[color=blue]namespace[/color] BlockTest
{
 [color=blue]public[/color] [color=blue]class[/color] [color=teal]BlockCmds[/color]
 {
   [[color=teal]CommandMethod[/color]([color=maroon]"CC"[/color])]
   [color=blue]public[/color] [color=blue]void[/color] ChangeColor()
   {
     [color=teal]Document[/color] doc =
       [color=teal]Application[/color].DocumentManager.MdiActiveDocument;
     [color=teal]Database[/color] db = doc.Database;
     [color=teal]Editor[/color] ed = doc.Editor;


     [color=teal]PromptIntegerResult[/color] pr =
       ed.GetInteger(
         [color=maroon]"\nEnter color index to change all entities to: "[/color]
       );


     [color=blue]if[/color] (pr.Status == [color=teal]PromptStatus[/color].OK)
     {
       [color=blue]short[/color] newColorIndex = ([color=blue]short[/color])pr.Value;
       [color=teal]ObjectId[/color] msId;
       [color=teal]Transaction[/color] tr =
         doc.TransactionManager.StartTransaction();
       [color=blue]using[/color] (tr)
       {
         [color=teal]BlockTable[/color] bt =
           ([color=teal]BlockTable[/color])tr.GetObject(
             db.BlockTableId,
             [color=teal]OpenMode[/color].ForRead
           );
         msId =
           bt[[color=teal]BlockTableRecord[/color].ModelSpace];


         [color=green]// Not needed, but quicker than aborting[/color]
         tr.Commit();
       }
       [color=blue]int[/color] count =
         ChangeNestedEntitiesToColor(msId, newColorIndex);
       ed.Regen();
       ed.WriteMessage(
         [color=maroon]"\nChanged {0} entit{1} to color {2}."[/color],
         count,
         count == 1 ? [color=maroon]"y"[/color] : [color=maroon]"ies"[/color],
         newColorIndex
       );
     }
   }


   [color=blue]private[/color] [color=blue]int[/color] ChangeNestedEntitiesToColor(
     [color=teal]ObjectId[/color] btrId, [color=blue]short[/color] colorIndex)
   {
     [color=blue]int[/color] changedCount = 0;
     [color=teal]Document[/color] doc =
       [color=teal]Application[/color].DocumentManager.MdiActiveDocument;
     [color=teal]Database[/color] db = doc.Database;
     [color=teal]Editor[/color] ed = doc.Editor;
     [color=teal]Transaction[/color] tr =
       doc.TransactionManager.StartTransaction();
     [color=blue]using[/color] (tr)
     {
       [color=teal]BlockTableRecord[/color] btr =
         ([color=teal]BlockTableRecord[/color])tr.GetObject(
           btrId,
           [color=teal]OpenMode[/color].ForRead
         );
       [color=blue]foreach[/color] ([color=teal]ObjectId[/color] entId [color=blue]in[/color] btr)
       {
         [color=teal]Entity[/color] ent =
           tr.GetObject(entId, [color=teal]OpenMode[/color].ForRead)
           [color=blue]as[/color] [color=teal]Entity[/color];


         [color=blue]if[/color] (ent != [color=blue]null[/color])
         {
           [color=teal]BlockReference[/color] br = ent [color=blue]as[/color] [color=teal]BlockReference[/color];
           [color=blue]if[/color] (br != [color=blue]null[/color])
           {
             [color=green]// Recurse for nested blocks[/color]
             changedCount +=
               ChangeNestedEntitiesToColor(
                 br.BlockTableRecord,
                 colorIndex
               );
           }
           [color=blue]else[/color]
           {
             [color=blue]if[/color] (ent.ColorIndex != colorIndex)
             {
               changedCount++;
               [color=green]// Entity is only open for read[/color]
               ent.UpgradeOpen();
               ent.ColorIndex = colorIndex;
               ent.DowngradeOpen();
             }
           }
         }
       }
       tr.Commit();
     }
     [color=blue]return[/color] changedCount;
   }
 }
}

 

 

2) Add the location of the .dll to the AutoCAD Search locations (I have called my .dll Change_Nested_Colour.dll, and it's in MyDocuments)

3) Make the lisp for the batch process netload the .dll you created, and input the colour value which the C# code asks for when run (I want colour 140).

4) Finished result =

 

[color=#ff0000]([/color][color=#0000ff]defun[/color] C:BATCH[color=#ff0000]([/color][color=#0000ff]/[/color] dwgs scr-name lsp-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]setq[/color] dwgs '[color=#ff0000]([/color][color=#ff00ff]"C:/A.DWG" "C:/B.DWG" "C:/C.DWG" "C:/D.DWG"[/color][color=#ff0000])[/color]
       scr-name [color=#ff00ff]"c:/tmp.scr"[/color]
       lsp-name [color=#ff00ff]"c:/batch.lsp"[/color]
 [color=#ff0000])[/color]
 (create-script scr-name dwgs lsp-name [color=#ff00ff]"(ChangeColour)"[/color] [color=#0000ff]T[/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]command[/color] [color=#ff00ff]"_.SCRIPT"[/color] scr-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]vl-file-delete[/color] scr-name[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]princ[/color][color=#ff0000])[/color]
[color=#ff0000])[/color]

[color=#ff0000]([/color][color=#0000ff]defun[/color] ChangeColour[color=#ff0000]([/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]command[/color] [color=#ff00ff]"_.netload" "Change_Nested_Colour.dll"[/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]command[/color] [color=#ff00ff]"CC"[/color][color=#ff0000])[/color]
[color=#ff0000][color=#ff0000] ([/color][color=#0000ff]command [/color][color=#ff00ff]"140"[/color][color=#ff0000])[/color][/color]
[color=#ff0000])[/color]

[color=#ff0000]([/color][color=#0000ff]defun[/color] create-script[color=#ff0000]([/color]scr dwgs lsp cmd save [color=#0000ff]/[/color] f dwg[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]setq[/color] f [color=#ff0000]([/color][color=#0000ff]open[/color] scr [color=#ff00ff]"w"[/color][color=#ff0000])[/color][color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]foreach[/color] dwg dwgs
   [color=#ff0000]([/color][color=#0000ff]progn[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color]
       [color=#ff0000]([/color][color=#0000ff]strcat[/color] [color=#ff00ff]"_.OPEN \""[/color] dwg [color=#ff00ff]"\""[/color][color=#ff0000])[/color] f
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color]
       [color=#ff0000]([/color][color=#0000ff]strcat[/color] [color=#ff00ff]"(load \""[/color] lsp [color=#ff00ff]"\")"[/color][color=#ff0000])[/color] f
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color] cmd f[color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]if[/color] save
       [color=#ff0000]([/color][color=#0000ff]write-line[/color] [color=#ff00ff]"_.QSAVE"[/color] f[color=#ff0000])[/color]
     [color=#ff0000])[/color]
     [color=#ff0000]([/color][color=#0000ff]write-line[/color] [color=#ff00ff]"_.CLOSE"[/color] f[color=#ff0000])[/color]
   [color=#ff0000])[/color]
 [color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]close[/color] f[color=#ff0000])[/color]
 [color=#ff0000]([/color][color=#0000ff]princ[/color][color=#ff0000])[/color]
[color=#ff0000])[/color]

 

 

This changes the colour of all the nested objects within blocks, in all the drawings in the list.

 

Now I just need to use your advice for removing the (long) drawing list from my lisp code and I'll feel like a total pro.

 

:D

Edited by hosannabizarre
Posted

And by the way, thanks for the linestyle changing code (potentially colour changing code). I was looking for something like this last week.

Posted

Thanks heaps VVA.

 

Re: colour

 

I tried out the colorx command and it works great.

 

I should probably have searched more thoughly before posting. Still, what I've posted above works fine (if you can be bothered making the .dll).

 

Re: batch

 

Yeah that main.bat is handy. I can certainly see how useful it would be for remapping layers across a drawing set.

 

It's like a more advanced/ customisable version of "laytrans", with batch capability.

 

Your pointers are much appreciated.

 

Спасибо

:D

Posted

search for this vl-get-directory-files

 

or findfiles old lisp

 

Should be some good examples of opening a directory and getting a list of dwg's check help also

Posted

Thanks BIGAL. I'd been using Altap Salamander to print directory filenames to text. There are other ways it seems.

 

Cheers

Posted
search for this vl-get-directory-files

 

or findfiles old lisp

 

Should be some good examples of opening a directory and getting a list of dwg's check help also

 

;|=EN============================================================================
* Function z-files-in-directory returns a list of files located in a given
* directory
*    Author: Vitaly Zuenko (ZZZ)
* Parameters:
*    Directory - path eg "D:\\my documents\\ZEF\\Lisp"
*    Pattern - template such as "*. lsp", or a list'("*. dwg "" *. dxf ")
*    Nested  -  search in subfolders: t (yes) or nil (no)
* Example call:
(Z-files-in-directory "D:\\my documents\\ZEF\\Lisp" "*. dwg" t)
(Z-files-in-directory "D:\\my documents\\ZEF\\Lisp"'("*. dwg "" *. dwt ") t)
=============================================================================|;
(defun z-files-in-directory (directory pattern nested /)
 (if (not (listp pattern))(setq pattern (list pattern)))
 (if nested (apply 'append (append (mapcar	'(lambda (_pattern)
  (mapcar '(lambda (f) (strcat directory "\\" f))
  (vl-directory-files directory _pattern 1)))	pattern) ;_ mapcar
  (mapcar '(lambda (d) (z-files-in-directory (strcat directory "\\" d)
  pattern nested))
 (vl-remove "." (vl-remove ".." (vl-directory-files directory nil -1))))))
 (apply 'append (mapcar '(lambda (_pattern)(mapcar '(lambda (f) (strcat directory "\\" f))
 (vl-directory-files directory _pattern 1))) pattern))))

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...