Сообщество программистов Autodesk в СНГ

Статьи => Опубликованные статьи => Тема начата: Александр Ривилис от 21-12-2013, 17:30:03

Название: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Александр Ривилис от 21-12-2013, 17:30:03
Editor.SelectAll с фильтром выбора примитивов и слоёв
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 08:19:59
Как в фильтр для 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?
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Александр Ривилис от 26-08-2021, 12:28:44
doctorRAZ,
Информация о том является ли блок внешней ссылкой не в INSERT, а в BLOCK. Так что таким образом отфильтровать не получится.
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Александр Ривилис от 26-08-2021, 12:34:18
doctorRAZ,
Кстати, не думаю, что Editor.SelectAll будет быстрее, чем итерация по ModelSpace/PaperSpace
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 14:01:28
Кстати, не думаю, что 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 то нет
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Александр Ривилис от 26-08-2021, 14:25:00
doctorRAZ,
Только в твою выборку попадут не только вставки блоков, но и таблицы (Table наследник BlockReference).

(https://live.staticflickr.com/65535/51403547771_2f09e00431_o.png)

Так что нужно быть осторожнее.
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 15:24:41
(Table наследник BlockReference).
тогда так????
Table наследник BlockReference
Хех, точно...
Подумаю почитаю, как таблицы отловить
Спасибо
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Александр Ривилис от 26-08-2021, 15:34:47
тогда так?
Проверять не на наследование, а на равенство.
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 15:36:04
Просто получилось
Код - 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.  
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 15:38:19
Проверять не на наследование, а на равенство.
тогда так
Код - C# [Выбрать]
  1. RXClass blClass = RXObject.GetClass(typeof(MInsertBlock));
  2.  
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 26-08-2021, 16:51:38
RXClass blClass = RXObject.GetClass(typeof(MInsertBlock));
так не работает, ушел читать
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: Владимир Шу от 27-08-2021, 09:46:13
Александр предлагал просто сравнить равенство, для исключения наследников... что то типа
Код - C# [Выбрать]
  1. if (id.ObjectClass != RXObject.GetClass(typeof(BlockReference))){continue;}
Название: Re: Editor.SelectAll с фильтром выбора примитивов и слоёв
Отправлено: doctorRAZ от 27-08-2021, 10:36:40
Александр предлагал просто сравнить равенство, для исключения наследников
Да спасибо, это работает, к тому же в 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.