000

Index Labels

Highlight Selected Entity With DrawableOverrule

.
Every AutoCAD user is used to the fact that when an entity is selected, AutoCAD highlights the entity. However, the default highlight (dashed line) is not that eye-catching enough to satisfy particular drafting need.

I recently worked on a project to converting a fairly complicated VBA program. At a point during that VBA program progress, the VBA program converts the colors of a SelectionSet of entities into a highlight color (for example, yellow, or red), and converts the colors of all the rest of entities into a contrast color. This makes the selected entities much more visually stand out.

Although this achieves the goal of making some entities more eye-catching, it certainly has its drawbacks: it has to change almost all entities in the drawing database, just for the temporary visual effect. If something goes wrong that causes exception, it may leave the entities/drawing in unwanted state (i.e. in a color it should not be).

With Overrule, which was introduced into .NET API since AutoCAD 2010, customizing how an Entity is highlighted becomes an much easier task. There is even a HighlightOverrule class we can use (see one of my old post here ).

However, the HighlightOverrule isn't good enough to meet my need in the VBA conversion project. Besides highlighting the selected entities user selected, it also wants all entities that are not selected are in a plain/dull color so that the selected entities are visually stand-out, visually emphasized. So, I decided to give it a try of using DrawableOverrule. The code presented here is different from what I actually used in the project because of the specific business requirement, though.

Here is the code for a class called HighlightDrawableOverrule:

Code Snippet
  1. using System.Collections.Generic;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.GraphicsInterface;
  5. using Autodesk.AutoCAD.Runtime;
  6.  
  7. namespace SelectionHighlightOverrule
  8. {
  9.     public class HighlightDrawableOverrule : DrawableOverrule
  10.     {
  11.         private int _foreColorIndex;
  12.         private int _backColorIndex;
  13.         private bool _origialOverruling = false;
  14.         private List<ObjectId> _highlightEnts;
  15.         private bool _started = false;
  16.  
  17.         public HighlightDrawableOverrule(int foreColor, int backColor)
  18.         {
  19.             _foreColorIndex = foreColor;
  20.             _backColorIndex = backColor;
  21.             _highlightEnts = new List<ObjectId>();
  22.         }
  23.  
  24.         public bool Started
  25.         {
  26.             get { return _started; }
  27.         }
  28.  
  29.         public ObjectId[] SelectedEntIds
  30.         {
  31.             get { return _highlightEnts.ToArray(); }
  32.         }
  33.  
  34.         public HighlightDrawableOverrule(int foreColor,
  35.             int backColor, ObjectId[] entIds) : this(foreColor, backColor)
  36.         {
  37.             _highlightEnts.AddRange(entIds);
  38.         }
  39.  
  40.         public void Start()
  41.         {
  42.             _origialOverruling = DrawableOverrule.Overruling;
  43.  
  44.             DrawableOverrule.AddOverrule(
  45.                 RXClass.GetClass(typeof(Entity)), this, true);
  46.             DrawableOverrule.Overruling = true;
  47.             _started = true;
  48.  
  49.             Regen();
  50.         }
  51.  
  52.         public void Stop()
  53.         {
  54.             DrawableOverrule.RemoveOverrule(
  55.                 RXClass.GetClass(typeof(Entity)), this);
  56.             DrawableOverrule.Overruling = _origialOverruling;
  57.             _started = false;
  58.  
  59.             Regen();
  60.         }
  61.  
  62.         public void AddHightlightEntities(ObjectId[] entIds)
  63.         {
  64.             bool added = false;
  65.             foreach (var id in entIds)
  66.             {
  67.                 if (!_highlightEnts.Contains(id))
  68.                 {
  69.                     _highlightEnts.Add(id);
  70.                     if (!added) added = true;
  71.                 }
  72.             }
  73.  
  74.             if (_started && added) Regen();
  75.         }
  76.  
  77.         public void RemoveHighlightEntities(ObjectId[] entIds)
  78.         {
  79.             bool removed = false;
  80.             foreach (var id in entIds)
  81.             {
  82.                 if (!_highlightEnts.Contains(id))
  83.                 {
  84.                     _highlightEnts.Remove(id);
  85.                     if (!removed) removed = true;
  86.                 }
  87.             }
  88.  
  89.             if (_started && removed) Regen();
  90.         }
  91.  
  92.         public void ClearHightlightEntities()
  93.         {
  94.             _highlightEnts.Clear();
  95.             if (_started) Regen();
  96.         }
  97.  
  98.         public override bool WorldDraw(Drawable drawable, WorldDraw wd)
  99.         {
  100.             wd.SubEntityTraits.Color = (short)_backColorIndex;
  101.  
  102.             if (_highlightEnts.Count > 0)
  103.             {
  104.                 Entity ent = drawable as Entity;
  105.                 if (ent != null)
  106.                 {
  107.                     if (_highlightEnts.Contains(ent.ObjectId))
  108.                         wd.SubEntityTraits.Color = (short)_foreColorIndex;    
  109.                 }
  110.             }
  111.  
  112.             return base.WorldDraw(drawable, wd);
  113.         }
  114.  
  115.         private void Regen()
  116.         {
  117.             Application.DocumentManager.MdiActiveDocument.Editor.Regen();
  118.         }
  119.     }
  120. }

The code is fairly simple and straightforward: it draws all entities except for the selected in a background color and all selected entities in a highlighted color.

Here is the example of how the HighlightDrawableOverrule class is used:

Code Snippet
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. [assembly: CommandClass(typeof(SelectionHighlightOverrule.MyCommands))]
  7.  
  8. namespace SelectionHighlightOverrule
  9. {
  10.     public class MyCommands
  11.     {
  12.         [CommandMethod("HighlightSel")]
  13.         public static void HighlightedSelection()
  14.         {
  15.             Document dwg = Application.DocumentManager.MdiActiveDocument;
  16.             Editor ed = dwg.Editor;
  17.  
  18.             int foreColor = 2;  //Yellow
  19.             int backColor = 7;  //White
  20.  
  21.             ObjectId[] selectedIds = null;
  22.  
  23.             using (HighlightDrawableOverrule hOverrule =
  24.                 new HighlightDrawableOverrule(foreColor, backColor))
  25.             {
  26.                 hOverrule.Start();
  27.                 while (true)
  28.                 {
  29.                     PromptEntityOptions opt =
  30.                         new PromptEntityOptions("\nPlease pick an entity:");
  31.                     PromptEntityResult res = ed.GetEntity(opt);
  32.                     if (res.Status == PromptStatus.OK)
  33.                     {
  34.                         hOverrule.AddHightlightEntities(
  35.                             new ObjectId[] { res.ObjectId });
  36.                     }
  37.                     else
  38.                     {
  39.                         break;
  40.                     }
  41.                 }
  42.  
  43.                 hOverrule.Stop();
  44.                 selectedIds = hOverrule.SelectedEntIds;
  45.             }
  46.  
  47.             ed.WriteMessage("\n{0} entitit{1} selected.",
  48.                 selectedIds.Length, selectedIds.Length>1?"ies":"y");
  49.         }
  50.     }
  51. }

This video clip shows the effect of running the "HighlightSel" command.

As you can see, using Overrule to change entity's color for temporary visual effect is definitely better than what one have to do in VBA: the entity's color property is not changed at all, thus the draw database remain unchanged, although AutoCAD presents a different color as you needed.

Notice that Editor.Regen() has to be called when the DrawableOverrule started/stopped and when ObjectId is added into selected entity list. If the drawing database is huge, it may take too much time to Regen().

Blog Archive

Labels

3D Modeling 3D Sketch Inventor AI Design AI in Manufacturing AI Tools Architecture Artificial Intelligence AutoCAD AutoCAD advice AutoCAD Basics AutoCAD Beginners AutoCAD Civil3D AutoCAD commands AutoCAD efficiency AutoCAD features AutoCAD File Management AutoCAD Layer AutoCAD learning AutoCAD print settings AutoCAD productivity AutoCAD Teaching AutoCAD Techniques AutoCAD tips AutoCAD training. AutoCAD tricks AutoCAD Tutorial AutoCAD workflow AutoCAD Xref Autodesk Autodesk 2025 Autodesk AI Tools Autodesk AutoCAD Autodesk Fusion 360 Autodesk Inventor Autodesk Inventor Frame Generator Autodesk Inventor iLogic Autodesk Recap Autodesk Revit Autodesk Software Autodesk Video Automation Automation Tutorial Basic Commands Basics Beginner Beginner Tips BIM BIM Implementation Block Editor ByLayer CAD comparison CAD Design CAD File Size Reduction CAD line thickness CAD Optimization CAD Productivity CAD software clean CAD file cleaning command Cloud Collaboration command abbreviations Construction Technology Contraints Create resizable blocks CTB STB Data Reference Data Shortcut design software Design Workflow Digital Design Digital Twin Drafting Standards Drawing Automation Dref Dynamic Block Dynamic Block AutoCAD Dynamic Blocks Dynamic doors Dynamic windows eco design editing commands energy efficiency Engineering Engineering Design Engineering Innovation Engineering Technology engineering tools Excel Express Tools External Reference Fast Structural Design Fusion 360 Generative Design green building Grips heavy CAD file Heavy CAD Files iLogic Industry 4.0 Insight Inventor API Inventor Drawing Template Inventor Frame Generator Inventor Graphics Issues Inventor IDW Inventor Tips Keyboard Shortcuts Learn AutoCAD Machine Learning in CAD maintenance command Management Manufacturing Innovation Metal Structure ObjectARX .NET API Organization OVERKILL OVERKILL AutoCAD Palette PDF Plot Style AutoCAD Practice Drawing Printing Quality professional printing Professional Tips PTC Creo PURGE PURGE AutoCAD ReCap reduce CAD file size Resizable Block Revit Revit Best Practices Revit Workflow Ribbon screen shortcut keys Shortcuts Siemens NX Sketch Small Firms Smart Block Smart Factory SolidWorks Steel Structure Design sustainability Sustainable Manufacturing toolbar Tutorial User Interface (UI) Workbook Workspace XLS Xref