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

08/09/2014

Как получить неиспользуемые внешние ссылки, растры и подложки?

Вопрос: Мне нужно средствами AutoCAD .NET API получить неиспользуемые внешние ссылки (XREF), растры (IMAGE), pdf-подложки (PDFUNDERLAY) и dwf-подложки (DWFUNDERLAY). Как это можно сделать?

Ответ: Для внешних ссылок достаточно найти все записи таблицы блоков (BlockTableRecord), свойство XrefStatus которых отлично от NotAnXref и для них справедливо выражение GetBlockReferenceIds(false, true).Count == 0

Для растров и подложек процедура несколько иная. Необходимо найти соответствующую таблицу (ACAD_IMAGE_DICT – для IMAGE, ACAD_PDFDEFINITIONS – для PDFUNDERLAY, ACAD_DWFDEFINITIONS – для DWFUNDERLAY) и получить из неё все ObjectId элементов. После этого достаточно воспользоваться методом Database.Purge(), чтобы получить только те ObjectId элементов, которые не используются.

Ниже приводится код, который позволяет это сделать:

Код - C#: [Выделить]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using AcRx = Autodesk.AutoCAD.Runtime;
  8. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcGe = Autodesk.AutoCAD.Geometry;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12.  
  13. [assembly: CommandClass(typeof(TestUnref.MyCommands))]
  14.  
  15. namespace TestUnref
  16. {
  17.   public class MyCommands
  18.   {
  19.     // Печатаем имена неиспользуемых внешних ссылок
  20.     [CommandMethod("TestUnref")]
  21.     public void TestUnref()
  22.     {
  23.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  24.       AcDb.Database db = doc.Database;
  25.       AcEd.Editor ed = doc.Editor;
  26.       // Имена внешних ссылок
  27.       ed.WriteMessage("\nНе используемые внешние ссылки: ");
  28.       AcDb.ObjectId idBT = db.BlockTableId;
  29.       using (AcDb.BlockTable bt = idBT.Open(OpenMode.ForRead) as AcDb.BlockTable) {
  30.         foreach (AcDb.ObjectId idBTR in bt) {
  31.           using (AcDb.BlockTableRecord btr = idBTR.Open(OpenMode.ForRead) as AcDb.BlockTableRecord) {
  32.             if (btr.XrefStatus != AcDb.XrefStatus.NotAnXref && btr.GetBlockReferenceIds(false, true).Count == 0) {
  33.               ed.WriteMessage("\n\tИмя={0} Путь={1}", btr.Name, btr.PathName);
  34.             }
  35.           }
  36.         }
  37.       }
  38.       AcDb.ObjectIdCollection ids_unref = new AcDb.ObjectIdCollection();
  39.       // Имена растров
  40.       ed.WriteMessage("\nНе используемые растры: ");
  41.       AcDb.ObjectId idImgDict = AcDb.RasterImageDef.GetImageDictionary(db);
  42.       if (!idImgDict.IsNull) {
  43.         using (AcDb.DBDictionary imgDict = idImgDict.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  44.           foreach (AcDb.DBDictionaryEntry ent in imgDict) ids_unref.Add(ent.Value);
  45.           db.Purge(ids_unref); // Удаляем из набора те, которые используются
  46.           foreach (AcDb.ObjectId id in ids_unref) {
  47.             string name = imgDict.NameAt(id);
  48.             using (AcDb.RasterImageDef imgDef = id.Open(OpenMode.ForRead) as AcDb.RasterImageDef) {
  49.               ed.WriteMessage("\n\tИмя={0} Путь={1}", name, imgDef.SourceFileName);
  50.             }
  51.           }
  52.         }
  53.       }
  54.       ids_unref.Clear();
  55.       // Имена PDF-подложек
  56.       ed.WriteMessage("\nНе используемые PDF-подложки: ");
  57.       string pdfKeyName = AcDb.UnderlayDefinition.GetDictionaryKey(typeof(AcDb.PdfDefinition));
  58.       using (AcDb.DBDictionary nodeDict = db.NamedObjectsDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  59.         if (nodeDict.Contains(pdfKeyName)) {
  60.           using (AcDb.DBDictionary pdfDict = nodeDict.GetAt(pdfKeyName).Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  61.             foreach (AcDb.DBDictionaryEntry ent in pdfDict) ids_unref.Add(ent.Value);
  62.             db.Purge(ids_unref); // Удаляем из набора те, которые используются
  63.             foreach (AcDb.ObjectId id in ids_unref) {
  64.               string name = pdfDict.NameAt(id);
  65.               using (AcDb.PdfDefinition def = id.Open(OpenMode.ForRead) as AcDb.PdfDefinition) {
  66.                 ed.WriteMessage("\n\tИмя={0} Путь={1}", name, def.SourceFileName);
  67.               }
  68.             }
  69.           }
  70.         }
  71.       }
  72.       ids_unref.Clear();
  73.       // Имена DWF-подложек
  74.       ed.WriteMessage("\nНе используемые DWF-подложки: ");
  75.       string dwfKeyName = AcDb.UnderlayDefinition.GetDictionaryKey(typeof(AcDb.DwfDefinition));
  76.       using (AcDb.DBDictionary nodeDict = db.NamedObjectsDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  77.         if (nodeDict.Contains(dwfKeyName)) {
  78.           using (AcDb.DBDictionary dwfDict = nodeDict.GetAt(dwfKeyName).Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  79.             foreach (AcDb.DBDictionaryEntry ent in dwfDict) ids_unref.Add(ent.Value);
  80.             db.Purge(ids_unref); // Удаляем из набора те, которые используются
  81.             foreach (AcDb.ObjectId id in ids_unref) {
  82.               string name = dwfDict.NameAt(id);
  83.               using (AcDb.DwfDefinition def = id.Open(OpenMode.ForRead) as AcDb.DwfDefinition) {
  84.                 ed.WriteMessage("\n\tИмя={0} Путь={1}", name, def.SourceFileName);
  85.               }
  86.             }
  87.           }
  88.         }
  89.       }
  90.       ids_unref.Clear();
  91.       // Имена DataLink
  92.       ed.WriteMessage("\nНе используемые DataLink: ");
  93.       AcDb.ObjectId idLinkDict = db.DataLinkDictionaryId;
  94.       if (!idLinkDict.IsNull) {
  95.         using (AcDb.DBDictionary dLinkDict = db.DataLinkDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
  96.           foreach (AcDb.DBDictionaryEntry ent in dLinkDict) ids_unref.Add(ent.Value);
  97.         }
  98.         foreach (AcDb.ObjectId id in ids_unref) {
  99.           using (AcDb.DataLink def = id.Open(OpenMode.ForWrite) as AcDb.DataLink) {
  100.             bool bFindTable = false;
  101.             foreach (AcDb.ObjectId id_target in def.GetTargets()) {
  102.               if (id_target.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AcDb.Table)))) {
  103.                 bFindTable = true;
  104.                 break;
  105.               }
  106.             }
  107.             if (!bFindTable) {
  108.               ed.WriteMessage("\n\tИмя={0} Путь={1}", def.Name, def.ConnectionString);
  109.               def.Erase();
  110.             }
  111.           }
  112.         }
  113.       }
  114.     }
  115.   }
  116. }

 

Автор: Александр Ривилис

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

Опубликовано 08.09.2014
Отредактировано 11.07.2016 в 15:54:28