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

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 434
  • Карма: 1
Вот сокращенный пример с 20 вставками но от количества нет влияния. Я пробовал на разных.

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

  • ADN OPEN
  • ****
  • Сообщений: 434
  • Карма: 1
Это я пробовал, полное число блоков с нужным именем - 77, с нужной установленной видимостью - 51.
На полном файле тестировал сначала

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 434
  • Карма: 1
Явно какая-то проблема с блоком, но какая именно - сказать не могу.
Как так может быть технически? Если я правильно понимаю принцип работы блоков, то есть описание блока, которое для всех вставок одно и тоже. Как оно может для части вставок работать, а для другой нет? Ведь другого описания блока не существует.

Отмечено как Решение Atomohod 12-10-2021, 10:13:02

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

  • Administrator
  • *****
  • Сообщений: 13077
  • Карма: 1687
  • Рыцарь ObjectARX
  • Skype: rivilis
Ошибка в твоём коде. Проверь этот:
Код - 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 idsDynBlk = 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.           idsDynBlk.Add(id);
  28.         }
  29.       }
  30.  
  31.       foreach (ObjectId id in idsDynBlk)
  32.       {
  33.         BlockReference bref = tr.GetObject(id, OpenMode.ForRead) as BlockReference;
  34.         DynamicBlockReferencePropertyCollection props = bref.DynamicBlockReferencePropertyCollection;
  35.         foreach (DynamicBlockReferenceProperty prop in props)
  36.         {
  37.           if (prop.PropertyName.Contains("Visibility"))
  38.           {
  39.             if (prop.Value.ToString().StartsWith("Vertical"))
  40.             {
  41.               ids.Add(id);
  42.               break;
  43.             }
  44.           }
  45.         }
  46.       }
  47.     }
  48.     tr.Commit();
  49.   }
  50.  
  51.   return ids;
  52. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 434
  • Карма: 1
Заработало,
спасибо большое. То есть ошибка была в отсутствии break и вместо удаления из коллекции нужно было наоборот добавлять в новую? Верно?

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

  • ADN OPEN
  • ****
  • Сообщений: 434
  • Карма: 1
Еще заметил такой момент - внутри дин блока нарисованы два объекта, большой и менее габаритный. Однако вне зависимости от того какая видимость установлена, geometry extents всегда указаны по большему объекту. А как тогда получать габариты меньшего? Или это такой сбойный блок, вызывающий некорректное отображение габаритов?

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

  • Administrator
  • *****
  • Сообщений: 13077
  • Карма: 1687
  • Рыцарь ObjectARX
  • Skype: rivilis
То есть ошибка была в отсутствии break и вместо удаления из коллекции нужно было наоборот добавлять в новую? Верно?
Break - не влияло, но должно ускорить обработку. А вот с коллекциями хитрее. Похоже, что удаление из коллекции ids одновременно удаляло и из dynBlockRefs. И соответственно цикл по dynBlockRefs работал неправильно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13077
  • Карма: 1687
  • Рыцарь ObjectARX
  • Skype: rivilis
Однако вне зависимости от того какая видимость установлена, geometry extents всегда указаны по большему объекту.
Попробуй метод BlockReference.GeometryExtentsBestFit(). Мы это здесь обсуждали: https://adn-cis.org/forum/index.php?topic=10562.0
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение