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

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Не-не-не, мне именно это и надо - что объект один и тот же. В принципе, equal устраивает. Просто сейчас разбираюсь с копированием через буфер, там баз временных создается параллельно не одна штука (при переключении активного чертежа зачем-то создаются и практически сразу же уничтожаются 3 базы чертежа  :o). Хотелось бы понимать какая база в текущий момент вызвала событие.
А FileName - вообще не показатель. У нового чертежа там хранится адрес файла шаблона, у сохраненного - сохраненный путь, у базы данных без чертежа - пустая строка. А интересуют именно "бесчертежные" базы данных...

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

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Все я уже не ухватываю - зачем тебе базу сравнивать - каую ты базу хочешь отловить?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А из NET к нему можно добраться?
Да. Database.UnmanagedObject
У меня в одной переменной сохранена одна БД, в другой - другая.
Только по полному пути доступу к файлу, если они сохранены. А если они не сохранены, то непонятны критерии сравнения на эквивалентность.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Какая-то новая беда.
Разобрался с копированием объектов из чертежа во временный чертеж в папке Temp. В этом процессе все логично и понятно.
Анализирую IdMapping, были у объектов одни хендлы, стали другие. Открываю этот временный чертеж - да, там именно те хендлы у объектов, которые показал IdMapping. Связь между объектами записана в словарь и является актуальной.
Выполняю вставку скопированного в другой чертеж - IdMapping показывает уже совершенно другие хендлы! Причем, хендлы из оригинальной базы совпадают с хендлами в базе назначения! Соответственно, связь, записанная в словарях, не распознается :( Что это такое? Снова баг или я что-то не учитываю?
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.Runtime;
  8. using Autodesk.AutoCAD.EditorInput;
  9.  
  10. namespace PasteTest
  11. {
  12.     public class CmdClass
  13.     {
  14.         Document adoc = Application.DocumentManager.MdiActiveDocument;
  15.         Database db = Application.DocumentManager.MdiActiveDocument.Database;
  16.         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  17.  
  18.         [CommandMethod("PasteTest")]
  19.         public void AddPasteHandler()
  20.         {
  21.             db.BeginDeepCloneTranslation += new IdMappingEventHandler(db_BeginDeepCloneTranslation);          
  22.             db.InsertMappingAvailable += new IdMappingEventHandler(db_InsertMappingAvailable);
  23.             Database.DatabaseConstructed += new EventHandler(Database_DatabaseConstructed);
  24.             ed.WriteMessage("\nRun command PASTECLIP, PASTEBASE or PASTEBLOCK");
  25.         }
  26.  
  27.         void db_InsertMappingAvailable(object sender, IdMappingEventArgs e)
  28.         {
  29.             IdMappingSearch(e.IdMapping);
  30.         }      
  31.  
  32.         void Database_DatabaseConstructed(object sender, EventArgs e)
  33.         {
  34.             (sender as Database).BeginDeepCloneTranslation += new IdMappingEventHandler(CmdClass_BeginDeepCloneTranslation);
  35.         }
  36.  
  37.         void CmdClass_BeginDeepCloneTranslation(object sender, IdMappingEventArgs e)
  38.         {
  39.             IdMappingSearch(e.IdMapping);
  40.         }
  41.  
  42.         void db_BeginDeepCloneTranslation(object sender, IdMappingEventArgs e)
  43.         {
  44.             IdMappingSearch(e.IdMapping);
  45.         }
  46.  
  47.         void IdMappingSearch(IdMapping idMapping)
  48.         {
  49.             ed.WriteMessage("\nDeepCloneContext: " + idMapping.DeepCloneContext);
  50.             ed.WriteMessage("\nOriginalDatabase: " + idMapping.OriginalDatabase.UnmanagedObject.ToInt64() + " FileName: " + idMapping.OriginalDatabase.Filename);
  51.             ed.WriteMessage("\nDestinationDatabase: " + idMapping.DestinationDatabase.UnmanagedObject.ToInt64() + " FileName: " + idMapping.DestinationDatabase.Filename);
  52.             List<IdPair> idPairList = idMapping.Cast<IdPair>().Where(item => item.IsCloned).ToList();
  53.             ed.WriteMessage("\nIdPairs:");
  54.             foreach (IdPair idPair in idPairList)
  55.             {
  56.                 ed.WriteMessage("\nObjectType: {4}, KeyId: {0}, ValueId: {1}, KeyHandle: {2}, ValueHandle: {3}", idPair.Key, idPair.Value, idPair.Key.Handle, idPair.Value.Handle, idPair.Key.ObjectClass.Name);
  57.             }
  58.             ed.WriteMessage("\n");
  59.         }
  60.     }
  61. }
  62.  

Команда: _pasteclip Повторное определение блока _Oblique  пропущено.
DeepCloneContext: Insert
OriginalDatabase: 1221104048 FileName: C:\Users\ZAGORU~1\AppData\Local\Temp\A$C7CEB7907.DWG
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086484512), ValueId: (8796086071728), KeyHandle: 2019B, ValueHandle: 2019B              <------------------------------- !!! Хендлы одинаковые
ObjectType: AcDbCircle, KeyId: (8796086484528), ValueId: (8796086071744), KeyHandle: 2019C, ValueHandle: 2019C           <------------------------------- !!! Хендлы одинаковые
DeepCloneContext: Insert
OriginalDatabase: 1221104048 FileName: C:\Users\ZAGORU~1\AppData\Local\Temp\A$C7CEB7907.DWG
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086484512), ValueId: (8796086071728), KeyHandle: 2019B, ValueHandle: 2019B              <------------------------------- !!! Хендлы одинаковые
ObjectType: AcDbCircle, KeyId: (8796086484528), ValueId: (8796086071744), KeyHandle: 2019C, ValueHandle: 2019C           <------------------------------- !!! Хендлы одинаковые
Точка вставки:
DeepCloneContext: Explode
OriginalDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086071728), ValueId: (8796086071840), KeyHandle: 2019B, ValueHandle: 201A2
ObjectType: AcDbCircle, KeyId: (8796086071744), ValueId: (8796086071856), KeyHandle: 2019C, ValueHandle: 201A3

https://screencast.autodesk.com/main/details/a1be4073-e6f4-448a-853c-023bb3659707
« Последнее редактирование: 14-07-2014, 16:14:07 от Загорулькин Дмитрий »

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

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Разобрался с копированием объектов из чертежа во временный чертеж в папке Temp.В этом процессе все логично и понятно.
IdMapping показывает уже совершенно другие хендлы!
Вся беда в том, что примитивы при вставке берутся не из файла в папке temp - проверить просто - сотри их - вставка продолжит работать - хотя может как кэш он и используется - надо "рыть" - смотреть, что еще есть в Clipboard.GetDataObject().GetFormats() и где-то там, что-то явно лежит, на основе чего база и создается (и дай бог чтоб, это был какой-нибудь поток в памяти с "честным" файлом, а если это не так - то может и придется координально менять тактику).
з.ы. предпалагаю, что на этапе копирования, вначали wblo'чаться выбранные элементы, а потом из них создается и сам "буфер обмена" с которым уже непосредственно работает автокад.


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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Возможно и так, но это не объясняет, почему в разных базах данных объекты имеют одинаковые хендлы. Пускай копируется не из файла а из буфера обмена - события же все равно срабатывают. Базы данных различные - это тоже легко проверяется. Почему же одинаковые хендлы? Наверное, при реализации обертки над ARX, из одной переменной оба значения взяли. Другого объяснения я не вижу :(
Я, конечно, поковыряю буфер обмена. Сдается мне, что там я найду копию файла из Temp...

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Возможно и так, но это не объясняет, почему в разных базах данных объекты имеют одинаковые хендлы.
А что в этом не так? Могут иметь - не вижу в этом противоречия.
P.S.: Кстати зря в ролике во втором файле отключил реакторы из ARXDBG.  Вполне допускаю, что они бы что-то подсказали.
P.S.S.: А вообще-то в чем ты видишь проблему я совсем не понял. В твоём протоколе дважды DeepCloneContext: Insert с одними и теми же метками примитивов? Но это мне понятно. Сначала вставляется внешний файл как блок и таскается за курсором, а когда точка указана тут происходит повторная вставка в указанную точку. Ну и последний этап - расчленение вставленного блока (). Интересно, что если в момент когда запрашивается точка вставки нажать ESC, то вставленный блок (BlockTableRecord с именем типа "A$XXXXXXX") не удаляется и остается в чертеже, но вставки блока (BlockReference) с таким именем не возникает. Если же команда завершается штатно, то блока нет (он удаляется).
« Последнее редактирование: 15-07-2014, 01:53:00 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Моя проблема в том, что:
1) я использую хендлы примитивов для хранения связи между ними
2) в процессе вставки хендлы вставляемых объектов не соответствуют вообще ничему и откуда берутся непонятно :(

При копировании IdMapping четко и однозначно показывает - был такой объект (ID такой-то, хендл такой-то), стал другой объект (ID другой, и хендл другой). Я имею возможность отследить изменение хендлов и актуализировать данные о связях.
При вставке реакции срабатывают, IdMapping выдается, но там в парах хендлы объектов исходной и целевой базы одинаковые (хотя ID - разные, базы - разные) и откуда взявшиеся - неизвестно.

Как я понимаю, дважды DeepCloneContext: Insert потому, что срабатывают две реакции параллельно на одно и то же событие клонирования объектов в базу: InsertMappingAvailable и BeginDeepCloneTranslation. Потом уже, при указании точки, никакого "клонирования" из других БД не происходит, поэтому эти реакции не срабатывают, там будут уже ObjectAppended, ObjectModified и т.п.

ARXDBG я пробовал не отключать. К сожалению, утилита, при клонировании объектов между БД, показывает только хендлы объектов для целевой базы.

P.S. Александр Наумович, очень прошу Вас (если, конечно, возможности/время позволяет) проверить, что выдаст при вставке ARXовский аналог IdMapping! Я, конечно, могу оказаться неправ, но пока я склоняюсь к тому, что проблема именно из-за неправильной реализации.
« Последнее редактирование: 15-07-2014, 11:11:11 от Загорулькин Дмитрий »

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
P.S. Александр Наумович, очень прошу Вас (если, конечно, возможности/время позволяет) проверить, что выдаст при вставке ARXовский аналог IdMapping! Я, конечно, могу оказаться неправ, но пока я склоняюсь к тому, что проблема именно из-за неправильной реализации.
Боюсь что проблема вот в следующем. В момент возникновения события BeginDeepCloneTranslation IdMapping еще неправильный (необработанный) о чем говорится в документации. Правильным IdMapping становится в момент события AcEditorReactor::endDeepClone, эквивалент которого в .NET API Database.DeepCloneEnded. Но тут то и возникает проблема, т.к. у Database.DeepCloneEnded нет параметра, в котором был бы IdMapping, а у AcEditorReactor::endDeepClone он есть. Так что как получить правильный  IdMapping в AutoCAD .NET API я сейчас даже и не соображу...

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Стоп... Что-то у меня совсем ум за разум заходит... В IdMapping нет Handle. Там только пары Id и ссылки на базы. Id разные, базы разные - тут порядок. А хендлы я уже из Id получаю, может тут какой подвох?  :-\

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

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

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

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Подвох в том, что в тот момент когда ты их получаешь они еще не вычислены,
Кто не вычесленны id или handle - если handle - тогда все просто - сохранить IdMapping на момент вызова BeginDeepCloneTranslation, а получить handle по событию DeepCloneEnded - но ИХМО тут загвоздка еще в чем-то (то есть такой вариант скорее всего вернет все тоже-самое). Я думаю, что где-то в этой цеопчке создаются все-же невидимая для событий база - ту в которую копируют и соответственно "цепочка" преобразований - с пропуском.

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Попробовал сохранить объект IdMapping в событии BeginDeepCloneTranslation и прочитать его в событии DeepCloneEnded - объект IdMapping между этими событиями не изменился (хотя, особой надежды не было), хендлы тоже другими не стали.
Попробовал установить рабочей базу данных, из которой выполняем копирование, с помощью транзакции вытащить из нее объект и посмотреть его хендл - тот же самый, что и из Id. Это, в моем понимании, противоречит тому, что IdMapping некорректный, раз в исходной БД объект с тем же хендлом.

Посмотрел цепочку событий при вставке, порядок такой:
- создается пустая база данных (исходная БД)
- в нее читаются данные из временного ДВГ файла
- выполняется вставка блока в чертеж (БД назначения)
- запрашивается точка вставки
- исходная БД уничтожается
- взрывается блок

Провел опыт с закрытым исходным чертежом:
Временный файл создается по данным из буфера обмена, после вставки он удаляется. Еще раз вставляем - снова создается временный файл уже с другим случайным именем и опять после вставки он удаляется. После примерно пяти вставок, я его перехватил до удаления, переименовал и открыл - там мои объекты все еще с "актуальными" хендлами.

Попробовал сохранить исходную БД в другом файле - AutoCAD падает без каких-либо сообщений... Тупик :(

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

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