Отбор динамических блоков по видимости

Автор Тема: Отбор динамических блоков по видимости  (Прочитано 14327 раз)

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

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

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

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

Пытаюсь заменить один блок в чертеже на другой "ManholeRev1" на "MHF-400x600-fitted". Мой метод отбора нужных вставок блока отрабатывает лишь на их части, почему так происходит? Блоки вроде бы одни и те же.
Прикладываю пример файла с блоками, может дело в нем.
Код - C# [Выбрать]
  1.   public static ObjectIdCollection SelectManholes(string blockName)
  2.         {
  3.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  4.             Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.             ObjectIdCollection ids = new ObjectIdCollection();
  6.             using ( Transaction tr = db.TransactionManager.StartTransaction() )
  7.             {
  8.                 // получаем таблицу блоков и проходим по всем записям таблицы блоков
  9.                 BlockTable bt = (BlockTable) tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.                 foreach ( ObjectId btrId in bt )
  11.                 {
  12.                    
  13.                     BlockTableRecord btr = (BlockTableRecord) tr.GetObject(btrId, OpenMode.ForRead); // это описание блока, здесь же имя
  14.                     if ( btr.Name == blockName )
  15.                     {
  16.                         if ( btr.IsDynamicBlock )
  17.                         {
  18.                            
  19.                             ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  20.                            
  21.                             ObjectIdCollection dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  22.                             foreach ( ObjectId anonymousBtrId in anonymousIds )
  23.                             {
  24.                                
  25.                                 BlockTableRecord anonymousBtr = (BlockTableRecord) tr.GetObject(anonymousBtrId, OpenMode.ForRead);
  26.                                
  27.                                 ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  28.                                 foreach ( ObjectId id in blockRefIds )
  29.                                 {
  30.                                     dynBlockRefs.Add(id);
  31.                                 }
  32.                             }
  33.  
  34.                             ids = dynBlockRefs;
  35.                             foreach ( ObjectId entity in dynBlockRefs )
  36.                             {
  37.                                 BlockReference bref = tr.GetObject(entity, OpenMode.ForWrite, false, true) as BlockReference;
  38.                                 DynamicBlockReferencePropertyCollection props = bref.DynamicBlockReferencePropertyCollection;
  39.                                 foreach ( DynamicBlockReferenceProperty prop in props )
  40.                                 {
  41.                                    
  42.                                     if ( prop.PropertyName.Contains("Visibility") && !prop.ReadOnly )
  43.                                     {
  44.                                         if ( prop.Value.ToString().Contains("Vertical") )
  45.                                         {
  46.                                             ids.Remove(entity);
  47.                                         }
  48.                                     }
  49.                                 }
  50.                             }
  51.                         }
  52.                     }
  53.                 }
  54.             }
  55.  
  56.             return ids;
  57.         }

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Мой метод отбора нужных вставок блока отрабатывает лишь на их части, почему так происходит?
Почему бы не запустить код под отладчиком и не посмотреть сколько вставок блоков находит у вас код? GetBlockReferenceIds(true, true) не находит вложенные блоки. Это возможная причина.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Мой метод отбора нужных вставок блока отрабатывает лишь на их части, почему так происходит?
Почему бы не запустить код под отладчиком и не посмотреть сколько вставок блоков находит у вас код? GetBlockReferenceIds(true, true) не находит вложенные блоки. Это возможная причина.
Это я пробовал, полное число блоков с нужным именем - 77, с нужной установленной видимостью - 51. Фишка в том, что при фильтрации (удалении блоков с определенной видимостью-отображением) не все они удаляются из коллекции, а почему так происходит (что на это влияет) я никак не пойму. Вложенных блоков у меня нет - только сама вставка блока, получаемая либо копированием ранее вставленного, либо перетаскиванием в окно чертежа. Такие дела.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
tr.Commit()
Полностью с Вами согласен в случае создания объектов/модификации, но в моем случае - простой отбор, это может исказить результат?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Полностью с Вами согласен в случае создания объектов/модификации, но в моем случае - простой отбор, это может исказить результат?
Да.
P.S.: А зачем ты открываешь BlockReference для записи???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Подправил код,
Код - C# [Выбрать]
  1.         public static ObjectIdCollection SelectManholes2(string blockName)
  2.         {
  3.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  4.             Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.             ObjectIdCollection ids = new ObjectIdCollection();
  6.             using (Transaction tr = db.TransactionManager.StartTransaction())
  7.             {
  8.                
  9.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead); // это описание блока, здесь же имя
  11.  
  12.            
  13.                 if (btr.IsDynamicBlock)
  14.                 {
  15.                     // получаем все анонимные блоки динамического блока
  16.                     ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  17.                     // получаем все прямые вставки динамического блока
  18.                     ObjectIdCollection dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  19.                     foreach (ObjectId anonymousBtrId in anonymousIds)
  20.                     {
  21.                         // получаем анонимный блок
  22.                         BlockTableRecord anonymousBtr = (BlockTableRecord)tr.GetObject(anonymousBtrId, OpenMode.ForRead);
  23.                         // получаем все вставки анонимного блока
  24.                         ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  25.                         foreach (ObjectId id in blockRefIds)
  26.                         {
  27.                             dynBlockRefs.Add(id);
  28.                         }
  29.                     }
  30.  
  31.                     ids = dynBlockRefs;
  32.                     foreach (ObjectId entity in dynBlockRefs)
  33.                     {
  34.                         BlockReference bref = tr.GetObject(entity, OpenMode.ForRead, false, true) as BlockReference;
  35.                         DynamicBlockReferencePropertyCollection props = bref.DynamicBlockReferencePropertyCollection;
  36.                         foreach (DynamicBlockReferenceProperty prop in props)
  37.                         {
  38.                             //Switch Property
  39.                             if (prop.PropertyName.Contains("Visi") && !prop.ReadOnly)
  40.                             {
  41.                                 if (prop.Value.ToString().Contains("Vertical"))
  42.                                 {
  43.                                     ids.Remove(entity);
  44.                                 }
  45.                             }
  46.                         }
  47.                     }
  48.                 }
  49.                 tr.Commit();
  50.             }
  51.  
  52.             return ids;
  53.         }

Результат такой же часть блоков обрабатываются некорректно. Смотрел их внутренности MGDDBG, они идентичны (прикладываю скрин). В чем разница из-за которой код считает что они разные?! Я в тупике. Что можно еще попробовать?

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

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

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
У части блоков масштаб по X отличен от 1.0 - обычно это приводит к тому, что блок уже не рассматривается как динамический. Вполне возможно, что причина в этом.
Я думал об этом - в некоторых стоит (-1), но некорректное срабатывание есть и на тех где обычная 1. На приложенном мной скрине как раз такое - scale factors там (1,1,1) но не работает.

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Что показала отладка?
В том и фишка что ничего: есть 20 вставок блока всего, должно отфильтроваться 9 вставок. По итогу из них 5 отфильтрованы корректно, 4 не попали в фильтр. Они переключены в соответствующее visibility(для всех 9 одно и то же), но в DynamicBlockReferenceProperty приходит другое значение. Почему - я никак не врубаюсь.


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Что показала отладка?
В том и фишка что ничего: есть 20 вставок блока всего, должно отфильтроваться 9 вставок. По итогу из них 5 отфильтрованы корректно, 4 не попали в фильтр. Они переключены в соответствующее visibility(для всех 9 одно и то же), но в DynamicBlockReferenceProperty приходит другое значение. Почему - я никак не врубаюсь.
В чертеже 77 вставок блока "ManholeRev1". Про какие 20 ты говоришь?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Про какие 20 ты говоришь?
Мой тестовый пример - я сократил количество вставок чтобы не ходить по всем 77 отладчиком.