Book Image

Instant Autodesk AutoCAD 2014 Customization with .NET

By : Tom Nelson
Book Image

Instant Autodesk AutoCAD 2014 Customization with .NET

By: Tom Nelson

Overview of this book

<p>AutoCAD's .NET API can be used to create small but powerful applications that help CAD users achieve productivity gains and improve quality. CAD users can accelerate drafting and design processes, improve drawing accuracy, minimize time spent on repetitive or demanding tasks, and reduce errors. In short, users can deliver better drawings faster with customized CAD tools.</p> <p>Learn how to use AutoCAD's .NET API to create your own high-powered, custom applications for AutoCAD. This book is a toolbox of small projects for handling common AutoCAD tasks. You can add to these recipes to develop your own specialized AutoCAD program library. Clear, step-by-step instructions and complete code examples illustrate the process, making it easy to develop your own custom AutoCAD tools.</p> <p><br />Giving you the building blocks of AutoCAD application development, you&rsquo;ll learn to create compact user interfaces for your AutoCAD plugins and add command buttons to the ribbon interface. Next, you&rsquo;ll create programs to insert and modify AutoCAD block and attribute references, as well as working with custom data stored on AutoCAD objects. Learn how to publish layouts from external drawings in multi-sheet PDF files, export AutoCAD data to MS Excel for processing, and respond to AutoCAD event notifications (such as when an object is selected). With the tools presented in this book, you can develop and implement new functionality to address your specialized business needs.</p>
Table of Contents (7 chapters)

Working with blocks and attributes (Must know)


Blocks are collections of AutoCAD entities, which can be moved, erased, copied, scaled, or mirrored with a single cursor pick. Blocks are well-suited to represent standard parts such as fasteners, fixtures, gears, and motors. We can attach attributes (data) to blocks, which represent properties that our custom program can read and respond to. This project demonstrates block insertion, reading and writing attribute values, and setting block reference properties.

Getting ready

The code project is intended to be used with a test drawing, Ch4Drawing.dwg. The test drawing contains a block definition Test Block, which contains three attributes: Name (the block name), Color (a color/layer name), and Chapter (the current chapter). The first two can be set by end users, inserting the block in the drawing, and can also be read and modified by our code project. The third is a constant attribute, meaning that its value stays the same and is not set by the end user or by code.

How to do it...

  1. Let's create a new command, InsBlkAtt. Inside the transaction, we'll create an array of six layer names. As in the previous project, open the block table for read. This time, check for a block definition named Test Block (Test Block is defined in Ch4Drawing.dwg, which is included with your downloaded code package):

    [CommandMethod("MyGroup", "InsBlkAtt", "InsBlkAtt", CommandFlags.Modal)]
    public void InsBlkWithAtts() {
       Database db = 
       Application.DocumentManager.MdiActiveDocument.Database;
       Editor ed = 
       Application.DocumentManager.MdiActiveDocument.Editor;
       PromptPointResult ptRes;
       int iCtr = 0;
       do {
          using (Transaction trans = 
              db.TransactionManager.StartTransaction()){
             string[] lyrNam = { "RED", "YELLOW", "GREEN", "CYAN", 
               "BLUE", "MAGENTA" };
             string blkNam = "Test Block";
          //Open the block table for read
            BlockTable blkTbl = 
            db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
            //Check the block table for block definition "Test Block"
            if (blkTbl.Has(blkNam) == false) {
               return; //exit if not found
            }
  2. If found, open the Test Block definition for read:

    //Open "Test Block" definition for read
    BlockTableRecord blkDefn = blkTbl[blkNam].GetObject(OpenMode.ForRead) as BlockTableRecord;
  3. Also, open ModelSpace for write (we will be inserting block references in ModelSpace):

    //Open ModelSpace for write
    BlockTableRecord mdlSpc = 
    blkTbl[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite) 
    as BlockTableRecord;
  4. Next, add some code to prompt the user to pick an insertion point for the block reference on screen (configure the options to exit the command if the user right-clicks on or presses Enter). Then insert the block reference at the specified point:

    //Set prompt string and options for "Test Block" insertion point
    PromptPointOptions ptOpts = new PromptPointOptions 
       (System.Environment.NewLine + "Select insertion point");
    ptOpts.AllowNone = true; //Allow Enter key/Right-click as input
    ptRes = ed.GetPoint(ptOpts); //Get insertion point
    //If point was picked or coords entered, continue; otherwise, exit
    if (ptRes.Status != PromptStatus.OK) {
       ed.WriteMessage("Done.");
       return;
    }
    double X = ptRes.Value.X;
    double Y = ptRes.Value.Y;
    using (BlockReference blkRef = 
       new BlockReference(new Point3d(X, Y, 0), 	blkDefn.ObjectId)) {
       string blkClr = "";
       //Append block ref to ModelSpace
       mdlSpc.AppendEntity(blkRef);
       trans.AddNewlyCreatedDBObject(blkRef, true);
  5. Check the block definition for attribute definitions and create attribute references for them (unless they are constant attributes):

    foreach (ObjectId oId in blkDefn) {
       DBObject dbObj = oId.GetObject(OpenMode.ForRead);
       AttributeDefinition aDefn = dbObj as AttributeDefinition;
       if (aDefn != null) {
          //If not a 'constant' attribute, create a reference
          if (aDefn.Constant == false) {
             using (AttributeReference aRef = 
                new AttributeReference()) {
             aRef.SetAttributeFromBlock(aDefn, blkRef.BlockTransform);
  6. If there is a COLOR attribute, open the layer table for read:

             if (aDefn.Tag == "COLOR") {
                LayerTable lTbl = (LayerTable)trans.GetObject
                   (db.LayerTableId,  OpenMode.ForRead);
  7. If a layer has the same name as the layer name indexed in the array, set the COLOR attribute value (TextString property) to that layer name. Also, set the block reference's Layer property to match the COLOR attribute (at the same time, advance the index to point to the next layer name in the array):

                if (lTbl.Has(lyrNam[iCtr])) {
                   //Set attribute value to layer name indexed 
                   //in array, if it exists
                   aRef.TextString = lyrNam[iCtr];
                   if (iCtr == 5) {
                      iCtr = 0; //Only six layers added so reset to 0
                   }
                   else { 
                      iCtr = iCtr + 1; //Increment counter by 1
                   }
                   //Set block ref layer to same as attribute value
                   blkClr = aRef.TextString;
                   blkRef.Layer = blkClr;
                }
  8. If there is a NAME attribute, set its value to the block name, Test Block:

                else if (aDefn.Tag == "NAME") {
                   //Set attribute value to block name
                   aRef.TextString = blkNam;
                }
  9. Finally, append the attribute references to the block reference. Continue to prompt the user for an insertion point until they exit the command by right-clicking, or by pressing the ENTER or Esc keys:

    //Append attribute reference to block ref
      blkRef.AttributeCollection.AppendAttribute(aRef);
                   trans.AddNewlyCreatedDBObject(aRef, true);}}
                }
             }
          }
          trans.Commit();
       } //End transaction
    } while (ptRes.Status == PromptStatus.OK);

How it works...

The drawing has six layers named for their colors: red, yellow, green, cyan, blue, and magenta. The program prompts the user to pick an insertion point on screen. With each insertion, the program cycles through an array of layer names and the COLOR attribute of each inserted block is set to a different color/layer name, until the end of the array is reached and the cycle begins again. The program reads the COLOR attribute on each block reference, and sets the block's layer property according to the attribute value. Since the block was defined with the color set to Bylayer, the entities in the block reference take on the color of the layer to which they are assigned.