Getting Block Name from Associative Array(转)

通过AssocArray.GetAssociativeArray的静态方法获取对象的阵列,然后通过SourceEntities源实体来获取块名。

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(Rivilis.CheckAssocArray))]

namespace Rivilis
{

  public class CheckAssocArray
  {
    [CommandMethod("CAR")]
    public void MyCommand()
    {
      // Put your command code here
      Document doc = Application.DocumentManager.MdiActiveDocument;
      if (doc == null) return;
      Editor ed = doc.Editor;
      PromptEntityOptions prOpt = new PromptEntityOptions("Select Assoc Array: ");
      prOpt.SetRejectMessage("Not a Assoc Array");
      prOpt.AddAllowedClass(typeof(BlockReference), true);
      PromptEntityResult prRes = ed.GetEntity(prOpt);
      if (prRes.Status == PromptStatus.OK)
      {
        AssocArray asArr = AssocArray.GetAssociativeArray(prRes.ObjectId);
        if (asArr == null)
        {
          ed.WriteMessage("\nNot a Assoc Array");
          return;
        }
        ObjectIdCollection ids = asArr.SourceEntities;
        if (ids.Count >= 1)
        {
          ObjectId id = ids[0]; // Check only first entity in Array
          if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference))))
          {
            using (BlockReference br = id.Open(OpenMode.ForRead) as BlockReference)
            {
              using (BlockTableRecord btr = br.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord)
              {
                ed.WriteMessage("\nBlockName = {0}", btr.Name);
              }
            }
          } else
          {
            ed.WriteMessage("\nAssoc Array has not BlockReference");
          }
        }
      }
    }
  }
}

如果阵列后替换过块,原文是通过炸开阵列来判段。

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Linq;

#pragma warning disable 0618

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(Rivilis.CheckAssocArray))]

namespace Rivilis
{
  public class CheckAssocArray
  {
    public string GetBlockNameInBlock(BlockReference br)
    {
      string name = null;
      using (BlockTableRecord btr =
        br.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord)
      {
        name = btr.Name;
        // If block has only one entity == BlockReference
        // then getting name of this block
        if (btr.Cast<ObjectId>().Count() == 1)
        {
          ObjectId id = btr.Cast<ObjectId>().ElementAt(0);
          if (id.ObjectClass == RXClass.GetClass(typeof(BlockReference)))
          {
            using (BlockReference brInt =
              id.Open(OpenMode.ForRead) as BlockReference)
            using (BlockTableRecord btrInt =
              brInt.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord)
            {
              name = btrInt.Name;
            }
          }
        }
      }
      return name;
    }
    [CommandMethod("CAR")]
    public void MyCommand()
    {
      // Put your command code here
      Document doc = Application.DocumentManager.MdiActiveDocument;
      if (doc == null) return;
      Editor ed = doc.Editor;
      PromptEntityOptions prOpt = new PromptEntityOptions("Select Assoc Array: ");
      prOpt.SetRejectMessage("Not a Assoc Array");
      prOpt.AddAllowedClass(typeof(BlockReference), true);
      PromptEntityResult prRes = ed.GetEntity(prOpt);
      if (prRes.Status != PromptStatus.OK)
        return;
      if (!AssocArray.IsAssociativeArray(prRes.ObjectId))
      {
        ed.WriteMessage("\nNot a Assoc Array");
        return;
      }
      using (BlockReference br = prRes.ObjectId.Open(OpenMode.ForRead) as BlockReference)
      {
        using (DBObjectCollection brs = new DBObjectCollection())
        {
          br.Explode(brs);
          if (brs != null && brs.Count > 0)
          {
            int i = 0;
            foreach (DBObject obj in brs)
            {
              if (obj is BlockReference &&
                (obj as BlockReference).Layer != "*ADSK_ASSOC_ENTITY_BACKUPS")
              {
                ed.WriteMessage("\n{0} - {1}", i++, GetBlockNameInBlock(obj as BlockReference));
              }
              obj.Dispose();
            }
          }
        }
      }
    }
  }
}

应该有更好的方式,不过得理解AutoCAD Associative Framework的组织。

原始链接:https://forums.autodesk.com/t5/net/getting-block-name-from-associative-array/m-p/8479018

posted @ 2021-04-27 10:48  智图CAD  阅读(307)  评论(0编辑  收藏  举报