Связь между объектами чертежа. Есть ли какие-нибудь инструменты?

Автор Тема: Связь между объектами чертежа. Есть ли какие-нибудь инструменты?  (Прочитано 83478 раз)

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

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Код написанн красиво и главное разборчиво...
Если объекты копировать в чертеже любыми командами: копирование, зеркало и т.п., то связи к новым объектам тоже добавляются.
На этой фразе я понял, что где-то я такое уже видел - а ведь по сути то же самое реализованно в самом автокаде (интересно можно-ли воспользоваться для любых объектов, а не только для текстов и выносок), ведь если создать поле на объект, то при копировании его с целевым объектом (так-же неважно куда и как) ссылка "перерегестрируется" (будет видно при регенарции) - причем для этого ничего запущенного в памяти не нужно (то есть пара всегда будет связанна - вне зависимости на какой машине с ней работали, как копировали и пр.)

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Цитировать
Код написанн красиво и главное разборчиво...
Спасибо! IntelliSence помогал :)
А вообще, есть еще над чем поработать. Я уже сегодня нашел, что можно еще улучшить...

Цитировать
интересно можно-ли воспользоваться для любых объектов, а не только для текстов и выносок
Было бы неплохо, но вряд ли такое возможно.
Да, связь именно такая как в полях реализована. Но можно и другие виды связи сделать, и логику их поведения при копировании объектов другую прописать...

P.S. Обнаружил особенность. При создании блока в чертеже, срабатывает событие BeginDeepCloneTranslation, но при попытке получения IdMapping.OriginalDatabase возникает исключение. При этом не выскакивает никаких оповещений, но дальше приложение перестает отслеживать события баз данных, то есть, практически полностью перестает работать.

P.P.S Исправил. Исправленный исходник и сборка для AutoCAD 2014 x64 - во вложении.
Демо-ролик: https://screencast.autodesk.com/main/details/e92f1c81-99e0-4978-81fa-fbde6d21b338
« Последнее редактирование: 17-07-2014, 15:00:56 от Загорулькин Дмитрий »

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Видеопример использования связей между объектами: https://screencast.autodesk.com/main/details/af4422d2-b15f-4ab8-a62d-02d4e66563e3
Соединил выноску и блок связью, добавил отслеживание изменений связанных объектов.

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Браво! Вы наблюдательны :)
Я заметил это, когда первый вариант видео записывал. Пришлось даже остановить запись и поэкспериментировать. Все дело в том, что я использую событие CommandEnded для изменения объектов. При изменении свойств через палитру, этого события не происходит.
До этого я пробовал использовать событие Database.ObjectModified, поэтому, такой проблемы не было. Зато, была проблема при использовании команды отмены.
В принципе, ничего сильно критичного, хотя, конечно, можно придумать ситуацию, когда модификация останется необработанной.
Если подскажете, как можно отловить изменение объекта через панель свойств без использования Database.ObjectModified - буду очень признателен!

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Попробовал, не получается :(
Мне нужно в методе отклика модифицировать выноски. Когда я пытаюсь открыть объект на модификацию, выдает исключение eLockViolation.
Интересная картина получается, если попытаться заблокировать документ во время этой операции - автокад и мой плагин начинают соперничать за право блокировать документ и в итоге мой плагин сдается, вывалив ошибку :) По поведению это очень похоже на вот это: http://forum.dwg.ru/showthread.php?t=102587

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
То что нужно модифицировать, я отмечаю в событии Database.ObjectOpenedForModify. Пока со своими функциями справляется :)
Цитировать
Например, в Editor.EnteringQuiescentState?
В жизни не догадался бы... Я так понимаю, это какая-то реакция на "безмолвные" редактирования?
В общем, работает! Меняет, правда, не сразу, а только при переходе в чертеж из палитры свойств. Но это уже мелочи.
Спасибо!

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я так понимаю, это какая-то реакция на "безмолвные" редактирования?
Точнее реакция на то, что ничего в AutoCAD не происходит и он ожидает действия пользователя.
Меняет, правда, не сразу, а только при переходе в чертеж из палитры свойств.
Ну в этом событии именно так и должно быть.
Кстати, подозреваю, что если в DocumentLockModeWillChange ты бы проверял DocumentLockModeWillChangeEventArgs.CurrentMode и документ уже был заблокирован, то его блокировать уже не нужно и тогда ты можешь открыть объект для модификации. Если интересно - попробуй.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Попробовал. Если CurrentMode == DocumentLockMode.NotLocked - пробую блокировать документ. При этом сперва в комстроке выскакивает предупреждение, что выполняется команда, а если нажать "Повторить" - выскакивает исключение eLockChangeInProgress.
Проверил сейчас свойство Document.CommandInProgress перед блокировкой документа - пустая строка.

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Проверил порядок блокировки документа с помощью волшебной ARX-утилиты, получил такой листинг:
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
    MyCurMode:  Not Locked
    MyNewMode:  Write | Protected Auto Write
    CurMode:    Not Locked
    CmdName:    PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
    MyCurMode:  Auto Write
    MyNewMode:  Not Locked
    CurMode:    Auto Write
    CmdName:    #
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
    MyPrevMode: Auto Write
    MyCurMode:  Not Locked
    CurMode:    Not Locked
    CmdName:    #
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
    MyPrevMode: Not Locked
    MyCurMode:  Write | Protected Auto Write
    CurMode:    Write | Protected Auto Write
    CmdName:    PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
    MyCurMode:  Write | Protected Auto Write
    MyNewMode:  Not Locked
    CurMode:    Write | Protected Auto Write
    CmdName:    #PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
    MyPrevMode: Write | Protected Auto Write
    MyCurMode:  Not Locked
    CurMode:    Not Locked
    CmdName:    #PARTIALREGEN
Попробовав разные варианты (и словив кучу ошибок :)), пришел к выводу, что надо попадать в предпоследнее событие с помощью проверки:
Код - C# [Выбрать]
  1. (e.CurrentMode & DocumentLockMode.Write) == DocumentLockMode.Write
В итоге, все получилось: https://screencast.autodesk.com/main/details/be809ed7-bb4b-4afb-a322-38b29715e299
Александр Наумович, большое спасибо!

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Обнаружил интересный момент. При запуске команды _OPEN, а в диалоге выбора файла нажал отмену и словил исключение:
Код - C# [Выбрать]
  1. /// <summary>
  2.         /// Реакция на предстоящее изменение блокировки документа
  3.         /// </summary>
  4.         /// <param name="sender"></param>
  5.         /// <param name="e"></param>
  6.         static void DocumentManager_DocumentLockModeWillChange
  7.             (object sender, DocumentLockModeWillChangeEventArgs e)
  8.         {          
  9.                 Document adoc = e.Document;
  10.                
  11.                 // На всякий случай проверяем ссылку на документ
  12.                 if (adoc != null
  13.                     // и если текущий режим блокировки содержит флаг "запись"
  14.                     && ((e.CurrentMode & DocumentLockMode.Write) == DocumentLockMode.Write))
  15.                 {
  16.                     // ...
  17.                     Database = adoc.Database; // <-- тут исключение
  18.                     // ...
  19.                 }
  20.             }          
  21.         }
То, что бывают базы без документа, я знал. А вот что документ без базы - первый раз встретил!