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

Retrieve a block and its position from DWG file

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
chikito1990
1835 Views, 5 Replies

Retrieve a block and its position from DWG file

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

5 REPLIES 5
Message 2 of 6
Hallex
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
Message 3 of 6
Hallex
in reply to: chikito1990

You can use this code as well:
http://www.acadnetwork.com/index.php?topic=354.0
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 4 of 6
chikito1990
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

Message 5 of 6
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 6
Hallex
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

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