Hi,
Here're two little sample to get all references, whatever their nesting level, of the blocks which names match the supplied wild-card pattern argument.
Both functions return an ObjectIdCollection
"Imperative" style using C#
public static ObjectIdCollection GetAllBlockReferencesByNames(string pattern)
{
Database db = HostApplicationServices.WorkingDatabase;
ObjectIdCollection result = new ObjectIdCollection();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId id in bt)
{
BlockTableRecord btr = (BlockTableRecord)id.GetObject(OpenMode.ForRead);
if (Utils.WcMatch(btr.Name, pattern))
{
foreach (ObjectId refId in btr.GetBlockReferenceIds(true, false))
{
BlockTableRecord owner;
if (IsPrimary(refId, out owner))
result.Add(refId);
else
GetNestedReferences(refId, owner, ref result);
}
}
}
tr.Commit();
}
return result;
}
private static void GetNestedReferences(ObjectId refId, BlockTableRecord btr, ref ObjectIdCollection result)
{
foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
{
BlockTableRecord owner;
if (IsPrimary(id, out owner))
result.Add(refId);
else
GetNestedReferences(refId, owner, ref result);
}
}
private static bool IsPrimary(ObjectId id, out BlockTableRecord owner)
{
BlockReference br = (BlockReference)id.GetObject(OpenMode.ForRead);
owner = (BlockTableRecord)br.OwnerId.GetObject(OpenMode.ForRead);
return owner.IsLayout;
}
"Functional" style using F#
let getAllRefs pat =
let db = HostApplicationServices.WorkingDatabase
use tr = db.TransactionManager.StartTransaction()
let getOwner id =
let br = tr.GetObject(id, OpenMode.ForRead) :?> BlockReference
tr.GetObject(br.OwnerId, OpenMode.ForRead) :?> BlockTableRecord
let rec getNested (refId:ObjectId) (btr:BlockTableRecord) =
btr.GetBlockReferenceIds(true, false)
|> Seq.cast<ObjectId>
|> Seq.collect(fun id ->
let owner = getOwner id
if owner.IsLayout then Seq.singleton refId else getNested refId owner)
new ObjectIdCollection(
tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
|> Seq.cast<ObjectId>
|> Seq.map(fun id -> tr.GetObject(id, OpenMode.ForRead) :?> BlockTableRecord)
|> Seq.filter(fun btr -> Utils.WcMatch(btr.Name, pat))
|> Seq.collect(fun btr ->
btr.GetBlockReferenceIds(true, false)
|> Seq.cast<ObjectId>
|> Seq.collect(fun id ->
let owner = getOwner id
if owner.IsLayout then Seq.singleton id else getNested id owner))
|> Seq.toArray)