Author Topic: Inserting block, then writing it's attributes  (Read 2530 times)

0 Members and 1 Guest are viewing this topic.

mcarson

  • Guest
Inserting block, then writing it's attributes
« on: May 07, 2009, 10:09:26 AM »
Using various snippets on this forum, and from the ObjectArx Samples, I have attempted to create a method to
insert a block definition, create and insert a blockreference based on this, then write attribute values.
I know this should be much simpler...

I am using VS 2005 SP1 and AutoCAD 2008 SP1.

Code: [Select]
using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcRx = Autodesk.AutoCAD.Runtime;

public class Initialisation : AcRx.IExtensionApplication
{
    public void Initialize()
    {
       
    }
   
    public void Terminate()
    {
       
    }
}

public class Commands
{
   
    private const string attProjectTitle1 = "PROTIT01";
    private const string attProjectTitle2 = "PROTIT02";
    private const string attProjectTitle3 = "PROTIT03";
    private const string attProjectTitle4 = "PROTIT04";
    private const string attDrawingTitle1 = "DWGTIT01";
    private const string attDrawingTitle2 = "DWGTIT02";
    private const string attDrawingTitle3 = "DWGTIT03";
    private const string attDrawingTitle4 = "DWGTIT04";
    private const string attScale = "SCALE";
    private const string attStatus = "STATUS";
    private const string attDrawnBy = "DRWN";
    private const string attDrawnDate = "DDATE";
    private const string attModelNumber = "MODELNO";
   
    [AcRx.CommandMethod("TestBlock")]
    public static void InsertBlock()
    {
        string SourceFileName = "";
        // You'll need to supply the source file
        string NewBlockName = "";
        // You'll need to supply the block name
       
        AcDb.ObjectId blkoid = AcDb.ObjectId.Null;
       
        try {
            using (AcDb.Database dbSource = GetDatabaseFromFile(SourceFileName)) {
                blkoid = AcDb.HostApplicationServices.WorkingDatabase.Insert(NewBlockName, dbSource, false);
            }
        }
        catch (Exception ex) {
            AcAp.Application.ShowAlertDialog(ex.Message + Constants.vbCrLf + ex.InnerException.Message);
            return;
        }
       
        AcDb.Database db = AcDb.HostApplicationServices.WorkingDatabase;
        AcDb.TransactionManager tm = db.TransactionManager;
        using (AcDb.Transaction tr = tm.StartTransaction) {
            AcDb.BlockTable bt = (AcDb.BlockTable)tr.GetObject(db.BlockTableId, AcDb.OpenMode.ForWrite, true);
            AcDb.BlockTableRecord btr = (AcDb.BlockTableRecord)tr.GetObject(bt(AcDb.BlockTableRecord.ModelSpace), AcDb.OpenMode.ForWrite, true);
            AcDb.BlockReference blk = new AcDb.BlockReference(new AcGe.Point3d(100.0, 100.0, 0.0), blkoid);
            blk.ScaleFactors = new AcGe.Scale3d(1.0);
           
            AcDb.ObjectId broid = btr.AppendEntity(blk);
            tr.AddNewlyCreatedDBObject(blk, true);
           
            Hashtable attNameValues = new Hashtable();
            attNameValues.Add(attProjectTitle1, "Project.Description1");
            attNameValues.Add(attProjectTitle2, "Project.Description2");
            attNameValues.Add(attProjectTitle3, "Project.Description3");
            attNameValues.Add(attProjectTitle4, "Project.Description4");
            attNameValues.Add(attDrawingTitle1, "File.Content1");
            attNameValues.Add(attDrawingTitle2, "File.Content2");
            attNameValues.Add(attDrawingTitle3, "File.Content3");
            attNameValues.Add(attDrawingTitle4, "File.Content4");
            attNameValues.Add(attScale, "File.Scale");
            attNameValues.Add(attStatus, "File.Status");
            attNameValues.Add(attDrawnBy, "File.LastUpdatedBy");
            attNameValues.Add(attDrawnDate, "File.DateCreated");
            attNameValues.Add(attModelNumber, "File.DrawingReference");
           
            foreach (AcDb.ObjectId attoid in blk.AttributeCollection) {
                AcDb.AttributeReference attref = (AcDb.AttributeReference)tr.GetObject(attoid, AcDb.OpenMode.ForRead);
                if (((attref != null)) && attNameValues.ContainsKey(attref.Tag.ToUpper)) {
                    attref.UpgradeOpen();
                    attref.TextString = attNameValues.Item(attref.Tag.ToUpper).ToString;
                    attref.DowngradeOpen();
                }
            }
           
               
            tr.Commit();
           
        }
    }
   
    public static AcDb.Database GetDatabaseFromFile(string FileName)
    {
        AcDb.Database db = new AcDb.Database(false, true);
        db.ReadDwgFile(FileName, System.IO.FileShare.None, false, null);
        db.CloseInput(true);
        return db;
    }
   
}

The block definition is added okay, with the block reference inserted at the correct position, but the attributes are not being
written to the block reference.
When I attempt to manually edit the attributes 'attedit', the block reference contains no attributes.
When I manually create a block reference using the 'insert' command on the same block definition, attedit works okay.
The block reference cannot be exploded. (eh!)
The block editor shows me the Attribute Definitions clearly.

I'm stomped... Please could someone point me in the right direction.

Glenn R

  • Guest
Re: Inserting block, then writing it's attributes
« Reply #1 on: May 07, 2009, 10:28:35 AM »
Have a wee looky here - it should help.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: Inserting block, then writing it's attributes
« Reply #2 on: May 07, 2009, 10:48:38 AM »
You need to manually add the attributes

I.e.

Code: [Select]

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcDb = Autodesk.AutoCAD.DatabaseServices;

[assembly: CommandClass(typeof(ExecMethod.Commands))]
//// ++--
namespace ExecMethod
{
  public static class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      BlockRefInsert("index1", new Point3d(100, 100, 0), new Scale3d(30, 30, 30));
    }

    public static ObjectId BlockRefInsert(string name, Point3d point3d, Scale3d scaleBy)
    {
      ObjectId objId = ObjectId.Null;
      AcDb.Database db = AcDb.HostApplicationServices.WorkingDatabase;
      using (AcDb.Transaction trans = db.TransactionManager.StartTransaction())
      {
        AcDb.BlockTable bt = (AcDb.BlockTable)(trans.GetObject(db.BlockTableId, AcDb.OpenMode.ForRead));
        if (bt.Has(name))
        {
          ObjectId blkId = bt[name];
          AcDb.BlockTableRecord btr = (AcDb.BlockTableRecord)trans.GetObject
                        (bt[AcDb.BlockTableRecord.ModelSpace], AcDb.OpenMode.ForWrite);

          AcDb.BlockTableRecord blkDefRecord = (BlockTableRecord)trans.GetObject
                        (blkId, OpenMode.ForRead);

          AcDb.BlockReference br = new AcDb.BlockReference(point3d, blkId);

          br.ScaleFactors = scaleBy;
          btr.AppendEntity(br);
          if (blkDefRecord.HasAttributeDefinitions)
          {
            foreach (ObjectId idAtt in blkDefRecord)
            {
              AttributeDefinition AttDef = trans.GetObject(idAtt, OpenMode.ForRead) as AttributeDefinition;
              if (AttDef != null)
              {
                AttributeReference attRef = new AttributeReference();
                attRef.SetAttributeFromBlock(AttDef, br.BlockTransform);
                attRef.HorizontalMode = AttDef.HorizontalMode;
                attRef.VerticalMode = AttDef.VerticalMode;
                attRef.Visible = AttDef.Visible;
                attRef.Rotation = AttDef.Rotation;
                attRef.TextStyle = AttDef.TextStyle;
                attRef.Position = AttDef.Position + point3d.GetAsVector();
                attRef.Tag = AttDef.Tag;
                attRef.TextString = AttDef.TextString;
                // etc.
                br.AttributeCollection.AppendAttribute(attRef);
                trans.AddNewlyCreatedDBObject(attRef, true);
              }
            }
            trans.AddNewlyCreatedDBObject(br, true);
            trans.Commit();
            objId = br.ObjectId;
          }
        }
      }
      return objId;
    }
  }
}



« Last Edit: May 07, 2009, 11:04:04 AM by Daniel »

mcarson

  • Guest
Re: Inserting block, then writing it's attributes
« Reply #3 on: May 08, 2009, 03:52:08 AM »
Have a wee looky here - it should help.

Glenn; thanks for the link. Provided me with a good understanding of blocks with attributes.

Daniel; thanks! Was that one you made earlier?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: Inserting block, then writing it's attributes
« Reply #4 on: May 08, 2009, 04:17:44 AM »
Probably, I modified it though.  :-)