Through the Interface: Highlighting named blocks using AutoCAD 2010s overrule API from .NET

May 2015

Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30


« A learning path for newbie programmers | Main | A new project wizard for AutoCAD .NET development »

June 15, 2009

Highlighting named blocks using AutoCAD 2010’s overrule API from .NET

This is a nice sample provided by Stephen Preston, who manages DevTech’s Americas team. Stephen has put this together in anticipation of his upcoming AU class on the overrule API introduced in AutoCAD 2010. [I know the final class list has not yet been announced, but Stephen is co-owner of the Customization & Programming track at this year’s AU and presumably has the inside skinny on the selected classes. Which means he has a head-start on preparing his material, lucky fellow. :-)]

The sample allows the user to enter a text string that it uses to highlight any block containing that string in its name. This is quite handy for identifying the instances of a particular block in a drawing, but it might also be modified to highlight other objects (you might want to highlight mis-spelt words or standards violations, for instance).

Here’s the C# code, reformatted for this blog:

using System;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.GraphicsInterface;


namespace MyCustomFilterOverrule


  // This is our custom DrawableOverrule class. We're just

  // overruling WorldDraw and IsApplicable.

  // This class is implemented as a singleton class, and

  // includes subroutines that are called by the CommandMethods

  // in another class


  public class MyDrawOverrule : DrawableOverrule


    // Where properties have been defined, use the property rather

    // than the raw variable.

    // I'm using properties where I need some additional logic to

    // run as I get/set the variable.


    // The text we'll search for in our block name.


    private string mTxt;


    // Color Index of block highlight


    private short mColor = 3;


    // Used to track whether this Overrule has been registered

    // (so we don't try to register it more than once).


    private bool mRegistered = false;


    // Used to store one and only instance of our singleton class


    private static MyDrawOverrule mSingleton;


    // Used to reset Overruling value to the value it had before

    // we switched them on. (There may be other overrules in place)


    private static bool mOldOverruleValue;


    // The color we highlight blocks with

    private short HighlightColor


      get { return mColor; }

      set { if (value >= 0 && value <= 127) mColor = value; }



    // The text we'll search for in the block name


    private string SearchText


      get { return mTxt; }

      set { mTxt = value; }



    // Private constructor because its a singleton


    private MyDrawOverrule()


      // Do nothing



    // Shared propery to return our singleton instance

    // (and instantiate new instance on first call)


    public static MyDrawOverrule GetInstance




        if (mSingleton == null)


          mSingleton = new MyDrawOverrule();


        return mSingleton;




    private void InitOverrule()


      if (!mRegistered)



          RXObject.GetClass(typeof(BlockReference)), this, false



        mOldOverruleValue = Overrule.Overruling;

        mRegistered = true;


      Overrule.Overruling = true;



    // Prompts user to select the color index they want to

    // highlight blocks with


    public void SetColor()


      Editor ed =



      PromptIntegerOptions opts =

        new PromptIntegerOptions(

          "\nEnter block finder color index: "


      opts.DefaultValue = HighlightColor;

      opts.LowerLimit = 0;

      opts.UpperLimit = 127;

      opts.UseDefaultValue = true;

      PromptIntegerResult res = ed.GetInteger(opts);


      // If requested highlight color is a new color,

      // then we want to change it


      if (res.Status == PromptStatus.OK &&

          HighlightColor != res.Value)


        HighlightColor = (short)res.Value;


        // Regen is required to update changes on screen






    public void FindText()


      Editor ed =




        "\nCurrent block search text is \"{0}\".", SearchText


      PromptStringOptions opts =

        new PromptStringOptions(

          "\nEnter new block search text: "


      PromptResult res = ed.GetString(opts);


      // If the user cancelled then we exit the command


      if (res.Status != PromptStatus.OK)



      // If the user didn't type any text then we remove

      // the overrule and exit


      if (res.StringResult == "")


        SearchText = "";





        // Set search text for Overrule to that entered by user


        SearchText = res.StringResult.ToUpper();



        // Turn Overruling on


        Overrule.Overruling = true;


        // Regen is required to update changes on screen.






    // Removes our overrules


    public void ResetBlocks()


      Editor ed =



      Overrule.Overruling = mOldOverruleValue;

      if (mRegistered)



          RXObject.GetClass(typeof(BlockReference)), this


        mRegistered = false;





    // Overrule WorldDraw so we can draw our additional

    // graphics


    public override bool WorldDraw(Drawable drawable, WorldDraw wd)


      // Better safe than sorry - check it really is a

      // BlockReference before continuing.


      BlockReference br = drawable as BlockReference;

      if (br != null)


        // Now we want to draw a green box around the attributes

        // extents


        Extents3d ext = (Extents3d)br.Bounds;

        Point3d maxPt = ext.MaxPoint;

        Point3d minPt = ext.MinPoint;

        Point3dCollection pts = new Point3dCollection();


        // These are the vertices of the highlight box


        pts.Add(new Point3d(minPt.X, minPt.Y, minPt.Z));

        pts.Add(new Point3d(minPt.X, maxPt.Y, minPt.Z));

        pts.Add(new Point3d(maxPt.X, maxPt.Y, minPt.Z));

        pts.Add(new Point3d(maxPt.X, minPt.Y, minPt.Z));


        // Store current filltype and set to FillAlways


        FillType oldFillType = wd.SubEntityTraits.FillType;

        wd.SubEntityTraits.FillType = FillType.FillAlways;


        // Store old graphics color and set to the color we want


        short oldColor = wd.SubEntityTraits.Color;

        wd.SubEntityTraits.Color = HighlightColor;


        // Draw the filled polygon




        // Restore old settings


        wd.SubEntityTraits.FillType = oldFillType;

        wd.SubEntityTraits.Color = oldColor;



      // Let the overruled Drawable draw itself.


      return base.WorldDraw(drawable, wd);



    // This function is called if we call SetCustomFilter on our

    // custom overrule.

    // We add our own code to return true if the BlockReference

    // passed in is one we want to highlight.


    public override bool IsApplicable(RXObject overruledSubject)


      // If it's a BlockReference, we check if the Block Name

      // contains our string


      BlockReference br = overruledSubject as BlockReference;

      if (br != null && SearchText != "")


        // Returns whether the filter is applicable to this object


        return br.Name.Contains(SearchText);



      // Only get to here if object isn't a BlockReference


      return false;




  // Our command class, which relays commands to MyDrawOverrule.


  public class myPlugin



    public static void FindText()






    public static void SetColor()






Here’s what happens when we OPEN the “Mechanical – Multileaders.dwg” sample drawing, NETLOAD our application and use SHOWBLOCKS to look for the “M045” text string:

Highlighted blocks

Here’s what we see if we broaden the search to include all blocks with the string “M0” in their name and change the highlight colour to 1 using SHOWCOLOR:

More highlighted blocks

To clear the selection, the user simply has to run SHOWBLOCKS and specify an empty string as the search term.

Stephen will be presenting both C# and VB.NET versions of this sample application during his class at this year’s AU. If you find overrules interesting, then I strongly recommend signing up for the session (I’ll let you know when registrations are open). I’m sure that during the class Stephen will be demonstrating other interesting capabilities made available to AutoCAD .NET developers by this very cool API.


TrackBack URL for this entry:

Listed below are links to weblogs that reference Highlighting named blocks using AutoCAD 2010’s overrule API from .NET:

blog comments powered by Disqus


10 Random Posts