Проблема с осмыслением AcDbIdMapping при копировании-вставке

Автор Тема: Проблема с осмыслением AcDbIdMapping при копировании-вставке  (Прочитано 10987 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 10
  • Карма: 0
Добрый день.

Помогите, пожалуйста, разобраться.

Есть чертеж, на нем блоки, связи между которыми заданы через их хэндлы. При копировании/вставке эти связи, понятное дело, надо установить для новых объектов (где возможно). Хотел сделать через AcEditorReactor.

Столкнулся со следующей проблемой:
при просмотре idMapping в функции реактора endDeepClone некоторые блоки удается проследить от оригинала до копии по цепочке идентификаторов в базах чертежа и временной, некоторые - нет. (знаю, что по handle следить не имеет смысла, потому опираюсь на AcDbObjectId)

Пример: выделяю три блока (handle 341, 242, 2b4), копирую, вставляю, получаю новые три блока (4c0, 4b5, 4ac)

При этом в отладчике веду протокол - пишу содержимое idMapping в endDeepClone.
В протоколе указываются AcDbObjectId [handle] ключа --> AcDbObjectId [handle]  значения (дальше я привожу только для трех копируемых блоков):

на Wblock
ff604ba0 [242]  -->  ff613db0 [5b]
ff604ec0 [2b4]  -->  ff613f60 [76]
ff607890 [341]  -->  ff60b1d0 [95]

на Insert
ff613db0 [47a]  -->  ff60dca0 [47a]
ff613f60 [483]  -->  ff60dd30 [483]
(здесь ключ ff60b1d0 не встречается)

на Explode
ff60dca0 [47a]  -->  ff622040 [4ac]
ff60dd30 [483]  -->  ff6220d0 [4b5]
ff60dde0 [48e]  -->  ff622180 [4c0]

Интересно, что если копирую только один блок (тот же с handle 341), то цепочка идентификаторов прослеживается без проблем.


В архиве - исходники, файл чертежа для примера и полный протокол (logs.txt), который получился у меня.

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

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

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

  • ADN OPEN
  • Сообщений: 10
  • Карма: 0
Проверил

В многодокументном режиме  (SDI==0) картина идентичная - два блока можно определить, третий (h==341) "оторвался" между Wblock и Insert. (Были открыты оба документа, я выделил, скопировал, переключился через "Окно" в Чертеж2, вставил)

В однодокументном (SDI==1) все цепочки разорвались, на Insert нет подходящих Id, которые были получены после Wblock. (Был открыт Чертеж1, выделил, скопировал, открыл Чертеж2, вставил)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В однодокументном (SDI==1) все цепочки разорвались, на Insert нет подходящих Id, которые были получены после Wblock. (Был открыт Чертеж1, выделил, скопировал, открыл Чертеж2, вставил)
Вот у меня именно эта картина и наблюдается при SDI == 0. Причем если проследить, то видно что pDbDest, которая в Wblock больше ни разу не встречается:

20:55:27------endDeepClone--------
map->DeepCloneContext = 7,
map->pDbOrig=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg),
map->pDbDest=2ac6d470 (),
pWorkingDb=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg)
20:55:27pair Id's: class AcDbBlockReference 8796082576288 [242]  -->  8796082552240 [5B]
20:55:27pair Id's: class AcDbBlockReference 8796082576960 [2B4]  -->  8796082552672 [76]
20:55:27pair Id's: class AcDbBlockReference 8796082578320 [341]  -->  8796082614736 [95]

20:55:31------endDeepClone--------
map->DeepCloneContext = 6,
map->pDbOrig=2a98bf00 (C:\Temp\A$C78427FC6.DWG),
map->pDbDest=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg),
pWorkingDb=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg)
20:55:31pair Id's: class AcDbBlockReference 8796082598352 [50C]  -->  8796082579776 [50C]
20:55:31pair Id's: class AcDbBlockReference 8796082609584 [4F8]  -->  8796082579456 [4F8]
20:55:31pair Id's: class AcDbBlockReference 8796082610016 [501]  -->  8796082579600 [501]

20:55:32------endDeepClone--------
map->DeepCloneContext = 1,
map->pDbOrig=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg),
map->pDbDest=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg),
pWorkingDb=2a930560 (E:\RAN\VCSDK_2008\TestTrack\Чертеж1.dwg)
20:55:32pair Id's: class AcDbBlockReference 8796082579456 [4F8]  -->  8796082580256 [52A]
20:55:32pair Id's: class AcDbBlockReference 8796082579600 [501]  -->  8796082580400 [533]
20:55:32pair Id's: class AcDbBlockReference 8796082579776 [50C]  -->  8796082580576 [53E]
(я немного исправил твой код)

Я еще немного поиграюсь с этим кодом, и если ничего не получится - отправлю вопрос в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
P.S.: Кстати, у тебя в коде есть существенная ошибка:
Ты передаешь в функцию OutputDebugFormatedString значения idPair.key() и idPair.value(), т.е. адреса AcDbObjectId для ключа и значения. А нужно тебе передать сами ключ и значение, т.е. idPair.key().asOldId() и idPair.value().asOldId().
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 10
  • Карма: 0
Спасибо за подсказку.

При форматировании строки возвращается одно и то же число - и для idPair.key(), и для idPair.key().asOldId(), но это большая удача, что mId лежит в нужном месте памяти, чтобы получился такой результат.

OutputDebugFormatedString(_T("pair Id's: %016llx (mId=%016llx) [%x]  -->  %016llx (mId=%016llx) [%x]\n"),
idPair.key(),idPair.key().asOldId(),MyGetHandleValue(hKey),
idPair.value(),idPair.value().asOldId(),MyGetHandleValue(hVal));

протокол:
13:44:22pair Id's: 000007ffff609ba0 (mId=000007ffff609ba0) [242]  -->  000007ffff60ddb0 (mId=000007ffff60ddb0) [5b]

Отмечено как Решение Александр Ривилис 04-10-2014, 16:52:13

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Подумал я еще немного и понял, что таким способом получить цепочку преобразований невозможно. Чтобы это понять достаточно сделать следующее:
1) Запустить AutoCAD, открыть Чертеж1
2) Выделить всё и выполнить команду _COPYCLIP
3) Завершить AutoCAD и запустить его повторно.
4) Выполнить команду _PASTECLIP
Очевидно, что в разных сеансах работы AutoCAD эту цепочку проследить нельзя, т.к. AcDbObjectId живут в пределах одного сеанаса работы AutoCAD.
Теперь по поводу работы в одном сеансе работы с AutoCAD. При операции _COPYCLIP:
1) создается новая пустая база (AcDbDatabase)
2) в неё выполняется WBLOCK все что выбрано в текущей базе
3) эта база сохраняется во временный файл с именем вида A$XXXXXXXX.DWG (например, A$C203F465E.DWG) и параллельно в буфер обмена (если файл удалить, то всё-равно можно вставить - файл будет создан заново из буфера обмена и из него будет производится вставка) и (!!!) база закрывается, т.е. соотвественно все её AcDbObjectId становятся невалидными. Конечно возможно, что при следующем открытии этой же базы (в операции _PASTECLIP) они будут иметь те же значения, но вероятность этого не велика. Думаю, что как раз на этот вариант вы и наткнулись, когда из трех цепочек две получились нормальными. Кстати, если бы это были не вставки блока, а например отрезки, то вероятность сохранения цепочек увеличивается. Во всяком случае у меня они сохранялись. Почему именно так происходит можно лишь догадываться.
Если включить реакторы в ARXDBG (команда REACTORS) то можно еще много чего интересного увидеть. Как-то так.
« Последнее редактирование: 04-09-2014, 02:19:25 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 10
  • Карма: 0
Значит, совпадение (адресов). Жаль. Придется искать другие пути.
Спасибо за помощь!

PS. Я запускал ARXDBG, но заблудился в результатах.