Сбой при замене блоков

Автор Тема: Сбой при замене блоков  (Прочитано 2710 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Сбой при замене блоков
« : 01-08-2021, 12:17:08 »
Здравствуйте!

Пытаюсь заменить в чертеже все блоки с определенным именем на другой блок, файл которого расположен в папке на диске. При работе получается такая вещь - одни блоки заменяются, другие нет-вообще на применение команды никакой реакции. В чем может быть причина?
Мой код
Код - C# [Выбрать]
  1.  [CommandMethod("ReplaceB1")]
  2.         public static void ReplaceBlock()
  3.         {
  4.             string name = GetBlockName();
  5.             Document doc = Application.DocumentManager.MdiActiveDocument;
  6.             Database db = doc.Database;
  7.  
  8.             ReplaceBlock(db, name, "MHF-400X600");
  9.            
  10.         }
  11.  public static string GetBlockName()
  12.         {
  13.             string name = "NoName";
  14.             Document doc = Application.DocumentManager.MdiActiveDocument;
  15.             Database db = doc.Database;
  16.             Editor ed = doc.Editor;
  17.             PromptEntityOptions options = new PromptEntityOptions("\nSelect block reference");
  18.             options.SetRejectMessage("\nSelect only block reference");
  19.             options.AddAllowedClass(typeof(BlockReference), false);
  20.             PromptEntityResult acSSPrompt = ed.GetEntity(options);
  21.             using ( Transaction tx = db.TransactionManager.StartTransaction() )
  22.             {
  23.                 BlockReference blockRef = tx.GetObject(acSSPrompt.ObjectId, OpenMode.ForRead) as BlockReference;
  24.                 BlockTableRecord block = null;
  25.                 if ( blockRef.IsDynamicBlock )
  26.                 {
  27.                     //get the real dynamic block name.
  28.                     block = tx.GetObject(blockRef.DynamicBlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  29.                 }
  30.                 else
  31.                 {
  32.                     block = tx.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  33.                 }
  34.  
  35.                 if ( block != null )
  36.                 {
  37.                     name = block.Name;
  38.                 }
  39.  
  40.                 tx.Commit();
  41.             }
  42.  
  43.             return name;
  44.         }
  45.         private static void ReplaceBlock(Database db, string oldName, string newName)
  46.         {
  47.             using ( var tr = db.TransactionManager.StartTransaction() )
  48.             {
  49.                 var bt = (BlockTable) tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  50.  
  51.                 // check if the block table contains old block
  52.                 if ( !bt.Has(oldName) )
  53.                 {
  54.                     Application.ShowAlertDialog(oldName + " not found");
  55.                     return;
  56.                 }
  57.  
  58.                 var oldBlockId = bt[ oldName ];
  59.  
  60.                 // check if the block table contains new block
  61.                 ObjectId newBlockId;
  62.                 if ( bt.Has(newName) )
  63.                 {
  64.                     newBlockId = bt[ newName ];
  65.                 }
  66.                 // try to insert new bloc from a DWG file in search paths
  67.                 else
  68.                 {
  69.                     try
  70.                     {
  71.                         var filename = HostApplicationServices.Current.FindFile("M:\\MozDownloads\\Блоки для Ч\\Блоки для ИЧ\\MHF\\" + newName + ".dwg", db, FindFileHint.Default);
  72.                         using ( var sourceDb = new Database(false, true) )
  73.                         {
  74.                             sourceDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, true, null);
  75.                             newBlockId = db.Insert(newName, sourceDb, true);
  76.                         }
  77.                     }
  78.                     catch ( System.Exception )
  79.                     {
  80.                         Application.ShowAlertDialog(newName + " not found");
  81.                         return;
  82.                     }
  83.                 }
  84.  
  85.                 var oldBtr = (BlockTableRecord) tr.GetObject(oldBlockId, OpenMode.ForRead);
  86.                 foreach ( ObjectId id in oldBtr.GetBlockReferenceIds(true, true) )
  87.                 {
  88.                     var br = (BlockReference) tr.GetObject(id, OpenMode.ForWrite);
  89.                     br.BlockTableRecord = newBlockId;
  90.                     CreateBlockReference(newName, "0", br.Position);
  91.                 }
  92.  
  93.                 tr.Commit();
  94.             }
  95.         }
  96.  
  97.         public static void CreateBlockReference(string blockName, string blockRefLayer, Point3d blockRefPosition)
  98.         {
  99.             Document doc = Application.DocumentManager.MdiActiveDocument;
  100.             Database db = doc.Database;
  101.             Transaction tr = db.TransactionManager.StartTransaction();
  102.             using ( tr )
  103.             {
  104.                 BlockTable bt = (BlockTable) db.BlockTableId.GetObject(OpenMode.ForRead);
  105.                 BlockTableRecord btr = (BlockTableRecord) bt[ blockName ].GetObject(OpenMode.ForRead);
  106.                 BlockTableRecord curSpace_btr = (BlockTableRecord) tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  107.                 BlockReference bRef = new BlockReference(blockRefPosition, btr.ObjectId);
  108.                 bRef.SetDatabaseDefaults();
  109.                 bRef.Layer = blockRefLayer;
  110.                 curSpace_btr.AppendEntity(bRef);
  111.                 tr.AddNewlyCreatedDBObject(bRef, true);
  112.                 tr.Commit();
  113.             }
  114.         }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Сбой при замене блоков
« Ответ #1 : 01-08-2021, 14:11:56 »
В чем может быть причина?
1. Для того чтобы это понять, достаточно запустить код под отладчиком.
2. Скорее всего вместо oldBtr.GetBlockReferenceIds(true, true) должно быть oldBtr.GetBlockReferenceIds(false, true)
3. Так как у тебя блоки динамические, то ты должен найти и все анонимные блоки, связанные с динамическим блоком (через BlockTableRecord.GetAnonymousBlockIds), для них найти все их вставки блоков (через BlockTableRecord.GetBlockReferenceIds) и произвести для них замену BlockReference.BlockTableRecord. Возможно понадобится еще и переносить значения атрибутов и свойств динамического блока - зависит от постановки задачи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Re: Сбой при замене блоков
« Ответ #2 : 01-08-2021, 20:27:50 »
то ты должен найти и все анонимные блоки
Спасибо за подсказку, то есть если я правильно понимаю, то у динамического блока есть два имени - обычное и анонимное и по обычному его не найти? Но для чего так мудрено?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Сбой при замене блоков
« Ответ #3 : 01-08-2021, 23:39:05 »
Atomohod,
то ты должен найти и все анонимные блоки
Спасибо за подсказку, то есть если я правильно понимаю, то у динамического блока есть два имени - обычное и анонимное и по обычному его не найти? Но для чего так мудрено?
Ты понимаешь не совсем правильно. Если в динамическом блоке не изменено ни одного динамического параметра, то динамическое имя соответствует имени блока (т.е. blockRef.DynamicBlockTableRecord == blockRef.BlockTableRecord). Если же хоть один динамический параметр изменён, то для него генерируется анонимный блок и имена перестают совпадать (т.е. blockRef.DynamicBlockTableRecord != blockRef.BlockTableRecord, но blockRef.BlockTableRecord - это один из BlockTableRecord.GetAnonymousBlockIds для blockRef.DynamicBlockTableRecord)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение