OsnapOverrule тормозит на внешних ссылках

Автор Тема: OsnapOverrule тормозит на внешних ссылках  (Прочитано 6766 раз)

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

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

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. На пути тестирования различных Overrule, обрабатывающих блоки, отлавливаю баги и пытаюсь их устранить. Один баг был с таблицами и ручками, но вроде вопрос решил.
Теперь столкнулся с новой проблемой, но ни одной идеи нет.
Имеется Osnap Overrule:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.Runtime;
  5. using mpESKD.Base.Helpers;
  6. using ModPlusAPI.Windows;
  7.  
  8. namespace mpESKD.Functions.mpBreakLine.Overrules
  9. {
  10.     public class BreakLineOsnapOverrule : OsnapOverrule
  11.     {
  12.         protected static BreakLineOsnapOverrule _breakLineOsnapOverrule;
  13.         public static BreakLineOsnapOverrule Instance()
  14.         {
  15.             return _breakLineOsnapOverrule ?? (_breakLineOsnapOverrule = new BreakLineOsnapOverrule());
  16.         }
  17.  
  18.         public override void GetObjectSnapPoints(Autodesk.AutoCAD.DatabaseServices.Entity entity, ObjectSnapModes snapMode, IntPtr gsSelectionMark, Point3d pickPoint,
  19.             Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds)
  20.         {
  21.             AcadHelpers.WriteMessageInDebug("get object snap points");
  22.             if (IsApplicable(entity))
  23.             {
  24.                 AcadHelpers.WriteMessageInDebug("внутри");
  25.                 try
  26.                 {
  27.                     var breakLine = BreakLineXDataHelper.GetBreakLineFromEntity(entity);
  28.                     if (breakLine != null)
  29.                     {
  30.                         snapPoints.Add(breakLine.InsertionPoint);
  31.                         snapPoints.Add(breakLine.EndPoint);
  32.                     }
  33.                 }
  34.                 catch (Autodesk.AutoCAD.Runtime.Exception exception)
  35.                 {
  36.                     ExceptionBox.Show(exception);
  37.                 }
  38.             }
  39.             else base.GetObjectSnapPoints(entity, snapMode, gsSelectionMark, pickPoint, lastPoint, viewTransform, snapPoints, geometryIds);
  40.         }
  41.        
  42.         public override bool IsApplicable(RXObject overruledSubject)
  43.         {
  44.             return ExtendedDataHelpers.IsApplicable(overruledSubject, BreakLineFunction.MPCOEntName);
  45.         }
  46.     }
  47. }
Метод IsApplicable, на всякий случай:
Код - C# [Выбрать]
  1. public static bool IsApplicable(RXObject rxObject, string appName)
  2. {
  3.     DBObject dbObject = rxObject as DBObject;
  4.     if (dbObject == null) return false;
  5.     if (dbObject.IsAProxy ||
  6.         dbObject.IsErased ||
  7.         dbObject.IsEraseStatusToggled ||
  8.         dbObject.IsUndoing) return false;
  9.     return IsMPCOentity(dbObject, appName);
  10. }
  11. public static bool IsMPCOentity(DBObject dbObject, string appName)
  12. {
  13.     ResultBuffer rb = dbObject.GetXDataForApplication(appName);
  14.     return rb != null;
  15. }
Если в чертеж вставить внешнюю ссылку и начать перемещать любой объект - например вершину полилинии - автокад начинает зависать на очень долго. Секунд на 5-10. Особенно явно, когда при движении курсор  проходит над внешней ссылкой. После запуска кода выше, с выводом в командную строку, получаю такое:



Я пытался пролистать к началу, но ограничения на вывод в командную строку мне этого не позволили. Получается, что метод GetObjectSnapPoints() срабатывает для всех примитивов, находящихся внутри внешний ссылки!
Вопрос - как правильно исключить из работы OsnapOverrule обработку внешних ссылок?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Первая идея, которая пришла в голову - проверь в IsApplicable, что rxObject находится в текущей базе.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Попробовал так:
Код - C# [Выбрать]
  1. public static bool IsApplicable(RXObject rxObject, string appName)
  2. {
  3.     DBObject dbObject = rxObject as DBObject;
  4.     if (dbObject == null) return false;
  5.     if (!AcadHelpers.Database.HasObjectId(dbObject.ObjectId)) return false;
  6.     if (dbObject.IsAProxy ||
  7.         dbObject.IsErased ||
  8.         dbObject.IsEraseStatusToggled ||
  9.         dbObject.IsUndoing) return false;
  10.     return IsMPCOentity(dbObject, appName);
  11. }
  12. private static bool HasObjectId(this Database db, ObjectId objectId)
  13. {
  14.     return db.TryGetObjectId(objectId.Handle, out _);
  15. }
Не помогло

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Код жуткий. Достаточно было проверить на то, что dbObject.Database != HostApplicationServices.WorkingDatabase
Но похоже это не поможет. Иначе бы у тебя появлялось сообщение "внутри".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Код жуткий. Достаточно было проверить на то, что dbObject.Database != HostApplicationServices.WorkingDatabase
Это я проверял первым) Подумал, что идея не очень и попробовал вариант который написал.
Попробую еще раз...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я пытался пролистать к началу, но ограничения на вывод в командную строку мне этого не позволили.
Для этого есть команды LOGFILEON и LOGFILEOFF.
Хотелось бы всё-таки понять попадаешь ли ты внутрь проверки, где у тебя печатается "внутри".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Попробовал так:
Код - C# [Выбрать]
  1. public static bool IsApplicableForSnapTest(RXObject rxObject, string appName)
  2. {
  3.     AcadHelpers.WriteMessageInDebug("enter method");
  4.     DBObject dbObject = rxObject as DBObject;
  5.     AcadHelpers.WriteMessageInDebug("step 1");
  6.     if (dbObject == null) return false;
  7.     AcadHelpers.WriteMessageInDebug("step 2");
  8.     if (dbObject.Database != AcadHelpers.Database) return false;
  9.     AcadHelpers.WriteMessageInDebug("step 3");
  10.     if (dbObject.IsAProxy ||
  11.         dbObject.IsErased ||
  12.         dbObject.IsEraseStatusToggled ||
  13.         dbObject.IsUndoing) return false;
  14.     AcadHelpers.WriteMessageInDebug("step 4");
  15.     return IsMPCOentity(dbObject, appName);
  16. }
Но автокад зависает напрочь. Я подозреваю, что Editor.WriteMessage() тому виной




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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я подозреваю, что Editor.WriteMessage() тому виной
Сомневаюсь. Этот метод работает нормально.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Провел эксперимент и результаты меня просто обескураживают!
1 вариант - отключаю OsnapOverrule вообще. Открываю файл, выбираю вершину полилинии и начинаю водить мышкой над внешней ссылкой - тормозов нет вообще
2 вариант - включаю OsnapOverrule. Повторяю те же действия с тем же файлом - происходят зависания на 5-10 секунд
И самое интересное:
3 вариант - удаляю все из метода public override void GetObjectSnapPoints() и повторяю все тоже самое - хоть и менее заметные и частые, НО ТОРМОЗА ЕСТЬ!

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
И самое интересное:
3 вариант - удаляю все из метода public override void GetObjectSnapPoints() и повторяю все тоже самое - хоть и менее заметные и частые, НО ТОРМОЗА ЕСТЬ!
И это удалил:
Код - C# [Выбрать]
  1. base.GetObjectSnapPoints(entity, snapMode, gsSelectionMark, pickPoint, lastPoint, viewTransform, snapPoints, geometryIds);
?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: OsnapOverrule тормозит на внешних ссылках
« Ответ #10 : 15-10-2017, 17:12:27 »
И это удалил:
самое забавное, что да. Закомментировал просто все! Причем это не повлияло на работу привязок - они все также ловятся к элементам внутри внешней ссылки

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: OsnapOverrule тормозит на внешних ссылках
« Ответ #11 : 15-10-2017, 17:17:22 »
самое забавное, что да.
Собственно говоря этот вызов мне кажется лишним в любом случае. Ты как обычно проверяешь в AutoCAD 2010? Проверь в последних версиях.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Пекшев aka Modis 15-10-2017, 17:51:25

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Re: OsnapOverrule тормозит на внешних ссылках
« Ответ #12 : 15-10-2017, 17:18:06 »
А что, если в конструкторе BreakLineOsnapOverrule вызвать SetXDataFilter и убрать переопределение IsApplicable?

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: OsnapOverrule тормозит на внешних ссылках
« Ответ #13 : 15-10-2017, 17:27:31 »
Ты как обычно проверяешь в AutoCAD 2010? Проверь в последних версиях.
В этот раз все наоборот) Проверяю в 2018
А что, если в конструкторе BreakLineOsnapOverrule вызвать SetXDataFilter и убрать переопределение IsApplicable?
Покажи ка на примере

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: OsnapOverrule тормозит на внешних ссылках
« Ответ #14 : 15-10-2017, 17:30:11 »
Чуть позже попробую сделать тестовый проект и выложить сюда