Choosing the optimal method

Choosing the optimal method

youssefGC
Advocate Advocate
785 Views
8 Replies
Message 1 of 9

Choosing the optimal method

youssefGC
Advocate
Advocate

Hi everyone,

 

Today, I am faced with a choice between two mechanisms. Indeed, I have two programs that interact with each other.

The first program allows the user to draw polylines and stores information in the Xrecord of the entity to mark that this polyline was drawn by my own command.

The second program quantifies the number of entities (polylines) drawn by the first command.

Focusing on the second program, I find two solutions to access the entities:

  1. Method 1: I can scan all drawn entities and check if the polyline was drawn by the first command by examining the Xrecord field.

  2. Method 2: In the first command, during the drawing of each polyline, I can store their handle in the Named Object Dictionary (NOD). Then, to quantify the number, I can directly access the dictionary.

Which method seems to be the most effective?

 

Thank you.

 

 

0 Likes
786 Views
8 Replies
Replies (8)
Message 2 of 9

_gile
Consultant
Consultant

Hi,

Certainly the Method2 which only reads the data stored in a dictionary instead of scaming all the drawn entities. Instead of entities Handle, you can directly store the entities ObjectId as SoftPointer (dxf group 330) to let AutoCAD hande the erased entities (ObjectId.Null).

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 9

ActivistInvestor
Mentor
Mentor

What happens if the user copies one of these entities? Have you given consideration to that?

0 Likes
Message 4 of 9

youssefGC
Advocate
Advocate

Thank you @_gile for your response. Yes, it seems more logical to not sweep the entire drawing but rather to directly access the specified polyline using the previously stored list of Handle.

 

0 Likes
Message 5 of 9

youssefGC
Advocate
Advocate

Thank you @ActivistInvestor  for your remark. Currently, I haven't implemented a solution for the case you've mentioned. However, my idea going forward is to use "ObjectOverrule" to check if the user has copied an entity drawn by the command, and likewise store their new handle.

0 Likes
Message 6 of 9

_gile
Consultant
Consultant

@youssefGC wrote:

directly access the specified polyline using the previously stored list of Handle.


Storing ObjectIds instead of Handles will avoid you converting Objectid into Handle (with ObjectId.Handle) and converting back Handle into ObjectId (with .TryGetObjectId).

Here's an example:

 

        [CommandMethod("SETXRECORD")]
        public static void SetXrecord()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var psr = ed.GetSelection();
            if (psr.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                DBDictionary dict;
                if (nod.Contains(dictName))
                {
                    dict = (DBDictionary)tr.GetObject(nod.GetAt(dictName), OpenMode.ForRead);
                }
                else
                {
                    dict = new DBDictionary();
                    tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
                    nod.SetAt(dictName, dict);
                    tr.AddNewlyCreatedDBObject(dict, true);
                }
                Xrecord xrec;
                if (dict.Contains(xrecKey))
                {
                    xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecKey), OpenMode.ForWrite);
                }
                else
                {
                    xrec = new Xrecord();
                    if (!dict.IsWriteEnabled)
                        tr.GetObject(dict.ObjectId, OpenMode.ForRead);
                    dict.SetAt(xrecKey, xrec);
                    tr.AddNewlyCreatedDBObject(xrec, true);
                }
                xrec.Data = new ResultBuffer(
                    psr.Value.GetObjectIds()
                    .Select(id => new TypedValue(330, id))
                    .ToArray());
                tr.Commit();
            }
        }

        [CommandMethod("GETXRECORD", CommandFlags.Redraw)]
        public static void GetXrecord()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                if (!nod.Contains(dictName))
                    return;
                var dict = (DBDictionary)tr.GetObject(nod.GetAt(dictName), OpenMode.ForRead);
                if (!dict.Contains(xrecKey))
                    return;
                var xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecKey), OpenMode.ForRead);
                var data = xrec.Data;
                if (data == null)
                    return;
                var ids = data.AsArray().Select(tv => (ObjectId)tv.Value).Where(id => !id.IsNull);
                ed.SetImpliedSelection(ids.ToArray());
                tr.Commit();
            }
        }

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 9

youssefGC
Advocate
Advocate

To avoid the problem mentioned by @ActivistInvestor, we should revert to using the first method I had outlined in the post. Scanning all entities allows us to identify, using XData/XRecord, the relevant polylines. This appears simpler ?

 

0 Likes
Message 8 of 9

_gile
Consultant
Consultant

@youssefGC wrote:

To avoid the problem mentioned by @ActivistInvestor, we should revert to using the first method I had outlined in the post. Scanning all entities allows us to identify, using XData/XRecord, the relevant polylines. This appears simpler ?


Yes, it is simpler and even it should be less efficient, it won't be perceptible depending on the number of entities.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 9

ActivistInvestor
Mentor
Mentor

I would suggest that you keep your data 'self-contained' if possible, and avoid storing ObjectId/handle references to objects, so that you do not have to deal with all of the possible scenarios where objects can be copied, erased, etc.,

 

Copying happens not only within the same owner space but also across owner spaces and databases, using BLOCK, WBLOCK, INSERT, etc.