REMOVEALLPROXY

Автор Тема: REMOVEALLPROXY  (Прочитано 66949 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #45 : 20-11-2014, 13:58:49 »
Она не совсем пустышка и если делать много подмен (десятки/сотни тысяч), то база чертежа будет расти в памяти до того момента, пока чертеж не будет сохранён и открыт повторно. Я бы это делать не рекомендовал.
Я так понял, что он спрашивает о том, почему бы не ограничиться только HandOverTo. Насчёт "будет расти в памяти" я не понял. Смотрим код:
Код - C# [Выбрать]
  1. using (Db.Line rep = new Db.Line()) {
  2.         proxyEntity.HandOverTo(rep, false, false);
  3.         rep.Erase();
  4.         rep.Close();
  5.         proxyEntity.Dispose();
  6.         handOverTo_called = true;
  7. }
Видим, что удаляется как оригинал, так и пустышка (для обоих вызывается Dispose). И за счёт чего же у нас, в этом случае, будет "расти память"?

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
Re: REMOVEALLPROXY
« Ответ #46 : 20-11-2014, 14:27:34 »
Раз пошла такая пьянка, то зачем в Using Close?

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #47 : 20-11-2014, 14:29:47 »
аз пошла такая пьянка, то зачем в Using Close?
Чтобы применить это:
Код - C# [Выбрать]
  1. rep.Erase();

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #48 : 20-11-2014, 14:30:47 »
То что удаляется через Erase - удаляется не сразу, а только при сохранении чертежа. Соотвественно ты как-бы добавил примитив к базе, потом сделал ему Erase. Можешь поэкспериментировать и понаблюдать за памятью в AutoCAD. Не исключено, что я не прав.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #49 : 20-11-2014, 14:33:11 »
Чтобы применить это:
А bender прав. После HandOverTo у line появляется ненулевой ObjectId и соотвественно line.Dispose() приводит к line.Close(). Так что вызов line.Close() лишний.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #50 : 20-11-2014, 14:34:41 »
Спасибо, исправляю.
UPD Обновил код для ExtensionMethods.cs в последней версии, опубликованной мною выше (убрал лишние вызовы Close()).

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #51 : 20-11-2014, 14:52:07 »
То что удаляется через Erase - удаляется не сразу, а только при сохранении чертежа.
Тогда тем более:
Код - C# [Выбрать]
  1. if (canBeErased) {
  2.         proxyEntity.Erase();
  3.         handOverTo_called = false;
  4. }
  5. else {
  6.         using (Db.Line tmp = new Db.Line()) {
  7.                 proxyEntity.HandOverTo(tmp, false, false);
  8.                 tmp.Erase();
  9.                 proxyEntity.Dispose();
  10.                 handOverTo_called = true;
  11.         }
  12. }
Как в первом, так и во втором случаях - мы в итоге вызываем Erase.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #52 : 20-11-2014, 14:56:50 »
Как в первом, так и во втором случаях - мы в итоге вызываем Erase.
Но в первом случае ты вызываешь Erase для примитива, который уже находится в базе. Соотвественно объем памяти не изменяется. Во втором случае ты вызываешь Erase для примитива, который только что добавлен в базу. Вот за счет этого и возможно увеличение памяти.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #53 : 20-11-2014, 14:58:40 »
Кстати, если мы вызываем dbObj.HandOverTo, то у других объектов, ссылающихся на  dbObj, свойство ObjectId.IsEffectivelyErased начнёт показывать true (свойство DBObject.OwnerId), в то время как свойство ObjectId.IsErased будет по прежнему false. Именно по этой причине в фильтр я и добавил проверку ObjectId.IsEffectivelyErased.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #54 : 20-11-2014, 15:06:01 »
Именно по этой причине в фильтр я и добавил проверку ObjectId.IsEffectivelyErased.
Но в этом случае у тебя скорее всего не будет сходится статистика.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #55 : 20-11-2014, 15:07:55 »
Но в этом случае у тебя скорее всего не будет сходится статистика.
Да она и до этого не сходилась.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #56 : 20-11-2014, 16:33:13 »
Все дружно шлём апельсины (не путать с помидорами) в адрес Дмитрия Загорулькина, напомнившего о существовании перегруженной версии метода
Код - C# [Выбрать]
  1. Transaction.GetObject Method (ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode, [MarshalAs(UnmanagedType.U1)] bool, [MarshalAs(UnmanagedType.U1)] bool)
Последний параметр позволяет открывать и править объекты на заблокированных слоях. Т.о. отваливается необходимость и в методе GetLockedLayerIds, а так же в файле LayoutLockingSwitcher.cs.

Выкладываю очередную (вторую по счёту) модификацию кода (теперь только два файла):

Код - C# [Выбрать]
  1. // © Andrey Bushman, 2014
  2. // ExtensionMethods.cs
  3. // This code partially based on Alexander Rivilis's code (ARX version):
  4. // http://adn-cis.org/forum/index.php?topic=1060.msg4983#msg4983
  5.  
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9.  
  10. #if AUTOCAD
  11. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  12. using Ap = Autodesk.AutoCAD.ApplicationServices;
  13. using Db = Autodesk.AutoCAD.DatabaseServices;
  14. using Ed = Autodesk.AutoCAD.EditorInput;
  15. using Rt = Autodesk.AutoCAD.Runtime;
  16. using Gm = Autodesk.AutoCAD.Geometry;
  17. #endif
  18.  
  19. namespace Bushman.CAD {
  20.     public static class ExtensionMethods {
  21.  
  22.         static Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof(
  23.             Db.ProxyObject));
  24.  
  25.         static Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(
  26.             Db.ProxyEntity));
  27.  
  28.         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db) {
  29.             Db.ObjectId[] ids = GetDBObjectIds(db, (n => true));
  30.             return ids;
  31.         }
  32.  
  33.         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db,
  34.             Func<Db.ObjectId, Boolean> filter) {
  35.  
  36.             // Check arguments
  37.             if (null == db)
  38.                 throw new ArgumentNullException("null == db");
  39.             if (null == filter)
  40.                 throw new ArgumentNullException("null == filter");
  41.             if (db.IsDisposed)
  42.                 throw new ArgumentException("true == db.IsDisposed");
  43.  
  44.             // -------------------
  45.             Int32 approxNum = db.ApproxNumObjects;
  46.             List<Db.ObjectId> ids = new List<Db.ObjectId>();
  47.  
  48.             for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value
  49.                 && approxNum > 0; ++i) {
  50.  
  51.                 Db.Handle h = new Db.Handle(i);
  52.                 Db.ObjectId id = Db.ObjectId.Null;
  53.  
  54.                 Boolean parseResult = db.TryGetObjectId(h, out id);
  55.  
  56.                 if (parseResult) {
  57.                     --approxNum;
  58.                     if (filter(id)) {
  59.                         ids.Add(id);
  60.                     }
  61.                 }
  62.             }
  63.             return ids.ToArray();
  64.         }
  65.  
  66.         public static Db.ObjectId[] GetEntityIds(this Db.Database db) {
  67.             Db.ObjectId[] ids = GetEntityIds(db, (n => true));
  68.             return ids;
  69.         }
  70.  
  71.         public static Db.ObjectId[] GetEntityIds(this Db.Database db,
  72.             Func<Db.ObjectId, Boolean> filter) {
  73.  
  74.             // Check arguments
  75.             if (null == db)
  76.                 throw new ArgumentNullException("null == db");
  77.             if (null == filter)
  78.                 throw new ArgumentNullException("null == filter");
  79.             if (db.IsDisposed)
  80.                 throw new ArgumentException("true == db.IsDisposed");
  81.  
  82.             // -------------------
  83.             List<Db.ObjectId> ids = new List<Db.ObjectId>();
  84.             // Entity items can be located in the BlockTableRecord instances
  85.             // only.
  86.             using (Db.Transaction tr = db.TransactionManager.StartTransaction()
  87.                 ) {
  88.                 Db.BlockTable bt = tr.GetObject(db.BlockTableId,
  89.                     Db.OpenMode.ForRead) as Db.BlockTable;
  90.  
  91.                 // Skip erased BlockTableRecord instances.
  92.                 IEnumerable<Db.ObjectId> btrIds = bt.Cast<Db.ObjectId>()
  93.                     .Where(n => !n.IsErased);
  94.  
  95.                 foreach (Db.ObjectId btrId in btrIds) {
  96.                     Db.BlockTableRecord btr = tr.GetObject(btrId,
  97.                         Db.OpenMode.ForRead) as Db.BlockTableRecord;
  98.                     foreach (Db.ObjectId id in btr) {
  99.                         if (filter(id)) {
  100.                             ids.Add(id);
  101.                         }
  102.                     }
  103.                 }
  104.                 tr.Commit();
  105.             }
  106.             return ids.ToArray();
  107.         }
  108.  
  109.         public static Db.ObjectId[] ExplodeProxyEntity(
  110.             Db.ObjectId proxyEntityId, out Boolean handOverTo_called) {
  111.  
  112.             // Check arguments
  113.             if (null == proxyEntityId)
  114.                 throw new ArgumentException("null == proxyEntityId");
  115.             if (proxyEntityId.IsErased)
  116.                 throw new ArgumentException("true == proxyEntityId.IsErased");
  117.             if (null == proxyEntityId.Database)
  118.                 throw new ArgumentException("null == proxyEntityId.Database");
  119.             if (proxyEntityId.Database.IsDisposed)
  120.                 throw new ArgumentException(
  121.                     "true == proxyEntityId.Database.IsDisposed");
  122.             if (!proxyEntityId.ObjectClass.IsDerivedFrom(proxyEntityRXType))
  123.                 throw new ArgumentException("false == proxyEntityId." +
  124.                     "ObjectClass.IsDerivedFrom(proxyEntityRXType)");
  125.  
  126.             // -------------------
  127.             using (Db.DBObjectCollection newDBObjects =
  128.                 new Db.DBObjectCollection()) {
  129.                 Db.Database db = proxyEntityId.Database;
  130.  
  131.                 using (Db.Transaction tr = db.TransactionManager
  132.                     .StartOpenCloseTransaction()) {
  133.                     Db.ProxyEntity proxyEntity = tr.GetObject(
  134.                         proxyEntityId, Db.OpenMode.ForWrite, false, true)
  135.                         as Db.ProxyEntity;
  136.  
  137.                     if (proxyEntity.GraphicsMetafileType ==
  138.                         Db.GraphicsMetafileType.FullGraphics) {
  139.                         try {
  140.                             proxyEntity.Explode(newDBObjects);
  141.                         }
  142.                         catch {
  143.                         }
  144.                     }
  145.                     else if (proxyEntity.GraphicsMetafileType ==
  146.                         Db.GraphicsMetafileType.BoundingBox) {
  147.  
  148.                         Db.Extents3d ext = proxyEntity.GeometricExtents;
  149.                         Gm.Point3dCollection arr =
  150.                             new Gm.Point3dCollection();
  151.  
  152.                         arr.Add(ext.MinPoint);
  153.                         arr.Add(new Gm.Point3d(ext.MinPoint.X,
  154.                             ext.MaxPoint.Y, ext.MinPoint.Z));
  155.                         arr.Add(new Gm.Point3d(ext.MaxPoint.X,
  156.                             ext.MaxPoint.Y, ext.MinPoint.Z));
  157.                         arr.Add(new Gm.Point3d(ext.MaxPoint.X,
  158.                             ext.MinPoint.Y, ext.MinPoint.Z));
  159.  
  160.                         Db.Polyline3d pline = new Db.Polyline3d(
  161.                             Db.Poly3dType.SimplePoly, arr, true);
  162.  
  163.                         pline.LayerId = proxyEntity.LayerId;
  164.                         pline.LinetypeId = proxyEntity.LinetypeId;
  165.                         pline.Color = proxyEntity.Color;
  166.  
  167.                         newDBObjects.Add(pline);
  168.                     }
  169.  
  170.                     Db.BlockTableRecord btr = tr.GetObject(
  171.                         proxyEntity.BlockId, Db.OpenMode.ForWrite, false)
  172.                         as Db.BlockTableRecord;
  173.  
  174.                     // ----------------
  175.                     Boolean canBeErased = (proxyEntity.ProxyFlags & 0x1) != 0;
  176.  
  177.                     if (canBeErased) {
  178.                         proxyEntity.Erase();
  179.                         handOverTo_called = false;
  180.                     }
  181.                     else {
  182.                         using (Db.Line tmp = new Db.Line()) {
  183.                             proxyEntity.HandOverTo(tmp, false, false);
  184.                             tmp.Erase();
  185.                             proxyEntity.Dispose();
  186.                             handOverTo_called = true;
  187.                         }
  188.                     }
  189.  
  190.                     if (newDBObjects.Count > 0) {
  191.                         foreach (Db.DBObject item in newDBObjects) {
  192.                             if (item is Db.Entity) {
  193.                                 Db.Entity _ent = item as Db.Entity;
  194.                                 btr.AppendEntity(_ent);
  195.                                 tr.AddNewlyCreatedDBObject(item, true);
  196.                             }
  197.                         }
  198.                     }
  199.                     Db.ObjectIdCollection idsRef =
  200.                         btr.GetBlockReferenceIds(true, true);
  201.                     foreach (Db.ObjectId id in idsRef) {
  202.                         Db.BlockReference br = tr.GetObject(id,
  203.                             Db.OpenMode.ForWrite, false)
  204.                             as Db.BlockReference;
  205.                         br.RecordGraphicsModified(true);
  206.                     }
  207.                     tr.Commit();
  208.                 }
  209.                 return newDBObjects.Cast<Db.DBObject>().Select(n => n.ObjectId)
  210.                     .ToArray();
  211.             }
  212.         }
  213.  
  214.         public static void RemoveDBObject(Db.ObjectId id,
  215.             out Boolean handOverTo_called) {
  216.  
  217.             // Check arguments
  218.             if (null == id)
  219.                 throw new ArgumentException("null == id");
  220.             if (id.IsErased)
  221.                 throw new ArgumentException("true == id.IsErased");
  222.             if (null == id.Database)
  223.                 throw new ArgumentException("null == id.Database");
  224.             if (id.Database.IsDisposed)
  225.                 throw new ArgumentException("true == id.Database.IsDisposed");
  226.  
  227.             // -------------------
  228.             Db.Database db = id.Database;
  229.  
  230.             using (Db.Transaction tr = db.TransactionManager
  231.                 .StartOpenCloseTransaction()) {
  232.                 Db.DBObject obj = tr.GetObject(id, Db.OpenMode.ForWrite, false,
  233.                     true);
  234.                 EraseDBObject(obj, out handOverTo_called);
  235.                 tr.Commit();
  236.             }
  237.         }
  238.  
  239.         private static void EraseDBObject(Db.DBObject obj,
  240.             out Boolean handOverTo_called) {
  241.  
  242.             // Check argument
  243.             if (null == obj)
  244.                 throw new ArgumentNullException("null == obj");
  245.             if (obj.IsErased)
  246.                 throw new ArgumentException("true == obj.IsErased");
  247.             if (obj.IsDisposed)
  248.                 throw new ArgumentException("true == obj.IsDisposed");
  249.             if (null == obj.Database)
  250.                 throw new ArgumentException("null == obj.Database");
  251.             if (obj.Database.IsDisposed)
  252.                 throw new ArgumentException("true == obj.Database.IsDisposed");
  253.  
  254.             // ----------------
  255.             Boolean canBeErased = true;
  256.  
  257.             // AcDbProxyEntity::kEraseAllowed = 0x1
  258.             if (obj is Db.ProxyObject) {
  259.                 Db.ProxyObject proxy = obj as Db.ProxyObject;
  260.                 canBeErased = (proxy.ProxyFlags & 0x1) != 0;
  261.             }
  262.             else if (obj is Db.ProxyEntity) {
  263.                 Db.ProxyEntity proxy = obj as Db.ProxyEntity;
  264.                 canBeErased = (proxy.ProxyFlags & 0x1) != 0;
  265.             }
  266.  
  267.             if (canBeErased) {
  268.                 obj.Erase(true);
  269.                 handOverTo_called = false;
  270.             }
  271.             else {
  272.                 using (Db.DBObject tmp = obj is Db.Entity ?
  273.                     (Db.DBObject)new Db.Line() : new Db.DBDictionary()) {
  274.                     obj.HandOverTo(tmp, false, false);
  275.                     tmp.Erase(true);
  276.                     obj.Dispose();
  277.                     handOverTo_called = true;
  278.                 }
  279.             }
  280.         }
  281.  
  282.         public static Db.ObjectId[] GetFreeAnnotativeScaleIds(
  283.             this Db.Database db) {
  284.  
  285.             // Check argument
  286.             if (null == db)
  287.                 throw new ArgumentNullException("null == db");
  288.             if (db.IsDisposed)
  289.                 throw new ArgumentException("true == db.IsDisposed");
  290.  
  291.             // ----------------
  292.             using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection()) {
  293.                 Db.ObjectContextManager ocMng = db.ObjectContextManager;
  294.                 if (null != ocMng) {
  295.                     Db.ObjectContextCollection ocItems =
  296.                         ocMng.GetContextCollection("ACDB_ANNOTATIONSCALES");
  297.                     if (null != ocItems) {
  298.                         foreach (Db.ObjectContext item in ocItems) {
  299.                             if (item is Db.AnnotationScale)
  300.                                 ids.Add(new Db.ObjectId(item.UniqueIdentifier)
  301.                                     );
  302.                         }
  303.                         db.Purge(ids);
  304.                     }
  305.                 }
  306.                 return ids.Cast<Db.ObjectId>().Where(n => !n.IsErased
  307.                     && !n.IsEffectivelyErased).ToArray();
  308.             }
  309.         }
  310.  
  311.         public static void RemoveFreeAnnotativeScales(this Db.Database db) {
  312.  
  313.             // Check argument
  314.             if (null == db)
  315.                 throw new ArgumentNullException("null == db");
  316.             if (db.IsDisposed)
  317.                 throw new ArgumentException("true == db.IsDisposed");
  318.  
  319.             // -----------------
  320.             Db.ObjectId[] ids = db.GetFreeAnnotativeScaleIds();
  321.  
  322.             using (Db.Transaction tr = db.TransactionManager.StartTransaction()
  323.                 ) {
  324.                 foreach (Db.ObjectId id in ids) {
  325.                     try {
  326.                         Db.DBObject obj = tr.GetObject(id, Db.OpenMode
  327.                             .ForWrite, false);
  328.                         obj.Erase();
  329.                     }
  330.                     catch { }
  331.                 }
  332.                 tr.Commit();
  333.             }
  334.         }
  335.     }
  336. }

Код - C# [Выбрать]
  1. // © Andrey Bushman, 2014
  2. // Commands.cs
  3.  
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Diagnostics;
  8.  
  9. #if AUTOCAD
  10. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  11. using Ap = Autodesk.AutoCAD.ApplicationServices;
  12. using Db = Autodesk.AutoCAD.DatabaseServices;
  13. using Ed = Autodesk.AutoCAD.EditorInput;
  14. using Rt = Autodesk.AutoCAD.Runtime;
  15. using Gm = Autodesk.AutoCAD.Geometry;
  16. #endif
  17.  
  18. [assembly: Rt.CommandClass(typeof(Bushman.CAD.Commands))]
  19.  
  20. namespace Bushman.CAD {
  21.     public sealed class Commands {
  22.  
  23.         static Db.ObjectId circleId = Db.ObjectId.Null;
  24.  
  25.         [Rt.CommandMethod("Proxy", Rt.CommandFlags.Modal)]
  26.         public void Command_PrintProxyInfo() {
  27.  
  28.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  29.             Ed.Editor ed = doc.Editor;
  30.             Db.Database db = doc.Database;
  31.  
  32.             // Proxy types
  33.             Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof(
  34.                 Db.ProxyObject));
  35.             Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(
  36.                 Db.ProxyEntity));
  37.  
  38.             // Filters
  39.             Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased &&
  40.                  !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(
  41.                  proxyEntityRXType);
  42.  
  43.             Func<Db.ObjectId, Boolean> proxyObjectFilter = n => !n.IsErased &&
  44.                 !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(
  45.                 proxyObjectRXType);
  46.  
  47.             // Filtered ids
  48.             Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter);
  49.             Db.ObjectId[] proxyObjectIds = db.GetDBObjectIds(proxyObjectFilter
  50.                );
  51.             ed.WriteMessage(
  52.                 "{0} ProxyEntity and {1} ProxyObject items found.\n",
  53.                 proxyEntityIds.Length.ToString(), proxyObjectIds.Length
  54.                 .ToString());
  55.         }
  56.  
  57.         [Rt.CommandMethod("ClrScales", Rt.CommandFlags.Modal)]
  58.         public void Command_ClearUnusedAnnotativeScales() {
  59.  
  60.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  61.             Ed.Editor ed = doc.Editor;
  62.             Db.Database db = doc.Database;
  63.  
  64.             Db.ObjectId[] freeAnnotScaleIds = db.GetFreeAnnotativeScaleIds();
  65.             db.RemoveFreeAnnotativeScales();
  66.  
  67.             try {
  68.                 /* Remove erased objects from memory.
  69.                  * An exception occurs if erasedIds contain ids which was
  70.                  * removed from memory already. There is no method to check it
  71.                  * in advance. */
  72.                 Db.ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased);
  73.  
  74.                 /* This checking is neccessary, bacause if erasedIds.Length ==
  75.                  * 0 we get an exception in the ObjectIdCollection
  76.                  * initialization. */
  77.                 if (erasedIds.Length > 0) {
  78.                     using (Db.ObjectIdCollection ids =
  79.                         new Db.ObjectIdCollection(erasedIds)) {
  80.                         db.ReclaimMemoryFromErasedObjects(ids);
  81.                     }
  82.                 }
  83.             }
  84.             catch {/* nothing here */ }
  85.  
  86.             ed.WriteMessage("{0} unused annotation scales found and removed.\n",
  87.                 freeAnnotScaleIds.Length.ToString());
  88.         }
  89.  
  90.         [Rt.CommandMethod("rmProxy", Rt.CommandFlags.Modal)]
  91.         public void Command_RemoveAllProxyObjests() {
  92.  
  93.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  94.             Ed.Editor ed = doc.Editor;
  95.             Db.Database db = doc.Database;
  96.  
  97.             Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof(
  98.                 Db.ProxyObject));
  99.             Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(
  100.                 Db.ProxyEntity));
  101.  
  102.             Func<Db.ObjectId, Boolean> proxyObjectFilter = n => !n.IsErased &&
  103.                 !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(
  104.                 proxyObjectRXType);
  105.             Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased &&
  106.                  !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(
  107.                  proxyEntityRXType);
  108.  
  109.             Db.ObjectId[] proxyObjectIds = db.GetDBObjectIds(proxyObjectFilter
  110.                 );
  111.             Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter);
  112.  
  113.             Int64 handOverTo_object_count = 0;
  114.             Int64 handOverTo_entity_count = 0;
  115.  
  116.             foreach (Db.ObjectId id in proxyObjectIds) {
  117.                 Boolean handOverTo_called = false;
  118.                 ExtensionMethods.RemoveDBObject(id, out handOverTo_called);
  119.                 if (handOverTo_called)
  120.                     ++handOverTo_object_count;
  121.             }
  122.             ed.WriteMessage("{0} ProxyObject items found and removed.\n",
  123.                 proxyObjectIds.Length.ToString());
  124.             ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n\n",
  125.                 handOverTo_object_count.ToString());
  126.  
  127.             foreach (Db.ObjectId id in proxyEntityIds) {
  128.                 Boolean handOverTo_called = false;
  129.                 ExtensionMethods.RemoveDBObject(id, out handOverTo_called);
  130.                 if (handOverTo_called)
  131.                     ++handOverTo_entity_count;
  132.             }
  133.  
  134.             try {
  135.                 /* Remove erased objects from memory.
  136.                  * An exception occurs if erasedIds contain ids which was
  137.                  * removed from memory already. There is no method to check it
  138.                  * in advance. */
  139.                 Db.ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased);
  140.  
  141.                 /* This checking is neccessary, bacause if erasedIds.Length ==
  142.                  * 0 we get an exception in the ObjectIdCollection
  143.                  * initialization. */
  144.                 if (erasedIds.Length > 0) {
  145.                     using (Db.ObjectIdCollection ids =
  146.                         new Db.ObjectIdCollection(erasedIds)) {
  147.                         db.ReclaimMemoryFromErasedObjects(ids);
  148.                     }
  149.                 }
  150.             }
  151.             catch {/* nothing here */ }
  152.  
  153.             ed.WriteMessage("{0} ProxyEntity items found and removed.\n",
  154.                 proxyEntityIds.Length.ToString());
  155.             ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n\n",
  156.                 handOverTo_entity_count.ToString());
  157.  
  158.             ed.WriteMessage("Run the _AUDIT command with the _Y option, " +
  159.                 "please.\n");
  160.         }
  161.  
  162.         [Rt.CommandMethod("xProxy", Rt.CommandFlags.Modal)]
  163.         public void Command_ExplodeAllProxyEntities() {
  164.  
  165.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  166.             Ed.Editor ed = doc.Editor;
  167.             Db.Database db = doc.Database;
  168.  
  169.             Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(
  170.                 Db.ProxyEntity));
  171.  
  172.             Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased &&
  173.                  !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(
  174.                  proxyEntityRXType);
  175.  
  176.             Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter);
  177.  
  178.             Int64 newEntityCount = 0;
  179.             Int64 handOverTo_entity_count = 0;
  180.  
  181.             foreach (Db.ObjectId id in proxyEntityIds) {
  182.                 Boolean handOverTo_called = false;
  183.                 Db.ObjectId[] newEntityIds = ExtensionMethods
  184.                     .ExplodeProxyEntity(id, out handOverTo_called);
  185.                 newEntityCount += newEntityIds.Length;
  186.                 if (handOverTo_called)
  187.                     ++handOverTo_entity_count;
  188.             }
  189.  
  190.             try {
  191.                 /* Remove erased objects from memory.
  192.                  * An exception occurs if erasedIds contain ids which was
  193.                  * removed from memory already. There is no method to check it
  194.                  * in advance. */
  195.                 Db.ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased);
  196.  
  197.                 /* This checking is neccessary, bacause if erasedIds.Length ==
  198.                  * 0 we get an exception in the ObjectIdCollection
  199.                  * initialization. */
  200.                 if (erasedIds.Length > 0) {
  201.                     using (Db.ObjectIdCollection ids =
  202.                         new Db.ObjectIdCollection(erasedIds)) {
  203.                         db.ReclaimMemoryFromErasedObjects(ids);
  204.                     }
  205.                 }
  206.             }
  207.             catch {/* nothing here */ }
  208.  
  209.             ed.WriteMessage("{0} ProxyEntity items found and exloded.\n",
  210.                 proxyEntityIds.Length.ToString());
  211.             ed.WriteMessage("{0} new DBObjects created.\n", newEntityCount
  212.                 .ToString());
  213.             ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n",
  214.                 handOverTo_entity_count.ToString());
  215.  
  216.             ed.WriteMessage("Run the _AUDIT command with the _Y option, " +
  217.                 "please.\n");
  218.         }
  219.     }
  220. }
« Последнее редактирование: 21-11-2014, 12:46:51 от Андрей Бушман »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #57 : 20-11-2014, 17:28:20 »
Все дружно шлём апельсины (не путать с помидорами) в адрес Дмитрия Загорулькина, напомнившего о существовании перегруженной версии метода
Код - C#: [Выделить]

    Transaction.GetObject Method (ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode, [MarshalAs(UnmanagedType.U1)] bool, [MarshalAs(UnmanagedType.U1)] bool)

Последний параметр позволяет открывать и править объекты на заблокированных слоях. Т.о. отваливается необходимость и в методе GetLockedLayerIds, а так же в файле LayoutLockingSwitcher.cs.
1) Про этот метод я помнил, но он появился только в AutoCAD 2009, так что для тебя он актуален, но в случае необходимости писать универсальный код - не подходит (это касается и чистого ObjectARX)
2) По поводу твоей функции RemoveFreeAnnotativeScales. Её действия отличаются от стандартной команды _SCALELISTEDIT _Reset. В стандарте не удаляются неиспользуемые, но стандартные масштабы.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #58 : 20-11-2014, 17:31:38 »
но стандартные масштабы.
у иностранцев свой список стандартных масштабов, а в России свой. Так что удаление их стандартных записей нам [проектировщикам компании, в которой я работаю] только на руку - не будут попусту глаза мозолить.

Цитировать
но в случае необходимости писать универсальный код - не подходит
"Универсальность" - понятие относительное... Например для меня это слово означает переносимость на уровне кода для AutoCAD 2009 и выше (более старые версии мне не интересны), а так же между различными CAD платформами (AutoCAD, nanoCAD, BricsCAD и т.п.).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13072
  • Карма: 1685
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #59 : 20-11-2014, 17:41:58 »
Например для меня это слово означает переносимость на уровне кода для AutoCAD 2009 и выше (более старые версии мне не интересны)
Считай, что это было не для тебя, а для тех, кто еще пишет под версии AutoCAD до 2009.
Что касается списка масштабов, то восстановление в русской версии AutoCAD должно быть в стандартный список масштабов русской версии, что команда _SCALELISTEDIT _Reset и делает. Если вашим пользователям так удобнее, то и хорошо. Но это не всегда так. Допустим использовали только масштаб 1:2, ты все остальные масштабы удалил. Теперь пользователю самому придется создать масштаб 1:1.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение