Here're some examples assuming you want to get all the ObjectIds of block references inserted into model space.
The first method uses the Editor.SelectAll method. To filter blocks in paper spaces too only, you can remove the TypedValue(410, "Model") from the filter.
For this method you need acces to the AutoCAD editor (i.e. the drawing is opened in the editor).
private ObjectIdCollection SelectAllReferences()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
TypedValue
[] filter
= new TypedValue
[2] { new TypedValue
(0,
"INSERT"),
new TypedValue
(410,
"Model") }; PromptSelectionResult psr
= ed
.SelectAll(new SelectionFilter
(filter
)); if (psr.Status != PromptStatus.OK)
return new ObjectIdCollection
(); return new ObjectIdCollection
(psr
.Value.GetObjectIds()); }
This other method 'hard codes' the SelectAll() method iterating the model space BlockTableRecord.
It can be used without acces to the Editor (i.e. with side Database)
private ObjectIdCollection GetAllReferences(Database db)
{
ObjectIdCollection retVal
= new ObjectIdCollection
(); RXClass brClass
= RXClass
.GetClass(typeof(BlockReference
)); using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord model =
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
foreach (ObjectId id in model)
{
if (id.ObjectClass == brClass)
{
retVal.Add(id);
}
}
}
return retVal;
}
The same one written in a more functional/declarative style with the Linq extension methods.
private ObjectIdCollection GetAllReferencesDeclarative(Database db)
{
RXClass brClass
= RXClass
.GetClass(typeof(BlockReference
)); using (Transaction tr = db.TransactionManager.StartTransaction())
{
var ids =
((BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead))
.Cast<ObjectId>()
.Where(id => id.ObjectClass == brClass)
.ToArray();
return ids
.Length > 0 ? new ObjectIdCollection
(ids
) : new ObjectIdCollection
(); }
}
This last method uses a reverse process. It gets the block refrences from the block definitions in the BlockTable. It needs to evaluate the reference owner to know if it's the model space (or a layout) or another BlockTableRecord (for nested blocks).
It may be faster than the others if they're many entities in the drawing that aren't block references.
private ObjectIdCollection GetAllReferencesFromRecords(Database db)
{
ObjectIdCollection retVal
= new ObjectIdCollection
(); using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId btrId in bt)
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
if (!btr.IsLayout)
{
foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
{
BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
BlockTableRecord owner = (BlockTableRecord)tr.GetObject(br.OwnerId, OpenMode.ForRead);
if (owner.Name == "*Model_Space")
{
retVal.Add(br.ObjectId);
}
}
}
}
}
return retVal;
}
The same method using Linq:
private ObjectIdCollection GetAllReferencesFromRecordsDeclarative(Database db)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
var ids = ((BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead))
.Cast<ObjectId>()
.Select(id => (BlockTableRecord)id.GetObject(OpenMode.ForRead))
.Where(btr => !btr.IsLayout)
.SelectMany(btr => btr.GetBlockReferenceIds(true, false).Cast<ObjectId>())
.Select(id => (BlockReference)id.GetObject(OpenMode.ForRead))
.Where(br => ((BlockTableRecord)br.OwnerId.GetObject(OpenMode.ForRead)).Name == "*Model_Space")
.Select(br => br.ObjectId)
.ToArray();
return ids
.Count() > 0 ? new ObjectIdCollection
(ids
) : new ObjectIdCollection
(); }
}