Как скопировать массив блоков

Автор Тема: Как скопировать массив блоков  (Прочитано 86 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 22
  • Карма: 0
Вставляю блок в рисунок, командой ARRAY делаю массив. Подскажите пожалуйста, как скопировать массив.
Если использовать DeepCloneObjects, то выдает ошибку( не может преобразовать BlockTableReference в BlockReference.
Если использовать DeepClone или Clone , то копирует, но удаляет оригинал
Код - C# [Выбрать]
  1.   public void Test()
  2.         {
  3.             Document doc = AcApSrvApp.DocumentManager.MdiActiveDocument;
  4.             Editor ed = doc.Editor;
  5.             Matrix3d ucs = ed.CurrentUserCoordinateSystem;
  6.             PromptSelectionResult psr = ed.GetSelection();
  7.             if (psr.Status != PromptStatus.OK)
  8.                 return;
  9.             PromptPointResult ppr = ed.GetPoint("\nBase point: ");
  10.             if (ppr.Status != PromptStatus.OK)
  11.                 return;
  12.             Point3d basePoint = ppr.Value;
  13.             PromptPointOptions ppo = new PromptPointOptions("\nSecond point: ");
  14.             ppo.BasePoint = basePoint;
  15.             ppo.UseBasePoint = true;
  16.             ppr = ed.GetPoint(ppo);
  17.             if (ppr.Status != PromptStatus.OK)
  18.                 return;
  19.             Vector3d disp = basePoint.TransformBy(ucs).GetVectorTo(ppr.Value.TransformBy(ucs));
  20.             ObjectId[] ids = psr.Value.GetObjectIds();
  21.             try
  22.             {
  23.                 CopyMove(ids, disp);
  24.             }
  25.             catch (System.Exception ex)
  26.             {
  27.                 ed.WriteMessage("Error: " + ex.Message);
  28.             }
  29.         }
  30.  
  31.   private void CopyMove(ObjectId[] ids, Vector3d disp)
  32.         {
  33.             Document doc = AcApSrvApp.DocumentManager.MdiActiveDocument;
  34.             Database db = doc.Database;
  35.             using (Transaction tr = db.TransactionManager.StartTransaction())
  36.             {
  37.                 foreach (ObjectId Id in ids)
  38.                 {
  39.                     Entity ent = (Entity)tr.GetObject(Id, OpenMode.ForRead);
  40.                     ObjectId ownerId = ent.OwnerId;
  41.                     IdMapping IdMap = new IdMapping();
  42.                     ObjectIdCollection idsColl = new ObjectIdCollection(new ObjectId[] { Id });
  43.                     db.DeepCloneObjects(idsColl, db.CurrentSpaceId, IdMap, false);
  44.                     foreach (IdPair pair in IdMap)
  45.                     {
  46.                         if (pair.IsPrimary)
  47.                         {
  48.                             BlockReference btr = (BlockReference)tr.GetObject(pair.Value, OpenMode.ForWrite);
  49.                             if (btr != null) btr.TransformBy(Matrix3d.Displacement(disp));
  50.                         }
  51.                     }
  52.                 }
  53.                 tr.Commit();
  54.                
  55.             }
  56.             //Document doc = AcApSrvApp.DocumentManager.MdiActiveDocument;
  57.             //Database db = doc.Database;
  58.             //using (Transaction tr = db.TransactionManager.StartTransaction())
  59.             //{
  60.             //    foreach (ObjectId id in ids)
  61.             //    {
  62.             //        Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite, false);
  63.             //        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(ent.OwnerId, OpenMode.ForWrite);
  64.             //        IdMapping mapping = new IdMapping();
  65.             //        Entity copiedEnt = (Entity)ent.DeepClone(btr, mapping, false);
  66.             //        tr.AddNewlyCreatedDBObject(copiedEnt, true);
  67.             //        ent.TransformBy(Matrix3d.Displacement(disp));
  68.             //    }
  69.             //    tr.Commit();
  70.             //}
  71.             //Document doc = AcApSrvApp.DocumentManager.MdiActiveDocument;
  72.             //Database db = doc.Database;
  73.             //using (Transaction tr = db.TransactionManager.StartTransaction())
  74.             //{
  75.             //    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  76.             //    foreach (ObjectId id in ids)
  77.             //    {
  78.             //        Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite, false);
  79.             //        Entity copiedEnt = (Entity)ent.Clone();
  80.             //        btr.AppendEntity(copiedEnt);
  81.             //        tr.AddNewlyCreatedDBObject(copiedEnt, true);
  82.             //        ent.TransformBy(Matrix3d.Displacement(disp));
  83.             //    }
  84.             //    tr.Commit();
  85.             //}
  86.         }

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

  • Administrator
  • *****
  • Сообщений: 10373
  • Карма: 1314
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как скопировать массив блоков
« Ответ #1 : 03-12-2019, 18:00:43 »
Если использовать DeepCloneObjects, то выдает ошибку( не может преобразовать BlockTableReference в BlockReference.
Не понял. А подробнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 22
  • Карма: 0
Re: Как скопировать массив блоков
« Ответ #2 : 03-12-2019, 18:06:55 »
извиняюсь, BlockTableRecord а не BlockTableReference
 Unable to cast object of type 'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord' to type 'Autodesk.AutoCAD.DatabaseServices.BlockReference'.

Отмечено как Решение serhiy79 03-12-2019, 18:24:07

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

  • Administrator
  • *****
  • Сообщений: 10373
  • Карма: 1314
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как скопировать массив блоков
« Ответ #3 : 03-12-2019, 18:16:34 »
serhiy79,
Попробуй:

Код - C# [Выбрать]
  1. private void CopyMove(ObjectId[] ids, Vector3d disp)
  2. {
  3.   Document doc = Application.DocumentManager.MdiActiveDocument;
  4.   Database db = doc.Database;
  5.   using (Transaction tr = db.TransactionManager.StartTransaction())
  6.   {
  7.     foreach (ObjectId Id in ids)
  8.     {
  9.       Entity ent = (Entity)tr.GetObject(Id, OpenMode.ForRead);
  10.       ObjectId ownerId = ent.OwnerId;
  11.       IdMapping IdMap = new IdMapping();
  12.       ObjectIdCollection idsColl = new ObjectIdCollection(new ObjectId[] { Id });
  13.       db.DeepCloneObjects(idsColl, ownerId, IdMap, false);
  14.       foreach (IdPair pair in IdMap)
  15.       {
  16.         if (pair.IsPrimary)
  17.         {
  18.           Entity en = tr.GetObject(pair.Value, OpenMode.ForWrite) as Entity;
  19.           if (en != null)
  20.             en.TransformBy(Matrix3d.Displacement(disp));
  21.         }
  22.       }
  23.     }
  24.     tr.Commit();
  25.   }
  26. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 22
  • Карма: 0
Re: Как скопировать массив блоков
« Ответ #4 : 03-12-2019, 18:26:00 »
Спасибо большое!!! Работает.
А не подскажите, почему при использовании DeepClone или Clone массив копируется, но удаляется оригинал?

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

  • Administrator
  • *****
  • Сообщений: 10373
  • Карма: 1314
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как скопировать массив блоков
« Ответ #5 : 03-12-2019, 18:35:57 »
А не подскажите, почему при использовании DeepClone или Clone массив копируется, но удаляется оригинал?
Это сложный объект. Его так копировать нельзя.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение