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

ADN Club => AutoCAD .NET API => Тема начата: luphu от 19-03-2019, 17:50:19

Название: Undo и Erase
Отправлено: luphu от 19-03-2019, 17:50:19
Есть вот такой кусок кода.
Код - 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.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in5.MyCommands))]
  10.  
  11. namespace AutoCAD_CSharp_plug_in5
  12. {
  13.  
  14.     // This class is instantiated by AutoCAD for each document when
  15.     // a command is called by the user the first time in the context
  16.     // of a given document. In other words, non static data in this class
  17.     // is implicitly per-document!
  18.     public class MyCommands
  19.     {
  20.         // The CommandMethod attribute can be applied to any public  member
  21.         // function of any public class.
  22.         // The function should take no arguments and return nothing.
  23.         // If the method is an intance member then the enclosing class is
  24.         // intantiated for each document. If the member is a static member then
  25.         // the enclosing class is NOT intantiated.
  26.         //
  27.         // NOTE: CommandMethod has overloads where you can provide helpid and
  28.         // context menu.
  29.  
  30.         // Modal Command with localized name
  31.         [CommandMethod("ORAORA", CommandFlags.UsePickSet)]
  32.  
  33.         public void eraseCircles_2()
  34.         {
  35.             // получаем БД и Editor текущего документа
  36.             Document doc = Application.DocumentManager.MdiActiveDocument;
  37.             Database db = doc.Database;
  38.             Editor ed = doc.Editor;
  39.  
  40.             // создаем переменную, в которой будут содержаться данные для фильтра
  41.             TypedValue[] filterlist = new TypedValue[1];
  42.  
  43.             // первый аргумент (0) указывает, что мы задаем тип объекта                                   this
  44.             // второй аргумент ("CIRCLE") - собственно тип
  45.             filterlist[0] = new TypedValue(0, "CIRCLE");
  46.  
  47.             // создаем фильтр
  48.             SelectionFilter filter = new SelectionFilter(filterlist);
  49.  
  50.             // пытаемся получить ссылки на объекты с учетом фильтра
  51.             // ВНИМАНИЕ! Нужно проверить работоспособность метода с замороженными и заблокированными слоями!
  52.             PromptSelectionResult selRes = ed.SelectAll();
  53.  
  54.             // если произошла ошибка - сообщаем о ней
  55.             if (selRes.Status != PromptStatus.OK)
  56.             {
  57.                 ed.WriteMessage("\nError!\n");                                                            
  58.                 return;
  59.             }
  60.                                                                                                            //thi (вроде, все это не нужно, но удалять и переделывать немного страшно)                                                                                
  61.  
  62.             // получаем массив ID объектов
  63.             ObjectId[] ids = selRes.Value.GetObjectIds();
  64.  
  65.             long time1 = DateTime.Now.Ticks;
  66.             long t1 = Convert.ToInt64(time1);
  67.             Line acLine = new Line(new Point3d(25, 25, 0), new Point3d(33, 33, 0));
  68.             doc.Editor.Command("_undo", 1);
  69.             long time2 = DateTime.Now.Ticks;
  70.             long t2 = Convert.ToInt64(time2);
  71.             long tcontrol = t2 - t1;
  72.             Entity gov;
  73.  
  74.             // начинаем транзакцию
  75.             using (Transaction tr = db.TransactionManager.StartTransaction())
  76.             {
  77.                 // "пробегаем" по всем полученным объектам
  78.                 foreach (ObjectId id in ids)
  79.                 {
  80.                     // приводим каждый из них к типу Entity
  81.                     Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
  82.  
  83.                     // открываем приговоренный объект на запись
  84.                     entity.UpgradeOpen();
  85.  
  86.  
  87.                     // удаляем объект
  88.                     entity.Erase();
  89.  
  90.                     long timea = DateTime.Now.Ticks;
  91.                     long ta = Convert.ToInt64(time1);
  92.                     Line acLine2 = new Line(new Point3d(25, 25, 0), new Point3d(33, 33, 0));
  93.                     long timeb = DateTime.Now.Ticks;
  94.                     long tb = Convert.ToInt64(timeb);
  95.                     long t3 = tb - ta;
  96.                     doc.Editor.Command("_undo", 1);
  97.                     doc.Editor.Command("_undo", 1);
  98.  
  99.  
  100.  
  101.                     if (t3 < tcontrol)
  102.                     {
  103.                         tcontrol = t3;
  104.                         ed.WriteMessage("\n Id предгов: {entity}\n");
  105.                         gov = entity;
  106.                     }
  107.                     else
  108.                     {
  109.                         ed.WriteMessage("\nВсе чисто, вроде {entity}\n");
  110.                     }                    
  111.                 }
  112.                 tr.Commit();
  113.                 gov.Erase();
  114.             }
  115.         }
  116.  
  117.     }
  118.  
  119. }
Проблема в том, что
Код - C# [Выбрать]
  1. doc.Editor.Command("_undo", 1);
не позволяет отменить
Код - C# [Выбрать]
  1. entity.Erase();
Возможно, кто-то сталкивался. Буду благодарен за помощь
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 17:52:33
luphu,
Приветствую на форуме!
Прочитай у меня в подписи правило форматирования кода на форуме и исправь форматирование в своём коде.
Название: Re: Undo и Erase
Отправлено: avc от 19-03-2019, 17:59:51
вы еще не закрыли транзакцию, а уже пытаетесь вызвать undo. нечего отменять-то. ну и куча еще замечаний по коду...
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 18:01:43
avc,
Я бы еще отметил вызов gov.Erase(); после подтверждения транзакции.
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 18:08:32
Есть вот такой кусок кода.
Что должен делать этот кусок кода? И зачем вообще UNDO понадобилось?
Название: Re: Undo и Erase
Отправлено: luphu от 19-03-2019, 18:16:24
Александр Ривилис, задумка такова, чтобы поочередно удалять элементы, чертить линию, удалять линию, замерять, сколько времени ушло на то, чтобы эту линию начертить, выявить элемент, из-за которого линия чертиться дольше всего, а потом его удалить
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 18:20:55
luphu,
Жуть. Время отрисовки при каждом запуске будет разным. Время больше всего тратится на создание/завершение транзакции/запуск команды, а не на добавление/удаление примитива.
Название: Re: Undo и Erase
Отправлено: luphu от 19-03-2019, 18:27:20
Александр Ривилис, все основывается на том, что время отрисовки будет разным. Думаю, Вы сталкивались со случаями, когда из-за одного элемента виснет вес чертеж. По своей глупости я не могу придумать лучшего способа этот элемент найти
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 18:40:01
Александр Ривилис, все основывается на том, что время отрисовки будет разным. Думаю, Вы сталкивались со случаями, когда из-за одного элемента виснет вес чертеж. По своей глупости я не могу придумать лучшего способа этот элемент найти
Сразу тебе скажу, что таким образом ты ничего не добьешься.
Название: Re: Undo и Erase
Отправлено: Привалов Дмитрий от 19-03-2019, 18:42:01
Вы сталкивались со случаями, когда из-за одного элемента виснет вес чертеж. По своей глупости я не могу придумать лучшего способа этот элемент найти
Скорее всего твоя методика не сработает. Лучше опиши подробнее, что значит виснет чертеж из-за одного элемента. Может пример файла есть.

Часто причина в определенных  типах элементов, стилях линий, блоках. Реже штриховки, текст, таблицы. Есть еще настройки AutoCAD, которые следует проверить. Но без информации от тебя будет сложно найти решение ;-)
Название: Re: Undo и Erase
Отправлено: luphu от 19-03-2019, 18:46:45
Привалов Дмитрий, понимаете, у меня у самого нет примеров подобных чертежей, поэтому, к сожалению, ничего конкретного предоставить не могу. Только основываясь на словах людей о том, что они часто сталкиваются с проблемой, когда они не могут чертить, потому что создание какого-то одного объекта, любого, занимает неприлично большое количество времени. И это лечиться путем удаления какого-элемента, после чего все снова начинает работать как надо. Извините, ничего конкретнее у меня нет
Название: Re: Undo и Erase
Отправлено: luphu от 19-03-2019, 18:48:38
Александр Ривилис, я максимально неопытен и некомпетентен в данной теме. Пожалуйста, не могли бы Вы подсказать альтернативный путь решения проблемы. Разумеется, было бы лучше, если бы уже существовало готовое решение
Название: Re: Undo и Erase
Отправлено: Привалов Дмитрий от 19-03-2019, 18:51:12
И это лечиться путем удаления какого-элемента, после чего все снова начинает работать как надо. Извините, ничего конкретнее у меня нет
Ну хотя бы тип элемента люди могут назвать? Пользователи часто не достоверно предоставляют информацию в итоге оказываются причины другие.
Название: Re: Undo и Erase
Отправлено: luphu от 19-03-2019, 18:52:51
Привалов Дмитрий, в последний раз это было окно на фасаде
Название: Re: Undo и Erase
Отправлено: Привалов Дмитрий от 19-03-2019, 19:43:30
в последний раз это было окно на фасаде
возможно это был прокси примитив или блок.

1. первым делом проверь поведение после команды _audit. Лучше после нее сохранить, закрыть, открыть чертеж.

2. с блоком может помочь отключение в настройках подсказок для ролловеров на вкладке экран, или на вкладке выбор изменение параметров подсветки. В частности может тормозить выделение толщиной при наведении, требуется отключить или оставить только отображение пунктиром.(может зависеть от версии).

3. Если прокси примитив, то много нюансов, иногда решаемых только разбивкой на примитивы. (например прокси примитив получил upgrade в более новой версии приложения, а потом был открыт в более старой. После этого возможно что угодно.)
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 19:59:46
Привалов Дмитрий, в последний раз это было окно на фасаде
В AutoCAD нет примитивов "окно" и "фасад". Такие примитивы есть только в вертикальных приложениях.
Название: Re: Undo и Erase
Отправлено: Александр Ривилис от 19-03-2019, 20:03:43
И это лечиться путем удаления какого-элемента, после чего все снова начинает работать как надо.
К сожалению это очень похоже на иллюзию, которая не имеет отношения к действительности. И никакой код в решении такой проблемы не поможет.  Тут нужно разбираться с каждым чертежом отдельно.
Название: Re: Undo и Erase
Отправлено: Дмитрий Загорулькин от 20-03-2019, 11:05:36
Подозреваю, что в данном случае могут сильно помочь диагностические инструменты утилит ARXDBG и MGDDBG (http://adn-cis.org/forum/index.php?topic=7274.0).