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



    « 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:

    Comments

    Hello Kean...

    How get the Autodesk.AutoCAD.Runtime libraries without install Autocad?

    I need use a dwg/dft(Solid Edge) Viewer in a .NET Winform.

    Thanks afterhand

    Hi Carlos,

    The acdbmgd.dll assembly (which is only part of what you want, I expect), is available as part of RealDWG (http://www.autodesk.com/realdwg).

    To implement a DWG viewer from scratch would take a lot of work - I suggest looking at DWG TrueView (which can be embedded as an ActiveX control in a WinForm).

    Regards,

    Kean

    hello kean!

    i am just new to this civil3d, and find it convenient to use than in my accustomed Land Dev't, i was planning to shift but then i found out that the DaylightBench Sub-assemblies has its limited user inputs in benching, if i just can modify its user inputs and separating
    Cut from Fill Benching controls....
    is it possible to modify the default inputs?
    or do i have to make a new one?

    i have been researching about this Vb.net programming but i guess i need help regarding this one. your tip is highly much appreciated.

    thnks!

    Hello Zeus,

    I suggest posting a question to one of the Civil 3D discussion groups or submitting it via ADN, if you're a member.

    Regards,

    Kean

    How can you tell what arrow head a leader has?

    The Leader object's Dimldrblk property contains the ObjectID of the block definition for the arrow-head. You should be able to open that and extract the information you need (its name, for instance).

    Kean

    Hi Kean.

    I just had one of my users point out a problem, which used to work fine, but I recently migrated it to Managed code, from COM, and we have only been on 2009 for a short time, so I'm not sure which is the problem. The old com code did basically what this post does, except it assigned a block reference to the annotation property along with assigning a special arrow. Now the Managed code I have looks an awful lot like the code above, but replace the Mtext with a Block. It errors saying eNotApplicable when I try to set the Annotation to the Blockref's ID. Any Ideas?

    Hi again...
    I found it. Apparently it had nothing to do with the fact that I was using a block instead of text, nor the Managed code, but that my leader and block were not at Z = 0.

    Since the block I'm refering to is a tag for elevation, that's kind of a requirement, but if I create the leader and block at 0 elevation and assign the blocks ID to the annotation, then move them up to the proper elevation it works.

    On the discussion group thread where I found this info, the guy said he had the code working in C# but it would not work in VB, which is what I'm using... Only a problem in VB?

    David -

    No idea - this is the sort of question I'd typically suggest asking of the ADN team (I don't have time to research issues that are even slightly off-topic, at the moment).

    You might consider joining - it seems like it would be of use to you.

    Kean

    Hi Kean,

    in which version Autocad & which DLL we get this name space "using Autodesk.AutoCAD.EditorInput;"

    and
    "Application.SetSystemVariable"

    I am unable to get the above things

    currently i am Using Autocad 2005


    AutoCAD 2005 really only had a "preview" version of the .NET API - a lot changed in subsequent releases (and it's only since 2006 that we've attempted to maintain compatibilty - see the comments in this post).

    I strongly recommend working with a newer version of AutoCAD if you're expecting to use its managed API.

    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