.NET

Reply
Active Contributor
chikito1990
Posts: 40
Registered: ‎06-26-2013
Message 1 of 6 (516 Views)
Accepted Solution

Retrieve a block and its position from DWG file

516 Views, 5 Replies
07-01-2013 03:59 AM

Hi all,

 

How can I retrive a block from DWG file using Objectarx SDK.

 

Lets say I have a cinema hall design with a lot of chairs and I am using a blcok named chair to design it. Now I want to retrive this blocks and their positions. Is it possible?

 

Any help will be apreciated. Thank you in advance!

 

Best regards,

Dimitar Georgiev

Hi,

 

here's an example:

 

 private void ExportCsv(Database db, string blockName, string fileName)
{
string separator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
RXClass rxc = RXClass.GetClass(typeof(BlockReference));
using (Transaction tr = db.TransactionManager.StartTransaction())
using (StreamWriter writer = new StreamWriter(fileName))
{
BlockTableRecord modelSpace =
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
foreach (ObjectId id in modelSpace)
{
if (id.ObjectClass == rxc)
{
BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
if (br.Name.Equals(blockName, StringComparison.CurrentCultureIgnoreCase))
{
writer.WriteLine(string.Join(separator, br.Position.ToArray()));
}
}
}
tr.Commit();
}
}

 

or, in a more 'declarative style' using Linq:

 

 private void ExportCsv(Database db, string blockName, string fileName)
{
string separator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
RXClass rxc = RXClass.GetClass(typeof(BlockReference));
using (Transaction tr = db.TransactionManager.StartTransaction())
using (StreamWriter writer = new StreamWriter(fileName))
{
foreach (BlockReference br in (
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead))
.Cast<ObjectId>()
.Where(id => id.ObjectClass == rxc)
.Select(id => (BlockReference)tr.GetObject(id, OpenMode.ForRead))
.Where(br => br.Name.Equals(blockName, StringComparison.CurrentCultureIgnoreCase)))
{
writer.WriteLine(string.Join(separator, br.Position.ToArray()));
}
tr.Commit();
}
}

 

Try complete class, change project name to your project,

tested through A2009-14 (Win 7, 32 bit)

Command to write blocks: BLX

#region "Namespaces"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.IO;
#endregion
[assembly: CommandClass(typeof(ACAD2014_1.BlocksCommands))]
namespace ACAD2014_1
{
public static class BlocksCommands
{
//______________________________________________To Dimitar________________________________________________//
public static T GetObject<T>(this ObjectId id) where T : DBObject
{
return id.GetObject(OpenMode.ForRead, false, false) as T;
}
public static IEnumerable<T> GetObjects<T>(this IEnumerable ids) where T : DBObject
{
return ids
.Cast<ObjectId>()
.Select(id => id.GetObject(OpenMode.ForRead, false, false))
.OfType<T>();
}
public static Dictionary<string, ObjectId> GetAttributeDefinitions(this BlockReference br)
{
BlockTableRecord btr = (BlockTableRecord)(br.IsDynamicBlock ? br.BlockTableRecord.GetObject(OpenMode.ForRead,false) : br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead,false));
Dictionary<string, ObjectId> attdefs =
btr.GetObjects<AttributeDefinition>()
.ToDictionary(
a => a.Tag,
a => a.ObjectId,
StringComparer.OrdinalIgnoreCase);
return attdefs;
}
public static string[] GetBlockNamesInDrawing(Database db)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
return db.BlockTableId
.GetObject<BlockTable>()
.GetObjects<BlockTableRecord>()
.Where(btr =>
!btr.IsAnonymous &&
!btr.IsFromExternalReference &&
!btr.IsFromOverlayReference &&
!btr.IsLayout &&
!btr.IsAProxy)
.Select(btr => btr.Name)
.ToArray();
}
}
public static ObjectId[] GetBlockIdsOnLayout(Database db, string layoutName, string blockName)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
return ((BlockTableRecord)
((Layout)LayoutManager.Current.GetLayoutId(layoutName).GetObject(OpenMode.ForRead, false)).BlockTableRecordId
.GetObject(OpenMode.ForRead, false))
.GetObjects<BlockReference>()
.Where(br => EffectiveName(br).Equals(blockName))
.Select(bl => bl.ObjectId).ToArray();
}
}
static public string EffectiveName(BlockReference bref)
{
BlockTableRecord btr = null;
if (bref.IsDynamicBlock) //| (bref.Name.StartsWith("`*U*", StringComparison.InvariantCultureIgnoreCase)))
{
btr = bref.DynamicBlockTableRecord.GetObject( OpenMode.ForRead) as BlockTableRecord;
}
else if (bref.Name.StartsWith("`*U*", StringComparison.InvariantCultureIgnoreCase))
{
//if (btr.IsAnonymous)
//{
BlockTableRecord anbtr = bref.AnonymousBlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
ObjectIdCollection ids = anbtr.GetAnonymousBlockIds();
btr = ids[0].GetObject(OpenMode.ForRead) as BlockTableRecord;
//}
}
else
{
btr = bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
}
return btr.Name;
}
public static string[] GetBlockNamesOnLayout(Database db, string layoutName, string blockName)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
return ((BlockTableRecord)
((Layout)LayoutManager.Current.GetLayoutId(layoutName).GetObject(OpenMode.ForRead, false)).BlockTableRecordId
.GetObject(OpenMode.ForRead, false))
.GetObjects<BlockReference>()
.Where(bl => EffectiveName(bl) == blockName)
.Select(bl => EffectiveName(bl))
.ToArray();
}
}
[CommandMethod("blx")]
static public void testLayoutBlocksToFile()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
string layoutName = LayoutManager.Current.CurrentLayout;
string filename = "";
PromptStringOptions pso =
new PromptStringOptions("\nEnter block name (case-sensitive): ");
pso.AllowSpaces = true;
PromptResult res;
res = ed.GetString(pso);
if (res.Status != PromptStatus.OK)
return;
string blkname = res.StringResult;
ed.WriteMessage("\nBlock Name Entered\t{0}", blkname);
// string blkname = "wall";
List<List<string>> data = new List<List<string>>();
try
{
string[] blocks = GetBlockNamesOnLayout(HostApplicationServices.WorkingDatabase, layoutName, blkname);
ed.WriteMessage("\n\t---\tResult: {0}\n", blocks.GetUpperBound(0));
foreach (string bname in blocks)
{
ed.WriteMessage("\nBlock Name: {0}\n", bname);
}
ObjectId[] ids = GetBlockIdsOnLayout(db, layoutName, blkname);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
ObjectId btrid = bt[blkname];
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrid, OpenMode.ForRead);
List<string> headers = btr.GetObjects<AttributeDefinition>().Select(x => x.Tag).ToList();
headers.Insert(0, "Block Name");
headers.Insert(1, "Handle");
headers.Insert(2, "X");
headers.Insert(3, "Y");
headers.Insert(4, "Z");
headers.Insert(5, "Rotation");
data.Add(headers);
int i = 1;
foreach (ObjectId id in ids)
{
BlockReference bref = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
List<string> blockdata = bref.AttributeCollection.GetObjects<AttributeReference>().Select(x => x.TextString).ToList();
blockdata.Insert(0, EffectiveName(bref));
blockdata.Insert(1, bref.Handle.ToString());
Point3d bp = bref.Position;
blockdata.Insert(2, string.Format("{0:f3}", bp.X));
blockdata.Insert(3, string.Format("{0:f3}", bp.Y));
blockdata.Insert(4, string.Format("{0:f3}", bp.Z));
double rot = bref.Rotation;
blockdata.Insert(5, string.Format("{0:f3}", rot));
data.Add(blockdata);
i++;
}
// just to diplay result:
foreach (List<string> item in data)
{
string msg = "";
foreach (string st in item)
{
msg = msg + st + " :: ";
}
ed.WriteMessage("\nBlock Info\t{0}\n", msg);
}
string dirPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
filename = System.IO.Path.Combine(dirPath, "myblocks.csv");
//string filename = Path.Combine(@"C:\Test", "myblocks.csv");
WriteToTextFile(filename, ListsToCsv(data, "\t"));
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\n" + ex.Message);
}
finally
{
// display a text file just for info, optional
System.Diagnostics.Process.Start(filename);
}
}
// by O'Reily
public static void WriteToTextFile(string fileName, string txt)
{
if (!File.Exists(fileName))
{
using (StreamWriter file = File.CreateText(fileName))
{
file.Write(txt);
}
}
else
{
using (StreamWriter file = File.AppendText(fileName))
{
file.Write(txt);
}
}
}
public static string ListsToCsv(List<List<string>> myList, string sep)
{
StringBuilder sb = new StringBuilder();
myList.ForEach(x => sb.Append(string.Join(sep, x.Select(i => string.Format("{0}", i)).ToArray()) + Environment.NewLine));
return sb.ToString();
}
//______________________________________________To Dimitar________________________________________________//
[CommandMethod("TTD")]
public static void testTitleTags()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
string fileName = string.Empty;
try
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false, true);
PromptEntityOptions peo = new PromptEntityOptions("\nPlease, select a title block: ");
peo.SetRejectMessage("\nYou have to select BlockReference only!");
peo.AllowNone = false;
peo.AllowObjectOnLockedLayer = true;
peo.AddAllowedClass(typeof(BlockReference), false);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
ObjectId objId = per.ObjectId;
if (!objId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference))))
{
ed.WriteMessage("\nYou didn't select a BlockReference, please try again...\n");
return;
}
DBObject blkobj = (DBObject)tr.GetObject(objId, OpenMode.ForRead, false);
BlockReference bref = blkobj as BlockReference;
if (bref == null) return;
Dictionary<string, ObjectId> attefs = GetAttributeDefinitions(bref);
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, ObjectId> kvp in attefs)
{
ed.WriteMessage("\n{0}\t{1}", kvp.Key, kvp.Value);
sb.AppendLine(string.Format("{0}\t{1}", kvp.Key, kvp.Value));
}
tr.Commit();
// change output file name in MyDocuments folder
string dirPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
fileName = System.IO.Path.Combine(dirPath, "myTextFile.txt");
// you can use custom file name instead , say: System.IO.Path.Combine(@"C:\", "myTextFile.txt");
using (System.IO.StreamWriter file = System.IO.File.CreateText(fileName))
{
// write all text in the file
file.Write(sb.ToString());
}
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\n" + ex.Message);
}
finally
{
// display a text file just for info, optional
System.Diagnostics.Process.Start(fileName);
}
}
}
}

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 2 of 6 (461 Views)

Re: Retrieve a block and its position from DWG file

07-01-2013 10:24 AM in reply to: chikito1990

Hi Dimitar,

Try this code, this will allow you to write your block data

into System.Data.Datatable then you can to export this table

in any type of file you want, if you need to write this info in text file,

let me know about

Change attribute names and block name in the code below:

        [CommandMethod("ibsql", CommandFlags.Modal | CommandFlags.Session | CommandFlags.Transparent)]
        public void ImportDataTableToSQL()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            string ctab = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("ctab").ToString();
            System.Data.DataTable dt = new System.Data.DataTable();
            List<string> tags = new List<string>() { "TAG1", "TAG2", "TAG3", "TAG4" };// <-- change tag names to your needs
            using (DocumentLock docklock = ed.Document.LockDocument())
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        BlockTable tb = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                        BlockTableRecord tbr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;


                        dt.TableName = "MyBlockTable";
                        dt.Columns.Add("BlockName", typeof(string));
                        dt.Columns.Add("Handle", typeof(string));
                        dt.Columns.Add("X_Coordinate", typeof(double));
                        dt.Columns.Add("Y_Coordinate", typeof(double));
                        dt.Columns.Add("Z_Coordinate", typeof(double));
                        // add columns for attributes
                        foreach (string tag in tags)
                            dt.Columns.Add(tag, typeof(string));

                        TypedValue[] values = { new TypedValue(0, "INSERT"),
                                              new TypedValue(66, 1),
                                              new TypedValue(410, ctab),
                                              new TypedValue(2, "UserName, `*U*") };//UserName is a block name for test
                        SelectionFilter filter = new SelectionFilter(values);

                        PromptSelectionResult res = ed.SelectAll(filter);

                        if (res.Status != PromptStatus.OK) return;

                        SelectionSet sset = res.Value;

                        foreach (SelectedObject selobj in sset)
                        {
                            DBObject obj = (DBObject)tr.GetObject(selobj.ObjectId, OpenMode.ForRead);

                            BlockReference blk = obj as BlockReference;
                            string bname = string.Empty;
                            // get real block name
                            if (blk.IsDynamicBlock)
                            {
                                BlockTableRecord btrec = (BlockTableRecord)tr.GetObject(blk.DynamicBlockTableRecord, OpenMode.ForRead);
                                bname = btrec.Name;
                            }
                            else
                            {
                                BlockTableRecord btrec = (BlockTableRecord)tr.GetObject(blk.BlockTableRecord, OpenMode.ForRead);
                                bname = btrec.Name;
                            }

                            string hdl = blk.Handle.Value.ToString();
                            Point3d pt = blk.Position;
                            double xp = pt.X;
                            double yp = pt.Y;
                            double zp = pt.Z;

                            System.Data.DataRow dr = dt.NewRow();
                            dr[0] = bname;
                            dr[1] = hdl;
                            dr[2] = xp;
                            dr[3] = yp;
                            dr[4] = zp;
                            AttributeCollection attribs = blk.AttributeCollection;
                            int k = 5;
                            foreach (ObjectId attid in attribs)
                            {
                                AttributeReference attref = (AttributeReference)tr.GetObject(attid, OpenMode.ForRead);
                                dr[k] = attref.TextString;
                                k += 1;
                            }
                            dt.Rows.Add(dr);

                        }

                       

                        // read Datatable for debug only:
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            System.Data.DataRow dr = dt.Rows[i];

                            object[] rowarr = dr.ItemArray;
                            for (int j = 0; j < dt.Columns.Count; j++)
                            {
                                ed.WriteMessage("\n{0}\n", rowarr[j]);

                            }
                        }
                        tr.Commit();

                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("\n{0}\n{1}\n", ex.Message, ex.StackTrace);
                    }
                    finally
                    {
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("At this point you can export this table in SQL Server Database or in Excel file etc..");
                        dt.Dispose();
                    }
                }
            }
        }

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 3 of 6 (451 Views)

Re: Retrieve a block and its position from DWG file

07-01-2013 12:25 PM in reply to: chikito1990
You can use this code as well:
http://www.acadnetwork.com/index.php?topic=354.0
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
chikito1990
Posts: 40
Registered: ‎06-26-2013
Message 4 of 6 (417 Views)

Re: Retrieve a block and its position from DWG file

07-03-2013 02:09 AM in reply to: Hallex

Hi Hallex.

 

Thank you for your response!!! Is it possible to convert the code you gave in such way that it will write the blocks in CSV or TEXT file? Because the link you send me is not working for some reson. 

 

Thank you in advance.

 

Best regards.

Dimitar Georgiev

*Expert Elite*
_gile
Posts: 2,104
Registered: ‎04-29-2006
Message 5 of 6 (403 Views)

Re: Retrieve a block and its position from DWG file

07-03-2013 03:37 AM in reply to: chikito1990

Hi,

 

here's an example:

 

        private void ExportCsv(Database db, string blockName, string fileName)
        {
            string separator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
            RXClass rxc = RXClass.GetClass(typeof(BlockReference));
            using (Transaction tr = db.TransactionManager.StartTransaction())
            using (StreamWriter writer = new StreamWriter(fileName))
            {
                BlockTableRecord modelSpace =
                    (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
                foreach (ObjectId id in modelSpace)
                {
                    if (id.ObjectClass == rxc)
                    {
                        BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                        if (br.Name.Equals(blockName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            writer.WriteLine(string.Join(separator, br.Position.ToArray()));
                        }
                    }
                }
                tr.Commit();
            }
        }

 

or, in a more 'declarative style' using Linq:

 

        private void ExportCsv(Database db, string blockName, string fileName)
        {
            string separator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
            RXClass rxc = RXClass.GetClass(typeof(BlockReference));
            using (Transaction tr = db.TransactionManager.StartTransaction())
            using (StreamWriter writer = new StreamWriter(fileName))
            {
                foreach (BlockReference br in (
                    (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead))
                    .Cast<ObjectId>()
                    .Where(id => id.ObjectClass == rxc)
                    .Select(id => (BlockReference)tr.GetObject(id, OpenMode.ForRead))
                    .Where(br => br.Name.Equals(blockName, StringComparison.CurrentCultureIgnoreCase)))
                {
                    writer.WriteLine(string.Join(separator, br.Position.ToArray()));
                }
                tr.Commit();
            }
        }

 

Gilles Chanteau
*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 6 of 6 (395 Views)

Re: Retrieve a block and its position from DWG file

07-03-2013 05:09 AM in reply to: chikito1990

Try complete class, change project name to your project,

tested through A2009-14 (Win 7, 32 bit)

Command to write blocks: BLX

#region "Namespaces"

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.IO;


#endregion

[assembly: CommandClass(typeof(ACAD2014_1.BlocksCommands))]

namespace ACAD2014_1
{

    public static class BlocksCommands
    {
        //______________________________________________To Dimitar________________________________________________//
        public static T GetObject<T>(this ObjectId id) where T : DBObject
        {
            return id.GetObject(OpenMode.ForRead, false, false) as T;
        }

        public static IEnumerable<T> GetObjects<T>(this IEnumerable ids) where T : DBObject
        {
            return ids
                .Cast<ObjectId>()
                .Select(id => id.GetObject(OpenMode.ForRead, false, false))
                .OfType<T>();
        }
        public static Dictionary<string, ObjectId> GetAttributeDefinitions(this BlockReference br)
        {
            BlockTableRecord btr = (BlockTableRecord)(br.IsDynamicBlock ? br.BlockTableRecord.GetObject(OpenMode.ForRead,false) : br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead,false));

            Dictionary<string, ObjectId> attdefs =
               btr.GetObjects<AttributeDefinition>()
                  .ToDictionary(
                      a => a.Tag,
                      a => a.ObjectId,
                      StringComparer.OrdinalIgnoreCase);
            return attdefs;
        }


        public static string[] GetBlockNamesInDrawing(Database db)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                return db.BlockTableId
                    .GetObject<BlockTable>()
                    .GetObjects<BlockTableRecord>()
                    .Where(btr =>
                        !btr.IsAnonymous &&
                        !btr.IsFromExternalReference &&
                        !btr.IsFromOverlayReference &&
                        !btr.IsLayout &&
                        !btr.IsAProxy)
                    .Select(btr => btr.Name)
                    .ToArray();
            }
        }



        public static ObjectId[] GetBlockIdsOnLayout(Database db, string layoutName, string blockName)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                return ((BlockTableRecord)
                    ((Layout)LayoutManager.Current.GetLayoutId(layoutName).GetObject(OpenMode.ForRead, false)).BlockTableRecordId
                    .GetObject(OpenMode.ForRead, false))
                    .GetObjects<BlockReference>()
                    .Where(br => EffectiveName(br).Equals(blockName))
                    .Select(bl => bl.ObjectId).ToArray();
                    
            }
        }


        static public string EffectiveName(BlockReference bref)
        {
            BlockTableRecord btr = null;
            
            if (bref.IsDynamicBlock) //| (bref.Name.StartsWith("`*U*", StringComparison.InvariantCultureIgnoreCase)))
            {
                btr = bref.DynamicBlockTableRecord.GetObject( OpenMode.ForRead) as BlockTableRecord;
            }
            else if (bref.Name.StartsWith("`*U*", StringComparison.InvariantCultureIgnoreCase))
            {
                //if (btr.IsAnonymous)
                //{
                    BlockTableRecord anbtr = bref.AnonymousBlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
                    ObjectIdCollection ids = anbtr.GetAnonymousBlockIds();
                    btr = ids[0].GetObject(OpenMode.ForRead) as BlockTableRecord;
                //}
            }
            else
            {
                btr = bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
            }
            return btr.Name;
        }

        public static string[] GetBlockNamesOnLayout(Database db, string layoutName, string blockName)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                return ((BlockTableRecord)
                    ((Layout)LayoutManager.Current.GetLayoutId(layoutName).GetObject(OpenMode.ForRead, false)).BlockTableRecordId
                    .GetObject(OpenMode.ForRead, false))
                    .GetObjects<BlockReference>()
                    .Where(bl => EffectiveName(bl) == blockName)
                    .Select(bl => EffectiveName(bl))
                    .ToArray();
            }
        }
        [CommandMethod("blx")]
        static public void testLayoutBlocksToFile()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            string layoutName = LayoutManager.Current.CurrentLayout;
            string filename = "";
            PromptStringOptions pso =
                 new PromptStringOptions("\nEnter block name (case-sensitive): ");
            pso.AllowSpaces = true;

            PromptResult res;
            res = ed.GetString(pso);
            if (res.Status != PromptStatus.OK)
                return;

            string blkname = res.StringResult;

            ed.WriteMessage("\nBlock Name Entered\t{0}", blkname);

           // string blkname = "wall";
            List<List<string>> data = new List<List<string>>();
            try
            {
                string[] blocks = GetBlockNamesOnLayout(HostApplicationServices.WorkingDatabase, layoutName, blkname);
                ed.WriteMessage("\n\t---\tResult: {0}\n", blocks.GetUpperBound(0));
                foreach (string bname in blocks)
                {
                    ed.WriteMessage("\nBlock Name: {0}\n", bname);
                }
                ObjectId[] ids = GetBlockIdsOnLayout(db, layoutName, blkname);
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                    ObjectId btrid = bt[blkname];
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrid, OpenMode.ForRead);
                    List<string> headers = btr.GetObjects<AttributeDefinition>().Select(x => x.Tag).ToList();
                    headers.Insert(0, "Block Name");
                    headers.Insert(1, "Handle");
                    headers.Insert(2, "X");
                    headers.Insert(3, "Y");
                    headers.Insert(4, "Z");
                    headers.Insert(5, "Rotation");
                    data.Add(headers);
                    int i = 1;
                    foreach (ObjectId id in ids)
                    {
                        BlockReference bref = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                        List<string> blockdata = bref.AttributeCollection.GetObjects<AttributeReference>().Select(x => x.TextString).ToList();
                        blockdata.Insert(0, EffectiveName(bref));
                        blockdata.Insert(1, bref.Handle.ToString());
                        Point3d bp = bref.Position;
                        blockdata.Insert(2, string.Format("{0:f3}", bp.X));
                        blockdata.Insert(3, string.Format("{0:f3}", bp.Y));
                        blockdata.Insert(4, string.Format("{0:f3}", bp.Z));
                        double rot = bref.Rotation;
                        blockdata.Insert(5, string.Format("{0:f3}", rot));
                        data.Add(blockdata);

                        i++;
                    }
                    // just to diplay result:
                    foreach (List<string> item in data)
                    {
                        string msg = "";
                        foreach (string st in item)
                        {
                            msg = msg + st + " :: ";

                        }
                        ed.WriteMessage("\nBlock Info\t{0}\n", msg);
                    }
                    string dirPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                     filename = System.IO.Path.Combine(dirPath, "myblocks.csv");
                    //string filename = Path.Combine(@"C:\Test", "myblocks.csv");

                    WriteToTextFile(filename, ListsToCsv(data, "\t"));

                    
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n" + ex.Message);
            }
            finally
            {
                // display a text file just for info, optional
                System.Diagnostics.Process.Start(filename);
             
            }
        }

        // by O'Reily
        public static void WriteToTextFile(string fileName, string txt)
        {
            if (!File.Exists(fileName))
            {
                using (StreamWriter file = File.CreateText(fileName))
                {
            
                    file.Write(txt);
                }
            }
            else
            {
                using (StreamWriter file = File.AppendText(fileName))
                {
                
                    file.Write(txt);
                }
            }
        }
        public static string ListsToCsv(List<List<string>> myList, string sep)
        {
            StringBuilder sb = new StringBuilder();

            myList.ForEach(x => sb.Append(string.Join(sep, x.Select(i => string.Format("{0}", i)).ToArray()) + Environment.NewLine));
           
            return sb.ToString();
        }
        //______________________________________________To Dimitar________________________________________________//
        [CommandMethod("TTD")]
        public static void testTitleTags()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            string fileName = string.Empty;
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false, true);


                    PromptEntityOptions peo = new PromptEntityOptions("\nPlease, select a title block: ");
                    peo.SetRejectMessage("\nYou have to select BlockReference only!");
                    peo.AllowNone = false;
                    peo.AllowObjectOnLockedLayer = true;
                    peo.AddAllowedClass(typeof(BlockReference), false);
                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK) return;
                    ObjectId objId = per.ObjectId;
                    if (!objId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference))))
                    {
                        ed.WriteMessage("\nYou didn't select a BlockReference, please try again...\n");
                        return;
                    }
                    DBObject blkobj = (DBObject)tr.GetObject(objId, OpenMode.ForRead, false);
                    BlockReference bref = blkobj as BlockReference;
                    if (bref == null) return;
                    Dictionary<string, ObjectId> attefs = GetAttributeDefinitions(bref);
                    StringBuilder sb = new StringBuilder();
                    foreach (KeyValuePair<string, ObjectId> kvp in attefs)
                    {
                        ed.WriteMessage("\n{0}\t{1}", kvp.Key, kvp.Value);
                        sb.AppendLine(string.Format("{0}\t{1}", kvp.Key, kvp.Value));
                    }

                    tr.Commit();
                    // change output file name in MyDocuments folder 
                    string dirPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    fileName = System.IO.Path.Combine(dirPath, "myTextFile.txt");
                    // you can use custom file name instead , say: System.IO.Path.Combine(@"C:\", "myTextFile.txt");
                    using (System.IO.StreamWriter file = System.IO.File.CreateText(fileName))
                    {
                        // write all text in the file
                        file.Write(sb.ToString());
                    }

                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n" + ex.Message);
            }
            finally
            {
                // display a text file just for info, optional
                System.Diagnostics.Process.Start(fileName);

            }
        }
    }
}

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.