Author Topic: Saving Custom Data  (Read 2445 times)

0 Members and 1 Guest are viewing this topic.

Offline Kevin

  • Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Beginner
    • View Profile
Saving Custom Data
« on: October 16, 2012, 12:38:26 AM »
Hi Everybody,

I have a question.
I have created a class called "NewLine" that inherits from Line. Now I have
added some further properties. Strings, ints and so on.

Which opportunity do I have for saving my custom Data in the dwg?
I know Dictionaries but is there a better way?

Kind Regards,
Kevin

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Re: Saving Custom Data
« Reply #1 on: October 16, 2012, 09:42:01 PM »
Hi,

To save data in a dwg, (X)Dictionary/Xrecord or Xdata is the way.

Offline Kevin

  • Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Beginner
    • View Profile
Re: Saving Custom Data
« Reply #2 on: November 04, 2012, 12:50:07 PM »
Now I tried to save custom data.

I write to Functions. An AutoCad function and a static one.

AutoCad Code is:
Code: [Select]
[CommandMethod.....]
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
Transaction tr = ed.Document.Database.TransactionManager.StartTransaction();
PromptEntityResult getEntityResult = ed.GetEntity("Select Entity to Dic");

ObjectId new = new ObjectId();
new = getEntityResult.ObjectId;
StaticMethods.AddCustomData(new, tr, ed, true);

The second code is:
Code: [Select]
public static bool AddCustomData(ObjectId id, Transaction trans, Editor ed, bool add)
{
trans = ed.Document.Database.TransactionManager.StartTransaction()
Entity ent = (Entity)trans.GetObject(id, OpenMode.ForRead);
ent.UpgradeOpen();
ent.CreateExtensionDictionary();
DBDictionary extDictionary = (DBDictionary)trans.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite);
Xrecord xrec = new Xrecord();
extDictionary.SetAt("CustomData", xrec);
trans.AddNewlyCreatedDBObject(xrec, true);
trans.Commit();
}

I get no error and the ID is transfered.
If I do this in one function the result will be most ok, not everytime.

My second problem is... How is the right syntax of the following code?
Code: [Select]
ResultBuffer dataResBuf = new ResultBuffer(new TypedValue((int)DxfCode.Thickness, 5), new TypedValue((int)DxfCode.Real, 35));
xrec.Data = dataResBuf;

Thank you.

Kind regards,
Kevin
« Last Edit: November 04, 2012, 12:53:05 PM by Kevin »

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Re: Saving Custom Data
« Reply #3 on: November 04, 2012, 03:27:28 PM »
Hi,

Don't use new as variable name, it's a C# operator/keyword.

You'd rather test if the extension dictionary and the xrecord already exist.

While AddCustomData method is defined within the same class as the command, you don't need to declare it 'static' and it's a better practice to declare it 'private' (or 'internal' if it has to be used outside of the class within the same project).
If you want this method to be reusable, you can define an extension method for the DBObject type which ca be called on any DBObject instance  as an instance method.

Here's a first example with a private AddCustomData() method

Code: [Select]
    public class Commands
    {
        [CommandMethod("Test1")]
        public void Test1()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult per = ed.GetEntity("\nSelect an entity: ");
            if (per.Status != PromptStatus.OK)
                return;
            AddCustomData(
                per.ObjectId,
                "CustomData",
                new TypedValue((int)DxfCode.Thickness, 5.0),
                new TypedValue((int)DxfCode.Real, 35.0));
        }

        private void AddCustomData(ObjectId id, string key, params TypedValue[] values)
        {
            Database db = id.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBObject obj = tr.GetObject(id, OpenMode.ForRead);
                ObjectId dictId = obj.ExtensionDictionary;
                if (dictId == ObjectId.Null)
                {
                    obj.UpgradeOpen();
                    obj.CreateExtensionDictionary();
                    dictId = obj.ExtensionDictionary;
                }
                DBDictionary xdict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForRead);
                Xrecord xrec;
                if (xdict.Contains(key))
                {
                    xrec = (Xrecord)tr.GetObject((ObjectId)xdict[key], OpenMode.ForWrite);
                }
                else
                {
                    xdict.UpgradeOpen();
                    xrec = new Xrecord();
                    xdict.SetAt(key, xrec);
                    tr.AddNewlyCreatedDBObject(xrec, true);
                }
                xrec.Data = new ResultBuffer(values);
                tr.Commit();
            }
        }
    }

A second example using an extension method (this method have to be 'public static' and defined in a 'static' class):
Code: [Select]
    public class Commands
    {
        [CommandMethod("Test2")]
        public void Test2()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult per = ed.GetEntity("\nSelect an entity: ");
            if (per.Status != PromptStatus.OK)
                return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
                obj.SetXrecord(
                    "CustomData",
                    new TypedValue((int)DxfCode.Thickness, 5.0),
                    new TypedValue((int)DxfCode.Real, 35.0));
                tr.Commit();
            }
        }
    }

    public static class Extensions
    {
        public static void SetXrecord(this DBObject obj, string key, params TypedValue[] values)
        {
            Transaction tr = obj.Database.TransactionManager.TopTransaction;
            if (tr == null)
                throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NotTopTransaction);
            ObjectId dictId = obj.ExtensionDictionary;
            if (dictId == ObjectId.Null)
            {
                obj.UpgradeOpen();
                obj.CreateExtensionDictionary();
                dictId = obj.ExtensionDictionary;
            }
            DBDictionary xdict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForRead);
            Xrecord xrec;
            if (xdict.Contains(key))
            {
                xrec = (Xrecord)tr.GetObject((ObjectId)xdict[key], OpenMode.ForWrite);
            }
            else
            {
                xdict.UpgradeOpen();
                xrec = new Xrecord();
                xdict.SetAt(key, xrec);
                tr.AddNewlyCreatedDBObject(xrec, true);
            }
            xrec.Data = new ResultBuffer(values);
        }
    }
« Last Edit: November 04, 2012, 03:29:13 PM by (gile) »

Offline Kevin

  • Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Beginner
    • View Profile
Re: Saving Custom Data
« Reply #4 on: November 04, 2012, 05:58:24 PM »
Perfect! Thank you very much.
I will give it a try.

 :solved: