Changing the colour of nested AutoCAD entities through .NET

Someone asked me earlier today how to iteratively change the color of entities inside blocks.

The following code uses a recursive helper function to iterate down through the contents of a block, changing the various entities (other than block references, for which we simply recurse) to a specified colour.

Here's the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Colors;

namespace BlockTest

{

  public class BlockCmds

  {

    [CommandMethod("CC")]

    public void ChangeColor()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

      PromptIntegerResult pr =

        ed.GetInteger(

          "\nEnter color index to change all entities to: "

        );

      if (pr.Status == PromptStatus.OK)

      {

        short newColorIndex = (short)pr.Value;

        ObjectId msId;

        Transaction tr =

          doc.TransactionManager.StartTransaction();

        using (tr)

        {

          BlockTable bt =

            (BlockTable)tr.GetObject(

              db.BlockTableId,

              OpenMode.ForRead

            );

          msId =

            bt[BlockTableRecord.ModelSpace];

          // Not needed, but quicker than aborting

          tr.Commit();

        }

        int count =

          ChangeNestedEntitiesToColor(msId, newColorIndex);

        ed.Regen();

        ed.WriteMessage(

          "\nChanged {0} entit{1} to color {2}.",

          count,

          count == 1 ? "y" : "ies",

          newColorIndex

        );

      }

    }

    private int ChangeNestedEntitiesToColor(

      ObjectId btrId, short colorIndex)

    {

      int changedCount = 0;

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

      Transaction tr =

        doc.TransactionManager.StartTransaction();

      using (tr)

      {

        BlockTableRecord btr =

          (BlockTableRecord)tr.GetObject(

            btrId,

            OpenMode.ForRead

          );

        foreach (ObjectId entId in btr)

        {

          Entity ent =

            tr.GetObject(entId, OpenMode.ForRead)

            as Entity;

          if (ent != null)

          {

            BlockReference br = ent as BlockReference;

            if (br != null)

            {

              // Recurse for nested blocks

              changedCount +=

                ChangeNestedEntitiesToColor(

                  br.BlockTableRecord,

                  colorIndex

                );

            }

            else

            {

              if (ent.ColorIndex != colorIndex)

              {

                changedCount++;

                // Entity is only open for read

                ent.UpgradeOpen();

                ent.ColorIndex = colorIndex;

                ent.DowngradeOpen();

              }

            }

          }

        }

        tr.Commit();

      }

      return changedCount;

    }

  }

}

10 responses to “Changing the colour of nested AutoCAD entities through .NET”

  1. Dear Kean

    I´m working with .Net and Autocad. I´m trying to run a rutine that change the color of an object (line), I know how
    to do this with one color, but i want to change the line in various colors, for example from red to green to yellow in intervals of time, the rutine must be run while i´m working
    in the draw ( for example while i´m doing zoom ) but i need the line back to the original color when i do a click (event)
    with the mouse. I can´t find the solution, can you help me ?!

  2. Kean Walmsley Avatar

    Dear Claudio,

    It's certainly possible to set a timer and cycle through colours on a set of objects - the issue is doing so during a realtime pan/zoom and also accessing the database in a safe way irrespective of what is happening in the editor.

    Frankly I'd look at leveraging the in-built selection highlighting mechanism inside AutoCAD, which would be much safer.

    Regards,

    Kean

  3. Kean,
    thanks for your info, but I am still stuck. I am using acad2006 - I have a folder full of small A3 drgs, each with a title block. I want to update the attributes of the Revision from A to B and insert "issued for construction" and the date etc. How can I do this using Global Attribute Editing techniques for Multiple drawings?
    Cheers
    TonyE

  4. TonyE,

    I suggest checking out this post.

    Regards,

    Kean

  5. TonyE,

    I suggest checking out this post.

    Regards,

    Kean

  6. Is it possible to get a version of this code where the user is prompted to create a selection set of nested objects first, and then being propted for the new colour of the objects?

    i.e is it possible to get the code for changing colour working the same way as it does for changing layer, as detailed here: keanw.com/2010/06/changing-the-layer-of-an-entity-in-an-autocad-block-using-net.html ?

    This would allow the user to pick and choose the objects affected, rather than making a blanket change to all nested objects.

    Cheers, Adam

  7. Kean Walmsley Avatar

    It's certainly feasible. I'll add it to my list of possible future topics.

    Kean

  8. Mayuresh Watharkar Avatar
    Mayuresh Watharkar

    Hi Kean,
    Thanks for the detailed implementation. I used this code for coloring selected block-reference. It worked fine for me except one problem. In my architectural drawing I have 2 sofas(block references) that are referring the same block(sofa). I want to color one of them. But, if I colorize one sofa, the other one also gets that color. Is there any way to fix this?

    Regards,
    Mayuresh

  9. Hi Mayuresh,

    The typical way would be to have the geometry you want coloured differently to be done so "by block" or "by layer". At least that's my understanding.

    Regards,

    Kean

Leave a Reply to Adam Cancel reply

Your email address will not be published. Required fields are marked *