Как отключить регенерацию вида

Автор Тема: Как отключить регенерацию вида  (Прочитано 20011 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн neopentanАвтор темы

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Подскажите пожалуйста, как можно с помощью .NET отключить обновление (регенерацию) вида?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #1 : 19-12-2014, 19:56:24 »
Подскажите пожалуйста, как можно с помощью .NET отключить обновление (регенерацию) вида?
Уточни что ты имеешь в виду. Отключить регенерацию при переключении между листами?  Тогда системная переменная LAYOUTREGENCTL Если речь идет вообще о перерисовке в AutoCAD во время работы твоего кода, то это можно сделать при помощи P/Invoke следующих функций из ObjectARX:
Код - C++ [Выбрать]
  1. acedUpdateDisplayPause(true); // Запрещаем отображение на экране изменений
  2. //... Здесь твой код, который изменяет что-либо на экране
  3. acedUpdateDisplayPause(false); // Разрешаем отображение на экране изменений
  4. acedUpdateDisplay(); // Выполняем обновление графического окна AutoCAD
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн neopentanАвтор темы

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Как отключить регенерацию вида
« Ответ #2 : 19-12-2014, 22:20:03 »
Александр, большое спасибо за ответ. Речь идет именно об отключении перерисовки графики на время работы кода. Пока что удавалось обходиться без использования ObjectARX, видимо сейчас придется начать, раз нет альтернативы в .NET

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #3 : 19-12-2014, 22:42:15 »
Пока что удавалось обходиться без использования ObjectARX, видимо сейчас придется начать, раз нет альтернативы в .NET
Я же сказал про P/Invoke из .NET, т.е. нет необходимости писать на C++ с использованием ObjectARX.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение neopentan 24-12-2014, 09:54:01

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #4 : 20-12-2014, 01:21:09 »
Вот пример того, как это могло бы выглядеть. Проверял только в AutoCAD 2012 и 2014 SP1 x64.
Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13. using AcEd = Autodesk.AutoCAD.EditorInput;
  14.  
  15.  
  16. [assembly: CommandClass(typeof(Rivilis.MyCommands))]
  17.  
  18. namespace Rivilis
  19. {
  20.   public class SuppressUpdateDisplay : IDisposable
  21.   {
  22.     [DllImport("accore.dll", EntryPoint = "?acedIsUpdateDisplayPaused@@YA_NXZ",
  23.       CallingConvention = CallingConvention.Cdecl)]
  24.     [return: MarshalAs(UnmanagedType.I1)]
  25.     private static extern bool acedIsUpdateDisplayPaused13();
  26.     [DllImport("acad.exe", EntryPoint = "?acedIsUpdateDisplayPaused@@YA_NXZ",
  27.       CallingConvention = CallingConvention.Cdecl)]
  28.     [return: MarshalAs(UnmanagedType.I1)]
  29.     private static extern bool acedIsUpdateDisplayPaused12();
  30.     [DllImport("accore.dll", EntryPoint = "?acedUpdateDisplay@@YAXXZ",
  31.       CallingConvention = CallingConvention.Cdecl)]
  32.     private static extern void acedUpdateDisplay13();
  33.     [DllImport("acad.exe", EntryPoint = "?acedUpdateDisplay@@YAXXZ",
  34.       CallingConvention = CallingConvention.Cdecl)]
  35.     private static extern void acedUpdateDisplay12();
  36.     [DllImport("accore.dll", EntryPoint = "?acedUpdateDisplayPause@@YAX_N@Z",
  37.       CallingConvention = CallingConvention.Cdecl)]
  38.     private static extern void acedUpdateDisplayPause13(
  39.       [MarshalAs(UnmanagedType.I1)] bool bPaused);
  40.     [DllImport("acad.exe", EntryPoint = "?acedUpdateDisplayPause@@YAX_N@Z",
  41.       CallingConvention = CallingConvention.Cdecl)]
  42.     private static extern void acedUpdateDisplayPause12(
  43.       [MarshalAs(UnmanagedType.I1)] bool bPaused);
  44.     public static bool acedIsUpdateDisplayPaused()
  45.     {
  46.       if (Application.Version.Major > 18)
  47.         return acedIsUpdateDisplayPaused13();
  48.       else
  49.         return acedIsUpdateDisplayPaused12();
  50.     }
  51.     public static void acedUpdateDisplayPause(bool bPaused)
  52.     {
  53.       if (Application.Version.Major > 18)
  54.         acedUpdateDisplayPause13(bPaused);
  55.       else
  56.         acedUpdateDisplayPause12(bPaused);
  57.     }
  58.  
  59.     public static void acedUpdateDisplay()
  60.     {
  61.       if (Application.Version.Major > 18)
  62.         acedUpdateDisplay13();
  63.       else
  64.         acedUpdateDisplay12();
  65.     }
  66.  
  67.     public SuppressUpdateDisplay()
  68.     {
  69.       bWasPaused = acedIsUpdateDisplayPaused();
  70.       acedUpdateDisplayPause(true);
  71.     }
  72.     public void Dispose()
  73.     {
  74.       acedUpdateDisplay();
  75.       acedUpdateDisplayPause(bWasPaused);
  76.     }
  77.     private bool bWasPaused;
  78.   }
  79.  
  80.   public class MyCommands
  81.   {
  82.     /// <summary>
  83.     /// Пример для проверки использования класса
  84.     /// SuppressUpdateDisplay
  85.     /// </summary>
  86.     [CommandMethod("TestSuppress")]
  87.     public void TestSuppress()
  88.     {
  89.       using (SuppressUpdateDisplay UI = new SuppressUpdateDisplay())
  90.       {
  91.         AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  92.         AcDb.Database db = doc.Database;
  93.         AcGe.Point3d center = (AcGe.Point3d)Application.GetSystemVariable("VIEWCTR");
  94.         center = center.TransformBy(doc.Editor.CurrentUserCoordinateSystem);
  95.         double radius = (double)Application.GetSystemVariable("VIEWSIZE") * 0.3;
  96.  
  97.         using (AcDb.BlockTableRecord curSpace =
  98.           db.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  99.         {
  100.           using (AcDb.Circle circle = new AcDb.Circle(center, AcGe.Vector3d.ZAxis, radius))
  101.           {
  102.             circle.SetDatabaseDefaults(db);
  103.             curSpace.AppendEntity(circle);
  104.           }
  105.         }
  106.         doc.Editor.GetString("\nНажмите ENTER для появления окружности.");
  107.       }
  108.     }
  109.     [CommandMethod("UpdatePause")]
  110.     public void UpdatePause()
  111.     {
  112.       SuppressUpdateDisplay.acedUpdateDisplayPause(true);
  113.     }
  114.     [CommandMethod("UpdateNoPause")]
  115.     public void UpdateNoPause()
  116.     {
  117.       SuppressUpdateDisplay.acedUpdateDisplayPause(false);
  118.       SuppressUpdateDisplay.acedUpdateDisplay();
  119.     }
  120.   }
  121. }
  122.  
« Последнее редактирование: 26-12-2014, 15:05:05 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн neopentanАвтор темы

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Как отключить регенерацию вида
« Ответ #5 : 24-12-2014, 09:53:52 »
Огромное спасибо, в AutoCAD 2013 все заработало.

Оффлайн T72

  • ADN Club
  • Сообщений: 23
  • Карма: 4
Re: Как отключить регенерацию вида
« Ответ #6 : 26-12-2014, 09:06:58 »
Достаточно полезный класс. Но есть пара замечаний.
Для AutoCAD 2012 нужно исправить все
Код - C# [Выбрать]
  1. if (Application.Version.Major > 18/*12*/)
Код - C# [Выбрать]
  1. //и отключить паузу, иначе будут жуткие тормоза
  2. public void Dispose()
  3. {
  4.     acedUpdateDisplay();
  5.     acedUpdateDisplayPause(!bWasPaused);
  6. }
« Последнее редактирование: 26-12-2014, 09:33:11 от T72 »

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Как отключить регенерацию вида
« Ответ #7 : 26-12-2014, 09:11:46 »
Для AutoCAD 2012 нужно исправить все
Я предполагаю, что А.Н. не просто так указал 12 в качестве значения. Видимо предполагалось, что код может быть использовать и в более ранних версиях, но не старее чем R12.0. Твоя поправка автоматом накрывает медным тазом работу кода для более старых версий акада. Странно, что А.Н. многократно использует "магические числа", вместо того, чтобы оформить их в виде констант.

Оффлайн T72

  • ADN Club
  • Сообщений: 23
  • Карма: 4
Re: Как отключить регенерацию вида
« Ответ #8 : 26-12-2014, 09:31:51 »
Для AutoCAD 2012 нужно исправить все
Я предполагаю, что А.Н. не просто так указал 12 в качестве значения. Видимо предполагалось, что код может быть использовать и в более ранних версиях, но не старее чем R12.0. Твоя поправка автоматом накрывает медным тазом работу кода для более старых версий акада. Странно, что А.Н. многократно использует "магические числа", вместо того, чтобы оформить их в виде констант.

Александ, потрудитесь прочитать код и поймете, что она не накрывает ничего, а исправляет. 12 - скорее всего имелось ввиду AutoCAD 2012 который имеет Major = 18 т.к. "accore.dll" появился с R19.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #9 : 26-12-2014, 13:08:41 »
Для AutoCAD 2012 нужно исправить все
Да. Это моя опечатка. Ночная работа сказывается. Исправлю.
//и отключить паузу, иначе будут жуткие тормоза
А вот тут извините. Я восстанавливаю паузу в то состояние, которое было до того как код запустили. Так что если была пауза, то она и должна остаться.

P.S.: Перевёл методы acedIsUpdateDisplayPaused, acedUpdateDisplay, acedUpdateDisplayPause в разряд public static, чтобы ими можно было пользоваться отдельно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #10 : 26-12-2014, 13:18:04 »
T72,
Александ, потрудитесь прочитать код и поймете, что она не накрывает ничего, а исправляет. 12 - скорее всего имелось ввиду AutoCAD 2012 который имеет Major = 18 т.к. "accore.dll" появился с R19.
Александ - это что-то среднее между Андрей и Александр? :D Уточняю, что я еще не успел ответить на тот момент, так что полемика была с Андреем. 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн T72

  • ADN Club
  • Сообщений: 23
  • Карма: 4
Re: Как отключить регенерацию вида
« Ответ #11 : 26-12-2014, 14:12:55 »
Александ - это что-то среднее между Андрей и Александр? :D Уточняю, что я еще не успел ответить на тот момент, так что полемика была с Андреем. 
Это я виновен, не на того сослался.

давайте уточним:
bWasPaused = acedIsUpdateDisplayPaused(); - в простое возвращает true (по крайней мере в 2012), видать потому как ничего в данный момент не рисуется.

и в деструкторе опять паузить acedUpdateDisplayPause(bWasPaused = true);? С вашей точкой зрения я согласен она логична. Но как быть тогда с 2012?


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #12 : 26-12-2014, 14:14:50 »
bWasPaused = acedIsUpdateDisplayPaused(); - в простое возвращает true
"Простой" - это что? Возвращать true должно только если приостановлен вывод на экран.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн T72

  • ADN Club
  • Сообщений: 23
  • Карма: 4
Re: Как отключить регенерацию вида
« Ответ #13 : 26-12-2014, 14:21:26 »
Простой" - это что? Возвращать true должно только если приостановлен вывод на экран.
Я хотел сказать, что когда никаких команд не выполняется. Посмотрите видео

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как отключить регенерацию вида
« Ответ #14 : 26-12-2014, 14:41:26 »
Похоже это баг AutoCAD 2012. В 2014 всё нормально (т.е. bWasPaused в конструкторе == false в обычных ситуациях).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение