Hi all - I'm trying to create a plugin which iterates through every block nested within a given block, determines whether it is "Machine Readable" using block comments, and if it is opens it in a new file and then saves that file as a .dxf file. I originally planned to use a recursive helper function to accomplish this, but evidently I misunderstood the anatomy of the BlockTableRecord class. I assumed that a block's BlockTableRecord would contain pointers to the BlockTableRecords of its component nested blocks, but this does not seem to be the case. Does anyone have advice as to how I could accomplish this? Thanks.
PS - I have included my current code below:
[CommandMethod("TOCSV", CommandFlags.Session)]
public void ToCSV()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Database db = Application.DocumentManager.MdiActiveDocument.Database;
string rootPath = Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\" + "TOCSV").FullName;
string[] dirs = Directory.GetDirectories(rootPath);
//Note: ask andrew about potential security vulnerabilites with above filepath
//TODO: Implement "Export files to X" functionality
//TODO: CSV Functionality
//Gets name of block to convert and begins transaction
PromptStringOptions selectedBlockOptions = new PromptStringOptions("Enter the name of the block to convert : ");
selectedBlockOptions.AllowSpaces = true;
PromptResult selectedBlockResult = ed.GetString(selectedBlockOptions);
if (selectedBlockResult.Status == PromptStatus.OK)
{
Transaction trans = db.TransactionManager.StartTransaction();
try
{
//Checks to see if block name exists
BlockTable bT = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
if (!(bT.Has(selectedBlockResult.StringResult)))
{
ed.WriteMessage("There is no block with that name. No directory was created.");
return;
}
BlockTableRecord bTR = (BlockTableRecord)trans.GetObject(bT[selectedBlockResult.StringResult], OpenMode.ForRead);
//Create directory if definition contains _MR_ or _NMR_
string newDir = rootPath + @"\" + selectedBlockResult.StringResult + "_" + DateTime.Now.ToString("yyyyMMddHHmmss");
ed.WriteMessage("Your files are located at " + newDir);
var newDirInfo = Directory.CreateDirectory(newDir);
System.Diagnostics.Process.Start("explorer.exe", newDir);
ed.WriteMessage("Dir Info: " + newDirInfo);
//below I call the nonfunctional helper function
ed.WriteMessage(bTR.Comments);
BTRRecursor(bTR, newDir);
}
catch
{
}
finally
{
trans.Dispose();
}
}
}
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
Here's an example of recursive method to get the BlockTableRecords of all nested BlockReferences in the source BlockTableRecord.
static void GetNestedBlocks(BlockTableRecord sourceBtr, Transaction tr, HashSet<BlockTableRecord> blocks)
{
var brClass = RXObject.GetClass(typeof(BlockReference));
foreach (ObjectId id in sourceBtr)
{
if (id.ObjectClass == brClass)
{
var br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
if (blocks.Add(btr))
{
GetNestedBlocks(btr, tr, blocks);
}
}
}
}
I also replied you in stackoverflow with another example in a more functional style.