Author Topic: Setting attribute properly using ObjectARX  (Read 2928 times)

0 Members and 2 Guests are viewing this topic.

cannorth

  • Guest
Setting attribute properly using ObjectARX
« on: October 07, 2013, 06:30:15 PM »
Hello,

  This code won't let me set an attribute for a certain block.  I'd like to know if there's anything wrong with it.

Code: [Select]
            brID = modelspace.AppendEntity(blockRef)
            tr.AddNewlyCreatedDBObject(blockRef, True)

            For Each idAtt As ObjectId In btr
                Dim subent As Entity
                subent = CType(tr.GetObject(idAtt, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity)
                If TypeOf subent Is AttributeDefinition Then
                    Dim str_text As String
                    Dim attDef As AttributeDefinition
                    attDef = CType(subent, AttributeDefinition)
                    Dim attRef As New AttributeReference()
                    attRef.SetAttributeFromBlock(attDef, blockRef.BlockTransform)

                    Dim ptBase As New Autodesk.AutoCAD.Geometry.Point3d(attRef.Position.X, attRef.Position.Y, attRef.Position.Z)
                    attRef.Position = ptBase
                    attRef.Tag = attDef.Tag
                    attRef.TextString = str_text

                  End If

                    Dim idTmp As ObjectId
                    idTmp = blockRef.AttributeCollection.AppendAttribute(attRef)
                    tr.AddNewlyCreatedDBObject(attRef, True)

Thanks,
cannorth

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Setting attribute properly using ObjectARX
« Reply #1 on: October 08, 2013, 12:02:31 AM »
I can't remember exactly why the choice to call SetDatabaseDefaults first, I put this extension together quite awhile back and have never needed to think about it again.  It's use is for newly created blocks, only works when called from within a transaction.

Code: [Select]
            brID = modelspace.AppendEntity(blockRef)
            tr.AddNewlyCreatedDBObject(blockRef, True)

            For Each idAtt As ObjectId In btr
                Dim subent As Entity
                subent = CType(tr.GetObject(idAtt, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity) <--opening objects unnecessarily
                If TypeOf subent Is AttributeDefinition Then
                    Dim str_text As String
                    Dim attDef As AttributeDefinition
                    attDef = CType(subent, AttributeDefinition)
                    Dim attRef As New AttributeReference()
                    attRef.SetAttributeFromBlock(attDef, blockRef.BlockTransform)<--should set database defaults first

                    Dim ptBase As New Autodesk.AutoCAD.Geometry.Point3d(attRef.Position.X, attRef.Position.Y, attRef.Position.Z)<--this is useless, the last step sets the position for you
                    attRef.Position = ptBase
                    attRef.Tag = attDef.Tag<--ditto to redundant
                    attRef.TextString = str_text

                  End If

                    Dim idTmp As ObjectId
                    idTmp = blockRef.AttributeCollection.AppendAttribute(attRef)
                    tr.AddNewlyCreatedDBObject(attRef, True)
Code - C#: [Select]
  1.         public static void GenerateAttibutes(this BlockReference br)
  2.         {
  3.             using (Transaction tr = br.Database.TransactionManager.StartTransaction())
  4.             {
  5.                 if (!br.IsWriteEnabled) br.UpgradeOpen();
  6.                 using (BlockTableRecord btr = (BlockTableRecord)br.BlockTableRecord.GetObject(OpenMode.ForRead))
  7.                 {
  8.                     foreach (ObjectId id in btr)
  9.                     {
  10.                         if (id.ObjectClass == RXClass.GetClass(typeof(AttributeDefinition)))
  11.                         {
  12.                             AttributeDefinition ad = (AttributeDefinition)id.GetObject(OpenMode.ForRead);
  13.                             AttributeReference ar = new AttributeReference();
  14.                             ar.SetDatabaseDefaults();
  15.                             ar.SetAttributeFromBlock(ad, br.BlockTransform);
  16.                             br.AttributeCollection.AppendAttribute(ar);
  17.                             tr.AddNewlyCreatedDBObject(ar, true);
  18.                         }
  19.                     }
  20.                 }
  21.                 br.DowngradeOpen();
  22.                 tr.Commit();
  23.             }
  24.         }

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Setting attribute properly using ObjectARX
« Reply #2 on: October 08, 2013, 09:58:10 AM »
I can't remember exactly why the choice to call SetDatabaseDefaults first, I put this extension together quite awhile back and have never needed to think about it again...

One word: comments.  Highly useful for these types of situations where the code only documents the "how" and not the "why".
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}