Blockreference original Bounds value changes after adding attribute value

Blockreference original Bounds value changes after adding attribute value

mayur_kapadnis
Participant Participant
684 Views
3 Replies
Message 1 of 4

Blockreference original Bounds value changes after adding attribute value

mayur_kapadnis
Participant
Participant

I have a blockreference with some TextString attribute value, if I try to take its position, i am getting the block.Bounds value in between somewhere in the text, but i want its original center without any attribute, I have this code which is working perfectly, but is there any other simple way to do this?

mayur_kapadnis_0-1734082406272.png

 

 

public static Point3d GetBlockGeometricCenterWithoutAttribute(BlockReference originalBlock)
{
   // Dictionary to store original attribute values
   Dictionary<AttributeReference, string> originalAttributes = new Dictionary<AttributeReference, string>();

   // Store the original attribute values
   using (Transaction trans = originalBlock.Database.TransactionManager.StartTransaction())
   {
      foreach (ObjectId attId in originalBlock.AttributeCollection)
      {
         AttributeReference attrRef = (AttributeReference)trans.GetObject(attId, OpenMode.ForWrite);
         // Store the original value
         originalAttributes[attrRef] = attrRef.TextString;
         // Clear the attribute value
         attrRef.TextString = string.Empty;
      }

      // Commit the transaction (attributes are cleared)
      trans.Commit();
   }

   // Get the geometric center (position)
   Point3d center = GetBlockCenter(originalBlock);

   // Restore the original attribute values
   using (Transaction trans = originalBlock.Database.TransactionManager.StartTransaction())
   {
      foreach (var attrPair in originalAttributes)
      {
         AttributeReference attrRef = attrPair.Key;
         string originalValue = attrPair.Value;

         // Restore the original value
         if (!attrRef.IsErased)
         {
            attrRef.TextString = originalValue;
         }
      }

      // Commit the transaction (attributes are restored)
      trans.Commit();
   }
   originalAttributes.Clear();
   return center;  // Return the geometric center of the block
}

public static Point3d GetBlockCenter(BlockReference table)
{
   Point3d cornerPointMax = table.GeometricExtents.MaxPoint;
   Point3d cornerPointMin = table.GeometricExtents.MinPoint;
   return new Point3d((cornerPointMax.X + cornerPointMin.X) / 2, (cornerPointMax.Y + cornerPointMin.Y) / 2, 0);
}

 

 

0 Likes
Accepted solutions (1)
685 Views
3 Replies
Replies (3)
Message 2 of 4

_gile
Consultant
Consultant

Hi,

 

The BlockReference.Position (aka block insertion point) has nothing to do with the block attributes.

You should post your block if you want someone to be able to help you.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 4

mayur_kapadnis
Participant
Participant

actually I want to find the center of blockreference, so I have updated my post

0 Likes
Message 4 of 4

_gile
Consultant
Consultant
Accepted solution

Another way could be getting the center of the block definition (without attribute definitions) and transforming it with the BlockTransform matrix of the block reference.

private static Point3d GetBlockCenter(BlockReference br, Transaction tr)
{
    var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
    var attDefClass = RXObject.GetClass(typeof(AttributeDefinition));
    var extents = new Extents3d();
    foreach (ObjectId id in btr)
    {
        if (id.ObjectClass != attDefClass)
        {
            var entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
            var bounds = entity.Bounds;
            if (bounds.HasValue)
                extents.AddExtents(bounds.Value);
        }
    }
    var center = extents.MinPoint + extents.MinPoint.GetVectorTo(extents.MaxPoint) * 0.5;
    return center.TransformBy(br.BlockTransform);
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub