При записи в файл DWG выдает ошибку eWrongDataBase

Автор Тема: При записи в файл DWG выдает ошибку eWrongDataBase  (Прочитано 529 раз)

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

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
Не могу понять в чем дело. Что я не так делаю?
База в шаблоне без ошибок в файле источника,
 где хранятся вставки блоков тоже ошибок нет

Вот код функции, которая:
1) открывает базу файла шаблона
2) вставляет в него примитивы,
    которые я вынимаю методом BlockREference.Explode(...)
3) Сохраняет в файле по имени dest_dwg_FileName

Код - C# [Выбрать]
  1.         public static void add_ents_to_file(ref List<CAD_DBS.Entity> Ents,
  2.                                             string Template_dwg_FileName,
  3.                                             string dest_dwg_FileName)
  4.         {
  5.  
  6.             CAD_DBS.Database db = new CAD_DBS.Database(false, true);
  7.             if (db == null)
  8.                 return;
  9.             db.ReadDwgFile(Template_dwg_FileName, System.IO.FileShare.ReadWrite, false, null);
  10.             using (CAD_DBS.Transaction tr = db.TransactionManager.StartTransaction())
  11.             {
  12.                 CAD_DBS.BlockTable bt = (CAD_DBS.BlockTable)tr.GetObject(db.BlockTableId, CAD_DBS.OpenMode.ForWrite);
  13.                 CAD_DBS.BlockTableRecord btr =
  14.                    (CAD_DBS.BlockTableRecord)tr.GetObject(bt[CAD_DBS.BlockTableRecord.ModelSpace], CAD_DBS.OpenMode.ForWrite);
  15.                 foreach (CAD_DBS.Entity e in Ents)
  16.                 {
  17.                     if (e is CAD_DBS.BlockReference)
  18.                     {
  19.                         CAD_DBS.DBObjectCollection coll = new CAD_DBS.DBObjectCollection();
  20.                         (e as CAD_DBS.BlockReference).Explode(coll);
  21.                         foreach (CAD_DBS.DBObject dbo in coll)
  22.                         {
  23.                             if (dbo is CAD_DBS.Entity)
  24.                             {
  25.                                 CAD_DBS.Entity ent = dbo as CAD_DBS.Entity;
  26.                                 btr.AppendEntity(ent); // Ошибка вот тут eWrongDataBase
  27.                                 tr.AddNewlyCreatedDBObject(ent, true);
  28.                             }
  29.                         }
  30.                     }
  31.                 }
  32.                 tr.Commit();
  33.             }
  34.             db.CloseInput(true);
  35.             db.SaveAs(dest_dwg_FileName, DwgVersion.Current);
  36.             db.Dispose();
  37.         }

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
Пробовал в acad 2016 и acad 2018

Оффлайн avc

  • ADN Club
  • ****
  • Сообщений: 392
  • Карма: 72
    • Мои плагины к Автокаду
На первый взгляд должно работать. Насколько я помню объекты из Explode к БД не привязаны. Но раз сбоит - попробуйте вставлять ent.Clone().

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
попробуйте вставлять ent.Clone().
Clone тоже пробовал
Что еще странно, что это только BlockReference такое.
Если к примеру делаешь новый объект
вот так

Код - C# [Выбрать]
  1. var Ln = new Line(...)

то все нормально.

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

  • ADN Club
  • *****
  • Сообщений: 1284
  • Карма: 265
  • Отец modplus.org
Метод db.CloseInput(true); нужно вызывать непосредственно после метода db.ReadDwgFile();, а не в конце перед сохранением
ModPlus
Блог
Отвечаю в надежде получить плюсики в карму =))

Оффлайн avc

  • ADN Club
  • ****
  • Сообщений: 392
  • Карма: 72
    • Мои плагины к Автокаду
Скорее всего объекты связаны со старой БД через свойства (стиль, слой и т.п.) и копирование в другую БД сработает только рекурсивное. Я использовал WblockCloneObjects

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

  • ADN Club
  • *****
  • Сообщений: 1284
  • Карма: 265
  • Отец modplus.org
И скорее всего вот тут - CAD_DBS.Database db = new CAD_DBS.Database(false, true); - второй параметр нужно установить в false
ModPlus
Блог
Отвечаю в надежде получить плюсики в карму =))

Оффлайн avc

  • ADN Club
  • ****
  • Сообщений: 392
  • Карма: 72
    • Мои плагины к Автокаду
И скорее всего вот тут - CAD_DBS.Database db = new CAD_DBS.Database(false, true); - второй параметр нужно установить в false
Второй параметр noDocument - если пишем без открытия документа то true

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

  • ADN Club
  • *****
  • Сообщений: 1284
  • Карма: 265
  • Отец modplus.org
И скорее всего вот тут - CAD_DBS.Database db = new CAD_DBS.Database(false, true); - второй параметр нужно установить в false
Второй параметр noDocument - если пишем без открытия документа то true
Цитировать
The noDocument parameter is intended to indicate that the Database DWG file has no associated Document window (like it would in AutoCAD) – so when reading a side database with ReadDwgFile it’s a good idea to set this to True so that the document handlers know to exclude this DWG Database, making it very quick to process. The downside to setting noDocument=True is that it bypasses the setup internal document functionality, like document locking and UNDO filing – this means that Transactions won’t work, so you will have to use Open/Close or StartOpenCloseTransaction instead of StartTransaction.

Или поменяйте Transaction на OpenCloseTransaction
ModPlus
Блог
Отвечаю в надежде получить плюсики в карму =))

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
Скорее всего объекты связаны со старой БД через свойства (стиль, слой и т.п.)
Базы файлов (источника и шаблона) одинаковых версий.
и сформированная в одной версии AutoCAD.
Внешних ссылок нет прокси тоже нет обычные объекты штриховки отрезки тексты и вставки блоков (в блоках тоже объекты обычные)
Проверку на ошибки файлы прошли.

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
Спасибо!
Ваш совет использовать
WblockCloneObjects
мне помог.

Вот так нормально работает без сбоев.

Код - C# [Выбрать]
  1. ......
  2.                     if (e is CAD_DBS.BlockReference)
  3.                     {
  4.                         tr.TransactionManager.QueueForGraphicsFlush();
  5.                         IdMapping iMap = new IdMapping();
  6.                         ObjectIdCollection objIds = new ObjectIdCollection();
  7.                         objIds.Add(e.ObjectId);
  8.                         (e as CAD_DBS.BlockReference).Database.WblockCloneObjects(objIds, db.CurrentSpaceId, iMap, DuplicateRecordCloning.Ignore, false);
  9.                     }
  10.                 }
  11.                 tr.Commit();
  12. ....


 

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

  • ADN
  • *
  • Сообщений: 867
  • Карма: 4
    • idea-soft.ru
  • Skype: makar_govorun
Одна только штука.
Мне все же хотелось чтобы блок вставлялся разбитым.
Причина вот в чем
Файлы, которые формируются потом подгружаются в Revit,
А тот кто их вставляет в Revit не может ни как понять почему
Revit не понимает блоки AutoCAD 

Я вот и думаю. Наверное стоит написать в раздел Revit вопрос:

"ПОЧЕМУ REVIT НЕ ПОНИМАЕТ БЛОКИ ИЛИ ЧТО НУЖНО СДЕЛАТЬ ЧТО БЫ REIVIT ПОНИМАЛ БЛОКИ"


Оффлайн avc

  • ADN Club
  • ****
  • Сообщений: 392
  • Карма: 72
    • Мои плагины к Автокаду
Не приходит в голову ничего кроме как сохранить взорванные объекты в исходной БД, скопировать в другую и удалить в исходной. Костыль, да...

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

  • ADN Club
  • *****
  • Сообщений: 1284
  • Карма: 265
  • Отец modplus.org
Вот так работает (решение в строчках 11 и 56):
Код - C# [Выбрать]
  1. namespace CopyBlocks
  2. {
  3.     using System.Collections.Generic;
  4.     using System.IO;
  5.     using Autodesk.AutoCAD.DatabaseServices;
  6.     using Autodesk.AutoCAD.EditorInput;
  7.     using Autodesk.AutoCAD.Runtime;
  8.  
  9.     public class Class1
  10.     {
  11.         [CommandMethod("CopyBlocks", CommandFlags.Session)]
  12.         public void Start()
  13.         {
  14.             var ed = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor;
  15.             PromptSelectionResult selection = ed.GetSelection();
  16.             if (selection.Status == PromptStatus.OK && selection.Value.Count > 0)
  17.             {
  18.                 List<Entity> entities = new List<Entity>();
  19.                 using (var tr = ed.Document.Database.TransactionManager.StartOpenCloseTransaction())
  20.                 {
  21.                     foreach (SelectedObject o in selection.Value)
  22.                     {
  23.                         var obj = tr.GetObject(o.ObjectId, OpenMode.ForRead) as Entity;
  24.                         if(obj != null)
  25.                             entities.Add(obj);
  26.                     }
  27.                     tr.Commit();
  28.                 }
  29.                
  30.                 AddEntitiesToFile(entities, @"E:\Test\Test.dwg", @"E:\Test\TestNewFile.dwg");
  31.             }
  32.         }
  33.  
  34.         public static void AddEntitiesToFile(
  35.             List<Entity> entities,
  36.             string templateDwgFileName,
  37.             string destDwgFileName)
  38.         {
  39.             Database db = new Database(false, true);
  40.             db.ReadDwgFile(templateDwgFileName, FileShare.Read, false, null);
  41.             db.CloseInput(true);
  42.             using (Transaction tr = db.TransactionManager.StartTransaction())
  43.             {
  44.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  45.                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false, true);
  46.                 foreach (Entity e in entities)
  47.                 {
  48.                     if (e is BlockReference blockReference)
  49.                     {
  50.                         DBObjectCollection coll = new DBObjectCollection();
  51.                         blockReference.Explode(coll);
  52.                         foreach (DBObject dbo in coll)
  53.                         {
  54.                             if (dbo is Entity entity)
  55.                             {
  56.                                 var ent = (Entity)entity.Clone();
  57.                                 btr.AppendEntity(ent);
  58.                                 tr.AddNewlyCreatedDBObject(ent, true);
  59.                             }
  60.                         }
  61.                     }
  62.                 }
  63.                 tr.Commit();
  64.             }
  65.             db.SaveAs(destDwgFileName, DwgVersion.Current);
  66.             db.Dispose();
  67.         }
  68.     }
  69. }
ModPlus
Блог
Отвечаю в надежде получить плюсики в карму =))

Оффлайн avc

  • ADN Club
  • ****
  • Сообщений: 392
  • Карма: 72
    • Мои плагины к Автокаду
И все-таки транзакция в БД открытой с noDocument ?  ;)