Как можно в чертеже зафиксировать имена блоков ( в т.ч. дин.),чтобы удалить ?

Автор Тема: Как можно в чертеже зафиксировать имена блоков ( в т.ч. дин.),чтобы удалить ?  (Прочитано 8888 раз)

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

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Доброго времени суток!
В общем у меня стоит два вопроса,второй еще более менее,а первый не пойму как решить.
  • В файл вставляются блоки, один -стабильно не меняет название, второй меняет название в заивисмости от того с чьей машины ведется работа (т.е. меняется имя), ну и третий либо один,либо два.Все блоки кроме первого-динамические.Так вот, не знаю где их имена фиксировать,пыталась записать в Custom properties table, но  если со вторым блоком еще понятно,то с третьим -там ромашка.Да и считать у меня не получилось эту информацию.Мельком почитала про словари. Разумен ли в этом плане ход такой? Чтобы было более понятно про вариации блоков,нарисовала небольшую блок схему )) (в приложении)
  • А тут проблема удаления их.Т.е. ГИпотетически я имею какой то List<string> из имен блоков,и пишу функцию,для которой задаю аргумент-имя блока,и если обычный блок  как вхождение,так и запись (Blocktablerecords) удаляет,то с динамическими беда.Вроде мне понятно что для динамических есть вроде своя таблица,или свои записи в таблице блоков,но как добраться грамотно,что бы и то и то удалялось нормально?

Ниже приведу код,который тестировала для динамического блока. Запись удаляет, а само изображение становится не понятным,и вообще этот блок ,кажется становится анонимным..

Код - C# [Выбрать]
  1.                [CommandMethod("Udal")]
  2.         public void RemoveBLock()
  3.         {
  4.             Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = new Database(false, false);
  7.             Database curdb = doc.Database;
  8.             List<string> BlockList = new List<string>();
  9.              BlockList.Add("SHTAMP");
  10.              //BlockList.Add("ISO_TXT");
  11.              BlockList.Add("SAPR");
  12.              //BlockList.Add("GOST");
  13.  
  14.             using (Transaction tr = doc.TransactionManager.StartTransaction())
  15.             {
  16.                 //foreach (string blockname in BlockList)
  17.                 //{
  18.                     BlockTable bt = (BlockTable)tr.GetObject(curdb.BlockTableId, OpenMode.ForRead);
  19.                     foreach (ObjectId id in bt)
  20.                     {
  21.                         BlockTableRecord btr =
  22.                             (BlockTableRecord)tr.GetObject(id, OpenMode.ForWrite);
  23.                         ObjectIdCollection idCol = btr.GetBlockReferenceIds(true, false);
  24.                      
  25.                         if (btr.Name.ToUpper() == "ISO_TXT"&&btr.IsDynamicBlock)
  26.                         {
  27.                            
  28.                             foreach (ObjectId brId in idCol)
  29.                             {
  30.                                 BlockReference br =(BlockReference)tr.GetObject(brId, OpenMode.ForWrite);
  31.                                 br.UpgradeOpen();
  32.                                 br.Erase();
  33.                              }
  34.                             btr.UpgradeOpen();
  35.                             btr.Erase();
  36.                         }
  37.                     }
  38.                    
  39.                 //}
  40.                 tr.Commit();
  41.             }
  42.         }

п.с. файл для теста смогу только завтра кинуть,там фигурируют кое-какие личные данные.....
в приложении свойства этого "недоудаленного" блока.

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

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

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
 8) Спасибо!!!
пару часиков,и с динамическими справилась....
правда руки,так и чешутся сократить код,но я не знаю как можно сократить ))) впрочем ладно,это  потом
вот код.
Код - C# [Выбрать]
  1.          [CommandMethod("RemDin")]
  2.          public void RemoveDinBLock()
  3.          {
  4.              Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.              Editor ed = doc.Editor;
  6.              Database db = doc.Database;
  7.              List<string> BlockNameList = new List<string>();
  8.              BlockNameList.Add("ISO_TXT");
  9.              BlockNameList.Add("SAPR");
  10.              //BlockList.Add("GOST");
  11.              using (Transaction tr = doc.TransactionManager.StartTransaction())
  12.              {
  13.                  BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  14.                  foreach (ObjectId btrId in bt)
  15.                  {
  16.                      // получаем запись таблицы блоков и смотри анонимная ли она
  17.                      BlockTableRecord btr =
  18.                          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
  19.                      if (btr.IsDynamicBlock)
  20.                      {
  21.                          // получаем все анонимные блоки динамического блока
  22.                          ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  23.                          ObjectIdCollection dynBlockRefs = new ObjectIdCollection();
  24.                          foreach (ObjectId anonymousBtrId in anonymousIds)
  25.                          {
  26.                              // получаем анонимный блок
  27.                              BlockTableRecord anonymousBtr =
  28.                                        (BlockTableRecord)tr.GetObject(anonymousBtrId,
  29.                                                                      OpenMode.ForRead);
  30.                              // получаем все вставки этого блока
  31.                              ObjectIdCollection blockRefIds =
  32.                                          anonymousBtr.GetBlockReferenceIds(true, true);
  33.                              foreach (ObjectId id in blockRefIds)
  34.                              {
  35.                                  dynBlockRefs.Add(id);
  36.  
  37.                                  foreach (ObjectId dinId in dynBlockRefs)
  38.                                  {
  39.                                      BlockReference bref = (BlockReference)tr.GetObject(dinId, OpenMode.ForWrite);
  40.                                      foreach (string blockname in BlockNameList)
  41.                                      {
  42.                                          if (btr.Name == blockname)
  43.                                          {
  44.                                              bref.UpgradeOpen();
  45.                                              bref.Erase();
  46.                                              btr.UpgradeOpen();
  47.                                              btr.Erase();
  48.                                          }
  49.                                      }
  50.                                  }
  51.                              }
  52.                          }
  53.                      }
  54.                  }
  55.                  tr.Commit();
  56.              }
  57.          }
-----------------------------------------------------------------------------------------------------------------
а продолжение будет? По теме как записать имена блоков,в чертеже, что бы потом вот перебором их удалять..а  то,яж вручную сформировала список имён(7-9 строки).Или проще всего вот так внести в список - все возможные значения?(~ 10-15)

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
В коде много неправильного:
1) btr мужно удалять только после того, как все связанные с ней bref удалены.
2) ты не удаляешь анонимные btr
3) возможен случай (даже для динамического блока), когда bref указывает на сам btr, а не на анонимный блок.
а продолжение будет? По теме как записать имена блоков,в чертеже, что бы потом вот перебором их удалять..
Эту глубокую мысль я не понял, поэтому от меня продолжения не жди. ;) Зачем записывать имена блоков в чертеж? Но если уже очень надо, то пиши их в XData для BlockTable, если конечно количество блоков небольшое.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
В коде много неправильного:
1) btr мужно удалять только после того, как все связанные с ней bref удалены.
Код - C# [Выбрать]
  1. if (btr.IsDynamicBlock)
  2. { ///.......///
  3.       if (btr.Name == blockname)
  4.             {    
  5.               bref.UpgradeOpen();
  6.               bref.Erase();
  7.              }
  8.                  btr.UpgradeOpen();
  9.                  btr.Erase();
  10. } -закончился If
  11.  


2) ты не удаляешь анонимные btr
-как это можно проверить? если на графике, и в окне вставки блоков их нет?

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
-закончился If
У тебя может быть 100 bref на один btr. Так что сначала удаляешь все bref, а потом btr. А по тому огрызку кода, который ты показала, я не могу догадаться правилен ли он или нет. И похоже он не правилен, т.к. ты не проверяешь его имя.
-как это можно проверить? если на графике, и в окне вставки блоков их нет?
Например, при помощи ARXDBG/MGDDBG. Или в команде _PURGE. Мало ли чего ты не видишь на графике или в окне вставки блоков. Мусор остаётся если его не удалить.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
У тебя может быть 100 bref на один btr. Так что сначала удаляешь все bref, а потом btr. А по тому огрызку кода, который ты показала, я не могу догадаться правилен ли он или нет. И похоже он не правилен, т.к. ты не проверяешь его имя.
Код - C# [Выбрать]
  1.   [CommandMethod("RemDin")]
  2.         public void RemoveDinBLock()
  3.          {
  4.             Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             List<string> BlockNameList = new List<string>(); ///Собрать список блоков
  8.             System.Collections.IDictionaryEnumerator oEnu = db.SummaryInfo.CustomProperties;
  9.              while (oEnu.MoveNext())
  10.              {
  11.                  ed.WriteMessage("Ключ  : \"{0}\", Наименование блока \"{1}\n", oEnu.Key.ToString(),oEnu.Value.ToString());
  12.                  BlockNameList.Add(oEnu.Value.ToString());
  13.              }
  14.              ObjectId xrefId = ObjectId.Null;
  15.              using (Transaction tr = doc.TransactionManager.StartTransaction())
  16.              {
  17.                  BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  18.                  foreach (ObjectId btrId in bt)
  19.                  {
  20.                      // получаем запись таблицы блоков и смотри анонимная ли она
  21.                      BlockTableRecord btr =
  22.                          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
  23.                      
  24.                      if (btr.IsDynamicBlock)
  25.                      {
  26.                          // получаем все анонимные блоки динамического блока
  27.                          ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  28.                          ObjectIdCollection dynBlockRefs = new ObjectIdCollection();
  29.                          foreach (ObjectId anonymousBtrId in anonymousIds)
  30.                          {
  31.                              // получаем анонимный блок
  32.                              BlockTableRecord anonymousBtr =
  33.                                        (BlockTableRecord)tr.GetObject(anonymousBtrId,
  34.                                                                      OpenMode.ForRead);
  35.                              // получаем все вставки этого блока
  36.                              ObjectIdCollection blockRefIds =
  37.                                          anonymousBtr.GetBlockReferenceIds(true, true);
  38.                              foreach (ObjectId id in blockRefIds)
  39.                              {
  40.                                  dynBlockRefs.Add(id);
  41.  
  42.                                  foreach (ObjectId dinId in dynBlockRefs)
  43.                                  {
  44.                                      BlockReference bref = (BlockReference)tr.GetObject(dinId, OpenMode.ForWrite);
  45.                                      foreach (string blockname in BlockNameList)
  46.                                      {
  47.                                          if (btr.Name == blockname)
  48.                                          {
  49.                                            
  50.                                              bref.Erase();
  51.                                              bref.UpgradeOpen();
  52.                                          }
  53.                                      }
  54.                                  }
  55.                              }
  56. //                             ed.WriteMessage(String.Format("Динамическому блоку \"{0}\" соответствуют \"{1} \" анонимных блоков и \"{2}\" вставок блока\n",
  57. //btr.Name, anonymousIds.Count, dynBlockRefs.Count));
  58.                          }
  59.                          btr.UpdateAnonymousBlocks();
  60.                          btr.UpgradeOpen();
  61.                          btr.Erase();
  62.                      }
  63.                      else if (btr.Name == "SHTAMP")
  64.                      {
  65.                          ObjectIdCollection ShtIdS = btr.GetBlockReferenceIds(true, true);
  66.                          
  67.                          foreach (ObjectId ShtId in ShtIdS)
  68.                          {
  69.                              BlockReference ShtBref = (BlockReference)tr.GetObject(ShtId, OpenMode.ForWrite);
  70.                              ShtBref.UpgradeOpen();
  71.                              ShtBref.Erase();
  72.                          }
  73.                          btr.UpgradeOpen();
  74.                          btr.Erase();
  75.                      }
  76.                      //else if (btr.IsFromExternalReference || btr.IsFromOverlayReference)
  77.                      else if (btr.IsFromExternalReference || btr.IsFromOverlayReference)
  78.                      {
  79.                          ObjectIdCollection XrefIds = btr.GetBlockReferenceIds(true, true);
  80.                          foreach(ObjectId xId in XrefIds)
  81.                          {
  82.                              BlockReference xbref =(BlockReference)tr.GetObject(xId,OpenMode.ForWrite);
  83.                              if (btr.Name == "Logo")
  84.                              {
  85.                                 xrefId = xbref.BlockTableRecord;
  86.                                 db.DetachXref(xrefId);
  87.                              }
  88.                              xbref.Erase();
  89.                              xbref.UpgradeOpen();
  90.                          }
  91.                          ed.WriteMessage("\nExternal reference detached.");
  92.                      }
  93.                  }
  94.                  
  95.                  tr.Commit();
  96.                  ed.WriteMessage("\nШтамп удалён");
  97.              }
  98.          }

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Еще критиковать?
1) Использование SummaryInfo.CustomProperties - далеко не самое удачное место для хранения списка блоков. Хотя-бы по той причине, что у пользователя всегда есть возможность редактировать этот список.
2) Проходя по списку BlockTableRecord-ов ты не учитываешь тот факт, что анонимные блоки, которые ты получаешь через btr.GetAnonymousBlockIds тоже содержаться в этом же списке. Т.е. удаляя их ты таким образом это список портишь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Еще критиковать?
-да.
1) Использование SummaryInfo.CustomProperties - далеко не самое удачное место для хранения списка блоков. Хотя-бы по той причине, что у пользователя всегда есть возможность редактировать этот список.
-Ну я вас(и Вас) спрашивала как иначе хранить?) про Хдата не поняла,не нашла, взяла,то,что попроще ,всё таки в другой программе я там уже использовала Hypelink из тех же свойств,да конечно уже так же слышала от одного коллеги, что не особо удачное место,для шаловливых рук.

2) Проходя по списку BlockTableRecord-ов ты не учитываешь тот факт, что анонимные блоки, которые ты получаешь через btr.GetAnonymousBlockIds тоже содержаться в этом же списке. Т.е. удаляя их ты таким образом это список портишь.
-не очень поняла в каком это месте.

меня больше всего весь вечер заботил вопроо том,  что я удаляю запись-(blocktablerecords)- не проверив имя. В коде я поменяла местами  с 42-61 строки(вчерашний код) на 41-55 (сегодняшний),что бы запись блока попала в цикл "if"-правильно ли сделала?

Код - C# [Выбрать]
  1.         [CommandMethod("RemDin")]
  2.         public void RemoveDinBLock()
  3.          {
  4.             Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             List<string> BlockNameList = new List<string>(); ///Собрать список блоков
  8.             System.Collections.IDictionaryEnumerator oEnu = db.SummaryInfo.CustomProperties;
  9.              while (oEnu.MoveNext())
  10.              {
  11.                  ed.WriteMessage("Ключ  : \"{0}\", Наименование блока \"{1}\n", oEnu.Key.ToString(),oEnu.Value.ToString());
  12.                  BlockNameList.Add(oEnu.Value.ToString());
  13.              }
  14.              ObjectId xrefId = ObjectId.Null;
  15.              using (Transaction tr = doc.TransactionManager.StartTransaction())
  16.              {
  17.                  BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  18.                  foreach (ObjectId btrId in bt)
  19.                  {
  20.                      // получаем запись таблицы блоков и смотри анонимная ли она
  21.                      BlockTableRecord btr =
  22.                          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
  23.                      
  24.                      if (btr.IsDynamicBlock)
  25.                      {
  26.                          // получаем все анонимные блоки динамического блока
  27.                          ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  28.                          ObjectIdCollection dynBlockRefs = new ObjectIdCollection();
  29.                          foreach (ObjectId anonymousBtrId in anonymousIds)
  30.                          {
  31.                              // получаем анонимный блок
  32.                              BlockTableRecord anonymousBtr =
  33.                                        (BlockTableRecord)tr.GetObject(anonymousBtrId,
  34.                                                                      OpenMode.ForRead);
  35.                              // получаем все вставки этого блока
  36.                              ObjectIdCollection blockRefIds =
  37.                                          anonymousBtr.GetBlockReferenceIds(true, true);
  38.                              foreach (ObjectId id in blockRefIds)
  39.                              {
  40.                                  dynBlockRefs.Add(id);
  41.                                      foreach (string blockname in BlockNameList)
  42.                                      {
  43.                                          if (btr.Name == blockname)
  44.                                          {
  45.                                              foreach (ObjectId dinId in dynBlockRefs)
  46.                                              {
  47.                                                  BlockReference bref = (BlockReference)tr.GetObject(dinId, OpenMode.ForWrite);
  48.                                                  bref.Erase();
  49.                                                  bref.UpgradeOpen();
  50.                                              }
  51.                                              btr.UpdateAnonymousBlocks();
  52.                                              btr.UpgradeOpen();
  53.                                              btr.Erase();
  54.                                          }
  55.                                      }
  56.                              }
  57. //                             ed.WriteMessage(String.Format("Динамическому блоку \"{0}\" соответствуют \"{1} \" анонимных блоков и \"{2}\" вставок блока\n",
  58. //btr.Name, anonymousIds.Count, dynBlockRefs.Count));
  59.                          }
  60.                      }
  61.                          // удаляю главный блок штампа (не дин-ий)
  62.                      else if (btr.Name == "SHTAMP")
  63.                      {
  64.                          ObjectIdCollection ShtIdS = btr.GetBlockReferenceIds(true, true);
  65.                          
  66.                          foreach (ObjectId ShtId in ShtIdS)
  67.                          {
  68.                              BlockReference ShtBref = (BlockReference)tr.GetObject(ShtId, OpenMode.ForWrite);
  69.                              ShtBref.UpgradeOpen();
  70.                              ShtBref.Erase();
  71.                          }
  72.                          btr.UpgradeOpen();
  73.                          btr.Erase();
  74.                      }
  75.                          // Detach logotip
  76.                      else if (btr.IsFromExternalReference || btr.IsFromOverlayReference)
  77.                      {
  78.                          ObjectIdCollection XrefIds = btr.GetBlockReferenceIds(true, true);
  79.                          foreach(ObjectId xId in XrefIds)
  80.                          {
  81.                              BlockReference xbref =(BlockReference)tr.GetObject(xId,OpenMode.ForWrite);
  82.                              if (btr.Name == "Logo")
  83.                              {
  84.                                 xrefId = xbref.BlockTableRecord;
  85.                                 db.DetachXref(xrefId);
  86.                              }
  87.                              xbref.Erase();
  88.                              xbref.UpgradeOpen();
  89.                          }
  90.                          ed.WriteMessage("\nExternal reference detached.");
  91.                      }
  92.                  }
  93.                  tr.Commit();
  94.                  ed.WriteMessage("\nШтамп удалён");
  95.              }
  96.          }
  97.         /// Удалить логотип
  98.         private static void DetachXref(Database db, string xrefName)
  99.          {
  100.              using (Transaction trans = db.TransactionManager.StartOpenCloseTransaction())
  101.              {
  102.                  XrefGraph xrefGraph = db.GetHostDwgXrefGraph(true);
  103.                  int xrefCount = xrefGraph.NumNodes;
  104.                  for (int i = 0; i < xrefCount; i++)
  105.                  {
  106.                      XrefGraphNode xrefNode = xrefGraph.GetXrefNode(i);
  107.                      if (xrefNode.Name.ToLower() == xrefName.ToLower())
  108.                      {
  109.                          ObjectId xrefId = xrefNode.BlockTableRecordId;
  110.                          db.DetachXref(xrefId);
  111.  
  112.                          break;
  113.                      }
  114.                  }
  115.                  trans.Commit();
  116.              }
  117.          }


п.с. 51-строку удалила
Код - C# [Выбрать]
  1. btr.UpdateAnonymousBlocks();

код заругался,я втюхнула его(эту процедуру) не подумав, и не зная,что происходит..теоретически думала обновляется список какой то.

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
-Ну я вас(и Вас) спрашивала как иначе хранить?) про Хдата не поняла,не нашла
XData или Расширенные данные: http://adn-cis.org/ispolzovanie-.netapidlya-dobavleniya-i-udaleniya-rasshirennyix-dannyix.html
Всё тоже самое применимо не только к примитивам AutoCAD. но и к таким объектам как BlockTable, куда я и предлагал добавить в расширенные данные имена блоков.
В первую очередь до всех проверок после:
Код - C# [Выбрать]
  1. BlockTableRecord btr =
  2.                          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite); // <--- Кстати почему сразу ForWrite если возможны ты его править не будешь?
нужно проверить не анонимный ли блок. Если он анонимный (btr.IsAnonymous) , то мы его здесь(!!!) не трогаем и сразу пропускаем и переходим к следующему.
Он нам попадётся если он один из анонимных от динамического или не попадётся, но это нам уже не важно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение