Can any one guide how to implement select similar functionality using .net interface.
Issue facing: Am trying to get all the entities in drawing by block reference name ..But only one element is coming as result set ..But if right click and use select similar command all the similar block references are getting selected.
I am clueless what am i missing in this case?
Hi,
Here's a little example:
[CommandMethod("SELECTBLOCKBYNAME")] public static void SelectBlockByName() { var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var peo = new PromptEntityOptions("\nSelect a block: "); peo.SetRejectMessage("\nselected object is not a block reference."); peo.AddAllowedClass(typeof(BlockReference), true); var per = ed.GetEntity(peo); if (per.Status == PromptStatus.OK) { ObjectId[] ids; using (var tr = db.TransactionManager.StartOpenCloseTransaction()) { string GetEffectiveName(BlockReference br) => br.IsDynamicBlock ? ((BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead)).Name : br.Name; var source = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead); var name = GetEffectiveName(source); ids = ((BlockTableRecord)tr.GetObject(source.OwnerId, OpenMode.ForRead)) .Cast<ObjectId>() .Where(id => id.ObjectClass.DxfName == "INSERT") .Select(id => (BlockReference)tr.GetObject(id, OpenMode.ForRead)) .Where(br => GetEffectiveName(br) == name) .Select(br => br.ObjectId) .ToArray(); } ed.SetImpliedSelection(ids); } }
Hi @_gile
Thanks for the instant reply. But how to change this particular code
ids = ((BlockTableRecord)tr.GetObject(source.OwnerId, OpenMode.ForRead)) .Cast<ObjectId>() .Where(id => id.ObjectClass.DxfName == "INSERT") .Select(id => (BlockReference)tr.GetObject(id, OpenMode.ForRead)) .Where(br => GetEffectiveName(br) == name) .Select(br => br.ObjectId) .ToArray();
In the above code snippet
((BlockTableRecord)tr.GetObject(source.OwnerId, OpenMode.ForRead)) .Cast<ObjectId>()
How to avoid the above if i have only block name and not prompting
user to select a type from the user interface
Previously was using a function like this
static private ObjectIdCollection GetAllBlockReferenceByName(string name, Database db)
{
ObjectIdCollection ids_temp = null, ids = new ObjectIdCollection();
Transaction tr = db.TransactionManager.StartTransaction();
try
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[name], OpenMode.ForRead);
BlockTableRecord btr_model = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
ObjectId id_model = btr_model.ObjectId;
ids_temp = btr.GetBlockReferenceIds(true, true);
foreach (ObjectId id in ids_temp)
{
DBObject obj = (DBObject)tr.GetObject(id, OpenMode.ForWrite);
if (obj.OwnerId == id_model)
{
ids.Add(id);
}
}
tr.Commit();
}
finally
{
tr.Dispose();
}
return ids;
}
Assuming the block is not a dynamic block, you can try this:
private static ObjectId[] GetAllBlockReferenceByName(string name, Database db) { using (var tr = db.TransactionManager.StartOpenCloseTransaction()) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(name)) return null; var msId = SymbolUtilityServices.GetBlockModelSpaceId(db); var btr = (BlockTableRecord)tr.GetObject(bt[name], OpenMode.ForRead); return btr.GetBlockReferenceIds(true, true) .Cast<ObjectId>() .Where(id => tr.GetObject(id, OpenMode.ForRead).OwnerId == msId) .ToArray(); } }
Testing command:
[CommandMethod("TEST")] public static void Test() { var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var pr = ed.GetString("\nBlock Name: "); if (pr.Status != PromptStatus.OK) return; var ids = GetAllBlockReferenceByName(pr.StringResult, db); if (ids == null) ed.WriteMessage($"\nBloc '{pr.StringResult}' not found."); else ed.SetImpliedSelection(ids); }
This one will also work with dynamic blocks
private static ObjectId[] GetAllBlockReferenceByName(string name, Database db) { using (var tr = db.TransactionManager.StartOpenCloseTransaction()) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(name)) return null; var msId = SymbolUtilityServices.GetBlockModelSpaceId(db); var btr = (BlockTableRecord)tr.GetObject(bt[name], OpenMode.ForRead); return btr.GetBlockReferenceIds(true, true) .Cast<ObjectId>() .Concat(btr.GetAnonymousBlockIds() .Cast<ObjectId>() .SelectMany(anonId => ((BlockTableRecord)tr.GetObject(anonId, OpenMode.ForRead)) .GetBlockReferenceIds(true, true) .Cast<ObjectId>())) .Where(id => tr.GetObject(id, OpenMode.ForRead).OwnerId == msId) .ToArray(); } }
Can't find what you're looking for? Ask the community or share your knowledge.