Editor.SelectAll с фильтром выбора примитивов и слоёв

Автор Тема: Editor.SelectAll с фильтром выбора примитивов и слоёв  (Прочитано 10157 раз)

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

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

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

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Как в фильтр для SelectAll добавить условие что бы в набор не попадали внешние ссылки?
что то типа такого...
но не работает(((
Код - C# [Выбрать]
  1. //...
  2. LayoutManager layoutMgr = LayoutManager.Current;
  3. //...
  4.  TypedValue[] filterlist = new TypedValue[5];
  5.                     filterlist[0] = new TypedValue(0, "INSERT");
  6.                     filterlist[1] = new TypedValue(410, layoutMgr.CurrentLayout);
  7.                     filterlist[2] = new TypedValue(-4, "<NOT");
  8.                     filterlist[3] = new TypedValue(1, "*");
  9.                     filterlist[4] = new TypedValue(-4, "NOT>");
  10.  
или без вариантов проверять на IsFromExternalReference?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
doctorRAZ,
Информация о том является ли блок внешней ссылкой не в INSERT, а в BLOCK. Так что таким образом отфильтровать не получится.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
doctorRAZ,
Кстати, не думаю, что Editor.SelectAll будет быстрее, чем итерация по ModelSpace/PaperSpace
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Кстати, не думаю, что Editor.SelectAll будет быстрее
Ты как всегда прав
Не далее как вчера тестировал эту тему
4000 вхождений дин блоков (2 определения)
660 000 примитивов на чертеже
Задача посчитать вхождения в пространстве
Код - C# [Выбрать]
  1.  public void CountBlc()
  2.         {
  3.             Document doc = Application.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.             if (doc == null) return;
  6.             Editor ed = doc.Editor;
  7.  
  8.             Stopwatch s = new Stopwatch();
  9.             int cnt = 0;
  10.             PromptKeywordOptions pko = new PromptKeywordOptions(
  11.                 "\nСпособ выбора блоков? ");
  12.             pko.AllowNone = false;
  13.             pko.Keywords.Add("Enum");
  14.             pko.Keywords.Add("enumRX");
  15.             pko.Keywords.Add("Selset");
  16.             pko.Keywords.Default = "Selset";
  17.             PromptResult pr = ed.GetKeywords(pko);
  18.  
  19.             if (pr.StringResult == "Selset")
  20.             {
  21.                 s.Start();
  22.                 LayoutManager layoutMgr = LayoutManager.Current;
  23.                 TypedValue[] filterlist = new TypedValue[2];//фильтр
  24.                 filterlist[0] = new TypedValue(0, "INSERT");//только блоки
  25.                 filterlist[1] = new TypedValue(410, layoutMgr.CurrentLayout);//только в текущем пространстве
  26.                 SelectionFilter filter = new SelectionFilter(filterlist);
  27.                 PromptSelectionResult psr = ed.SelectAll(filter);
  28.  
  29.                 if (psr.Status == PromptStatus.OK)
  30.                 {
  31.                     s.Stop();
  32.                     ed.WriteMessage("\nSelSet получен блоков {0} за {1}\n",
  33.                                     psr.Value.Count,
  34.                                     s.Elapsed
  35.                                     );
  36.                     s.Start();
  37.                     SelectionSet set = psr.Value;
  38.                     using (Transaction tr = db.TransactionManager.StartTransaction())//открываем транзакцию
  39.                     {
  40.                         foreach (ObjectId brId in set.GetObjectIds())//перебираем полученные ID блоков
  41.                         {
  42.                             BlockReference br = tr.GetObject(brId, OpenMode.ForRead) as BlockReference;//получаем вставку блока
  43.                             if (br != null)
  44.                             {
  45.                                 BlockTableRecord btr = tr.GetObject(
  46.                                     br.BlockTableRecord,
  47.                                     OpenMode.ForRead) as BlockTableRecord;//по вставке получаем описание блока
  48.                                 if (!btr.IsFromExternalReference
  49.                                     && !btr.IsDependent
  50.                                     )//если не внешняя сылка и не зависимый блок, считаем
  51.                                 {
  52.                                     cnt++;
  53.                                 }
  54.                             }
  55.                         }
  56.  
  57.                         s.Stop();
  58.                         ed.WriteMessage(
  59.                                      "\nSelSet Before Commit {0}\n",
  60.                                     s.Elapsed
  61.                                     );
  62.                         s.Start();
  63.  
  64.                         tr.Commit();
  65.  
  66.                         s.Stop();
  67.                         ed.WriteMessage(
  68.                                      "\nSelSet After Commit {0}\n",
  69.                                     s.Elapsed
  70.                                     );
  71.                         s.Start();
  72.                     }
  73.                 }
  74.  
  75.                 s.Stop();
  76.                 ed.WriteMessage("\nSelSet блоков {0} за {1}\n",
  77.                                 cnt,
  78.                                 s.Elapsed
  79.                                 );
  80.                 s.Start();
  81.             }
  82.             else if (pr.StringResult == "Enum")
  83.             {
  84.                 s.Start();
  85.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  86.                 {
  87.                     ObjectId SpaceId = db.CurrentSpaceId;//ID активного пространства
  88.  
  89.                     BlockTableRecord btrs = tr.GetObject(
  90.                                                 SpaceId,
  91.                                                 OpenMode.ForRead
  92.                                                 ) as BlockTableRecord;//получаем запись BlockTableRecord активного пространства
  93.  
  94.                     foreach (ObjectId brId in btrs)//в активном пространстве перебираем все что в нем находится
  95.                     {
  96.                         BlockReference br = tr.GetObject(brId, OpenMode.ForRead) as BlockReference;//пытаемся получить вставку блока
  97.                         if (br != null)
  98.                         {
  99.                             BlockTableRecord btr = tr.GetObject(
  100.                                 br.BlockTableRecord,
  101.                                 OpenMode.ForRead) as BlockTableRecord;//по вставке получаем описание блока
  102.                             if (!btr.IsFromExternalReference
  103.                                 && !btr.IsDependent
  104.                                 )//если не внешняя сылка и не зависимый блок, считаем
  105.                             {
  106.                                 cnt++;
  107.                             }
  108.                         }
  109.                     }
  110.                     s.Stop();
  111.  
  112.                     ed.WriteMessage(
  113.                      "\nEnum Before Commit {0}\n",
  114.                     s.Elapsed);
  115.  
  116.                     s.Start();
  117.  
  118.                     tr.Commit();
  119.  
  120.                     s.Stop();
  121.  
  122.                     ed.WriteMessage(
  123.                      "\nEnum After Commit {0}\n",
  124.                     s.Elapsed);
  125.  
  126.                     s.Start();
  127.                 }
  128.                 s.Stop();
  129.                 ed.WriteMessage(
  130.                  "\nEnum блоков {0} за {1}\n",
  131.                 cnt,
  132.                 s.Elapsed
  133.                 );
  134.  
  135.                 s.Start();
  136.             }
  137.             else if (pr.StringResult == "enumRX")
  138.             {
  139.                 s.Start();
  140.                 RXClass dimenClass = RXObject.GetClass(typeof(BlockReference));
  141.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  142.                 {
  143.                     ObjectId SpaceId = db.CurrentSpaceId;//ID активного пространства
  144.  
  145.                     BlockTableRecord btrs = tr.GetObject(
  146.                                                 SpaceId,
  147.                                                 OpenMode.ForRead
  148.                                                 ) as BlockTableRecord;//получаем запись BlockTableRecord активного пространства
  149.  
  150.                     foreach (ObjectId brId in btrs)//в активном пространстве перебираем все что в нем находится
  151.                     {
  152.                         //var objTest = brId.ObjectClass.Name;
  153.                         if (!brId.ObjectClass.IsDerivedFrom(dimenClass))
  154.                         {
  155.                             continue;
  156.                         }
  157.  
  158.  
  159.                         BlockReference br = tr.GetObject(brId, OpenMode.ForRead) as BlockReference;//пытаемся получить вставку блока
  160.                         if (br != null)
  161.                         {
  162.                             BlockTableRecord btr = tr.GetObject(
  163.                                 br.BlockTableRecord,
  164.                                 OpenMode.ForRead) as BlockTableRecord;//по вставке получаем описание блока
  165.                             if (!btr.IsFromExternalReference
  166.                                 && !btr.IsDependent
  167.                                 )//если не внешняя сылка и не зависимый блок, считаем
  168.                             {
  169.                                 cnt++;
  170.                             }
  171.                         }
  172.                     }
  173.                     s.Stop();
  174.  
  175.                     ed.WriteMessage(
  176.                      "\nEnumRX Before Commit {0}\n",
  177.                     s.Elapsed);
  178.  
  179.                     s.Start();
  180.  
  181.                     tr.Commit();
  182.  
  183.                     s.Stop();
  184.  
  185.                     ed.WriteMessage(
  186.                      "\nEnumRX After Commit {0}\n",
  187.                     s.Elapsed);
  188.  
  189.                     s.Start();
  190.                 }
  191.                 s.Stop();
  192.                 ed.WriteMessage(
  193.                  "\nEnumRX блоков {0} за {1}\n",
  194.                 cnt,
  195.                 s.Elapsed
  196.                 );
  197.  
  198.                 s.Start();
  199.             }
  200.             else
  201.             {
  202.                 ed.WriteMessage("\nОтмена");
  203.                 return;
  204.             }
  205.  
  206.             s.Stop();
  207.             ed.WriteMessage(
  208.                          "\nBefore Regen {0}\n",
  209.                         s.Elapsed
  210.                         );
  211.             s.Start();
  212.  
  213.             ed.Regen();
  214.  
  215.             s.Stop();
  216.             ed.WriteMessage(
  217.                  "\nTotal {0}",
  218.                 s.Elapsed
  219.                 );
  220.         }
  221.  
Результат
Цитировать
Способ выбора блоков? [Enum/enumRX/Selset] <Selset>: RX
  • EnumRX Before Commit 00:00:00.3504943
    EnumRX After Commit 00:00:00.3518743
    EnumRX блоков 4000 за 00:00:00.3518893
    Before Regen 00:00:00.3518897
    Выполняется регенерация модели.
    Total 00:00:10.8143822

Способ выбора блоков? [Enum/enumRX/Selset] <Selset>: E
  • Enum Before Commit 00:00:00.9359413
    Enum After Commit 00:00:01.0952777
    Enum блоков 4000 за 00:00:01.0952828
    Before Regen 00:00:01.0952828
    Выполняется регенерация модели.
    Total 00:00:11.4400038
Способ выбора блоков? [Enum/enumRX/Selset] <Selset>:
  • SelSet получен блоков 4000 за 00:00:00.9500616
    SelSet Before Commit 00:00:00.9636216
    SelSet After Commit 00:00:00.9647280
    SelSet блоков 4000 за 00:00:00.9647331
    Before Regen 00:00:00.9647331
    Выполняется регенерация модели.
    Total 00:00:12.2005454
если без учета регенерации прямой перебор с проверкой типа в три раза быстрее SelectAll (хотя наверное меньше, я же его выборку в цикле второй раз перебираю, но на самом деле мне не количество ведь надо)))
без открытия чертежа в редакторе еще быстрее.. regen то нет

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
doctorRAZ,
Только в твою выборку попадут не только вставки блоков, но и таблицы (Table наследник BlockReference).



Так что нужно быть осторожнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
(Table наследник BlockReference).
тогда так????
Table наследник BlockReference
Хех, точно...
Подумаю почитаю, как таблицы отловить
Спасибо

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

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

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Просто получилось
Код - C# [Выбрать]
  1. //вне  цикла
  2.                 RXClass blClass = RXObject.GetClass(typeof(BlockReference));
  3.                 RXClass tbClass = RXObject.GetClass(typeof(Table));
  4. //потом в цикле
  5.                 if (!brId.ObjectClass.IsDerivedFrom(blClass) || brId.ObjectClass.IsDerivedFrom(tbClass))
  6.                         {
  7.                             continue;
  8.                         }
  9.  

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Проверять не на наследование, а на равенство.
тогда так
Код - C# [Выбрать]
  1. RXClass blClass = RXObject.GetClass(typeof(MInsertBlock));
  2.  

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
RXClass blClass = RXObject.GetClass(typeof(MInsertBlock));
так не работает, ушел читать

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Александр предлагал просто сравнить равенство, для исключения наследников... что то типа
Код - C# [Выбрать]
  1. if (id.ObjectClass != RXObject.GetClass(typeof(BlockReference))){continue;}

Оффлайн doctorRAZ

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Александр предлагал просто сравнить равенство, для исключения наследников
Да спасибо, это работает, к тому же в AutoCAD еще один наследник появился
Код - C# [Выбрать]
  1. Autodesk.AutoCAD.DatabaseServices.DBObject
  2.     Autodesk.AutoCAD.DatabaseServices.Entity
  3.         Autodesk.AutoCAD.DatabaseServices.BlockReference
  4.             Autodesk.AutoCAD.DatabaseServices.MInsertBlock
  5.             Autodesk.AutoCAD.DatabaseServices.Table
  6.             Autodesk.AutoCAD.DatabaseServices.ViewRepBlockReference
  7.