The objects stored in the database get an handle value that gets incremented sequentially, so the fastest approach if one wants to iterate through the whole content of a Database, is to start from handle = 1 to the max handle existing in the Database. P/Invoking "acdbHandEnt" can then help to retrieve the ObjectId from an handle.
The following C# code illustrates how to do that:
public struct ads_name
{
public IntPtr a;
public IntPtr b;
};
[DllImport("acdb19.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "acdbHandEnt")]
public static extern int acdbHandEnt(
string handle, ref ads_name name);
[CommandMethod("IterateDb")]
static public void IterateDb()
{
ads_name ename = new ads_name();
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ObjectIdCollection validIds = new ObjectIdCollection();
// now get the last handle in the db
Handle handseed = db.Handseed;
// copy the handseed total into an efficient raw datatype
long handseedTotal = handseed.Value;
// loop from 0 to the last handle (this could be a big loop)
for (long i = 1; i < handseedTotal; ++i)
{
string handle = Convert.ToString(i, 16);
// get the ename by converting
// the long to a hex value string
int res = acdbHandEnt(handle, ref ename);
if (res != 5100) // RTNORM
continue;
// convert the ename to an objectid
ObjectId id = new ObjectId(ename.a);
// check if it’s a valid objectId
if (!id.IsValid)
continue;
try
{
// open if not erased
using (DBObject obj =
id.Open(OpenMode.ForRead, false))
{
validIds.Add(id);
}
}
catch
{
}
}
ed.WriteMessage("\nNumber of retrieved valid ObjectIds: "
+ validIds.Count.ToString());
validIds.Clear();
}
<
p style=”line-height: normal;margin: 0in 0in 0pt” class=”MsoNormal”>

Leave a Reply