000

Index Labels

Highlight Attributes in BlockReference

.
An interesting question is posted in Autodesk's user discussion forum here, asking how to highlight attributes of a block (BlockReference, of course). The code posted in the question indicates that calling AttributeReference.Highlight() does nothing, which I have never tried (and never needed to), but have verified it with my own code.

Obviously, the method Highlight() of AttributeReference, although being derived from Entity, has its own overridden implementation, so that it behaves the same as its owner, the BlockReference.

Now that AttributeReference.Highlight() does not work, I thought looking into Overrule could lead to easy solution.

Naturally, I turned to HighlightOverrule first, which I posted an article about it a few years ago here. However, seeing the code in that article, I realize that it will not work, because the code still need to call AttributeReference.Highlight() inside the overridden Overrule's Hightlight() method.

As alternative, I tried to use DrawableOverrule. In this try, I successfully made AttributeRefernce being drawn in different colors (thus, a sort of "highlighting"). However, I have difficulties to make the attribute text showing in the way being highlighted in AutoCAD.

Nevertheless, using DrawableOverrule is a viable solution to "highlight" attribute. Since I have found a even better solution, I am not going to show the DrawableOverrule for attribute in this article (maybe later, if I can manage a bit time).

The solution I post here is to use Transient Graphics. The code is rather simple and does not need much explanation.

Here is the class called AttributeHighlighter:

    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using Autodesk.AutoCAD.DatabaseServices;
    5 using Autodesk.AutoCAD.Geometry;
    6 using Autodesk.AutoCAD.GraphicsInterface;
    7 
    8 namespace HighlightAttribute
    9 {
   10     public class AttributeHighlighter : IDisposable
   11     {
   12         private TransientManager _tManager =
   13             TransientManager.CurrentTransientManager;
   14         private List<Drawable> _entities = new List<Drawable>();
   15 
   16         public void Dispose()
   17         {
   18             DisposeDrawables();
   19         }
   20 
   21         public void Highlight(IEnumerable<ObjectId> blkIds)
   22         {
   23             DisposeDrawables();
   24 
   25             CollectDrawables(blkIds);
   26 
   27             foreach (var ent in _entities)
   28             {
   29                 _tManager.AddTransient(
   30                     ent,
   31                     TransientDrawingMode.Highlight,
   32                     128,
   33                     new IntegerCollection());
   34             }
   35         }
   36 
   37         public void Unhighlight()
   38         {
   39             _tManager.EraseTransients(
   40                 TransientDrawingMode.Highlight,
   41                 128,
   42                 new IntegerCollection());
   43         }
   44 
   45         private void DisposeDrawables()
   46         {
   47             foreach (var ent in _entities)
   48             {
   49                 ent.Dispose();
   50             }
   51 
   52             _entities.Clear();
   53         }
   54 
   55         private void CollectDrawables(IEnumerable<ObjectId> ids)
   56         {
   57             Database db = ids.First().Database;
   58             using (var tran = db.TransactionManager.StartTransaction())
   59             {
   60                 foreach (var id in ids)
   61                 {
   62                     BlockReference bref =
   63                         tran.GetObject(id, OpenMode.ForRead)
   64                         as BlockReference;
   65 
   66                     if (bref == null) continue;
   67 
   68                     foreach (ObjectId attId in bref.AttributeCollection)
   69                     {
   70                         AttributeReference att = (AttributeReference)
   71                             tran.GetObject(attId, OpenMode.ForRead);
   72 
   73                         _entities.Add(att.Clone() as Drawable);
   74                     }
   75                 }
   76 
   77                 tran.Commit();
   78             }
   79         }
   80     }
   81 }

Then here is the command to use AttributeHighlighter:

    1 using System.Collections.Generic;
    2 using Autodesk.AutoCAD.ApplicationServices;
    3 using Autodesk.AutoCAD.DatabaseServices;
    4 using Autodesk.AutoCAD.Runtime;
    5 using Autodesk.AutoCAD.EditorInput;
    6 using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
    7 
    8 [assembly: CommandClass(typeof(HighlightAttribute.Commands))]
    9 
   10 namespace HighlightAttribute
   11 {
   12     public class Commands
   13     {
   14         [CommandMethod("MyAtt")]
   15         public static void SetAttHighlight()
   16         {
   17             Document dwg = CadApp.DocumentManager.MdiActiveDocument;
   18             Editor ed = dwg.Editor;
   19 
   20             IEnumerable<ObjectId> ids = SelectAllBlocks(ed);
   21             if (ids != null)
   22             {
   23                 using (AttributeHighlighter hl = new AttributeHighlighter())
   24                 {
   25                     hl.Highlight(ids);
   26                     ed.UpdateScreen();
   27                     ed.GetString("\nPress any key to continue...");
   28                     hl.Unhighlight();
   29                     ed.UpdateScreen();
   30                 }
   31             }
   32 
   33             Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
   34         }
   35 
   36         private static IEnumerable<ObjectId> SelectAllBlocks(Editor ed)
   37         {
   38             TypedValue[] vals = new TypedValue[]
   39             {
   40                 new TypedValue((int)DxfCode.Start,"INSERT")
   41             };
   42 
   43             PromptSelectionResult res = ed.SelectAll(new SelectionFilter(vals));
   44             if (res.Status == PromptStatus.OK)
   45                 return res.Value.GetObjectIds();
   46             else
   47                 return null;
   48         }
   49     }
   50 }

What the command does is select all blocks, which have attributes, and pass the selected blocks' ObjectId to AttributeHighlighter, which searches through all the blocks and create a set of clones of all attributes and uses these cloned attributes to draw Transient Graphics (highlight) on top of the attributes. To user's eye, it looks like the attributes are highlighted. See this short video clip.


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