Выбор набора примитивов по Entity

Автор Тема: Выбор набора примитивов по Entity  (Прочитано 9477 раз)

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

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
К примеру есть объект Entity

Мне нужно через класс SelectionSet выбрать подобные объекты
1) По слою. (Тут все мне понятно просто передать Entity.Layer)
2) По классу примитива. (А как быть с типом примитива?)

Как из объекта Entity взять информацию что это к примеру "LWPOLYLINE"?
Чтобы передать в фильтр объекта SelectionSet
 


Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Выбор набора примитивов по Entity
« Ответ #1 : 15-11-2017, 17:32:29 »
object.GetType().Name

Хотя, это не будет Dxf-имя...

В общем - подходов много на самом деле

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Выбор набора примитивов по Entity
« Ответ #2 : 15-11-2017, 17:40:28 »
А можно не использовать фильтр вообще, а просто перебрать все объекты в базе и взять те, которые подходят по условию. И могу сказать сразу - это быстро работает (если конечно не косячно сделать)
И говорю я так потому-что уже сто лет назад реализовал такую функцию. Надо видео сделать

В таком случае проверять то, что это нужный объект можно так
Код - C# [Выбрать]
  1. if(ent is Polyline polyline)
  2. {
  3. //....
  4. }
Или так
Код - C# [Выбрать]
  1. if(baseEnt.GetType().Equals(ent.GetType())
  2. {
  3. //....
  4. }
Ну и еще можно придумать варианты =)

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Выбор набора примитивов по Entity
« Ответ #3 : 15-11-2017, 17:47:14 »
А можно не использовать фильтр вообще, а просто перебрать все объекты в базе
А перебрать не медленнее будет чем SelectionSet?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #4 : 15-11-2017, 17:47:31 »
object.GetType().Name

Хотя, это не будет Dxf-имя...
Как-то так без проверки:
Код - C# [Выбрать]
  1. RXClass.GetClass(ent.GetType()).DxfName;
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #5 : 15-11-2017, 17:47:54 »
А перебрать не медленнее будет чем SelectionSet?
Будет намного быстрее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Выбор набора примитивов по Entity
« Ответ #6 : 16-11-2017, 21:04:14 »
А можно не использовать фильтр вообще, а просто перебрать все объекты в базе и взять те, которые подходят по условию. И могу сказать сразу - это быстро работает (если конечно не косячно сделать)

Есть код, как сделать это не "косячно"?
И ещё путаница небольшая есть. Чем отличается Entity от DBObject? DBObject это любой объект в базе? И пока что непонятно какой объект, а как только делаем as Entity то автокад стал понимать что перед ним например либо полилиния либо круг либо размер?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #7 : 16-11-2017, 22:48:19 »
Есть код, как сделать это не "косячно"?
А что такое "косячно"?
Чем отличается Entity от DBObject? DBObject это любой объект в базе?
Да. Например слой (LayerTableRecord) или блок (BlockTableRecord) или полилиния (Polyline), но только последний из них еще и примитив (Entity)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Выбор набора примитивов по Entity
« Ответ #8 : 17-11-2017, 06:49:23 »
А что такое "косячно"?
Не знаю. Александр написал, лишь бы сделать некосячно. Может нюансы есть.



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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Выбор набора примитивов по Entity
« Ответ #9 : 17-11-2017, 07:35:33 »
Чем отличается Entity от DBObject?
Я предполагаю, что Вы знакомы с основными принципами ООП и думаю для полной ясности кто и что, достаточно будет посмотреть диаграмму классов в файле ...\ObjectARX_20ХХ\classmap\classmap.dwg , раздел ObjectARX  20XX Managed Class Hierarchy

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Выбор набора примитивов по Entity
« Ответ #10 : 18-11-2017, 07:42:28 »
Чем отличается Entity от DBObject?
Я предполагаю, что Вы знакомы с основными принципами ООП и думаю для полной ясности кто и что, достаточно будет посмотреть диаграмму классов в файле ...\ObjectARX_20ХХ\classmap\classmap.dwg , раздел ObjectARX  20XX Managed Class Hierarchy
:) Не очень знаком. Но данная диаграммка полезная штука кое что прояснилось. Спасибо.

Т.е. у объекта не может быть слоя например. И так, как в коде ниже можно найти только объекты, потом из них сделать Entity и дальше отсеивать по слоям и XData?
Код - C# [Выбрать]
  1.          foreach (ObjectId id in btr)
  2.                 {
  3.                     if (id.ObjectClass.DxfName == "CIRCLE" && id... == "NameLayer")
  4.                     {
  5.                         ids.Add(id);
  6.                     }
  7.                 }
  8.  

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #11 : 18-11-2017, 09:41:14 »
И так, как в коде ниже можно найти только объекты, потом из них сделать Entity и дальше отсеивать по слоям и XData?
Ниже не код, а обрывок кода. Каким образом кто-то может узнать что такое btr и как ты его получил?
По типу примитива можно отобрать не открывая объект, а только зная его ObjectId. А вот чтобы проверить его слой или анализировать Xdata его придётся открыть (с транзакцией или без - не столь существенно).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Выбор набора примитивов по Entity
« Ответ #12 : 18-11-2017, 11:18:40 »
Прошу прощения.
Код - C# [Выбрать]
  1.             ObjectIdCollection ids = new ObjectIdCollection();
  2.             Database db = HostApplicationServices.WorkingDatabase;
  3.             using (Transaction tr = db.TransactionManager.StartTransaction())
  4.             {
  5.                 BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  6.                 BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  7.                 foreach (ObjectId id in btr)
  8.                 {
  9.                     if (id.ObjectClass.DxfName == "CIRCLE")
  10.                     {
  11.                         ids.Add(id);
  12.                     }
  13.                 }
  14.                 tr.Commit();
  15.             }
  16.             return ids;
  17.  

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #13 : 18-11-2017, 11:38:18 »
Это тоже огрызок, хотя и подлиннее. А вот это законченная функция:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Функция отбирает все окружности на заданном слое, имеющие расширенные данные заданного приложения
  3. /// </summary>
  4. /// <param name="layerName">Имя слоя</param>
  5. /// <param name="appname">Имя приложения</param>
  6. /// <returns></returns>
  7. static ObjectIdCollection GetAllCirclesOnLayerAndApplication(string layerName, string appname)
  8. {
  9.   ObjectIdCollection ids = new ObjectIdCollection();
  10.   Database db = HostApplicationServices.WorkingDatabase;
  11.   using (Transaction tr = db.TransactionManager.StartTransaction())
  12.   {
  13.     BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  14.     BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  15.     foreach (ObjectId id in btr)
  16.     {
  17.       if (id.ObjectClass.Name == RXClass.GetClass(typeof(Circle)).Name)
  18.       {
  19.         Circle circle = tr.GetObject(id, OpenMode.ForRead) as Circle;
  20.         if (circle.Layer.ToUpper() == layerName.ToUpper())
  21.         using (ResultBuffer rb = circle.GetXDataForApplication(appname))
  22.         {
  23.             if (rb != null) ids.Add(id);
  24.         }
  25.       }
  26.     }
  27.     tr.Commit();
  28.   }
  29.   return ids;
  30. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Выбор набора примитивов по Entity
« Ответ #14 : 18-11-2017, 12:27:41 »
Александр можете объяснить по этому фрагменту
Код - C# [Выбрать]
  1. ...
  2.     BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  3.     BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  4.     foreach (ObjectId id in btr)
  5.     {
  6.       if (id.ObjectClass.Name == RXClass.GetClass(typeof(Circle)).Name)
  7.       {
  8.         Circle circle = tr.GetObject(id, OpenMode.ForRead) as Circle;
  9. ...
  10. }

Код - C# [Выбрать]
  1. ObjectId id in btr
здесь id - это объект
А
Код - C# [Выбрать]
  1.  Circle circle = tr.GetObject(id, OpenMode.ForRead) as Circle;
здесь опять GetObject опять какой то объект получаем. Получается circle это ещё один какой то объект или это уже Entity. Или Entity он станет, когда написать circle as Entity.

И вообще проходясь циклом по BlockTableRecord
Код - C# [Выбрать]
  1. foreach (ObjectId id in btr)
вроде как находим объект circle внутри BlockTableRecord
а объект получаем почему то из транзакции
Код - C# [Выбрать]
  1. Circle circle = tr.GetObject(id,
В BlockTableRecord не хранятся сами объекты? Там только ссылки какие то?

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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Выбор набора примитивов по Entity
« Ответ #15 : 18-11-2017, 12:29:49 »
ObjectId - ссылка на объект
Код - C# [Выбрать]
  1. Circle circle = tr.GetObject(id, OpenMode.ForRead) as Circle;
Получение объекта по ссылке

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Re: Выбор набора примитивов по Entity
« Ответ #16 : 09-05-2022, 17:33:38 »
Здравствуйте, а можно пример на VB NET. Я знаю objectID а вот мне с этим делать не знаю? Надо выбрать примитив (блок) считать его имя, координаты и атрибут.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #17 : 09-05-2022, 18:18:45 »
Здравствуйте, а можно пример на VB NET. Я знаю objectID а вот мне с этим делать не знаю? Надо выбрать примитив (блок) считать его имя, координаты и атрибут.
Здесь все коды приведены из расчета использования AutoCAD .NET API, а не COM/ActiveX
Тебе нужно искать примеры на VBA и переводить их на VB.NET если собираешься и в дальнейшем использовать COM/ActiveX с AutoCAD. Так как этим практически никто не занимается, то тебе придется это делать самостоятельно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Re: Выбор набора примитивов по Entity
« Ответ #18 : 09-05-2022, 19:15:46 »
Не давно начал  разбираться и пока не понимаю в чём разница то есть где писать код, но спасибо за ответ.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #19 : 09-05-2022, 19:26:47 »
Не давно начал  разбираться и пока не понимаю в чём разница то есть где писать код, но спасибо за ответ.
Разница в том, что использовать AutoCAD .NET API можно только в dll-сборке, которая загружается внутрь AutoCAD (команда _NETLOAD). И возможностей в AutoCAD .NET API на порядок больше, чем в COM/ActiveX (которое можно использовать вне AutoCAD и которое или запускает AutoCAD или подключается к уже запущенному). Заодно сразу рекомендую изучать C# вместо VB.NET - даже по этому форуму видно, что из 10 программистов 9 использует C# и только одни VB.NET. И соответственно примеров на C# в 10 раз больше.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Re: Выбор набора примитивов по Entity
« Ответ #20 : 10-05-2022, 09:30:31 »
Я не профессиональный программист, я инженер ВК и попросту раньше баловался макросами. Вообще раньше автокад очень не любил различные надстройки - фатальной ошибкой часто завершалась работа и поэтому я не сторонник надстроек. Всю бьюсь над разбивкой листов программно и для этого мне нужны били свойства блоков и саму структуру я плохо понимаю автокада, но нашёл материалы от самого авкада и по ним всё получилось (только сбор данных создание листов и настройка ещё впереди)
Код - vb.net [Выбрать]
  1.         Dim msObj As AcadObject ' переменная для перебора примитивов модели
  2.         Dim CadBlock As AcadBlockReference ' переменная для получения информации по блокам
  3.  
  4.         For i = 0 To CadDoc.ModelSpace.Count - 1 'для всех объектов в простр. модели
  5.             msObj = CadDoc.ModelSpace.Item(i)
  6.             If (msObj.ObjectName = "AcDbBlockReference") Then ' проверяю что за примитив
  7.                 CadBlock = msObj ' и присваиваю его другой переменной, на прямую не получилось, тут же в принципе можно сортировать по имени и по слою
  8.                 grdPrint.Rows.Add()
  9.                 grdPrint.Rows(grdPrint.RowCount - 2).HeaderCell.Value = Str(grdPrint.RowCount - 1) ' просто счётчик
  10.                 grdPrint.Rows(grdPrint.RowCount - 2).Cells(0).Value = CadBlock.EffectiveName ' имя которое я дал блоку, а не то что сгенерировал автокад
  11.                 grdPrint.Rows(grdPrint.RowCount - 2).Cells(1).Value = "X_S=" & CadBlock.XScaleFactor & ", Y_S =" & CadBlock.YScaleFactor & ", Z_S =" & CadBlock.ZScaleFactor ' масштабы по осям
  12.                 grdPrint.Rows(grdPrint.RowCount - 2).Cells(2).Value = "X=" & CadBlock.InsertionPoint(0) & ", Y =" & CadBlock.InsertionPoint(1) & ", Z =" & CadBlock.InsertionPoint(2) ' точка вставки
  13.                 ' получаю атрибуты
  14.                 X = LBound(CadBlock.GetAttributes) ' значения доступных атрибутов
  15.                 Do Until X = UBound(CadBlock.GetAttributes) + 1
  16.                     grdPrint.Rows(grdPrint.RowCount - 2).Cells(3).Value = grdPrint.Rows(grdPrint.RowCount - 2).Cells(3).Value & CadBlock.GetAttributes(X).TagString & ", " & CadBlock.GetAttributes(X).TextString & ";"
  17.                     X = X + 1
  18.                 Loop
  19.             End If
  20.         Next

А читал тему тут про перебор всех примитивов в чертеже - но у меня не заработало (теперь знаю по чему). Перевожу данные из одного типа в другой просто знаком равенства. В общем код далёк от образца, но он работает правда иногда выскакивает исключение типа

тоже видел несколько Ваших постов, но пока не пойму как реализовать.

В общем я искал как обратиться по ObjectID а оказалось надо сразу менять тип переменной и считывать свойства.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Re: Выбор набора примитивов по Entity
« Ответ #21 : 10-05-2022, 12:41:16 »
А это точно VB.NET, а не VBA?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Выбор набора примитивов по Entity
« Ответ #22 : 10-05-2022, 13:23:17 »
но он работает правда иногда выскакивает исключение типа
Стандартное исключение, которое возникает при работе через COM/ActiveX.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Re: Выбор набора примитивов по Entity
« Ответ #23 : 10-05-2022, 14:15:40 »
Алексей Кулик, Visual Studio 2017 да поэтому и начал и продолжаю VB.NET так как в те далёкие года макросы были более распространены

Примеры оказывается лежат вот тут "Program Files\Common Files\Autodesk Shared" и вот по ним я более или менее стал понимать структуру обращения и именование примитивов, ну как стал понимать )) просто получилось извлечь данные.

DLL наверное хорошая вещь, я вот смотрю и понимаю что Civil наверное на нём построен, но надо отделать графику от расчётов, он в какой то момент начинает ужасно тормозить при любых манипуляциях. Это уже не по теме. Спасибо за помощь с клонированием листа Александр я видел Ваш ответ, но пока не пробовал.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Re: Выбор набора примитивов по Entity
« Ответ #24 : 11-05-2022, 11:56:05 »
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Re: Выбор набора примитивов по Entity
« Ответ #25 : 14-06-2022, 18:46:14 »
Алексей Кулик, помогло, спасибо, пока пробую и извлекаю полезное