Customizing the display of standard AutoCAD objects using .NET

The code in this post is a direct port of the F# code in this previous post, which was entered by Qun Lu in the recent F# programming contest. Someone – very validly - commented on the fact the post involved both a new language and a new API, which was probably pushing things a little from a learning perspective. 🙂

Without repeating my various comments in the previous post, I will reiterate the fact that this API is extremely interesting for developers who wish to customize the appearance and behaviour of standard AutoCAD objects without going through the pain of implementing full custom objects.

Here's the equivalent C# code that works with AutoCAD 2010:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.GraphicsInterface;

using Autodesk.AutoCAD.Colors;

 

namespace DrawOverrule

{

  public class DrawOverrule : DrawableOverrule

  {

    static public DrawOverrule theOverrule =

      new DrawOverrule();

 

    static private double Radius = 0.5;

 

    private SweepOptions sweepOpts = new SweepOptions();

 

    public override bool WorldDraw (Drawable d, WorldDraw wd)

    {

      if (d is Line)

      {

        Line line = (Line)d;

 

        // Draw the line as is, with overruled attributes

 

        base.WorldDraw(line, wd);

        if (!line.Id.IsNull && line.Length > 0.0)

        {

          // Draw a pipe around the line

 

          EntityColor c =

            wd.SubEntityTraits.TrueColor;

          wd.SubEntityTraits.TrueColor =

            new EntityColor(0x00AfAfff);

          wd.SubEntityTraits.LineWeight =

            LineWeight.LineWeight000;

          Circle clr =

            new Circle(

              line.StartPoint,

              line.EndPoint - line.StartPoint,

              DrawOverrule.Radius

            );

          ExtrudedSurface pipe = new ExtrudedSurface();

          try

          {

            pipe.CreateExtrudedSurface(

              clr, line.EndPoint-line.StartPoint, sweepOpts

            );

          }

          catch

          {

            Document doc =

              Application.DocumentManager.MdiActiveDocument;

            doc.Editor.WriteMessage(

              "\nFailed with CreateExtrudedSurface."

            );

          }

          clr.Dispose();

          pipe.WorldDraw(wd);

          pipe.Dispose();

          wd.SubEntityTraits.TrueColor = c;

        }

        return true;

      }

      else if (d is Circle)

      {

        Circle circle = (Circle)d;

 

        // Draw the circle as is, with overruled attributes

 

        base.WorldDraw(circle, wd);

 

        // Needed to avoid ill-formed swept surface

 

        if (circle.Radius > DrawOverrule.Radius)

        {

          // Draw a pipe around the cirle

 

          EntityColor c = wd.SubEntityTraits.TrueColor;

          wd.SubEntityTraits.TrueColor =

            new EntityColor(0x3fffe0e0);

          wd.SubEntityTraits.LineWeight =

            LineWeight.LineWeight000;

          Vector3d normal =

            (circle.Center-circle.StartPoint).

              CrossProduct(circle.Normal);

          Circle clr =

            new Circle(

              circle.StartPoint, normal, DrawOverrule.Radius

            );

          SweptSurface pipe = new SweptSurface();

          pipe.CreateSweptSurface(clr, circle, sweepOpts);

          clr.Dispose();

          pipe.WorldDraw(wd);

          pipe.Dispose();

          wd.SubEntityTraits.TrueColor = c;

        }

        return true;

      }

      return base.WorldDraw(d, wd);

    }

 

    public override int SetAttributes (Drawable d, DrawableTraits t)

    {

      int b = base.SetAttributes(d, t);

      if (d is Line)

      {

        // If d is LINE, set color to index 6

 

        t.Color = 6;

 

        // and lineweight to .40 mm

 

        t.LineWeight = LineWeight.LineWeight040;

      }

      else if (d is Circle)

      {

        // If d is CIRCLE, set color to index 2

 

        t.Color = 2;

 

        // and lineweight to .60 mm

 

        t.LineWeight = LineWeight.LineWeight060;

      }

      return b;

    }

  }

 

  public class Commands

  {

    public void Overrule(bool enable)

    {

      // Regen to see the effect

      // (turn on/off Overruling and LWDISPLAY)

 

      DrawableOverrule.Overruling = enable;

      if (enable)

        Application.SetSystemVariable("LWDISPLAY", 1);

      else

        Application.SetSystemVariable("LWDISPLAY", 0);

 

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      doc.SendStringToExecute("REGEN3\n", true, false, false);

      doc.Editor.Regen();

    }

 

    [CommandMethod("OVERRULE1")]

    public void OverruleStart()

    {

      ObjectOverrule.AddOverrule

        (RXClass.GetClass(typeof(Drawable)),

        DrawOverrule.theOverrule, true);

      Overrule(true);

    }

 

    [CommandMethod("OVERRULE0")]

    public void OverruleEnd()

    {

      Overrule(false);

    }

  }

}

[Repeating the results from the previous post…]

Here's what happens when we load the application, turn the overrule on using the OVERRULE1 command (OVERRULE0 is the command to turn the overrule off) and draw some lines and circles:

Overruled 2D wireframe display of lines and circles

Even in a 3D view – this time with the realistic visual style applied – you get the piping effect when you draw simple geometry:

Overruled 3D display of lines and circles

These are standard AutoCAD lines and circles. When you use the OVERRULE0 command to disable the overrule, they revert to their original form:

Standard display of lines and circles

6 responses to “Customizing the display of standard AutoCAD objects using .NET”

  1. A question about the overrule.
    Is there anyway to apply overrule to entity instance?
    If Overrule is only applied to entity type. We still need custom entity, otherwise all the lines in the drawing will be pipes, as in this example.

    Thanks much.

  2. A great question. You can certainly check instance-related information to determine whether your override should be applied on an instance basis.

    I'll put a quick post together demonstrating this for tomorrow.

    Kean

  3. I am a .net developer and now I have a requirement to draw an interactive autocad diagram in a windows application. Clicking on an object in the drawing need to fire some event. Could you help me in selecting the correct api?

  4. This isn't a forum for support.

    Your comment doesn't appear to relate directly to this post, so please submit your question to the ADN team, if you're a member, or otherwise the AutoCAD .NET Discussion Group.

    Kean

  5. Hello,
    I am trying to just display CAD object in wpf application
    could you help in that!!thanks in advance!!!

  6. Sorry - see the above comment.

    Kean

Leave a Reply to Layman Cancel reply

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