Вызов переопределенного метода Explode при создании штриховки

Автор Тема: Вызов переопределенного метода Explode при создании штриховки  (Прочитано 11297 раз)

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

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Всем привет!
Вчера столкнулся с одной неприятной особенностью. Если у меня есть переопределенный метод Explode, то он почему-то автоматически вызывается при нажатии на кнопку "Штриховка" на ленте. Если переопределение этого метода применяется к линии, то вопросов нет, а вот если к полилинии, то при создании штриховки вылетает ошибка:



Вот весь код для теста:
Извините, вам запрещён просмотр содержимого спойлеров.

Если закомментировать строку 192 "_ents.Add(ent);", то этой ошибки нет, но объект не будет взрываться.
Эту "особенность" можно обойти добавив в самое начало метода Explode проверку:
Код - C# [Выбрать]
  1. Document doc = Application.DocumentManager.MdiActiveDocument;
  2. if (doc.CommandInProgress == "HATCH")
  3.     return;

Возникает закономерный вопрос: это что - ошибка в API, особенность работы или я чего-то не понимаю?

PS. проверялось на 2016 и 2018 версии.
PPS. конечно же проверку лучше делать не на исключение команды HATCH, а на определение команды EXLODE  :)

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

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

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Строка 43: Зачем вызывается принудительное Dispose для объекта под управлением транзакции?
Строка 81, 137, 180: Объект ResultBuffer тоже нужно(?) "диспозить" после использования. Либо через использование конструкции using, либо явным вызовом метода Dispose. Не ручаюсь, правда, что это действительно необходимо, но в примерах из интернета это делают. Думаю, что хуже точно не будет.
Строки 124-129 и 165-170: "или крестик снимите, или трусы наденьте" - если используется шаблон "одиночка", то никаких публичных конструкторов.
Строки 195-198: Вообще не понял этих действий. Это такой хитрый способ удаления данных? Но тогда потом, если я всё правильно понимаю, при вызове Overrule при попытке получения радиуса (строка 142 или 185) будет исключение.
Ну и самое главное, что действительно является большой ошибкой - объекты ents в строках 145-150 после использования в отрисовке должны уничтожаться. Опять же - либо Dispose, либо using.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну и я добавлю замечание по поводу этого:
Код - C# [Выбрать]
  1. ResultBuffer rb = new ResultBuffer
  2. {
  3.     new TypedValue((int)DxfCode.ExtendedDataRegAppName, MainClass.AppName),
  4.     new TypedValue((int)DxfCode.ExtendedDataInteger32, Convert.ToDouble(5)) // <------ зачем в double, если должно быть целое???
  5. };
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Исправил ошибки, причесал код, проверил - действительно, при запуске команды "Штриховка" вызывается метод Explode для полилинии. И при выходе из команды AutoCAD падает.

Похоже, это какой-то внутренний баг. Так что, проверка текущей команды перед выполнением - вполне подходящее решение, на мой взгляд.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Строка 43: Зачем вызывается принудительное Dispose для объекта под управлением транзакции?
Это остатки прошлых экспериментов, когда я искал причины других ошибок. Все не доходят руки убрать.

Строка 81, 137, 180: Объект ResultBuffer тоже нужно(?) "диспозить" после использования. Либо через использование конструкции using, либо явным вызовом метода Dispose. Не ручаюсь, правда, что это действительно необходимо, но в примерах из интернета это делают. Думаю, что хуже точно не будет.
label1:
Согласен - хорошим тоном считается "подчистка" за собой, но в современных условиях и при подобных небольших приложениях я пока не заметил в этом острой необходимости.

Строки 124-129 и 165-170: "или крестик снимите, или трусы наденьте" - если используется шаблон "одиночка", то никаких публичных конструкторов.
Почему публичные конструкторы в этом контексте не допустимы? В примере от Kean Walmsley есть и "крестик" и "трусы".

Строки 195-198: Вообще не понял этих действий. Это такой хитрый способ удаления данных? Но тогда потом, если я всё правильно понимаю, при вызове Overrule при попытке получения радиуса (строка 142 или 185) будет исключение.
А как ты удаляешь XData? После этих строк при чтении данных исключения не будет, поскольку у меня везде для этого случая есть проверки. Это тестовый пример, упрощенный.

Ну и самое главное, что действительно является большой ошибкой - объекты ents в строках 145-150 после использования в отрисовке должны уничтожаться. Опять же - либо Dispose, либо using.
goto label1;  :)

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Ну и я добавлю замечание по поводу этого:
Это тестовый пример - "я его слепила из того, что было"  ;D

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А добавлять новые объекты в БД за вас кто будет? Автокад чтоль? ))
Код - C# [Выбрать]
  1. public override void Explode(Entity _ent, DBObjectCollection _ents)
  2. {
  3.     Document doc = Application.DocumentManager.MdiActiveDocument;
  4.  
  5.     if (_ent is Polyline l)
  6.     {
  7.         if (l.XData != null)
  8.         {
  9.             ResultBuffer rb = l.GetXDataForApplication(MainClass.AppName);
  10.  
  11.             if (rb != null)
  12.             {
  13.                 TypedValue[] tvs = rb.AsArray();
  14.                 double r = Convert.ToDouble(tvs[1].Value);
  15.  
  16.                 LineCircleClass lc = new LineCircleClass(r);
  17.                 List<Entity> ents = lc.GetEnts(l);
  18.                 Database db = doc.Database;
  19.                 using (OpenCloseTransaction trans = db.TransactionManager.StartOpenCloseTransaction())
  20.                 {
  21.                     BlockTableRecord ms = (BlockTableRecord)trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  22.                     foreach (Entity ent in ents)
  23.                     {
  24.                         trans.AddNewlyCreatedDBObject(ent, true);
  25.                         ms.AppendEntity(ent);
  26.                         _ents.Add(ent);
  27.                     }
  28.                     trans.Commit();
  29.                 }
  30.  
  31.                 TypedValue tv = new TypedValue((int)DxfCode.ExtendedDataRegAppName, MainClass.AppName);
  32.                 l.UpgradeOpen();
  33.                 l.XData = new ResultBuffer(tv);
  34.                 l.DowngradeOpen();
  35.             }
  36.         }
  37.     }
  38. }

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
А добавлять новые объекты в БД за вас кто будет? Автокад чтоль?
Александр, Вы не поверите... ;)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А добавлять новые объекты в БД за вас кто будет? Автокад чтоль? ))
Здрасте! Не путай метод Explode и команду Explode.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Почему публичные конструкторы в этом контексте не допустимы? В примере от Kean Walmsley есть и "крестик" и "трусы".
Видимо, ты не до конца понимаешь в чём смысл использования этого шаблона.
А как ты удаляешь XData? После этих строк при чтении данных исключения не будет, поскольку у меня везде для этого случая есть проверки.
Да, наверное, ты прав. Я просто забыл, что XData так хитро удаляется. Я бы только не стал это делать прямо в методе Explode.

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, Александр Ривилис,
с добавленными мной строчками все сработало. Так что...

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
с добавленными мной строчками все сработало. Так что...
Так и без них работает.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Видимо, ты не до конца понимаешь в чём смысл использования этого шаблона.
Смысл в том, чтобы переопределение работало только с определенными приложениями, зарегистрированными в БД.