Как получить неиспользуемые внешние ссылки, растры и подложки?
Вопрос: Мне нужно средствами 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 элементов, которые не используются.
Ниже приводится код, который позволяет это сделать:
- using System;
- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.EditorInput;
- using AcRx = Autodesk.AutoCAD.Runtime;
- using AcAp = Autodesk.AutoCAD.ApplicationServices;
- using AcDb = Autodesk.AutoCAD.DatabaseServices;
- using AcGe = Autodesk.AutoCAD.Geometry;
- using AcEd = Autodesk.AutoCAD.EditorInput;
- [assembly: CommandClass(typeof(TestUnref.MyCommands))]
- namespace TestUnref
- {
- public class MyCommands
- {
- // Печатаем имена неиспользуемых внешних ссылок
- [CommandMethod("TestUnref")]
- public void TestUnref()
- {
- AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
- AcDb.Database db = doc.Database;
- AcEd.Editor ed = doc.Editor;
- // Имена внешних ссылок
- ed.WriteMessage("\nНе используемые внешние ссылки: ");
- AcDb.ObjectId idBT = db.BlockTableId;
- using (AcDb.BlockTable bt = idBT.Open(OpenMode.ForRead) as AcDb.BlockTable) {
- foreach (AcDb.ObjectId idBTR in bt) {
- using (AcDb.BlockTableRecord btr = idBTR.Open(OpenMode.ForRead) as AcDb.BlockTableRecord) {
- if (btr.XrefStatus != AcDb.XrefStatus.NotAnXref && btr.GetBlockReferenceIds(false, true).Count == 0) {
- ed.WriteMessage("\n\tИмя={0} Путь={1}", btr.Name, btr.PathName);
- }
- }
- }
- }
- AcDb.ObjectIdCollection ids_unref = new AcDb.ObjectIdCollection();
- // Имена растров
- ed.WriteMessage("\nНе используемые растры: ");
- AcDb.ObjectId idImgDict = AcDb.RasterImageDef.GetImageDictionary(db);
- if (!idImgDict.IsNull) {
- using (AcDb.DBDictionary imgDict = idImgDict.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- foreach (AcDb.DBDictionaryEntry ent in imgDict) ids_unref.Add(ent.Value);
- db.Purge(ids_unref); // Удаляем из набора те, которые используются
- foreach (AcDb.ObjectId id in ids_unref) {
- string name = imgDict.NameAt(id);
- using (AcDb.RasterImageDef imgDef = id.Open(OpenMode.ForRead) as AcDb.RasterImageDef) {
- ed.WriteMessage("\n\tИмя={0} Путь={1}", name, imgDef.SourceFileName);
- }
- }
- }
- }
- ids_unref.Clear();
- // Имена PDF-подложек
- ed.WriteMessage("\nНе используемые PDF-подложки: ");
- string pdfKeyName = AcDb.UnderlayDefinition.GetDictionaryKey(typeof(AcDb.PdfDefinition));
- using (AcDb.DBDictionary nodeDict = db.NamedObjectsDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- if (nodeDict.Contains(pdfKeyName)) {
- using (AcDb.DBDictionary pdfDict = nodeDict.GetAt(pdfKeyName).Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- foreach (AcDb.DBDictionaryEntry ent in pdfDict) ids_unref.Add(ent.Value);
- db.Purge(ids_unref); // Удаляем из набора те, которые используются
- foreach (AcDb.ObjectId id in ids_unref) {
- string name = pdfDict.NameAt(id);
- using (AcDb.PdfDefinition def = id.Open(OpenMode.ForRead) as AcDb.PdfDefinition) {
- ed.WriteMessage("\n\tИмя={0} Путь={1}", name, def.SourceFileName);
- }
- }
- }
- }
- }
- ids_unref.Clear();
- // Имена DWF-подложек
- ed.WriteMessage("\nНе используемые DWF-подложки: ");
- string dwfKeyName = AcDb.UnderlayDefinition.GetDictionaryKey(typeof(AcDb.DwfDefinition));
- using (AcDb.DBDictionary nodeDict = db.NamedObjectsDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- if (nodeDict.Contains(dwfKeyName)) {
- using (AcDb.DBDictionary dwfDict = nodeDict.GetAt(dwfKeyName).Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- foreach (AcDb.DBDictionaryEntry ent in dwfDict) ids_unref.Add(ent.Value);
- db.Purge(ids_unref); // Удаляем из набора те, которые используются
- foreach (AcDb.ObjectId id in ids_unref) {
- string name = dwfDict.NameAt(id);
- using (AcDb.DwfDefinition def = id.Open(OpenMode.ForRead) as AcDb.DwfDefinition) {
- ed.WriteMessage("\n\tИмя={0} Путь={1}", name, def.SourceFileName);
- }
- }
- }
- }
- }
- ids_unref.Clear();
- // Имена DataLink
- ed.WriteMessage("\nНе используемые DataLink: ");
- AcDb.ObjectId idLinkDict = db.DataLinkDictionaryId;
- if (!idLinkDict.IsNull) {
- using (AcDb.DBDictionary dLinkDict = db.DataLinkDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
- foreach (AcDb.DBDictionaryEntry ent in dLinkDict) ids_unref.Add(ent.Value);
- }
- foreach (AcDb.ObjectId id in ids_unref) {
- using (AcDb.DataLink def = id.Open(OpenMode.ForWrite) as AcDb.DataLink) {
- bool bFindTable = false;
- foreach (AcDb.ObjectId id_target in def.GetTargets()) {
- if (id_target.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AcDb.Table)))) {
- bFindTable = true;
- break;
- }
- }
- if (!bFindTable) {
- ed.WriteMessage("\n\tИмя={0} Путь={1}", def.Name, def.ConnectionString);
- def.Erase();
- }
- }
- }
- }
- }
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=947
Опубликовано 08.09.2014Отредактировано 11.07.2016 в 15:54:28