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

ADN Club => AutoCAD .NET API => Тема начата: Kirill2001 от 16-07-2024, 07:59:51

Название: Доработка формы поиска
Отправлено: Kirill2001 от 16-07-2024, 07:59:51
Доброго времени суток!
Дорабатываю свою программу по поиску текста на чертеже. МТекст и обычный текст ищет, но в блоках не ищет. Как можно пройтись по ModelSpace и обратиться к тексту в блоках и найти текст в блоках??. С выводом результата поиска в блоках в datagridwiew
Собственно код как у меня написан поиск текста.
Код - C# [Выбрать]
  1.         foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.             {
  3.                 AcadLayout val = item;
  4.  
  5.                 IAcadBlock block = val.Block;
  6.  
  7.                 foreach (AcadEntity item2 in block)
  8.                 {
  9.                
  10.                     AcadEntity val2 = item2;
  11.  
  12.  Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  13.  
  14.  
Название: Re: Доработка формы поиска
Отправлено: avc от 16-07-2024, 08:09:37
Я бы порекомендовал не по модели искать, по всем блокам. Открыть таблицу блоков (BlockTable) и перебрать все блоки (BlockTableRecord) и их содержимое. А уж дальше по желанию - выводить в список только блоки вставленные в модель или все подряд. Для каждой BTR можно посмотреть все ее ссылки (BlockReference)
 - метод GetBlockReferenceIds
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 16-07-2024, 09:10:48
Вот так


Код - C# [Выбрать]
  1. HostMgd.ApplicationServices.Document doc = HostMgd.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  2. Database dbase = doc.Database;
  3.  
  4. using (Transaction trans = dbase.TransactionManager.StartTransaction())
  5. {
  6.     BlockTable blockTable = trans.GetObject(dbase.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead) as BlockTable;
  7.  
  8.     foreach (ObjectId blockRecId in blockTable)
  9.     {
  10.         BlockTableRecord blockRec = trans.GetObject(blockRecId, Teigha.DatabaseServices.OpenMode.ForRead) as BlockTableRecord;
  11.  
  12.         foreach (ObjectId entId in blockRec)
  13.         {
  14.  

AcadEntity не принимает значений ObjectId. Как вывести блочный текст найденный в datagridview?

Название: Re: Доработка формы поиска
Отправлено: Владимир Шу от 16-07-2024, 12:31:37
Kirill2001, Вас вот за это "Teigha" на этом форуме сильно приветливо не встретят...
А так, для проверки типа объекта, совсем не обязательно его открывать:
if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) , а выяснив тип объекта,
можно его открывать не как Entity, а как Mtext или какие еще у вас там должны быть объекты

А и еще, нужно понимать разницу между СОМ объектам и .NET и если их смешиваешь, то делай это осознано.
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 16-07-2024, 15:14:49
Можно пожалуйста по конкретнее, как по средствам Odax можно получить доступ к описанию блоков через AcadEntity, IAcadBlock  ?
Код - C# [Выбрать]
  1.  
  2. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  3.  IAcadBlock block = val.Block;
  4.  
  5.   foreach (AcadEntity item2 in block)
  6.   {
  7.  
  8.       AcadEntity val2 = item2;
  9.  
Так у меня не получается добраться до текста в блоках. Как этот код использовать if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) не очень понимаю
Название: Re: Доработка формы поиска
Отправлено: Владимир Шу от 16-07-2024, 16:12:49
Вот это очень, очень упрощенный код... специально написанный, как можно проще и понятнее для Вас.
Правильнее делать по другому, но судя по Вашим вопросам, лучше вот так.

Код - C# [Выбрать]
  1.       App.Document doc = App.Application.DocumentManager.MdiActiveDocument;
  2.       Db.Database db = doc.Database;
  3.       Ed.Editor ed = doc.Editor;
  4.  
  5.       Db.ObjectId modelSpaceId = Db.SymbolUtilityServices.GetBlockModelSpaceId(db);
  6.  
  7.       using (Db.Transaction tr = db.TransactionManager.StartTransaction())
  8.       {
  9.         //Открываем пространство модели
  10.         using (var ms = tr.GetObject(modelSpaceId, Db.OpenMode.ForRead) as Db.BlockTableRecord)
  11.         {
  12.           //Перебираем все объекты в модели
  13.           foreach (Db.ObjectId entId in ms)
  14.           {
  15.             //если не блок, то пропускаем
  16.             if (entId.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.BlockReference))) continue;
  17.  
  18.             Db.ObjectId btrId = Db.ObjectId.Null;
  19.  
  20.             //Открываем блок и получаем ссылку на его описание
  21.             using (var br = tr.GetObject(entId, Db.OpenMode.ForRead) as Db.BlockReference)
  22.             {
  23.               btrId = br.BlockTableRecord;
  24.             }
  25.  
  26.             //Открывает описание блока
  27.             using (var btr = tr.GetObject(btrId, Db.OpenMode.ForRead) as Db.BlockTableRecord)
  28.             {
  29.               //Перебираем содержимое описания блока
  30.               foreach (Db.ObjectId id in btr)
  31.               {
  32.                 //Если это не текст, то пропускаем
  33.                 if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) continue;
  34.  
  35.                 //Открываем текст и получаем его содержимое
  36.                 using (var mtext = tr.GetObject(id, Db.OpenMode.ForRead) as Db.MText)
  37.                 {
  38.                   //Содержимое текста
  39.                   string text = mtext.Contents.ToString();
  40.                 }
  41.               }
  42.             }
  43.           }
  44.         }
  45.  
  46.         tr.Commit();
  47.       }
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 17-07-2024, 11:31:48
Спасибо)! Пытаюсь вывести результаты поиска в datagriview криво выводит.
Код - C# [Выбрать]
  1.  Grid.Rows.Add(text5, Conversions.ToString(checked(Grid.Rows.Count - 0)));
Может надо создать отдельный класс для поиска блоков.

Код - C# [Выбрать]
  1.                                AcadEntity val2 = item2;
  2.  
  3. if (LikeOperator.LikeString(Versioned.TypeName(val2), "*IAcad*Text*", CompareMethod.Binary) && LikeOperator.LikeString(Strings.LCase(Cable_Net.Привести_к_Русскому_без_пробелов(Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)))), pattern, CompareMethod.Binary))
  4.  
  5.                                {
  6.                                    ModuleZoom.Найдено = true;
  7.  
  8. string text3 = ((!LikeOperator.LikeString(Versioned.TypeName(val2), "IAcadMText*", CompareMethod.Binary)) ? Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)) : searchBox.Text);
  9.  
  10.                                    string name = val.Name;
  11.                                    string handle = val2.Handle;
  12.  
  13.              Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  14.  
  15.                                }
  16.                            }
  17.                        }

Подскажите пожалуйста как результаты поиска в блоках встроить в мой уже существующий поиск. У меня получается пересечение каша. И поиск тормозит 5 сек на одну позицию ?
Название: Re: Доработка формы поиска
Отправлено: Владимир Шу от 17-07-2024, 12:23:02
Kirill2001, если Вы хотите получить помощь, то прикладывайте полный код в котором у Вас возникают проблемы, а не какие-то непонятные обрывки.  Уважайте чужое время, это Вам нужно, что бы другие люди смогли запустить Ваш код у себя и подсказали Вам, что нужно поправить.
Название: Re: Доработка формы поиска
Отправлено: trir от 17-07-2024, 13:36:48
Что значит искать в блоках? Искать в описании или атрибутах?
Если искать в описании - сначала получаем список описаний блоков, а потом для найденных описаний - находим вставки (если они есть)
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 17-07-2024, 14:26:48
Нужен Текст и Мтекст получается в описании искать. Атрибуты не нужны (настройки). Получается нужно описание, например - в блоке "50 шп. смотри в нос" и таких блоков и выносок много
Название: Re: Доработка формы поиска
Отправлено: Александр Ривилис от 17-07-2024, 17:15:16
Kirill2001,
Прочитай правило форматирования кода на нашем форуме и неукоснительно соблюдай его. Мне надоело править твой текст.
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 18-07-2024, 18:51:08
Спасибо! Вопрос решился. Код работает
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 25-07-2024, 10:57:40
Не пойму, что делал неправильно вот код без транзакций, блоки находи. Но теперь местоположение layouts не показывает при нажатии на найденную позицию в datagridview. Мтекст находит но символы в ячейке datagridview  отображаются пустыми


Код - C# [Выбрать]
  1. foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.                 {
  3.                         AcadLayout val = item;
  4.                         AcadBlock block = ((IAcadLayout)val).Block;
На выходе получаю одинаковые строки если добавить AcadLayout


Код - C# [Выбрать]
  1. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  2. foreach (AcadBlock item in ModuleZoom.ThisDrawing.Blocks)
  3. {
  4.     AcadBlock val = item;
  5.  
  6.     foreach (AcadEntity item2 in val)
  7.     {
  8.         AcadEntity val2 = item2;
  9. internal static void ActivViePortLock()
  10. {
  11.     if (LikeOperator.LikeString(ThisDrawing.ActiveLayout.Block.Name, "*Paper*", CompareMethod.Binary) && ThisDrawing.MSpace)
  12.     {
  13.         ThisDrawing.MSpace = false;
  14.     }
  15.            string name = val.Name;
  16.  
  17.            string handle = val2.Handle;
  18.  
  19. Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  20.  

Как сделать так что бы и блоки искало и местоположение показывало при нажатии на найденный текст в ячейке :) ?
Название: Re: Доработка формы поиска
Отправлено: Алексей Кулик от 26-07-2024, 10:46:49
Не пойму, что делал неправильно вот код без транзакций, блоки находи. Но теперь местоположение layouts не показывает при нажатии на найденную позицию в datagridview. Мтекст находит но символы в ячейке datagridview  отображаются пустыми


Код - C# [Выбрать]
  1. foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.                 {
  3.                         AcadLayout val = item;
  4.                         AcadBlock block = ((IAcadLayout)val).Block;
На выходе получаю одинаковые строки если добавить AcadLayout


Код - C# [Выбрать]
  1. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  2. foreach (AcadBlock item in ModuleZoom.ThisDrawing.Blocks)
  3. {
  4.     AcadBlock val = item;
  5.  
  6.     foreach (AcadEntity item2 in val)
  7.     {
  8.         AcadEntity val2 = item2;
  9. internal static void ActivViePortLock()
  10. {
  11.     if (LikeOperator.LikeString(ThisDrawing.ActiveLayout.Block.Name, "*Paper*", CompareMethod.Binary) && ThisDrawing.MSpace)
  12.     {
  13.         ThisDrawing.MSpace = false;
  14.     }
  15.            string name = val.Name;
  16.  
  17.            string handle = val2.Handle;
  18.  
  19. Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  20.  

Как сделать так что бы и блоки искало и местоположение показывало при нажатии на найденный текст в ячейке :) ?
Очень похоже на работу с CAD через COM вместо того, чтоб работать "напрямую". Напоминает вырезание гланд автогеном.
---
Добавлено: и есть логический вопрос - один и тот же текст входит в описания 2 разных блоков. Первый вставлен 2 раза - один раз в пространстве модели, второй раз - внутри третьего блока. Второй блок вообще не имеет вхождений. Чего делать надо?
Название: Re: Доработка формы поиска
Отправлено: Kirill2001 от 26-07-2024, 11:37:51
Как привести val2 ?  И дальше прогнать по алгоритму приведенному ниже. И вывести в грид найденное в чертеже в описании блоков(мтекст, текст).
Код - C# [Выбрать]
  1. if (LikeOperator.LikeString(Versioned.TypeName(val2), "*IAcad*Text*", CompareMethod.Binary) && LikeOperator.LikeString(Strings.LCase(Cable_Net.Привести_к_Русскому_без_пробелов(Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)))), pattern, CompareMethod.Binary))
  2.  
  3.                     {
  4.                  ModuleZoom.Найдено = true;
  5.  
  6.  string text3 = ((!LikeOperator.LikeString(Versioned.TypeName(val2), "IAcadMText*", CompareMethod.Binary)) ? Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)) : searchBox.Text);
  7.  string name = val.Name;
  8.  
  9.  string handle = val2.Handle;
  10.  
  11.  Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  12.  

У меня находит текст на чертеже и даже местоположение указывает, если итерацию в layout задать . Только найденные значения повторяются по много раз.  Итерация не заканчивается. На чертеже находит больше 70к объектов
Название: Re: Доработка формы поиска
Отправлено: Алексей Кулик от 26-07-2024, 12:31:30
Как привести val2 ?  И дальше прогнать по алгоритму приведенному ниже. И вывести в грид найденное в чертеже в описании блоков(мтекст, текст).
Код - C# [Выбрать]
  1. if (LikeOperator.LikeString(Versioned.TypeName(val2), "*IAcad*Text*", CompareMethod.Binary) && LikeOperator.LikeString(Strings.LCase(Cable_Net.Привести_к_Русскому_без_пробелов(Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)))), pattern, CompareMethod.Binary))
  2.  
  3.                     {
  4.                  ModuleZoom.Найдено = true;
  5.  
  6.  string text3 = ((!LikeOperator.LikeString(Versioned.TypeName(val2), "IAcadMText*", CompareMethod.Binary)) ? Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)) : searchBox.Text);
  7.  string name = val.Name;
  8.  
  9.  string handle = val2.Handle;
  10.  
  11.  Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  12.  

У меня находит текст на чертеже и даже местоположение указывает, если итерацию в layout задать . Только найденные значения повторяются по много раз.  Итерация не заканчивается. На чертеже находит больше 70к объектов

Угу, а проверять наличие такого же текста - никак?
Название: Re: Доработка формы поиска
Отправлено: trir от 26-07-2024, 14:43:41
Цитировать
местоположение layouts
Чё? :o