- // © Andrey Bushman, 2014 
- // ExtensionMethods.cs 
- // This code partially based on Alexander Rivilis's code (ARX version): 
- // http://adn-cis.org/forum/index.php?topic=1060.msg4983#msg4983 
-   
- using System; 
- using System.Collections.Generic; 
- using System.Linq; 
-   
- #if AUTOCAD 
- using cad = Autodesk.AutoCAD.ApplicationServices.Application; 
- using Ap = Autodesk.AutoCAD.ApplicationServices; 
- using Db = Autodesk.AutoCAD.DatabaseServices; 
- using Ed = Autodesk.AutoCAD.EditorInput; 
- using Rt = Autodesk.AutoCAD.Runtime; 
- using Gm = Autodesk.AutoCAD.Geometry; 
- #endif 
-   
- namespace Bushman.CAD { 
-     public static class ExtensionMethods { 
-   
-         static Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof( 
-             Db.ProxyObject)); 
-   
-         static Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof( 
-             Db.ProxyEntity)); 
-   
-         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db) { 
-             Db.ObjectId[] ids = GetDBObjectIds(db, (n => true)); 
-             return ids; 
-         } 
-   
-         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db, 
-             Func<Db.ObjectId, Boolean> filter) { 
-   
-             // Check arguments 
-             if (null == db) 
-                 throw new ArgumentNullException("null == db"); 
-             if (null == filter) 
-                 throw new ArgumentNullException("null == filter"); 
-             if (db.IsDisposed) 
-                 throw new ArgumentException("true == db.IsDisposed"); 
-   
-             // ------------------- 
-             Int32 approxNum = db.ApproxNumObjects; 
-             List<Db.ObjectId> ids = new List<Db.ObjectId>(); 
-   
-             for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value 
-                 && approxNum > 0; ++i) { 
-   
-                 Db.Handle h = new Db.Handle(i); 
-                 Db.ObjectId id = Db.ObjectId.Null; 
-   
-                 Boolean parseResult = db.TryGetObjectId(h, out id); 
-   
-                 if (parseResult) { 
-                     --approxNum; 
-                     if (filter(id)) { 
-                         ids.Add(id); 
-                     } 
-                 } 
-             } 
-             return ids.ToArray(); 
-         } 
-   
-         public static Db.ObjectId[] GetEntityIds(this Db.Database db) { 
-             Db.ObjectId[] ids = GetEntityIds(db, (n => true)); 
-             return ids; 
-         } 
-   
-         public static Db.ObjectId[] GetEntityIds(this Db.Database db, 
-             Func<Db.ObjectId, Boolean> filter) { 
-   
-             // Check arguments 
-             if (null == db) 
-                 throw new ArgumentNullException("null == db"); 
-             if (null == filter) 
-                 throw new ArgumentNullException("null == filter"); 
-             if (db.IsDisposed) 
-                 throw new ArgumentException("true == db.IsDisposed"); 
-   
-             // ------------------- 
-             List<Db.ObjectId> ids = new List<Db.ObjectId>(); 
-             // Entity items can be located in the BlockTableRecord instances  
-             // only. 
-             using (Db.Transaction tr = db.TransactionManager.StartTransaction() 
-                 ) { 
-                 Db.BlockTable bt = tr.GetObject(db.BlockTableId, 
-                     Db.OpenMode.ForRead) as Db.BlockTable; 
-   
-                 // Skip erased BlockTableRecord instances. 
-                 IEnumerable<Db.ObjectId> btrIds = bt.Cast<Db.ObjectId>() 
-                     .Where(n => !n.IsErased); 
-   
-                 foreach (Db.ObjectId btrId in btrIds) { 
-                     Db.BlockTableRecord btr = tr.GetObject(btrId, 
-                         Db.OpenMode.ForRead) as Db.BlockTableRecord; 
-                     foreach (Db.ObjectId id in btr) { 
-                         if (filter(id)) { 
-                             ids.Add(id); 
-                         } 
-                     } 
-                 } 
-                 tr.Commit(); 
-             } 
-             return ids.ToArray(); 
-         } 
-   
-         public static Db.ObjectId[] ExplodeProxyEntity( 
-             Db.ObjectId proxyEntityId, out Boolean handOverTo_called) { 
-   
-             // Check arguments 
-             if (null == proxyEntityId) 
-                 throw new ArgumentException("null == proxyEntityId"); 
-             if (proxyEntityId.IsErased) 
-                 throw new ArgumentException("true == proxyEntityId.IsErased"); 
-             if (null == proxyEntityId.Database) 
-                 throw new ArgumentException("null == proxyEntityId.Database"); 
-             if (proxyEntityId.Database.IsDisposed) 
-                 throw new ArgumentException( 
-                     "true == proxyEntityId.Database.IsDisposed"); 
-             if (!proxyEntityId.ObjectClass.IsDerivedFrom(proxyEntityRXType)) 
-                 throw new ArgumentException("false == proxyEntityId." + 
-                     "ObjectClass.IsDerivedFrom(proxyEntityRXType)"); 
-   
-             // ------------------- 
-             using (Db.DBObjectCollection newDBObjects = 
-                 new Db.DBObjectCollection()) { 
-                 Db.Database db = proxyEntityId.Database; 
-   
-                 using (Db.Transaction tr = db.TransactionManager 
-                     .StartOpenCloseTransaction()) { 
-                     Db.ProxyEntity proxyEntity = tr.GetObject( 
-                         proxyEntityId, Db.OpenMode.ForWrite, false, true) 
-                         as Db.ProxyEntity; 
-   
-                     if (proxyEntity.GraphicsMetafileType == 
-                         Db.GraphicsMetafileType.FullGraphics) { 
-                         try { 
-                             proxyEntity.Explode(newDBObjects); 
-                         } 
-                         catch { 
-                         } 
-                     } 
-                     else if (proxyEntity.GraphicsMetafileType == 
-                         Db.GraphicsMetafileType.BoundingBox) { 
-   
-                         Db.Extents3d ext = proxyEntity.GeometricExtents; 
-                         Gm.Point3dCollection arr = 
-                             new Gm.Point3dCollection(); 
-   
-                         arr.Add(ext.MinPoint); 
-                         arr.Add(new Gm.Point3d(ext.MinPoint.X, 
-                             ext.MaxPoint.Y, ext.MinPoint.Z)); 
-                         arr.Add(new Gm.Point3d(ext.MaxPoint.X, 
-                             ext.MaxPoint.Y, ext.MinPoint.Z)); 
-                         arr.Add(new Gm.Point3d(ext.MaxPoint.X, 
-                             ext.MinPoint.Y, ext.MinPoint.Z)); 
-   
-                         Db.Polyline3d pline = new Db.Polyline3d( 
-                             Db.Poly3dType.SimplePoly, arr, true); 
-   
-                         pline.LayerId = proxyEntity.LayerId; 
-                         pline.LinetypeId = proxyEntity.LinetypeId; 
-                         pline.Color = proxyEntity.Color; 
-   
-                         newDBObjects.Add(pline); 
-                     } 
-   
-                     Db.BlockTableRecord btr = tr.GetObject( 
-                         proxyEntity.BlockId, Db.OpenMode.ForWrite, false) 
-                         as Db.BlockTableRecord; 
-   
-                     // ---------------- 
-                     Boolean canBeErased = (proxyEntity.ProxyFlags & 0x1) != 0; 
-   
-                     if (canBeErased) { 
-                         proxyEntity.Erase(); 
-                         handOverTo_called = false; 
-                     } 
-                     else { 
-                         using (Db.Line tmp = new Db.Line()) { 
-                             proxyEntity.HandOverTo(tmp, false, false); 
-                             tmp.Erase(); 
-                             proxyEntity.Dispose(); 
-                             handOverTo_called = true; 
-                         } 
-                     } 
-   
-                     if (newDBObjects.Count > 0) { 
-                         foreach (Db.DBObject item in newDBObjects) { 
-                             if (item is Db.Entity) { 
-                                 Db.Entity _ent = item as Db.Entity; 
-                                 btr.AppendEntity(_ent); 
-                                 tr.AddNewlyCreatedDBObject(item, true); 
-                             } 
-                         } 
-                     } 
-                     Db.ObjectIdCollection idsRef = 
-                         btr.GetBlockReferenceIds(true, true); 
-                     foreach (Db.ObjectId id in idsRef) { 
-                         Db.BlockReference br = tr.GetObject(id, 
-                             Db.OpenMode.ForWrite, false) 
-                             as Db.BlockReference; 
-                         br.RecordGraphicsModified(true); 
-                     } 
-                     tr.Commit(); 
-                 } 
-                 return newDBObjects.Cast<Db.DBObject>().Select(n => n.ObjectId) 
-                     .ToArray(); 
-             } 
-         } 
-   
-         public static void RemoveDBObject(Db.ObjectId id, 
-             out Boolean handOverTo_called) { 
-   
-             // Check arguments 
-             if (null == id) 
-                 throw new ArgumentException("null == id"); 
-             if (id.IsErased) 
-                 throw new ArgumentException("true == id.IsErased"); 
-             if (null == id.Database) 
-                 throw new ArgumentException("null == id.Database"); 
-             if (id.Database.IsDisposed) 
-                 throw new ArgumentException("true == id.Database.IsDisposed"); 
-   
-             // ------------------- 
-             Db.Database db = id.Database; 
-   
-             using (Db.Transaction tr = db.TransactionManager 
-                 .StartOpenCloseTransaction()) { 
-                 Db.DBObject obj = tr.GetObject(id, Db.OpenMode.ForWrite, false, 
-                     true); 
-                 EraseDBObject(obj, out handOverTo_called); 
-                 tr.Commit(); 
-             } 
-         } 
-   
-         private static void EraseDBObject(Db.DBObject obj, 
-             out Boolean handOverTo_called) { 
-   
-             // Check argument 
-             if (null == obj) 
-                 throw new ArgumentNullException("null == obj"); 
-             if (obj.IsErased) 
-                 throw new ArgumentException("true == obj.IsErased"); 
-             if (obj.IsDisposed) 
-                 throw new ArgumentException("true == obj.IsDisposed"); 
-             if (null == obj.Database) 
-                 throw new ArgumentException("null == obj.Database"); 
-             if (obj.Database.IsDisposed) 
-                 throw new ArgumentException("true == obj.Database.IsDisposed"); 
-   
-             // ---------------- 
-             Boolean canBeErased = true; 
-   
-             // AcDbProxyEntity::kEraseAllowed = 0x1 
-             if (obj is Db.ProxyObject) { 
-                 Db.ProxyObject proxy = obj as Db.ProxyObject; 
-                 canBeErased = (proxy.ProxyFlags & 0x1) != 0; 
-             } 
-             else if (obj is Db.ProxyEntity) { 
-                 Db.ProxyEntity proxy = obj as Db.ProxyEntity; 
-                 canBeErased = (proxy.ProxyFlags & 0x1) != 0; 
-             } 
-   
-             if (canBeErased) { 
-                 obj.Erase(true); 
-                 handOverTo_called = false; 
-             } 
-             else { 
-                 using (Db.DBObject tmp = obj is Db.Entity ? 
-                     (Db.DBObject)new Db.Line() : new Db.DBDictionary()) { 
-                     obj.HandOverTo(tmp, false, false); 
-                     tmp.Erase(true); 
-                     obj.Dispose(); 
-                     handOverTo_called = true; 
-                 } 
-             } 
-         } 
-   
-         public static Db.ObjectId[] GetFreeAnnotativeScaleIds( 
-             this Db.Database db) { 
-   
-             // Check argument 
-             if (null == db) 
-                 throw new ArgumentNullException("null == db"); 
-             if (db.IsDisposed) 
-                 throw new ArgumentException("true == db.IsDisposed"); 
-   
-             // ---------------- 
-             using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection()) { 
-                 Db.ObjectContextManager ocMng = db.ObjectContextManager; 
-                 if (null != ocMng) { 
-                     Db.ObjectContextCollection ocItems = 
-                         ocMng.GetContextCollection("ACDB_ANNOTATIONSCALES"); 
-                     if (null != ocItems) { 
-                         foreach (Db.ObjectContext item in ocItems) { 
-                             if (item is Db.AnnotationScale) 
-                                 ids.Add(new Db.ObjectId(item.UniqueIdentifier) 
-                                     ); 
-                         } 
-                         db.Purge(ids); 
-                     } 
-                 } 
-                 return ids.Cast<Db.ObjectId>().Where(n => !n.IsErased 
-                     && !n.IsEffectivelyErased).ToArray(); 
-             } 
-         } 
-   
-         public static void RemoveFreeAnnotativeScales(this Db.Database db) { 
-   
-             // Check argument 
-             if (null == db) 
-                 throw new ArgumentNullException("null == db"); 
-             if (db.IsDisposed) 
-                 throw new ArgumentException("true == db.IsDisposed"); 
-   
-             // ----------------- 
-             Db.ObjectId[] ids = db.GetFreeAnnotativeScaleIds(); 
-   
-             using (Db.Transaction tr = db.TransactionManager.StartTransaction() 
-                 ) { 
-                 foreach (Db.ObjectId id in ids) { 
-                     try { 
-                         Db.DBObject obj = tr.GetObject(id, Db.OpenMode 
-                             .ForWrite, false); 
-                         obj.Erase(); 
-                     } 
-                     catch { } 
-                 } 
-                 tr.Commit(); 
-             } 
-         } 
-     } 
- }