This one seems to work fine with a selected block reference.
static IEnumerable<Matrix3d> GetNestedBlockTransform(BlockReference br, Matrix3d xform, string nestedBlockName)
{
xform *= br.BlockTransform;
string blockName = ((BlockTableRecord)br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead)).Name;
if (blockName == nestedBlockName)
{
yield return xform;
}
else
{
var btr = (BlockTableRecord)br.BlockTableRecord.GetObject(OpenMode.ForRead);
var nestedBrs = btr
.Cast<ObjectId>()
.Where(id => id.ObjectClass.Name == "AcDbBlockReference")
.Select(id => (BlockReference)id.GetObject(OpenMode.ForRead));
foreach (var nestedBr in nestedBrs)
{
foreach (var matrix in GetNestedBlockTransform(nestedBr, xform, nestedBlockName))
{
yield return matrix;
}
}
}
}
A testing command:
[CommandMethod("TEST")]
public static void Test()
{
var doc = AcAp.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var filter = new SelectionFilter(new[] { new TypedValue(0, "INSERT") });
var selection = ed.GetSelection(filter);
if (selection.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
if (bt.Has(blockToInsertName))
{
foreach (var id in selection.Value.GetObjectIds())
{
var source = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
foreach (var xform in GetNestedBlockTransform(source, Matrix3d.Identity, nestedBlockName))
{
var br = new BlockReference(Point3d.Origin, bt[blockToInsertName]);
br.TransformBy(xform);
curSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
}
}
}
tr.Commit();
}
}