ADN Open CIS
Сообщество программистов Autodesk в СНГ

27/01/2015

Отслеживание меток примитивов в команде БЛОКРЕД

Метки примитивов в AutoCAD являются уникальными внутри базы, но AutoCAD может их менять, при этом оставляя их уникальными. Редактирование блока при помощи команды БЛОКРЕД (BEDIT) – это одна из операций, когда можно ожидать что метки примитивов будут меняться. Если ваш код хранит значений меток примитивов внутри BlockTableRecord, вам может быть интересным отследить изменение значений меток примитивов при редактировании блока.

Вот пример кода, который мониторит несколько событий для отслеживания цепочки изменения значений меток.

Код - C#: [Выделить]
  1.   public class Class1
  2.   {
  3.     private static String _blockName = "Test";
  4.  
  5.     private static ObjectIdCollection _idsToMonitor
  6.              = new ObjectIdCollection();
  7.  
  8.     private static System.Collections.Generic.Dictionary<long, long> _idMap
  9.            = new System.Collections.Generic.Dictionary<long, long>();
  10.  
  11.     [CommandMethod("StartTracking")]
  12.     public void StartTracking()
  13.     {
  14.       CreateBlockDef();
  15.  
  16.       Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  17.  
  18.       activeDoc.CommandWillStart += new CommandEventHandler(activeDoc_CommandWillStart);
  19.  
  20.       activeDoc.CommandEnded += new CommandEventHandler(activeDoc_CommandEnded);
  21.  
  22.       Database db = activeDoc.Database;
  23.  
  24.       db.BeginDeepCloneTranslation += new IdMappingEventHandler(db_BeginDeepCloneTranslation);
  25.  
  26.       db.ObjectErased += new ObjectErasedEventHandler(db_ObjectErased);
  27.     }
  28.  
  29.     void activeDoc_CommandEnded(object sender, CommandEventArgs e)
  30.     {
  31.       String cmdName = e.GlobalCommandName;
  32.       if (cmdName.Equals("BCLOSE")) {
  33.         Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  34.         Database db = activeDoc.Database;
  35.         // Проверяем существует ли ObjectId
  36.         int i = 0;
  37.         foreach (ObjectId id in _idsToMonitor) {
  38.           bool findReplacement = id.IsErased || id.IsEffectivelyErased;
  39.  
  40.           if (findReplacement) { // Изменился. Находим новое значение.
  41.             if (_idMap.ContainsKey(id.Handle.Value)) {
  42.               Handle newHandle = new Handle(_idMap[id.Handle.Value]);
  43.  
  44.               ObjectId newId = ObjectId.Null;
  45.               if (db.TryGetObjectId(newHandle, out newId)) {
  46.                 // Новый ObjectId существует
  47.                 _idsToMonitor[i] = newId;
  48.                 activeDoc.Editor.WriteMessage(
  49.                 String.Format("\n{0} mapped to {1} {2}", id.Handle,
  50.                   newId.Handle, (newId.IsEffectivelyErased || newId.IsErased) ? "Удален" : String.Empty));
  51.               } else {
  52.                 // Нельзя определить новую метку!!
  53.                 activeDoc.Editor.WriteMessage("Увы! Не могу найти новую метку !!");
  54.               }
  55.             } else {
  56.               // Нельзя определить новую метку!! 
  57.               activeDoc.Editor.WriteMessage("Увы! Не могу найти новую метку !!");
  58.             }
  59.           }
  60.           i++;
  61.         }
  62.  
  63.         // Новый набор ids для мониторинга
  64.         _idsToMonitor.Clear();
  65.         using (Transaction tr = db.TransactionManager.StartTransaction()) {
  66.           BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  67.  
  68.           if (bt.Has(_blockName)) {
  69.             BlockTableRecord btr = tr.GetObject(bt[_blockName], OpenMode.ForRead) as BlockTableRecord;
  70.             foreach (ObjectId id in btr) {
  71.               _idsToMonitor.Add(id);
  72.             }
  73.           }
  74.           tr.Commit();
  75.         }
  76.       }
  77.     }
  78.  
  79.     void activeDoc_CommandWillStart(object sender, CommandEventArgs e)
  80.     {
  81.       String cmdName = e.GlobalCommandName;
  82.       if (cmdName.Equals("BEDIT")) {
  83.         _idMap.Clear();
  84.       }
  85.     }
  86.  
  87.     [CommandMethod("EndTracking")]
  88.     public void EndTracking()
  89.     {
  90.       Database db = Application.DocumentManager.MdiActiveDocument.Database;
  91.  
  92.       db.BeginDeepCloneTranslation -= new IdMappingEventHandler(db_BeginDeepCloneTranslation);
  93.  
  94.       db.ObjectErased -= new ObjectErasedEventHandler(db_ObjectErased);
  95.     }
  96.  
  97.     static void db_BeginDeepCloneTranslation(object sender, IdMappingEventArgs e)
  98.     {
  99.       foreach (ObjectId id in _idsToMonitor) {
  100.         if (e.IdMapping.Contains(id)) {
  101.           Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  102.           IdPair idPair = e.IdMapping[id];
  103.           _idMap.Add(idPair.Key.Handle.Value, idPair.Value.Handle.Value);
  104.           ed.WriteMessage(String.Format("\n{0} mapped to {1}", idPair.Key.Handle, idPair.Value.Handle));
  105.         }
  106.       }
  107.     }
  108.  
  109.     void db_ObjectErased(object sender, ObjectErasedEventArgs e)
  110.     {
  111.       foreach (ObjectId id in _idsToMonitor) {
  112.         if (e.DBObject.ObjectId.Equals(id)) {
  113.           Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  114.           ed.WriteMessage(String.Format("\n{0} erased", id.Handle));
  115.         }
  116.       }
  117.  
  118.       foreach (System.Collections.Generic.KeyValuePair<long, long> kvp in _idMap) {
  119.         if (e.DBObject.ObjectId.Handle.Value.Equals(kvp.Value)) {
  120.           Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  121.           ed.WriteMessage(String.Format("{0} erased", kvp.Value.ToString("X")));
  122.         }
  123.       }
  124.     }
  125.  
  126.     public static void CreateBlockDef()
  127.     {
  128.       Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  129.       Database db = activeDoc.Database;
  130.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  131.  
  132.       _idsToMonitor.Clear();
  133.  
  134.       using (Transaction tr = db.TransactionManager.StartTransaction()) {
  135.         BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  136.  
  137.         if (bt.Has(_blockName) == false) {
  138.           bt.UpgradeOpen();
  139.           BlockTableRecord btr = new BlockTableRecord();
  140.           btr.Name = _blockName;
  141.           btr.Origin = Point3d.Origin;
  142.           bt.Add(btr);
  143.           tr.AddNewlyCreatedDBObject(btr, true);
  144.  
  145.           ObjectId id = ObjectId.Null;
  146.  
  147.           Circle c1 = new Circle(Point3d.Origin, Vector3d.ZAxis, 1.0);
  148.  
  149.           id = btr.AppendEntity(c1);
  150.           _idsToMonitor.Add(id);
  151.           tr.AddNewlyCreatedDBObject(c1, true);
  152.  
  153.           Circle c2 = new Circle(Point3d.Origin, Vector3d.ZAxis, 2.0);
  154.  
  155.           id = btr.AppendEntity(c2);
  156.           _idsToMonitor.Add(id);
  157.           tr.AddNewlyCreatedDBObject(c2, true);
  158.         } else {
  159.           BlockTableRecord btr = tr.GetObject(bt[_blockName], OpenMode.ForRead) as BlockTableRecord;
  160.           foreach (ObjectId id in btr) {
  161.             _idsToMonitor.Add(id);
  162.           }
  163.         }
  164.         tr.Commit();
  165.       }
  166.     }
  167.   }

Чтобы проверить этот код, откройте новый чертеж в AutoCAD и запустите команду StartTracking. Затем запустите команду БЛОКРЕД (или _BEDIT) для только что созданного блока с именем "TEST". Следите за сообщениями в командной строке для отслеживания изменений меток примитивов. Вот пример вывода в командную строку, хотя реальные метки могут отличаться:

Источник: http://adndevblog.typepad.com/autocad/2015/01/tracking-entity-handles-through-bedit.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1801

Опубликовано 27.01.2015
Отредактировано 27.01.2015 в 02:55:53