Jump to content
hosannabizarre

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

Recommended Posts

hosannabizarre

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.

Share this post


Link to post
Share on other sites
BIGAL

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

Share this post


Link to post
Share on other sites
BIGAL

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.

Share this post


Link to post
Share on other sites
hosannabizarre

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

Share this post


Link to post
Share on other sites
hosannabizarre

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

Share this post


Link to post
Share on other sites
hosannabizarre

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

Share this post


Link to post
Share on other sites
BIGAL

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

Share this post


Link to post
Share on other sites
hosannabizarre

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

 

Cheers

Share this post


Link to post
Share on other sites
VVA
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))))

Share this post


Link to post
Share on other sites

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
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  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...