Как избежать затирание информации в Xdata

Автор Тема: Как избежать затирание информации в Xdata  (Прочитано 20547 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Atomohod,
В качестве idOwner - передаёшь destDb.RegAppTableId. 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
В моем случае предыдущую xData нужно копировать вручную и ее отсутствие вызывает ошибки? Так?
Не XData копировать, а RegAppTableRecord
Стоп. Ты меня совсем запутал. В исходной базе тебе нужно добавлять XData к твоим объектам? Если нет, то тогда создаёшь свою RegAppTableRecord в базе, в которую копируешь и добавляешь XData к скопированным объектам. И еще. WblockCloneObjects крайне желательно вызывать вне всяких транзакций. Кстати, как я заметил, у тебя куча вложенных транзакций. Это допустимо, но нежелательно. Если без этого можно обойтись (а у тебя точно можно), то лучше обойтись без вложенных транзакций.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Благо, что в idMap сохраняются пары исходный ObjectId и скопированный ObjectId.
При замене порядка - то есть не присваивать xData внутри чертежа источника, а сначала скопировать объекты в конечный чертеж и присваивать там, я хватаю ошибку и Автокад падает.  В момент  работы с IdPair. Такие дела.


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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Полный код класса:
Код - C# [Выбрать]
  1.  public static class Synchronizer
  2.     {
  3.         [CommandMethod("syncdrawings")]
  4.         public static void SynchronizeDrawings()
  5.         {
  6.             List<string> fileNames = Drawing.SelectDrawings();
  7.             if (fileNames.Count == 0)
  8.             {
  9.                 return;
  10.             }
  11.  
  12.             Document acDoc = Application.DocumentManager.MdiActiveDocument;
  13.             Database destDb = acDoc.Database;
  14.             ObjectId idMSpace = ObjectId.Null;
  15.             var layerResourcePath = PluginConfigurator.GetResourcePath("layer");
  16.             List<string> layersToSync = EntityProcessor.GetLayersToSync(layerResourcePath);
  17.             var blockListPath = PluginConfigurator.GetResourcePath("block");
  18.             List<string> blockNames = EntityProcessor.GetBlockNames(blockListPath);
  19.             using (Transaction acTrans = destDb.TransactionManager.StartTransaction())
  20.             {
  21.                 BlockTable acBlkTbl = acTrans.GetObject(destDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  22.                 idMSpace = acBlkTbl[BlockTableRecord.ModelSpace];
  23.  
  24.                 var startTime = System.Diagnostics.Stopwatch.StartNew();
  25.  
  26.                 foreach (string fileName in fileNames)
  27.                 {
  28.                     using (Database sourceDb = new Database(false, true))
  29.                     {
  30.                         sourceDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
  31.                         string areaNumber = null;
  32.                         try
  33.                         {
  34.                             areaNumber = sourceDb.GetBuildingAreaNumber();
  35.                         }
  36.                         catch (NullReferenceException)
  37.                         {
  38.                             // Application.ShowAlertDialog("Set construction area number in source drawing by Drawing properties => subject");
  39.                         }
  40.  
  41.                         DeletePreviousEntities(areaNumber, destDb);
  42.                         using (IdMapping idMap = new IdMapping())
  43.                         {
  44.                             ObjectIdCollection iDrObjects = Drawing.GetObjects(sourceDb, layersToSync);
  45.                             sourceDb.WblockCloneObjects(iDrObjects, idMSpace, idMap, DuplicateRecordCloning.Ignore, false);
  46.  
  47.                             ObjectIdCollection iDrObjects2 = new ObjectIdCollection();
  48.                             foreach (ObjectId item in iDrObjects)
  49.                             {
  50.                                 IdPair idpair = idMap.Lookup(item);
  51.                                 iDrObjects2.Add(idpair.Value);
  52.                             }
  53.  
  54.                             Marker.AttachXDataToSelectionSetObjects(iDrObjects2, destDb, areaNumber);
  55.  
  56.  
  57.                         }
  58.  
  59.                     }
  60.                     startTime.Stop();
  61.                     var resultTime = startTime.Elapsed;
  62.                     string elapsedTime = String.Format("{0:00}:m{1:00}:s{2:00}.{3:000}",
  63.                         resultTime.Hours,
  64.                         resultTime.Minutes,
  65.                         resultTime.Seconds,
  66.                         resultTime.Milliseconds);
  67.                     Logger logger = new Logger();
  68.                     logger.CreateSynchronizationLog(fileName, elapsedTime);
  69.                     startTime.Restart();
  70.                 }
  71.                 EntityProcessor.SetDynamicBlockProperty(destDb, blockNames);
  72.  
  73.                 acTrans.Commit();
  74.             }
  75.         }
  76.  
  77.         public static void DeletePreviousEntities(string label, Database db)
  78.         {
  79.             Transaction tr = db.TransactionManager.StartTransaction();
  80.  
  81.             using (tr)
  82.             {
  83.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  84.                 ObjectId btrId = bt[BlockTableRecord.ModelSpace];
  85.                 {
  86.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  87.                     foreach (ObjectId entId in btr)
  88.                     {
  89.                         Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
  90.                         if ((ent != null) && ent.GetXData2().Contains(label))
  91.                         {
  92.                             ent.UpgradeOpen();
  93.                             ent.Erase();
  94.                             ent.DowngradeOpen();
  95.                         }
  96.                     }
  97.                 }
  98.  
  99.                 tr.Commit();
  100.             }
  101.         }
  102.                
  103.  
  104.         public static List<string> GetXData2(this DBObject item)
  105.  
  106.         {
  107.             Document doc = Application.DocumentManager.MdiActiveDocument;
  108.  
  109.             Editor ed = doc.Editor;
  110.  
  111.             Transaction tr = doc.TransactionManager.StartTransaction();
  112.             List<string> xData = new List<string>();
  113.             using (tr)
  114.  
  115.             {
  116.                 DBObject obj = tr.GetObject(item.ObjectId, OpenMode.ForRead);
  117.  
  118.                 ResultBuffer rb = obj.XData;
  119.  
  120.                 if (rb != null)
  121.  
  122.                 {
  123.                     foreach (TypedValue tv in rb)
  124.  
  125.                     {
  126.                         xData.Add(tv.Value.ToString());
  127.                     }
  128.  
  129.                     rb.Dispose();
  130.                 }
  131.             }
  132.  
  133.             return xData;
  134.         }
  135.     }
« Последнее редактирование: 13-04-2021, 10:50:47 от Александр Ривилис »

Оффлайн Lemieux

  • ADN OPEN
  • ****
  • Сообщений: 389
  • Карма: 21
Atomohod, оформи код в теги C#

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
По поводу форматирования тебе уже написали.
Каюсь, второпях не уследил.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Проект в zip-архиве сюда. Мне надоело смотреть на обрывки кода.
Прикладываю проект в архиве. txt файлики для конфига тоже.

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Нужен минимальный тестовый пример, созданный с нуля, который воспроизводит ошибку.
Александр Ривилис, фишка то в том и есть, что я получаю разные ошибки (перетертые xData, AcDbRegAppTable(9) Invalid Entry, pure virtual function call, исчезновение ранее добавленных объектов) причем хаотично - 20 раз отработает нормально, на 21 выдаст ошибку, на 22 норм, затем совершенно другая ошибка и снова нормально.
На тех файлах, что я сейчас приложил к этому сообщению воспроизводится, по крайней мере у меня, одна из ошибок - исчезновение ранее добавленных объектов.
Это самая критичная - проверить после сборки из 20 чертежей, что где-то исчезла пара объектов нереально.


Последовательность моих действий:
Запускаю код - команда syncdrawings
Выбираю 1.dwg.
Код отрабатывает.
Выбираю 2.dwg.
Код отрабатывает и после его работы исчезает часть объектов из 1.dwg, добавленных ранее.

Пытался запускать несколько чертежей конвейером (в коде предусмотрен выбор одновременно нескольких файлов) результат тот же.

Audit выдает либо ноль ошибок, либо AcDbRegAppTable(9) Invalid Entry - заранее не угадаешь. Либо в процессе работы pure virtual function call - пока словил один раз.

Код один и тот же. Все dwg одни и те же. Сборку единого чертежа всегда провожу в чистый новый файл.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Новый пример с dwg.

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Ты или не понимаешь что я прошу
Не понимаю, что не так. Чертежи с нуля с объектами приложил, все решение с файлами необходимыми для сборки и для конфига тоже.
Нужен минимальный тестовый пример, созданный с нуля, который воспроизводит ошибку
В моем случае стабильно воспроизводится одна проблема - исчезновение ранее добавленных объектов после вставки последующих. Другие ошибки я хватаю хаотично на ЭТОМ ЖЕ коде, не меняя его. Воспроизвести их нарочно у меня нет возможности - я не знаю что их вызывает и условия под это мне не создать.

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

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