.NET

.NET

Reply
Active Contributor
DouceDeux
Posts: 46
Registered: ‎09-04-2012
Message 1 of 6 (568 Views)

XData Creatiion and Extration to .txt file and or .csv floating format C#

568 Views, 5 Replies
11-12-2012 09:23 AM

Hello!!!

Glad to be here coding for AutoCAD plug-ings :smileyvery-happy:

This time I'm trying to save custom data(is that the name for integers, floating points, stings, chars?) into objects for later use.

I've gotten to the point where I can save the data (using XData on a set command) and retrieve said data on a different command.

Here's the code:

 

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

[assembly: CommandClass(typeof(Project.MyCommands))]

namespace Project
{
    public class MyCommands
    {
        public const string XDataReg = "MY_APP";

        //Separate method to register the APP ID on the app table
        private void AddRegAppID(Database db)
        {
            using (Transaction newTransaction = db.TransactionManager.StartTransaction())
            {
                RegAppTable newAppTable = (RegAppTable)newTransaction.GetObject(db.RegAppTableId, OpenMode.ForRead);
                if (!newAppTable.Has(XDataReg))
                {
                    RegAppTableRecord newAppTblRec = new RegAppTableRecord();
                    newAppTable.UpgradeOpen();
                    newAppTblRec.Name = XDataReg;
                    newAppTable.Add(newAppTblRec);
                    newTransaction.AddNewlyCreatedDBObject(newAppTblRec, true);
                }
                newTransaction.Commit();
            }
        }

        //Command to created entity and get data to save
        [CommandMethod("HOLLER")]
        public void MyCommand()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            PromptStringOptions pHoller = new PromptStringOptions("\nSay something!: ");
            PromptResult resultHoller = ed.GetString(pHoller);
            if (resultHoller.Status != PromptStatus.OK)
                return;
            String sHoller = resultHoller.StringResult;
            using (Transaction newTransaction = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
            {
                BlockTable newBlockTable;
                newBlockTable = newTransaction.GetObject(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord newBlockTableRecord;
                newBlockTableRecord = (BlockTableRecord)newTransaction.GetObject(newBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                //Creating entity polyline
                Polyline newPolyline = new Polyline();
                newPolyline.SetDatabaseDefaults();
                newPolyline.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 255, 255);//is there a better way to pass a color to an entity? I'd rather just use a printable color
                newPolyline.AddVertexAt(0, new Point2d(0, 0), 0, 0, 0);
                newPolyline.AddVertexAt(1, new Point2d(1, 1), 0, 0, 0);

                newBlockTableRecord.AppendEntity(newPolyline);
                newTransaction.AddNewlyCreatedDBObject(newPolyline, true);

                //Creating XData
                AddRegAppID(doc.Database);
                DBObject attRef = newTransaction.GetObject(newPolyline.ObjectId, OpenMode.ForWrite);
                ResultBuffer rb = new ResultBuffer(new TypedValue(1001, XDataReg),
                                                   new TypedValue(1000, sHoller)
                                                  );
                attRef.XData = rb;
                newTransaction.Commit();
            }
        }

        //Command to Show XData on command line
        [CommandMethod("ISAID")]
        public void Propiedades()
        {
            Document newDoc = Application.DocumentManager.MdiActiveDocument;
            Editor newEditor = newDoc.Editor;

            PromptEntityOptions pOpt = new PromptEntityOptions("\nSelect a polyline: ");
            PromptEntityResult rOpt = newEditor.GetEntity(pOpt);

            if (rOpt.Status == PromptStatus.OK)
            {
                using (Transaction newTransaction = newDoc.TransactionManager.StartTransaction())
                {
                    DBObject newObj = newTransaction.GetObject(rOpt.ObjectId, OpenMode.ForRead);
                    ResultBuffer rb = newObj.XData;
                    if (rb == null)
                    {
                        newEditor.WriteMessage("\nYou didn't say anything then.");
                    }
                    else
                    {
                        //How exactly can I check that the found XData has MY XData and is not another app's XData?
                        //I reckon it has to do something with the registered app table record and the first
                        //value in the buffer, but I'm not sure how to use it
                        TypedValue[] tv = rb.AsArray();
                        newEditor.WriteMessage("\nYou said: {0}", tv[1].Value);
                        rb.Dispose();
                    }
                }
            }
        }
    }
}

 The code is tested and works for AutoCAD 2010 and .net 3.5 (I'm sure for other versions too)

I have a few questions I would really like your help with.

 

255, 255, 255 doesn't seem to be the best way of setting something of white color because ACAD has other options for white that uses for printing and user/visual ease, it's not translated into "WHITE". How can I solve this and pass printable colors?

 

How can we read our XData separately from other app's/plug-ing/command XData. So far I've only tried creating a new buffer for XData but not writing on (not on top, which would mean deleting the previous XData) a previously saved XData, how would that work?

 

How can I format a floating point value?

When I ask for points for distances I get a lot of decimals but say I just want to show 2 decimals on command line.

How can I format

double myDouble = 123.123456

newEditor.WriteMessage("\nMy floating point number is {0}", myDouble);

so that it shows as 123.12 or 123.123 if I wanted to.

This would also help when exporting the data since we have to parse the XData by knowing the type codes.

 

Last and most important:
How can I import any entity data and specifically XData into a csv or txt file.

 

If you think my code can be better by being more generic and accepting more types of entities( lines, arcs, circles, etc) please let me know how.

 

Thanks in advance for your help.

 

P.D. If you've seen a previous post by me, I haven't got to write the solution and mark it as Solved yet. I will when I get the time, sorry >.<

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

Re: XData Creatiion and Extration to .txt file and or .csv floating format C#

11-13-2012 02:31 AM in reply to: DouceDeux

Not tested your code, about your last question try

something like this:

 

      public static void WriteToCsv( string filename,Dictionary<string,string> dict, string delimiter)
        {
            using (StreamWriter sw = new StreamWriter(filename))
            {
                foreach (KeyValuePair<string, string> kvp in dict)
                {
                    sw.WriteLine(string.Format("{0}{1}{2}",kvp.Key,delimiter,kvp.Value));
                }
                sw.Close();

            }
        }
        //usage:
        //WriteToCsv(myXDataToDictionary,",", @"mycsv.csv");

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
DouceDeux
Posts: 46
Registered: ‎09-04-2012
Message 3 of 6 (478 Views)

New findings

11-26-2012 01:37 PM in reply to: DouceDeux

Posting some findings of mine so far. WIll update as I stumble upon new information.

 

Best method of creating colors

(some entity).color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByLayer, 3);

3 is the index and it can range from 0 to 255 or 256, not sure. Test it.

The .ColorMethod can also change.

This way you are creating printable colors that AutoCAD recognizes with names white, blue, red, etc. and not by rgb (i.e. 255, 255, 255 (which is not compatible with printer color, I think, but you manually would have to change to 'white' anyway))

 

Floating points are tricky. You can try casting to an int after a multiplication and then dividing after casting back to a double, but it doesn't return all decimals if the result is an even number

 

double d = 1234.5678
d = (double)( (int) ( d * 1000.0) ) / 1000.0

That's the main idea. You just have to be careful with the decimals

Distinguished Mentor
andrewpuller3811
Posts: 770
Registered: ‎07-30-2008
Message 4 of 6 (469 Views)

Re: New findings

11-26-2012 06:29 PM in reply to: DouceDeux

0 to 256 for index colours.

 

0 is for "ByBlock" and 256 is for "ByLayer"

If this fixed your issue, click on "Accept as Solution"

Andrew Puller
Maitland, NSW, Australia
Windows 7 Enterprise 64bit
Intel core i7 2600 @ 3.40 GHz with 16GB Ram
Civil 3d 2013 64bit
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 5 of 6 (463 Views)

Re: XData Creatiion and Extration to .txt file and or .csv floating format C#

11-26-2012 09:47 PM in reply to: DouceDeux

 

How can I format a floating point value?

When I ask for points for distances I get a lot of decimals but say I just want to show 2 decimals on command line.

How can I format

double myDouble = 123.123456

newEditor.WriteMessage("\nMy floating point number is {0}", myDouble);

so that it shows as 123.12 or 123.123 if I wanted to.

This would also help when exporting the data since we have to parse the XData by knowing the type codes.

 

 


Autodesk.AutoCAD.Runtime.Converter.DistanceToString() converts a double to distince units.

 

Other methods of the same class convert to/from other AutoCAD unit types.

Distinguished Mentor
andrewpuller3811
Posts: 770
Registered: ‎07-30-2008
Message 6 of 6 (451 Views)

Re: XData Creatiion and Extration to .txt file and or .csv floating format C#

11-27-2012 02:22 AM in reply to: DiningPhilosopher

Try

 

newEditor.WriteMessage("\nMy floating point number is {0:f3}", myDouble);

 

 

Some references -

 

http://davidpenton.com/testsite/scratch/formats.aspx

http://www.techotopia.com/index.php/Formatting_Strings_in_C_Sharp

If this fixed your issue, click on "Accept as Solution"

Andrew Puller
Maitland, NSW, Australia
Windows 7 Enterprise 64bit
Intel core i7 2600 @ 3.40 GHz with 16GB Ram
Civil 3d 2013 64bit
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

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