Задача: Прочитать атрибуты в динамическом блоке

Автор Тема: Задача: Прочитать атрибуты в динамическом блоке  (Прочитано 7207 раз)

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

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

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Добрый день, простая задача но никак не получается
Надо из динамического блока прочитать атрибут и его значение

Код - C# [Выбрать]
  1. [CommandMethod("ListAtributes")]
  2.             public void ListAttributes2()
  3.             {
  4.                 String SourceAtribut = "ФРАЗРАБ";
  5.                 ListAttributes("Штамп", ref  SourceAtribut);
  6.  
  7.             }

Первое значение Штамп - название динамического блока
Второе значение Название атрибута, а потом в нем вернется Значение атрибута

Код - C# [Выбрать]
  1. public void ListAttributes(String blockName, ref String SourceAtribut)
  2.  
  3.             {
  4.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.                 Database db = HostApplicationServices.WorkingDatabase;
  6.                 Transaction tr = db.TransactionManager.StartTransaction();
  7.  
  8.                 // Start the transaction
  9.                 try
  10.                 {
  11.                    // открываем таблицу блоков на чтение
  12.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  13.  
  14.                     ObjectId btrId = bt[blockName]; // ID - Главного блока
  15.  
  16.                     BlockTableRecord acBlkTblRec = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
  17.                     foreach (ObjectId entId in acBlkTblRec)
  18.                     {
  19.                         Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
  20.  
  21.                         if (ent != null)
  22.                         {
  23.                             BlockReference br = ent as BlockReference;
  24.  
  25.                             if (br != null)
  26.                             {
  27.                                 // Check each of the attributes...
  28.  
  29.                                 foreach (ObjectId arId in br.AttributeCollection)
  30.                                 {
  31.                                     DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
  32.  
  33.                                     AttributeReference ar = obj as AttributeReference;
  34.  
  35.                                     if (ar != null)
  36.                                     {
  37.                              
  38.                                     if (SourceAtribut == ar.Tag)
  39.                                     {
  40.                                         SourceAtribut = ar.TextString;
  41.                                         return;
  42.                                     }
  43.                                  
  44.                                 }
  45.                                     }
  46.                                 }
  47.                             }
  48.                            
  49.                             tr.Commit();
  50.                         }
  51.                     }
  52.                 }
  53.                 catch (Autodesk.AutoCAD.Runtime.Exception ex)
  54.                 {
  55.                     ed.WriteMessage(("Exception: " + ex.Message));
  56.                 }
  57.                 finally
  58.                 {
  59.                     tr.Dispose();
  60.                 }
  61.             }

Выскакивает ошибка при получении - BlockReference

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
потому что это не BlockReference

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

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
потому что это не BlockReference
согласен

подскажите пожалуйста, где я ошибаюсь?

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
Нужно открыть ModelSpace и перебрать все Entity - и смотреть их тип, например через wEnt.ObjectId.ObjectClass.DxfName
http://adndevblog.typepad.com/autocad/2012/05/identifying-block-name-from-the-block-reference.html

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

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

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

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Продолжим
добрался до атрибутов, считал значения, но столкнулся с новой бедой
пытаюсь прочитать значение поля а получаю только кучу решоток (######)

так как поле является ссылкой, но значение поля указано и на чертеже отображается


Вопрос: как прочитать значение поля?

Код - C# [Выбрать]
  1.             public void GettingAttributes2()
  2.            
  3.             {
  4.                 // Get the current database and start a transaction
  5.                 Database acCurDb;
  6.                 acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
  7.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  8.  
  9.                 using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  10.                 {
  11.                     // Open the Block table for read
  12.                     BlockTable acBlkTbl;
  13.                     acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  14.  
  15.                     ObjectId blkRecId = ObjectId.Null;
  16.                         blkRecId = acBlkTbl["Штамп"];
  17.                    
  18.                    if (blkRecId != ObjectId.Null)
  19.                     {
  20.                         BlockTableRecord acBlkTblRec;
  21.                         acBlkTblRec = acTrans.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
  22.  
  23.                         // Verify block table record has attribute definitions associated with it
  24.                         if (acBlkTblRec.HasAttributeDefinitions)
  25.                             {
  26.                                 // GET attributes from the block table record
  27.                                 foreach (ObjectId objID in acBlkTblRec)
  28.                                 {
  29.                                     DBObject dbObj = acTrans.GetObject(objID, OpenMode.ForRead) as DBObject;
  30.  
  31.                                     if (dbObj is AttributeDefinition)
  32.                                     {
  33.                                         AttributeDefinition acAtt = dbObj as AttributeDefinition;
  34.  
  35.                                         if (!acAtt.Constant)
  36.                                         {
  37.                                                
  38.                                              string acAttTag = acAtt.Tag;
  39.  
  40.                                             if (acAtt.Tag == "ФРАЗРАБ")
  41.                                         {
  42.                                          
  43. // Здесь и получаем одни решеточки
  44.                                              ed.WriteMessage("\nАтрибут \"{0}\" значение {1} \n", acAtt.Tag, acAtt.TextString);
  45.                                         }
  46.  
  47.                                        
  48.                                        
  49.                                     }
  50.                                     }
  51.                                 }
  52.                                
  53.                             }
  54.           }
  55.  
  56.                    acTrans.Commit();
  57.  
  58.                     // Dispose of the transaction
  59.                 }
  60.             }
  61.  


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ты смотришь в определении блока (BlockTableRecord) определение атрибута (AttributeDefinition). А должен найти вставку блока (BlockReference) и относящийся к нему атрибут (AttributeReference) и из него брать значение.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
корявенько, но получилось

Код - C# [Выбрать]
  1.  public void selectDynamicBlockReferences2()
  2.             {
  3.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  4.                 Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.                 using (Transaction trans = db.TransactionManager.StartTransaction())
  6.                 {
  7.                     // получаем таблицу блоков
  8.                     BlockTable bt =
  9.                       (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.                     ObjectId btrId = ObjectId.Null;
  11.                     btrId = bt["Штамп"];
  12.  
  13.                         // получаем запись таблицы блоков и смотри анонимная ли она
  14.                         BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForRead);
  15.                         if (btr.IsDynamicBlock)
  16.                         {
  17.                             // получаем все анонимные блоки динамического блока
  18.                             ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  19.                             // получаем все прямые вставки динамического блока
  20.                             ObjectIdCollection dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  21.                             foreach (ObjectId anonymousBtrId in anonymousIds)
  22.                             {
  23.                                 // получаем анонимный блок
  24.                                 BlockTableRecord anonymousBtr = (BlockTableRecord)trans.GetObject(anonymousBtrId, OpenMode.ForRead);
  25.                                 // получаем все вставки этого блока
  26.                                 ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  27.                                 foreach (ObjectId id in blockRefIds)
  28.                                 {
  29.                                     dynBlockRefs.Add(id);
  30.                                
  31.                                     BlockReference blkRef = (BlockReference)trans.GetObject(id, OpenMode.ForRead);
  32.  
  33.                                     BlockTableRecord btr2 = (BlockTableRecord)trans.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  34.  
  35.                                     ed.WriteMessage("\nBlock: " + btr2.Name);
  36.                                     btr2.Dispose();
  37.  
  38.                                     AttributeCollection attCol = blkRef.AttributeCollection;
  39.  
  40.                                     foreach (ObjectId attId in attCol)
  41.                                     {
  42.                                         AttributeReference attRef = (AttributeReference)trans.GetObject(attId, OpenMode.ForRead);
  43.  
  44.                                     string str = ("\n  Attribute Tag: " + attRef.Tag + "\n    Attribute String: " + attRef.TextString);
  45.                                         ed.WriteMessage(str);
  46.                                     }
  47.                                 }
  48.                             }
  49.                             // Что-нибудь делаем с созданным нами набором
  50.                             ed.WriteMessage("\nДинамическому блоку \"{0}\" соответствуют {1} анонимных блоков и {2} вставок блока\n",
  51.                                 btr.Name, anonymousIds.Count, dynBlockRefs.Count);
  52.                         }
  53.                 }
  54.             }
  55.  

вопрос,
никак не нашел объяснения путнего между Анонимным блоком и Вхождением блока

(в целях ликвидации безграмотности, среди отдельно взятого индивидума, объясните пожалуйста)

как это понимаю я:
в чертеже, в Таблице блоков хранятся все Именованные блоки, которые создал пользователь
Когда блок вставляем на лист или модель  - получаем Вхождение блока и сразу Анонимный блок (*U)
Когда блок вставили на лист 10 раз  - получили 10 Вхождений и 10 Анонимных блоков (*U1, *U2, ... ,*U10)

Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не просто корявенько, а очень корявенько. Где trans.Commit()? Зачем btr2.Dispose();?
как это понимаю я:
в чертеже, в Таблице блоков хранятся все Именованные блоки, которые создал пользователь
Когда блок вставляем на лист или модель  - получаем Вхождение блока и сразу Анонимный блок (*U)
Когда блок вставили на лист 10 раз  - получили 10 Вхождений и 10 Анонимных блоков (*U1, *U2, ... ,*U10)

Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии
1. В таблице блоков хранятся как именованные блоки созданные пользователем или попавшие туда другим образом (например, вставили из другого чертежа), так и неименованные - это и варианты динамического блока и размерные блоки и т.д. и т.п.
2. При вставке динамического блока получается анонимный если мы изменили параметры динамического блока (например, параметр видимости).
3. Не при каждой вставке динамического блока появлется новый анонимный. На один и тот же анонимный могут ссылаться несколько вставок блока если их параметры совпадают.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии
Потому что ты обрабатываешь только вставки анонимного блока, но не обрабатываешь вставки основного (динамического) блока.
Т.е. в коде должно быть как-то так:
Код - C# [Выбрать]
  1. foreach (ObjectId id in blockRefIds)
  2. {
  3.   dynBlockRefs.Add(id);
  4. }
  5. foreach (ObjectId id in dynBlockRefs)
  6. {
  7.   // Здесь печатаешь атрибуты блока
  8. }
  9.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение