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

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

5 REPLIES 5
Reply
Message 1 of 6
DouceDeux
1414 Views, 5 Replies

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

Hello!!!

Glad to be here coding for AutoCAD plug-ings 😄

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 >.<

5 REPLIES 5
Message 2 of 6
Hallex
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
Message 3 of 6
DouceDeux
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

Message 4 of 6

0 to 256 for index colours.

 

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



If a post provides a fix for your issue, click on "Accept as Solution" to help other users find solutions to problems they might have that are similar to yours.

Andrew Puller
Maitland, NSW, Australia
Windows 10 Enterprise 64bit
Intel core i7 11800 @ 2.30 GHz with 32GB Ram
Civil 3d 2021
Message 5 of 6

 

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.

Message 6 of 6

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 a post provides a fix for your issue, click on "Accept as Solution" to help other users find solutions to problems they might have that are similar to yours.

Andrew Puller
Maitland, NSW, Australia
Windows 10 Enterprise 64bit
Intel core i7 11800 @ 2.30 GHz with 32GB Ram
Civil 3d 2021

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