.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Getting and exporting all nested blocks within a given block

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
tyler.stevens979L4
452 Views, 4 Replies

Getting and exporting all nested blocks within a given block

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();
                }
            }
        }
Tags (1)
Labels (1)
4 REPLIES 4
Message 2 of 5
_gile
in reply to: tyler.stevens979L4

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);
                    }
                }
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 5
_gile
in reply to: _gile

Using snippet:

var blocks = new HashSet<BlockTableRecord>();
GetNestedBlocks(bTR, trans, blocks);
foreach (BlockTableRecord block in blocks)
{
    // do your stuff with block
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 5
_gile
in reply to: _gile

I also replied you in stackoverflow with another example in a more functional style.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 5
tyler.stevens979L4
in reply to: _gile

Thanks so much! I'll work on trying to implement this soon. 🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost