При копировании объектов из одного чертежа в другой не наследуются слои объектов

Автор Тема: При копировании объектов из одного чертежа в другой не наследуются слои объектов  (Прочитано 8388 раз)

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!

Прошу разъяснить почему при копировании объектов из одного чертежа в другой не наследуются слои объектов, или я что-то не то делаю? При обычном ручном копировании объект приходит в новый чертеж со своим слоем и на нем остается, у меня же так не выходит объекты не приносят свои слои с собой и кладутся на текущий слой нового чертежа вызывая кучу ошибок в файле. Как это исправить? Для копирования между чертежами я пользуюсь  db.WblockCloneObjects(originDrawing.GetObjects(db), acBlkTblRec.ObjectId, idMap, DuplicateRecordCloning.Replace, true);


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

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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Кроме того правильнее в твоём случае должно быть:
Код - C# [Выбрать]
  1. db.WblockCloneObjects(originDrawing.GetObjects(db), idMSpace /* это ObjectId для ModelSpace */, idMap, DuplicateRecordCloning.Ignore, false);
2. Не нужно открывать ModelSpace (да еще и для записи), только для того чтобы получить его ObjectId.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
У тебя случайно не открыта в момент копирования таблица слоёв?
Кода специально открывающего таблицу у меня нет-сам я его точно не писал. Если только что-то вдруг автоматом без моего ведома открывается.
Я использую код по поводу которого вчера писал на форум, только чуток корректированный с Вашей помощью. А еще этот самый badLayer присваивается перенесенному объекту. Предварительное создание слоя переносимого объекта в целевом чертеже не помогает - объект все равно приходит битый и на предварительно созданный под него слой не кладется. см. скриншот


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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Выкладываю код. Эта версия без DoсumentLock и флага сессии, при использовании блокировки документа поведение кода не меняется- ошибки те же. Мастер-файл - результирующий, в нем ошибки, два других - источники.
Код - C# [Выбрать]
  1. namespace DrawingSynchronizer
  2. {
  3.     public class Synchronizer
  4.     {
  5.         [CommandMethod("syncdrawings"/*, CommandFlags.Session*/)]
  6.         public static void SynchronizeDrawings()
  7.         {
  8.             Drawing originDrawing = new Drawing();
  9.             var originDrawings = originDrawing.GetDrawingDatabases(@"K:\sync\");
  10.  
  11.             // Get the current document and database
  12.             Document acDoc = Application.DocumentManager.MdiActiveDocument;
  13.             Database acCurDb = acDoc.Database;
  14.  
  15.            
  16.                 // Start a transaction
  17.                 using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  18.                 {
  19.                     // Open the Block table record for read
  20.                     BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  21.  
  22.                     // Open the Block table record Model space for write
  23.                     BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  24.  
  25.  
  26.                     IdMapping idMap = new IdMapping();
  27.                    
  28.                     foreach (var db in originDrawings)
  29.                     {
  30.                        db.WblockCloneObjects(originDrawing.GetObjects(db), acBlkTblRec.ObjectId, idMap, DuplicateRecordCloning.Replace, true);
  31.                     }
  32.                     //acCurDb.Save();
  33.  
  34.                     acTrans.Commit();
  35.                 }
  36.            
  37.         }
  38.  
  39.         public static bool CheckEntityLayer(Entity entity)
  40.         {
  41.             if ( BasicLayers.layersToSync.Contains(entity.Layer) )
  42.             {
  43.                 return true;
  44.             }
  45.             else
  46.             {
  47.                 return false;
  48.             }
  49.         }
  50.     }
  51.  
  52. }
Код - C# [Выбрать]
  1. namespace DrawingSynchronizer
  2. {
  3.     class Drawing
  4.     {
  5.         public List < Database > GetDrawingDatabases(string path)
  6.         {
  7.             List < Database > originDrawings = new List < Database >();
  8.             try
  9.             {
  10.                 DirectoryInfo d = new DirectoryInfo(path);
  11.                 FileInfo[] Files = d.GetFiles("*.dwg");
  12.  
  13.                 foreach ( FileInfo file in Files )
  14.                 {
  15.                     var fileName = Path.GetFileName(file.FullName);
  16.                     string dwgFlpath = path + fileName;
  17.  
  18.                     Database db = new Database(false, true);
  19.  
  20.                     db.ReadDwgFile(dwgFlpath, FileOpenMode.OpenForReadAndAllShare, false, null);
  21.                     db.CloseInput(true);
  22.                     originDrawings.Add(db);
  23.                 }
  24.             }
  25.             catch ( Exception ex )
  26.             {
  27.                 Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
  28.             }
  29.  
  30.             return originDrawings;
  31.         }
  32.  
  33.         public ObjectIdCollection GetObjects(Database db)
  34.         {
  35.             ObjectIdCollection objectIdCollection = new ObjectIdCollection();
  36.             Transaction tr = db.TransactionManager.StartTransaction();
  37.             using ( tr )
  38.             {
  39.                 BlockTable bt = (BlockTable) tr.GetObject(db.BlockTableId, OpenMode.ForRead, false, false);
  40.                 BlockTableRecord btr = (BlockTableRecord) tr.GetObject(bt[ BlockTableRecord.ModelSpace ], OpenMode.ForRead);
  41.  
  42.                 foreach ( var item in btr )
  43.                 {
  44.                     Entity ent = (Entity) tr.GetObject(item, OpenMode.ForRead);
  45.  
  46.                     if ( Synchronizer.CheckEntityLayer(ent) )
  47.                     {
  48.                         objectIdCollection.Add(ent.ObjectId);
  49.                     }
  50.                 }
  51.  
  52.                 tr.Commit();
  53.             }
  54.  
  55.             return objectIdCollection;
  56.         }
  57.     }
  58. }
Код - C# [Выбрать]
  1. namespace Utilities
  2. {
  3.     public static class BasicLayers
  4.     {
  5.         public const string Titles = "-10-Titles";
  6.         public const string Equipment = "-10-Equipment";
  7.         public const string Auxiliary = "-10-Auxiliary";
  8.         public const string Adapter1C = "-10-Adapter1C";
  9.         public const string Cabins = "-10-Cabins";
  10.         public const string FrameRulers = "-10-FrameRulers";
  11.         public const string Dimensions = "-10-Dimensions";
  12.         public const string Doors = "-10-Doors";
  13.         public const string Coverings = "-10-Coverings";
  14.         public const string Openings = "-10-Openings";
  15.         public const string Hull = "-10-Hull";
  16.         public const string Ladders = "-10-Ladders";
  17.         public const string Manholes = "-10-Manholes";
  18.         public const string FrameGrid = "-10-FrameGrid";
  19.         public const string PhantomLines = "-10-PhantomLines";
  20.         public const string Projections = "-10-Projections";
  21.         public const string Railing = "-10-Railings";
  22.         public const string RemovableFloors = "-10-RemovableFloors";
  23.         public const string SpaceDesignations = "-10-SpaceDesignations";
  24.         public const string BulkheadsAndDecks = "-10-Bulkheads&Decks";
  25.         public const string BulkheadsAndDecksThin = "-10-Bulkheads&DecksThin";
  26.         public const string Stiffeners = "-10-Stiffeners";
  27.         public const string SystemTraces = "-10-SystemTraces";
  28.         public const string Text = "-10-Text";
  29.         public const string Viewports = "-10-Viewports";
  30.         public const string Windows = "-10-Windows";
  31.         public const string ServiceAreas = "-10-ServiceAreas";
  32.         public const string HVAC = "-10-HVAC";
  33.         public const string Bioshield = "-10-Bioshield";
  34.  
  35.         public static List < string > layersToSync = new List < string >
  36.         {
  37.             BulkheadsAndDecks, BulkheadsAndDecksThin, SpaceDesignations
  38.         };
  39.  
  40.  
  41.     }
  42. }

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1. В файле мастер-файл.dwg сразу 3 ошибки.
2. Я написал, что нужно заменить строку:
Код - C# [Выбрать]
  1. db.WblockCloneObjects(originDrawing.GetObjects(db), idMSpace /* это ObjectId для ModelSpace */, idMap, DuplicateRecordCloning.Ignore, false);
3. Этот код у меня работает и не даёт дополнительных ошибок:
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using System.IO;
  9.  
  10. [assembly: CommandClass(typeof(DrawingSynchronizer.Synchronizer))]
  11.  
  12. namespace DrawingSynchronizer
  13. {
  14.   public class Synchronizer
  15.   {
  16.     [CommandMethod("syncdrawings"/*, CommandFlags.Session*/)]
  17.     public static void SynchronizeDrawings()
  18.     {
  19.       Drawing originDrawing = new Drawing();
  20.       var originDrawings = originDrawing.GetDrawingDatabases(@"E:\sync\");
  21.  
  22.       // Get the current document and database
  23.       Document acDoc = Application.DocumentManager.MdiActiveDocument;
  24.       Database acCurDb = acDoc.Database;
  25.  
  26.  
  27.       // Start a transaction
  28.       using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  29.       {
  30.         // Open the Block table record for read
  31.         BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  32.  
  33.         // Open the Block table record Model space for write
  34.         BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  35.  
  36.         IdMapping idMap = new IdMapping();
  37.  
  38.         foreach (var db in originDrawings)
  39.         {
  40.           db.WblockCloneObjects(originDrawing.GetObjects(db), acBlkTbl[BlockTableRecord.ModelSpace],
  41.             idMap, DuplicateRecordCloning.Ignore, false); // !!!!
  42.           db.Dispose(); // !!!!
  43.         }
  44.         //acCurDb.Save();
  45.  
  46.         acTrans.Commit();
  47.       }
  48.  
  49.     }
  50.  
  51.     public static bool CheckEntityLayer(Entity entity)
  52.     {
  53.       if (Utilities.BasicLayers.layersToSync.Contains(entity.Layer))
  54.       {
  55.         return true;
  56.       }
  57.       else
  58.       {
  59.         return false;
  60.       }
  61.     }
  62.   }
  63.  
  64.   class Drawing
  65.   {
  66.  
  67.     public List<Database> GetDrawingDatabases(string path)
  68.     {
  69.       List<Database> originDrawings = new List<Database>();
  70.       try
  71.       {
  72.         DirectoryInfo d = new DirectoryInfo(path);
  73.         FileInfo[] Files = d.GetFiles("*.dwg");
  74.  
  75.         foreach (FileInfo file in Files)
  76.         {
  77.           var fileName = Path.GetFileName(file.FullName);
  78.           string dwgFlpath = path + fileName;
  79.  
  80.           Database db = new Database(false, true);
  81.  
  82.           db.ReadDwgFile(dwgFlpath, FileOpenMode.OpenForReadAndAllShare, false, null);
  83.           db.CloseInput(true);
  84.           originDrawings.Add(db);
  85.         }
  86.       }
  87.       catch (System.Exception ex)
  88.       {
  89.         Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
  90.       }
  91.  
  92.       return originDrawings;
  93.     }
  94.  
  95.     public ObjectIdCollection GetObjects(Database db)
  96.     {
  97.       ObjectIdCollection objectIdCollection = new ObjectIdCollection();
  98.  
  99.       using (Transaction tr = db.TransactionManager.StartTransaction())
  100.       {
  101.         BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false, false);
  102.         BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  103.  
  104.         foreach (var item in btr)
  105.         {
  106.           Entity ent = (Entity)tr.GetObject(item, OpenMode.ForRead);
  107.  
  108.           if (Synchronizer.CheckEntityLayer(ent))
  109.           {
  110.             objectIdCollection.Add(ent.ObjectId);
  111.           }
  112.         }
  113.  
  114.         tr.Commit();
  115.       }
  116.  
  117.       return objectIdCollection;
  118.     }
  119.   }
  120.  
  121.   namespace Utilities
  122.   {
  123.     public static class BasicLayers
  124.     {
  125.       public const string Titles = "-10-Titles";
  126.       public const string Equipment = "-10-Equipment";
  127.       public const string Auxiliary = "-10-Auxiliary";
  128.       public const string Adapter1C = "-10-Adapter1C";
  129.       public const string Cabins = "-10-Cabins";
  130.       public const string FrameRulers = "-10-FrameRulers";
  131.       public const string Dimensions = "-10-Dimensions";
  132.       public const string Doors = "-10-Doors";
  133.       public const string Coverings = "-10-Coverings";
  134.       public const string Openings = "-10-Openings";
  135.       public const string Hull = "-10-Hull";
  136.       public const string Ladders = "-10-Ladders";
  137.       public const string Manholes = "-10-Manholes";
  138.       public const string FrameGrid = "-10-FrameGrid";
  139.       public const string PhantomLines = "-10-PhantomLines";
  140.       public const string Projections = "-10-Projections";
  141.       public const string Railing = "-10-Railings";
  142.       public const string RemovableFloors = "-10-RemovableFloors";
  143.       public const string SpaceDesignations = "-10-SpaceDesignations";
  144.       public const string BulkheadsAndDecks = "-10-Bulkheads&Decks";
  145.       public const string BulkheadsAndDecksThin = "-10-Bulkheads&DecksThin";
  146.       public const string Stiffeners = "-10-Stiffeners";
  147.       public const string SystemTraces = "-10-SystemTraces";
  148.       public const string Text = "-10-Text";
  149.       public const string Viewports = "-10-Viewports";
  150.       public const string Windows = "-10-Windows";
  151.       public const string ServiceAreas = "-10-ServiceAreas";
  152.       public const string HVAC = "-10-HVAC";
  153.       public const string Bioshield = "-10-Bioshield";
  154.  
  155.       public static List<string> layersToSync = new List<string>
  156.             {
  157.                 BulkheadsAndDecks, BulkheadsAndDecksThin, SpaceDesignations
  158.             };
  159.     }
  160.   }
  161. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
У меня нeудача - хватаю Fatal error.
Поясните пожалуйста почему
Ни в коем случае не следует создавать базы для всех чертежей сразу
, а то магия получается какая-то. Я думал использовать в окончательном коде что-то типа "получить базы каждого чертежа, создать из них очередь и последовательно их обработать", а выходит что так нельзя. И вторая непонятка - почему DuplicateRecordCloning.Ignore? Что подразумевается под дубликатом, если при вставке в другой чертеж не сохраняются ни исходные ObjectID, ни Handle и почему их нужно именно игнорить?



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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
У меня нeудача - хватаю Fatal error.
Поясните пожалуйста почему
На моём коде и с теми чертежами, которые ты предоставил для теста? Надеюсь, что мастер-файл.dwg не находится в том же каталоге, что и остальные два чертежа. Ну и я изменил путь к каталогу dwg-файлов, так как диска K: у меня нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
На моём коде и с теми чертежами, которые ты предоставил для теста?
Код исправленный, к двум чертежам добавил еще один, более насыщенный. За путями проследил-все верно. Мастер-файл вообще получается каждый раз новый- я просто создаю его по Qnew при открытии автокада по встроенному шаблону. Такие дела. Что можно мне попробовать?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я думал использовать в окончательном коде что-то типа "получить базы каждого чертежа, создать из них очередь и последовательно их обработать"
Так нельзя, потому что количество одновременно открытых файлов ограничено и оперативная память компьютера не резиновая.
И вторая непонятка - почему DuplicateRecordCloning.Ignore?
Если у тебя есть уже слой с определённым именем, то нечего его заменять из каждого открываемого чертежа. Даже если, например, у одного и того же слоя будут разные состояния (цвет, тип линии, вкл/выкл и т.д.), то нет смысла его его заменять каждый раз. С одноимёнными блоками будет хуже. Если под одним и тем же именем будут разные блоки, то получится ерунда. В общем случае чтобы ничего не потерять нужно использовать DuplicateRecordCloning.MangleName - при этом имена слоёв/блоков/типов линий и т.д. изменятся.

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

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

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

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

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


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

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