<?xml encoding=”UTF-8″>By Balaji Ramamoorthy
Entity handles in AutoCAD are unique within a database, but AutoCAD can still change them while still retaining them as unique. Block editing using BEDIT command is one such operation where you can expect the handle values to change. If your code is holding handle values of entities within a BlockTableRecord, you may be interested in tracking the handle values as they get changed during block editing.
Here is a sample code that monitors a few events to keep track of the handle values.
<span>private</span><span> <span>static</span><span> String _blockName = <span>"Test"</span><span> ;</span></span></span>
<span>private</span><span> <span>static</span><span> ObjectIdCollection _idsToMonitor </span></span>
= <span>new</span><span> ObjectIdCollection();</span>
<span>private</span><span> <span>static</span><span> Dictionary<<span>long</span><span> , <span>long</span><span> > _idMap </span></span></span></span>
= <span>new</span><span> Dictionary<<span>long</span><span> , <span>long</span><span> >();</span></span></span>
[CommandMethod(<span>"StartTracking"</span><span> )]</span>
<span>public</span><span> <span>void</span><span> StartTracking()</span></span>
<span>{</span>
CreateBlockDef();
Document activeDoc
= Application.DocumentManager.MdiActiveDocument;
activeDoc.CommandWillStart
+=<span>new</span><span> CommandEventHandler(activeDoc_CommandWillStart);</span>
activeDoc.CommandEnded
+=<span>new</span><span> CommandEventHandler(activeDoc_CommandEnded);</span>
Database db = activeDoc.Database;
db.BeginDeepCloneTranslation
+= <span>new</span><span> IdMappingEventHandler(db_BeginDeepCloneTranslation);</span>
db.ObjectErased
+= <span>new</span><span> ObjectErasedEventHandler(db_ObjectErased);</span>
<span>}</span>
<span>void</span><span> activeDoc_CommandEnded(object sender, CommandEventArgs e)</span>
<span>{</span>
String cmdName = e.GlobalCommandName;
<span>if</span><span> (cmdName.Equals(<span>"BCLOSE"</span><span> ))</span></span>
<span>{</span>
Document activeDoc
= Application.DocumentManager.MdiActiveDocument;
Database db = activeDoc.Database;
<span>// Check if the ObjectId exist</span><span> </span>
<span>int</span><span> i = 0;</span>
foreach (ObjectId id in _idsToMonitor)
<span>{</span>
<span>bool</span><span> findReplacement </span>
= id.IsErased || id.IsEffectivelyErased;
<span>if</span><span> (findReplacement)</span>
<span>{</span> <span>// Has changed. Find the new one.</span><span> </span>
<span>if</span><span> (_idMap.ContainsKey(id.Handle.Value))</span>
<span>{</span>
Handle newHandle
= <span>new</span><span> Handle(_idMap[id.Handle.Value]);</span>
ObjectId newId = ObjectId.Null;
<span>if</span><span> (db.TryGetObjectId(newHandle, </span>
out newId))
<span>{</span>
<span>// New Id Exists</span><span> </span>
_idsToMonitor[i] = newId;
activeDoc.Editor.WriteMessage(
String.Format(
<span>"<span>{</span>0<span>}</span> <span>{</span>1<span>}</span> mapped to <span>{</span>2<span>}</span> <span>{</span>3<span>}</span>"</span><span> , </span>
Environment.NewLine,
id.Handle,
newId.Handle,
(newId.IsEffectivelyErased
|| newId.IsErased) ?
<span>"Erased"</span><span> : String.Empty)</span>
);
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
<span>// Cannot determine the new handle !!</span><span> </span>
activeDoc.Editor.WriteMessage(
<span>"Sorry, Cannot find the new handle !!"</span><span> );</span>
<span>}</span>
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
<span>// Cannot determine the new handle !!</span><span> </span>
activeDoc.Editor.WriteMessage(
<span>"Sorry, Cannot find the new handle !!"</span><span> );</span>
<span>}</span>
<span>}</span>
i++;
<span>}</span>
<span>// New set of ids to monitor</span><span> </span>
_idsToMonitor.Clear();
<span>using</span><span> (Transaction tr </span>
= db.TransactionManager.StartTransaction())
<span>{</span>
BlockTable bt
= tr.GetObject(db.BlockTableId, OpenMode.ForRead)
as BlockTable;
<span>if</span><span> (bt.Has(_blockName))</span>
<span>{</span>
BlockTableRecord btr
= tr.GetObject(bt[_blockName], OpenMode.ForRead)
as BlockTableRecord;
foreach (ObjectId id in btr)
<span>{</span>
_idsToMonitor.Add(id);
<span>}</span>
<span>}</span>
tr.Commit();
<span>}</span>
<span>}</span>
<span>}</span>
<span>void</span><span> activeDoc_CommandWillStart(</span>
object sender, CommandEventArgs e)
<span>{</span>
String cmdName = e.GlobalCommandName;
<span>if</span><span> (cmdName.Equals(<span>"BEDIT"</span><span> ))</span></span>
<span>{</span>
_idMap.Clear();
<span>}</span>
<span>}</span>
[CommandMethod(<span>"EndTracking"</span><span> )]</span>
<span>public</span><span> <span>void</span><span> EndTracking()</span></span>
<span>{</span>
Database db
= Application.DocumentManager.MdiActiveDocument.Database;
db.BeginDeepCloneTranslation
-= <span>new</span><span> IdMappingEventHandler(db_BeginDeepCloneTranslation);</span>
db.ObjectErased
-= <span>new</span><span> ObjectErasedEventHandler(db_ObjectErased);</span>
<span>}</span>
<span>static</span><span> <span>void</span><span> db_BeginDeepCloneTranslation(</span></span>
object sender, IdMappingEventArgs e)
<span>{</span>
foreach (ObjectId id in _idsToMonitor)
<span>{</span>
<span>if</span><span> (e.IdMapping.Contains(id))</span>
<span>{</span>
Editor ed
= Application.DocumentManager.MdiActiveDocument.Editor;
IdPair idPair = e.IdMapping[id];
_idMap.Add(
idPair.Key.Handle.Value,
idPair.Value.Handle.Value);
ed.WriteMessage(
String.Format(<span>"<span>{</span>0<span>}</span> <span>{</span>1<span>}</span> mapped to <span>{</span>2<span>}</span>"</span><span> , </span>
Environment.NewLine,
idPair.Key.Handle,
idPair.Value.Handle));
<span>}</span>
<span>}</span>
<span>}</span>
<span>void</span><span> db_ObjectErased(object sender, ObjectErasedEventArgs e)</span>
<span>{</span>
foreach (ObjectId id in _idsToMonitor)
<span>{</span>
<span>if</span><span> (e.DBObject.ObjectId.Equals(id))</span>
<span>{</span>
Editor ed
= Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage(String.Format(<span>"<span>{</span>0<span>}</span> <span>{</span>1<span>}</span> erased"</span><span> , </span>
Environment.NewLine, id.Handle));
<span>}</span>
<span>}</span>
foreach(KeyValuePair<<span>long</span><span> , <span>long</span><span> > kvp in _idMap)</span></span>
<span>{</span>
<span>if</span><span> (e.DBObject.ObjectId.Handle.Value.Equals(kvp.Value))</span>
<span>{</span>
Editor ed
= Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage(String.Format(<span>"<span>{</span>0<span>}</span> <span>{</span>1<span>}</span> erased"</span><span> , </span>
Environment.NewLine, kvp.Value.ToString(<span>"X"</span><span> )));</span>
<span>}</span>
<span>}</span>
<span>}</span>
<span>public</span><span> <span>static</span><span> <span>void</span><span> CreateBlockDef()</span></span></span>
<span>{</span>
Document activeDoc
= Application.DocumentManager.MdiActiveDocument;
Database db = activeDoc.Database;
Editor ed
= Application.DocumentManager.MdiActiveDocument.Editor;
_idsToMonitor.Clear();
<span>using</span><span> (Transaction tr </span>
= db.TransactionManager.StartTransaction())
<span>{</span>
BlockTable bt = tr.GetObject(
db.BlockTableId, OpenMode.ForRead) as BlockTable;
<span>if</span><span> (bt.Has(_blockName) == <span>false</span><span> )</span></span>
<span>{</span>
bt.UpgradeOpen();
BlockTableRecord btr = <span>new</span><span> BlockTableRecord();</span>
btr.Name = _blockName;
btr.Origin = Point3d.Origin;
bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, <span>true</span><span> );</span>
ObjectId id = ObjectId.Null;
Circle c1 = <span>new</span><span> Circle(</span>
Point3d.Origin,
Vector3d.ZAxis, 1.0);
id = btr.AppendEntity(c1);
_idsToMonitor.Add(id);
tr.AddNewlyCreatedDBObject(c1, <span>true</span><span> );</span>
Circle c2 = <span>new</span><span> Circle(</span>
Point3d.Origin,
Vector3d.ZAxis, 2.0);
id = btr.AppendEntity(c2);
_idsToMonitor.Add(id);
tr.AddNewlyCreatedDBObject(c2, <span>true</span><span> );</span>
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
BlockTableRecord btr
= tr.GetObject(bt[_blockName], OpenMode.ForRead)
as BlockTableRecord;
foreach (ObjectId id in btr)
<span>{</span>
_idsToMonitor.Add(id);
<span>}</span>
<span>}</span>
tr.Commit();
<span>}</span>
<span>}</span>
To try this code, open a new drawing in AutoCAD and run “StartTracking” command. Now “BEDIT” the newly created “Test” block. Watch out for messages in the command line to track the entity handles. Here is a sample output in the command line during my test, although the actual handle values can vary in your case.


Leave a Reply to BalajiCancel reply