Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

How to purge useless blocks generated by importing sidedb, anonymous blocks

swaywood
Collaborator

How to purge useless blocks generated by importing sidedb, anonymous blocks

swaywood
Collaborator
Collaborator

Hello,my question is like this.
Inserting sidedb into the current drawing will import many useless blocks, anonymous blocks, etc
I want to precisely purge all of these now,

but I need to keep all the blocks before inserting action.

I have some code, but it will purge all the blocks.

I see a method
Public void Purge (ObjectidGraph idGraph);
But I don't know how to use it to achieve my goal.

    public static void PurgeBlock(this Database db)
    {
      string sLine = db.OriginalFileName;
      using (var tr = db.TransactionManager.StartTransaction())
      {
        try
        {
          #region 块
          var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
          ObjectIdCollection idsBt;
          do
          {
            idsBt = new ObjectIdCollection(bt.Cast<ObjectId>().ToArray());
            db.Purge(idsBt);
            foreach (ObjectId id in idsBt)
            {
              tr.GetObject(id, OpenMode.ForWrite).Erase();
            }
          } while (0 < idsBt.Count);
          #endregion 块        
        }
        catch (SystemException ex1)
        {
          string message = string.Format("错误名称:【{0}】\nStackTrace:【{1}】\n:TargetSite【{2}】\n【{3}】",
            ex1.Message, ex1.StackTrace.ToString(), ex1.TargetSite.ToString(), sLine);
          TestHelper.AddError(message);
        }
        catch (Runtime.Exception ex2)
        {
          string message = string.Format("错误名称:【{0}】\nStackTrace:【{1}】\n:TargetSite【{2}】,【{3}】",
            ex2.Message, ex2.StackTrace.ToString(), ex2.TargetSite.ToString(), sLine);
          TestHelper.AddError(message);
        }
        tr.Commit();
      }
    }
0 Likes
Reply
Accepted solutions (1)
314 Views
3 Replies
Replies (3)

ActivistInvestor
Advisor
Advisor
Accepted solution

You can use the overload of Purge() that takes an ObjectIdCollection.

 

That method doesn't actually purge anything, it simply returns the ObjectIds of objects that can be purged (e.g., the same ones the Purge command would allow you to purge).  You just need to erase them, and that's it. You may need to call the method multiple times, because erasing some objects can cause other objects to become unreferenced. The other method that takes an ObjectIdGraph can be used to do it in a single pass, by traversing the graph and erasing objects along the way.

 

   public static class Purger
   {
      public static int PurgeAll()
      {
         using(Transaction tr = new OpenCloseTransaction())
         {
            Database db = HostApplicationServices.WorkingDatabase;
            ObjectIdCollection ids = new ObjectIdCollection();
            int count = 0;
            while(true)
            {
               db.Purge(ids);
               if(ids.Count == 0)
                  break;
               count += ids.Count;
               for(int i = 0; i < ids.Count; i++)
               {
                  var obj = tr.GetObject(ids[i], OpenMode.ForWrite, false, true);
                  obj.Erase(true);
               }
               ids.Clear();
            }
            tr.Commit();
            return count;
         }
      }
   }
0 Likes

swaywood
Collaborator
Collaborator

ActivistInvestor,
thanks for your reply.
I found that blocktablerecord was cleared after running the following code.

 

 

    public static ObjectIdCollection GetCanPurgeObjectids(this Database db)
    {
      using (Transaction tr = new OpenCloseTransaction())
      {
        ObjectIdCollection idsA = new ObjectIdCollection();
        var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        ObjectIdCollection ids;

        while (true)
        {
          ids = new ObjectIdCollection(bt.Cast<ObjectId>().ToArray());

          db.Purge(ids);
          if (ids.Count == 0)
            break;
          for (int i = 0; i < ids.Count; i++)
          {
            var obj = tr.GetObject(ids[i], OpenMode.ForWrite, false, true);
            obj.Erase(false);
            idsA.Add(ids[i]);
          }
          ids.Clear();
        }
        tr.Commit();
        return idsA;
      }
    }

0 Likes

swaywood
Collaborator
Collaborator

I got it,

just don't submit it

0 Likes