[CommandMethod("TestDynamic")]
public void getDynamicBlocks()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo
= new PromptEntityOptions
("\nSelect Block"); peo.SetRejectMessage("\nNot a BlockReference!");
peo
.AddAllowedClass(typeof(BlockReference
),
true); PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
string BlockName;
using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockReference br = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
BlockTableRecord testblockdef = (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
BlockName = testblockdef.Name;
}
Stopwatch timer
= new Stopwatch
(); timer.Start();
List<BlockReference> dynamicblocks = GetDynamicLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using LINQ method", timer.Elapsed, timer.ElapsedTicks, dynamicblocks.Count, timer.ElapsedTicks / dynamicblocks.Count);
timer.Reset();
timer.Start();
List<BlockReference> mydynamicblocks = MyGetDynamicLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using my method", timer.Elapsed, timer.ElapsedTicks, mydynamicblocks.Count, timer.ElapsedTicks/ mydynamicblocks.Count);
timer.Reset();
timer.Start();
List<BlockReference> xdatablocks = GetLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using Kean's method", timer.Elapsed, timer.ElapsedTicks, xdatablocks.Count, timer.ElapsedTicks/ xdatablocks.Count);
timer.Reset();// <---- Fixed... Thanks Jeff!
timer.Start();
List<BlockReference> dynamicblocks2 = GetDynamicLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using LINQ method", timer.Elapsed, timer.ElapsedTicks, dynamicblocks2.Count, timer.ElapsedTicks/ dynamicblocks2.Count);
timer.Reset();
timer.Start();
List<BlockReference> mydynamicblocks2 = MyGetDynamicLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using my method", timer.Elapsed, timer.ElapsedTicks, mydynamicblocks2.Count, timer.ElapsedTicks/ mydynamicblocks2.Count);
timer.Reset();
timer.Start();
List<BlockReference> xdatablocks2 = GetLabelInserts(doc, db, ed, BlockName);
timer.Stop();
ed.WriteMessage("\nTook {0} ({1} ticks) to get {2} blocks ({3} ticks/block) using Kean's method", timer.Elapsed, timer.ElapsedTicks, xdatablocks2.Count, timer.ElapsedTicks/ xdatablocks2.Count);
}
// LINQ method
public List<BlockReference> GetDynamicLabelInserts(Document doc, Database db, Editor ed, string BlockName)
{
List
<BlockReference
> labels
= new List
<BlockReference
>(); using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
//don't waste time if the block isn't in the drawing
if (!bt.Has(BlockName))
{
ed.WriteMessage("/nCannot find block {0}", BlockName);
return labels;
}
BlockTableRecord ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockName], OpenMode.ForRead);
Handle blkHandle = btr.Handle;
IEnumerable<BlockReference> potentials = ps.GetObjects<BlockReference>(OpenMode.ForRead).Where(BlockReference => BlockReference.Name == BlockName || BlockReference.IsDynamicBlock == true);
foreach (BlockReference block in potentials)
{
if (block.Name == BlockName)
{
labels.Add(block);
continue;
}
BlockTableRecord blockDef = (BlockTableRecord)tr.GetObject(block.DynamicBlockTableRecord, OpenMode.ForRead);
if (blockDef.Name == BlockName)
{
labels.Add(block);
continue;
}
}
tr.Commit();
}
return labels;
}
// My mod to Kean's method
public List<BlockReference> MyGetDynamicLabelInserts(Document doc, Database db, Editor ed, string BlockName)
{
List
<BlockReference
> labels
= new List
<BlockReference
>(); using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
//don't waste time if the block isn't in the drawing
if (!bt.Has(BlockName))
{
ed.WriteMessage("/nCannot find block {0}", BlockName);
return labels;
}
BlockTableRecord ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockName], OpenMode.ForRead);
Handle blkHandle = btr.Handle;
foreach (ObjectId id in ps)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent != null)
{
BlockReference br = ent as BlockReference;
if (br != null)
{
if (br.Name == BlockName)
{
labels.Add(br);
}
else
{
if (br.IsDynamicBlock == true)
{
BlockTableRecord btr2 = (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
if (btr2.Name == BlockName)
{
labels.Add(br);
}
}
}
}
}
}
tr.Commit();
}
return labels;
}
//Kean's method
public List<BlockReference> GetLabelInserts(Document doc, Database db, Editor ed, string BlockName)
{
List
<BlockReference
> labels
= new List
<BlockReference
>(); using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
//don't waste time if the block isn't in the drawing
if (!bt.Has(BlockName))
{
ed.WriteMessage("/nCannot find block {0}", BlockName);
return labels;
}
BlockTableRecord ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockName], OpenMode.ForRead);
Handle blkHandle = btr.Handle;
foreach (ObjectId id in ps)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent != null)
{
BlockReference br = ent as BlockReference;
if (br != null)
{
BlockTableRecord bd =
(BlockTableRecord)tr.GetObject(
br.BlockTableRecord,
OpenMode.ForRead
);
if (bd.Name == BlockName)
{
labels.Add(br);
//ed.WriteMessage("\n{0},{1}", br.Position, br.Rotation);
}
else
{
BlockTableRecord btr2 = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
var xdata = btr2.XData;
if (xdata != null)
{
// Get the XData as an array of TypeValues and loop
// through it
var tvs = xdata.AsArray();
for (int i = 0; i < tvs.Length; i++)
{
// The first value should be the RegAppName
var tv = tvs[i];
if (
tv.TypeCode == (int)DxfCode.ExtendedDataRegAppName
)
{
// If it's the one we care about...
if ((string)tv.Value == "AcDbBlockRepBTag")
{
// ... then loop through until we find a
// handle matching our blocks or otherwise
// another RegAppName
for (int j = i + 1; j < tvs.Length; j++)
{
tv = tvs[j];
if (
tv.TypeCode ==
(int)DxfCode.ExtendedDataRegAppName
)
{
// If we have another RegAppName, then
// we'll break out of this for loop and
// let the outer loop have a chance to
// process this section
i = j - 1;
break;
}
if (
tv.TypeCode ==
(int)DxfCode.ExtendedDataHandle
)
{
// If we have a matching handle...
if ((string)tv.Value == blkHandle.ToString())
{
// ... then we can add the block's name
// to the list and break from both loops
// (which we do by setting the outer index
// to the end)
labels.Add(br);
//ed.WriteMessage("\n{0},{1}", br.Position, br.Rotation);
i = tvs.Length - 1;
break;
}
}
}
}
}
}
}
}
}
}
}
tr.Commit();
}
return labels;
}