August 2014

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
31            








« Merry Christmas, Joyeux Noël, Fröhliche Weihnachten, Buon Natale | Main | Protecting intellectual property in AutoCAD application modules »

January 12, 2007

Creating an AutoCAD leader with a different arrowhead using .NET

Most of this week I've spent catching up after a nice, long break, as well as spending a few days in Prague helping interview potential recruits for our European team. Now it's finally time for me to climb back into the blogging saddle...

This first entry of 2007 is based on some code provided by Viru Aithal, a member of our team based in Bangalore. The code demonstrates how to create a leader using an arrowhead other than the current default (the one referred to by the DIMBLK system variable).

Here's the C# code:

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using System;


[assembly:

  CommandClass(

    typeof(

      DimensionLibrary.DimensionCommands

    )

  )

]


namespace DimensionLibrary

{

  public class DimensionCommands

  {

    static ObjectId GetArrowObjectId(string newArrName)

    {

      ObjectId arrObjId = ObjectId.Null;


      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;


      // Get the current value of DIMBLK

      string oldArrName =

        Application.GetSystemVariable(

          "DIMBLK"

        ) as string;


      // Set DIMBLK to the new style

      // (this action may create a new block)

      Application.SetSystemVariable(

        "DIMBLK",

        newArrName

      );


      // Reset the previous value of DIMBLK

      if (oldArrName.Length != 0)

        Application.SetSystemVariable(

          "DIMBLK",

          oldArrName

        );


      // Now get the objectId of the block

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using(tr)

      {

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId,

            OpenMode.ForRead

          );


        arrObjId = bt[newArrName];

        tr.Commit();

      }

      return arrObjId;

    }


    // Define Command "ld"

    [CommandMethod("ld")]

    static public void CreateLeader()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      Database db = doc.Database;


      const string arrowName = "_DOT";

      ObjectId arrId = GetArrowObjectId(arrowName);


      // Get the start point of the leader

      PromptPointResult result =

        ed.GetPoint(

          "\nSpecify leader start point: "

        );

      if (result.Status != PromptStatus.OK)

        return;

      Point3d startPt = result.Value;


      // Get the end point of the leader

      PromptPointOptions opts =

        new PromptPointOptions(

          "\nSpecify end point: "

        );

      opts.BasePoint = startPt;

      opts.UseBasePoint = true;

      result = ed.GetPoint(opts);

      if (result.Status != PromptStatus.OK)

        return;

      Point3d endPt = result.Value;


      // Now let's create the leader itself

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        try

        {

          BlockTable bt =

            (BlockTable)tr.GetObject(

              db.BlockTableId,

              OpenMode.ForRead

            );

          BlockTableRecord btr =

            (BlockTableRecord)tr.GetObject(

              bt[BlockTableRecord.ModelSpace],

              OpenMode.ForWrite

            );


          // Add the MText

          MText mt = new MText();

          mt.Contents =

            "Leader with the \"" +

            arrowName +

            "\" arrow head";

          mt.Location = endPt;

          ObjectId mtId = btr.AppendEntity(mt);

          tr.AddNewlyCreatedDBObject(mt, true);


          // Add the Leader

          Leader ld = new Leader();

          ld.AppendVertex(startPt);

          ld.AppendVertex(endPt);

          btr.AppendEntity(ld);

          tr.AddNewlyCreatedDBObject(ld, true);

          ld.Annotation = mtId;

          ld.Dimldrblk = arrId;


          tr.Commit();

        }

        catch

        {

          tr.Abort();

        }

      }

    }

  }

}

Some comments on the technique used:

A helper function (GetArrowObjectId(arrowName)) is used to get the ObjectID of the block of our arrow head. To make sure this block exists, the function sets the value of DIMBLK to the arrowhead name, which - assuming the name is valid - will create the block in the block table. Then we simply have to get its ID and return it.

Once you've built the code, simply run the "LD" command, and select two points defining your leader (the code can easily be extended to allow selection of additional points and entry of a user-defined annotation string, of course).

Here's what you should see:

Createleader

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200d83519067869e2

Listed below are links to weblogs that reference Creating an AutoCAD leader with a different arrowhead using .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts