Kean Walmsley


  • About the Author
    Kean on Google+

April 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      







« DWG-capable 2D CAD on the web | Main | Creating an AutoCAD group using .NET »

January 22, 2010

Creating an AutoCAD block using .NET

This post – and its sister post, which will cover creating a group – are further topics I would expect to have already covered in this blog at some point, or perhaps to see covered by the AutoCAD .NET Developer’s Guide (and I’m sure they will be in a future incarnation of it). So thanks to Adam Nagy, from DevTech EMEA, for suggesting these topics. It’s nice to go back to basics once in a while (although this means I do have to beg the patience of the readers out there who know this stuff inside out).

So, here’s some simple C# code that creates a simple block definition (a BlockTableRecord in the BlockTable) and a corresponding block insertion (a BlockReference in the model-space BlockTableRecord).

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

 

namespace CollectionCreation

{

  public class Commands

  {

    [CommandMethod("CB")]

    public void CreateBlock()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

 

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        // Get the block table from the drawing

 

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId,

            OpenMode.ForRead

          );

 

        // Check the block name, to see whether it's

        // already in use

 

        PromptStringOptions pso =

          new PromptStringOptions(

            "\nEnter new block name: "

          );

        pso.AllowSpaces = true;

 

        // A variable for the block's name

 

        string blkName = "";

 

        do

        {

          PromptResult pr = ed.GetString(pso);

 

          // Just return if the user cancelled

          // (will abort the transaction as we drop out of the using

          // statement's scope)

 

          if (pr.Status != PromptStatus.OK)

            return;

 

          try

          {

            // Validate the provided symbol table name

 

            SymbolUtilityServices.ValidateSymbolName(

              pr.StringResult,

              false

            );

 

            // Only set the block name if it isn't in use

 

            if (bt.Has(pr.StringResult))

              ed.WriteMessage(

                "\nA block with this name already exists."

              );

            else

              blkName = pr.StringResult;

          }

          catch

          {

            // An exception has been thrown, indicating the

            // name is invalid

 

            ed.WriteMessage(

              "\nInvalid block name."

            );

          }

 

        } while (blkName == "");

 

        // Create our new block table record...

 

        BlockTableRecord btr = new BlockTableRecord();

 

        // ... and set its properties

 

        btr.Name = blkName;

 

        // Add the new block to the block table

 

        bt.UpgradeOpen();

        ObjectId btrId = bt.Add(btr);

        tr.AddNewlyCreatedDBObject(btr, true);

 

        // Add some lines to the block to form a square

        // (the entities belong directly to the block)

 

        DBObjectCollection ents = SquareOfLines(5);

        foreach (Entity ent in ents)

        {

          btr.AppendEntity(ent);

          tr.AddNewlyCreatedDBObject(ent, true);

        }

 

        // Add a block reference to the model space

 

        BlockTableRecord ms =

          (BlockTableRecord)tr.GetObject(

            bt[BlockTableRecord.ModelSpace],

            OpenMode.ForWrite

          );

 

        BlockReference br =

          new BlockReference(Point3d.Origin, btrId);

 

        ms.AppendEntity(br);

        tr.AddNewlyCreatedDBObject(br, true);

 

        // Commit the transaction

 

        tr.Commit();

 

        // Report what we've done

 

        ed.WriteMessage(

          "\nCreated block named \"{0}\" containing {1} entities.",

          blkName, ents.Count

        );

      }

    }

 

    private DBObjectCollection SquareOfLines(double size)

    {

      // A function to generate a set of entities for our block

 

      DBObjectCollection ents = new DBObjectCollection();

      Point3d[] pts =

          { new Point3d(-size, -size, 0),

            new Point3d(size, -size, 0),

            new Point3d(size, size, 0),

            new Point3d(-size, size, 0)

          };

      int max = pts.GetUpperBound(0);

 

      for (int i = 0; i <= max; i++)

      {

        int j = (i == max ? 0 : i + 1);

        Line ln = new Line(pts[i], pts[j]);

        ents.Add(ln);

      }

      return ents;

    }

  }

}

Let’s see what happens when we run the CB command to create a block:

Command: CB

Enter new block name: Square

Created block named "Square" containing 4 entities.

That's really all there is to it: after the code has been run you’ll see a block (named “Square”) made up of four lines aligned in a square around the origin.

I might have separated the above code out into functions to create the block definition and the block reference, but my main goal for this post was to show the procedure in a linear fashion. I did use one separate function – as we’ll also use that to create our group in the next post – which creates a collection of objects that will make up our block.

blog comments powered by Disqus

10 Random Posts