Kean Walmsley

July 2009

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  

Twitter Updates

    follow me on Twitter



    « "Creating an Installer" webcast recording available for download | Main | Creating an AutoCAD multileader spraying out from central text using .NET »

    September 03, 2007

    Creating a spline-segment multileader in AutoCAD using .NET

    I thought it would be interesting to spend a few posts looking into the multileader or MLeader functionality in AutoCAD 2008.

    To get things started, here's some simple code that prompts the user for a couple of points and then creates a single spline-segment multileader with multi-line text at the points specified. It also uses the technique shown in this previous post to specify a custom arrow-head.

    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;


    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;

        }


        [CommandMethod("mymld")]

        static public void CreateMultiLeader()

        {

          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 arrowhead location: "

            );

          if (result.Status != PromptStatus.OK)

            return;

          Point3d startPt = result.Value;


          // Get the end point of the leader

          PromptPointOptions opts =

            new PromptPointOptions(

              "\nSpecify landing location: "

            );

          opts.BasePoint = startPt;

          opts.UseBasePoint = true;

          result = ed.GetPoint(opts);

          if (result.Status != PromptStatus.OK)

            return;

          Point3d endPt = result.Value;


          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

                );


              // Create the MLeader

              MLeader mld = new MLeader();

              int ldNum = mld.AddLeader();

              int lnNum = mld.AddLeaderLine(ldNum);

              mld.AddFirstVertex(lnNum, startPt);

              mld.AddLastVertex(lnNum, endPt);

              mld.ArrowSymbolId = arrId;

              mld.LeaderLineType =

                LeaderType.SplineLeader;


              // Create the MText

              MText mt = new MText();

              mt.Contents =

                "Multi-line leader\n" +

                "with the \"" +

                arrowName +

                "\" arrow head";

              mt.Location = endPt;

              mld.ContentType =

                ContentType.MTextContent;

              mld.MText = mt;


              // Add the MLeader

              btr.AppendEntity(mld);

              tr.AddNewlyCreatedDBObject(mld, true);


              tr.Commit();

            }

            catch

            {

              // Would also happen automatically

              // if we didn't commit

              tr.Abort();

            }

          }

        }

      }

    }

    Here's what you get when you run the MYMLD command:

    Mleader_single_segment_spline

    There seem to be a lot of interesting possibilities with this new class... be sure to let me know if you have suggestions for further topics related to MLeaders (or anything else, come to think of it).

    TrackBack

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

    Listed below are links to weblogs that reference Creating a spline-segment multileader in AutoCAD using .NET:

    Comments

    Dear Keen,
    Thanks a lot for the code. I have yet to see 2008 and MultiLeader. But I presume that it works on both Model and paper spaces. In that case, what is the best method to make the operation space independent? ie, it should work on active space irrespective of whether it's model or paper. I think this will be generally applicable to almost all the entitiy creations.

    BlockTableRecord btr =
    (BlockTableRecord)tr.GetObject(
    bt[BlockTableRecord.ModelSpace],
    OpenMode.ForWrite
    );

    Thanks for any suggestion,
    har!s

    Hi har!s,

    A very good question. I’ve shown this buried in a recent post, but only the once. Here’s the code you need to add the object to the currently active space:

    BlockTableRecord btr =
    (BlockTableRecord)tr.GetObject(
    db.CurrentSpaceId,
    OpenMode.ForWrite
    );

    Kean

    I know this post is old, but how about adding a scaled block instead of text. Also how do you set or create a mleader style? Any help would be great. By the way, thanks for all the examples!

    I'll add these items to my list...

    Kean

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search