Найти все примитивы, по типу, из которых состоят блоки в чертеже.

Автор Тема: Найти все примитивы, по типу, из которых состоят блоки в чертеже.  (Прочитано 9319 раз)

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

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

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Добрый день,
Может у кого есть процедура или подскажите.
В чертеже есть много разных блоков, но отрисованных по одним правилам (слои и пр.).
В каких-то блоках есть точки.
Задача - как можно выбрать точки у блоков, на определенном слое?
Т.е. на выходе должна быть таблица:
Имя блока / Слой точки в блоке / Координаты точки в блоке / хэндл точки

или например найти весь текст в блоках:
Имя блока / Слой текста / Текст / хэндл текста

Спасибо.
Пытаюсь на vb.net сделать - но что-то тупик

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
pavelii,
Сформулируйте нормально задачу - тогда будут шансы найти решение. И сразу рекомендую забыть про VB.NET и изучать C#.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Например в проекте есть 1000 блоков (разных, но часть может повторяться).
В каждом блоке, на слое Х есть объект Point. Но может и не быть (пусть у 90% есть).
Задача - найти координаты этой точки в МСК у каждого блока.

С vb проще (я когда то знал vba и lisp), в моем возрасте c# уже не реально изучить ))
Если есть пример на c# то думаю смогу разобраться в логике ))

Да - и надо чтобы это все быстро работало.

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
опять путаем вставку и описание

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
pavelii,
Вы оперируете своими терминами, а не терминами AutoCAD.
1) Что такое "проект"? Это чертеж AutoCAD (dwg-файл)?
2) Речь идет о вставках блоков в Пространство Модели чертежа AutoCAD?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Вы оперируете своими терминами, а не терминами AutoCAD.
1) Что такое "проект"? Это чертеж AutoCAD (dwg-файл)?
2) Речь идет о вставках блоков в Пространство Модели чертежа AutoCAD?

Прошу прощения, впредь буду оперировать терминами AutoCAD.
1. Да - это чертеж AutoCAD.
2. Да - блоки вставлены в пространстве модели.

Вставку и описание - не путаю, в чем разница прекрасно понимаю.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
pavelii,
Ну тогда не вижу проблемы.
1. Проходишь по всем примитивам в пространстве модели
2. Если примитив  - BlockReference, то обрабатываешь его, если нет переходишь к следующему.
3. Находишь для BlockReference соответствующий BlockTableRecord (метод BlockReference.BlockTableRecord возвращает ObjectId для соответствующий BlockTableRecord)
4. Проходишь по всем примитивам в  BlockTableRecord и находишь там все DBPoint со слоем X
5. Для каждой DBPoint используя метод DBPoint.Position находишь ее координаты в блоке. Чтобы получить реальные координаты в МСК нужно выполнить трансформацию этой координаты по матрице BlockReference.BlockTransform.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Спасибо,
но на п.3 у меня затык - нет метода BlockTableRecord у BlockReference
а п.1,2 я сделал через селекшнсет по фильтру.
по п.4,5 все понятно

Вложил картинку с кодом, как вложение - как картинка почему-то не добавляется.
в проекте 2 ссылки на dll
C:\Program Files\Autodesk\AutoCAD 2022\Autodesk.AutoCAD.Interop.Common.dll
C:\Program Files\Autodesk\AutoCAD 2022\Autodesk.AutoCAD.Interop.dll

                                Dim sset As AutoCAD.AcadSelectionSet
                                Dim filterData(1) As Object
                                filterData(0) = "INSERT"
                                filterData(1) = "Model"
                                Dim filterType(1) As Short
                                filterType(0) = 0
                                filterType(1) = 410
                                sset = AcadDoc.SelectionSets.Add("MySel")
                                sset.Select(AutoCAD.AcSelect.acSelectionSetAll,,, filterType, filterData) 'выбираю в чертеже все блоки в модели
                                Dim i As Integer
                                Dim MyBl As AutoCAD.AcadBlockReference
                                Dim Bl_ID As Object
                                For i = 0 To sset.Count - 1
                                    MyBl = sset.Item(i) 'беру i-й блок
                                    Bl_ID = MyBl.BlockTableRecord
                                Next
                                sset.Delete()

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

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

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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Я немного поискал ко форуму и в той или иной мере все необходимые коды для выполнения Вашей задачи уже опубликованы, нужно только свести все это вместе...
В итоге Ваш код должен выглядеть как то так (я не проверял на работоспособность):
Код - C# [Выбрать]
  1. using App = Autodesk.AutoCAD.ApplicationServices;
  2. using Db = Autodesk.AutoCAD.DatabaseServices;
  3. using Rtm = Autodesk.AutoCAD.Runtime;
  4.  
  5. [assembly: Rtm.CommandClass(typeof(Tester.Commands))]
  6.  
  7. namespace Tester
  8. {
  9.   public static class Commands
  10.   {
  11.  
  12.     [Rtm.CommandMethod("test")]
  13.     public static void test()
  14.     {
  15.       // Получение текущего документа и базы данных
  16.       App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  17.       if (acDoc == null) return;
  18.       Db.Database acCurDb = acDoc.Database;
  19.  
  20.       using (var ms = acCurDb.CurrentSpaceId.Open(Db.OpenMode.ForRead)
  21.                                                         as Db.BlockTableRecord)
  22.       {
  23.         foreach (var id in ms)
  24.         {
  25.           if (id.ObjectClass != Rtm.RXClass.GetClass(typeof(Db.BlockReference)))
  26.             continue;
  27.  
  28.           //нашли вставку блока
  29.           using (var br = id.Open(Db.OpenMode.ForRead) as Db.BlockReference)
  30.           {
  31.             //Открыли описание блока
  32.             using (var btr = br.BlockTableRecord.Open(Db.OpenMode.ForRead)
  33.                                                         as Db.BlockTableRecord)
  34.             {
  35.               foreach (var btrId in btr)
  36.               {
  37.                 if (id.ObjectClass != Rtm.RXClass.GetClass(typeof(Db.DBPoint)))
  38.                   continue;
  39.                 //открыли точку
  40.                 using (var p = btrId.Open(Db.OpenMode.ForRead) as Db.DBPoint)
  41.                 {
  42.                   var blockName = br.GetEffectiveName();
  43.                   var pointLayer = p.Layer;
  44.                   var pointPosition = p.Position.TransformBy(br.BlockTransform);
  45.                   var pointHandle = p.Handle;
  46.                 }
  47.               }
  48.             }
  49.           }
  50.         }
  51.       }
  52.  
  53.       acDoc.Editor.WriteMessage("\nDone!");
  54.     }
  55.     public static string GetEffectiveName(this Db.BlockReference br)
  56.     {
  57.       string result = "NAN";
  58.       Db.ObjectId id = br.BlockTableRecord;
  59.       if (br.IsDynamicBlock)
  60.         id = br.DynamicBlockTableRecord;
  61.  
  62.       using (Db.BlockTableRecord btr = id.Open(Db.OpenMode.ForRead, true)
  63.                                                   as Db.BlockTableRecord)
  64.         result = btr.Name;
  65.  
  66.       return result;
  67.     }
  68.   }
  69. }
  70.  

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

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Спасибо большое, буду разбираться.

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Это выкопировка из моей проги, она ищет динамические блоки для создания спецификации. Фрагменты кода собирал по справке, по инету, но в принципе по имени динамического блока выписываются нужные мне параметры блока и самое главное я вижу его координаты
Код - vb.net [Выбрать]
  1. Private Sub F_Block_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  2.         SetDoubleBuffered(grdBlock)
  3.  
  4.         acApp = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  5.         CadDoc = acApp.ActiveDocument
  6.         CadSelectionSet = CadDoc.SelectionSets.Add("SpecBlockSelect") ' создаю именнованный выбор
  7.  
  8.         Refresh_Load()
  9.     End Sub
  10.  
  11.  Private Sub tsFind_Click(sender As Object, e As EventArgs) Handles tsFind.Click
  12.         CadDoc.SendCommand("РЕГЕН" & vbCr) ' пытаюсь обновить атрибуты, так как угол считывается только после регенерации модели
  13.  
  14.         Dim F1(0) As Short
  15.         Dim F2(0) As Object
  16.         If tsBlock.Text <> "" Then
  17.             ' для выбора по блоку и по слою
  18.             ' F1(0) = 0 ' поиск по слою
  19.             ' F2(0) = "INSERT" ' "BLOCK"
  20.             ' F1(1) = 8 ' поиск по имени 2
  21.             ' F2(1) = tsLayer.Text ' tsBlock.Text ' F2(1) = "`*U*," & tsBlock.Text
  22.  
  23.             ' для выбора по блоку
  24.             F1(0) = 0 ' поиск по слою
  25.             F2(0) = "INSERT" ' "BLOCK"
  26.         Else
  27.             MsgBox("Блок не выбран, продолжеие не возможно", vbOKOnly + vbCritical, "Сбор данных")
  28.             Exit Sub
  29.         End If
  30.         CadSelectionSet.Select(AcSelect.acSelectionSetAll, , , F1, F2)
  31.         lblFind.Text = "Всего блоков на слое " & CStr(CadSelectionSet.Count)
  32.  
  33.         Dim CadBlock As AcadBlockReference
  34.  
  35.         pbStatus.Visible = True
  36.         tsStatus.Text = "Чтение данных блоков"
  37.         tsStatus.Visible = True
  38.         pbStatus.Value = 0
  39.         pbStatus.Maximum = CadSelectionSet.Count
  40.  
  41.         grdBlock.Rows.Clear()
  42.         grdBlock.Columns(9).HeaderText = ""
  43.         grdBlock.Columns(10).HeaderText = ""
  44.         grdBlock.Columns(11).HeaderText = ""
  45.         grdBlock.Columns(12).HeaderText = ""
  46.         grdBlock.Columns(13).HeaderText = ""
  47.         grdBlock.Columns(14).HeaderText = ""
  48.         grdBlock.Columns(15).HeaderText = ""
  49.         grdBlock.Columns(16).HeaderText = ""
  50.         grdBlock.Columns(17).HeaderText = ""
  51.         grdBlock.Columns(18).HeaderText = ""
  52.         grdBlock.Columns(19).HeaderText = ""
  53.         grdBlock.Columns(20).HeaderText = ""
  54.  
  55.         For i = 0 To CadSelectionSet.Count - 1 'для всех объектов в простр. модели
  56.             ' If (CadSelectionSet.Item(i).ObjectName = "AcDbBlockReference") Then ' выбираю именно блоки
  57.             CadBlock = CadSelectionSet.Item(i) ' назначаю так как только объекты можно перебирать
  58.             If (CadBlock.EffectiveName = tsBlock.Text) Then ' получаю видимое в свойствах имя блока
  59.                 grdBlock.Rows.Add()
  60.                 grdBlock.Rows(grdBlock.RowCount - 1).HeaderCell.Value = Str(grdBlock.RowCount)
  61.  
  62.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(0).Value = CadBlock.Name & " слой " & CadBlock.Layer
  63.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(1).Value = CadBlock.EffectiveName
  64.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(2).Value = FormatNumber(CadBlock.InsertionPoint(0), 2) ' координата Х
  65.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(3).Value = FormatNumber(CadBlock.InsertionPoint(1), 2) ' координата Y
  66.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(4).Value = FormatNumber(CadBlock.InsertionPoint(2), 2) ' координата Z
  67.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(5).Value = CadBlock.XScaleFactor ' масштаб блока по Х
  68.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(6).Value = CadBlock.YScaleFactor ' масштаб блока по Y
  69.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(7).Value = CadBlock.ZScaleFactor ' масштаб блока по Z
  70.                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(8).Value = FormatNumber(CadBlock.Rotation * 180 / Math.PI, 2) ' угол
  71.  
  72.                 ' получаю параметры
  73.                 Dim oBlockRef As IAcadBlockReference = CadBlock
  74.                 Dim Props
  75.                 With oBlockRef
  76.                     If .IsDynamicBlock = True Then
  77.                         Props = .GetDynamicBlockProperties
  78.  
  79.                         Y = 9
  80.                         For Index = LBound(Props) To UBound(Props)
  81.                             Dim oProp As AcadDynamicBlockReferenceProperty
  82.  
  83.                             oProp = Props(Index)
  84.  
  85.                             'is the value an array for an insertion point
  86.                             If IsArray(oProp.Value) Then
  87.                                 Dim SubIndex As Long
  88.  
  89.                                 For SubIndex = LBound(oProp.Value) To UBound(oProp.Value)
  90.                                     ' grdBlock.Rows(grdBlock.RowCount - 1).Cells(10).Value = grdBlock.Rows(grdBlock.RowCount - 1).Cells(10).Value & oProp.PropertyName & ", " & oProp.Value(SubIndex)
  91.                                 Next SubIndex
  92.  
  93.                             Else
  94.                                 grdBlock.Rows(grdBlock.RowCount - 1).Cells(Y).Value = oProp.Value
  95.                                 grdBlock.Columns(Y).HeaderText = oProp.PropertyName
  96.                                 If Len(oProp.PropertyName) > 4 Then ' пробую отловить и перевести углы из ражианов в градусы
  97.                                     If Mid(oProp.PropertyName, 1, 4) = "Угол" Then
  98.                                         grdBlock.Rows(grdBlock.RowCount - 1).Cells(Y).Value = FormatNumber(grdBlock.Rows(grdBlock.RowCount - 1).Cells(Y).Value * 180 / Math.PI, 2) ' угол
  99.                                     End If
  100.                                 End If
  101.                                 Y = Y + 1
  102.                             End If
  103.                         Next Index
  104.                     End If
  105.                 End With
  106.             End If
  107.  
  108.             ' End If
  109.             pbStatus.Value = i
  110.             Windows.Forms.Application.DoEvents()
  111.         Next
  112.         lblFind.Text = lblFind.Text & ". Выбрано - " & grdBlock.RowCount
  113.  
  114.         Y = 0
  115.         Do Until Y = grdBlock.ColumnCount
  116.             If grdBlock.Columns(Y).HeaderText = "" Then
  117.                 grdBlock.Columns(Y).Visible = False
  118.             Else
  119.                 grdBlock.Columns(Y).Visible = True
  120.             End If
  121.             Y = Y + 1
  122.         Loop
  123.         CadSelectionSet.Clear() ' Почистим выборку
  124.         tsStatus.Visible = False
  125.         pbStatus.Visible = False
  126.     End Sub
  127. ' ещё часть кода, заполняю combobox именами просто я искал именно определённые блоки, есть ещё пример, но там много информации считывается в общем код чистить устану
  128. Private Sub Refresh_Load()
  129.         ' форматирую картинки блокоВ, так как далее буду обрабатывать
  130.         picCapka.Enabled = False
  131.         picCapka.BorderStyle = Windows.Forms.BorderStyle.None
  132.         picCol.Enabled = False
  133.         picCol.BorderStyle = Windows.Forms.BorderStyle.None
  134.         picFlanecP.Enabled = False
  135.         picFlanecP.BorderStyle = Windows.Forms.BorderStyle.None
  136.         picFlanecS.Enabled = False
  137.         picFlanecS.BorderStyle = Windows.Forms.BorderStyle.None
  138.         picGrib.Enabled = False
  139.         picGrib.BorderStyle = Windows.Forms.BorderStyle.None
  140.         picKrest.Enabled = False
  141.         picKrest.BorderStyle = Windows.Forms.BorderStyle.None
  142.         picPerehod.Enabled = False
  143.         picPerehod.BorderStyle = Windows.Forms.BorderStyle.None
  144.         picPG.Enabled = False
  145.         picPG.BorderStyle = Windows.Forms.BorderStyle.None
  146.         picRamka.Enabled = False
  147.         picRamka.BorderStyle = Windows.Forms.BorderStyle.None
  148.         picSpusk.Enabled = False
  149.         picSpusk.BorderStyle = Windows.Forms.BorderStyle.None
  150.         picTroynik.Enabled = False
  151.         picTroynik.BorderStyle = Windows.Forms.BorderStyle.None
  152.         picZadv.Enabled = False
  153.         picZadv.BorderStyle = Windows.Forms.BorderStyle.None
  154.  
  155.         ' список блоков документа
  156.         X = 0
  157.         tsBlock.Items.Clear() ' сразу заполняю блоки и для таблицы
  158.         Do Until X = CadDoc.Blocks.Count
  159.             If CadDoc.Blocks.Item(X).IsDynamicBlock = True Then
  160.                 tsBlock.Items.Add(CadDoc.Blocks.Item(X).Name)
  161.                 ' проверяю доступность блока
  162.                 Select Case CadDoc.Blocks.Item(X).Name
  163.                     Case "Гребёнка"
  164.                         picGrib.Enabled = True
  165.                         picGrib.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  166.                     Case "Задвижка 30ч39р"
  167.                         picZadv.Enabled = True
  168.                         picZadv.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  169.                     Case "Колодец"
  170.                         picCol.Enabled = True
  171.                         picCol.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  172.                     Case "Крест стальной"
  173.                         picKrest.Enabled = True
  174.                         picKrest.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  175.                     Case "ПГ"
  176.                         picPG.Enabled = True
  177.                         picPG.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  178.                     Case "Переход"
  179.                         picPerehod.Enabled = True
  180.                         picPerehod.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  181.                     Case "Спускной"
  182.                         picSpusk.Enabled = True
  183.                         picSpusk.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  184.                     Case "Тройник стальной"
  185.                         picTroynik.Enabled = True
  186.                         picTroynik.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  187.                     Case "Фланец ПЭ"
  188.                         picFlanecP.Enabled = True
  189.                         picFlanecP.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  190.                     Case "Фланец стальной"
  191.                         picFlanecS.Enabled = True
  192.                         picFlanecS.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  193.                     Case "Цапковая головка"
  194.                         picCapka.Enabled = True
  195.                         picCapka.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  196.                     Case "Форматы"
  197.                         picRamka.Enabled = True
  198.                         picRamka.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
  199.                 End Select
  200.             End If
  201.             X = X + 1
  202.         Loop
  203.         tsBlock.Sorted = True
  204.  
  205.         ' X = 0
  206.         ' tsLayer.Items.Clear()
  207.         ' Do Until X = CadDoc.Layers.Count
  208.         ' tsLayer.Items.Add(CadDoc.Layers.Item(X).Name)
  209.         ' X = X + 1
  210.         ' Loop
  211.         ' tsLayer.Sorted = True
  212.  
  213.         lblFind.Text = ""
  214.  
  215.         grdBlock.Columns(9).HeaderText = ""
  216.         grdBlock.Columns(10).HeaderText = ""
  217.         grdBlock.Columns(11).HeaderText = ""
  218.         grdBlock.Columns(12).HeaderText = ""
  219.         grdBlock.Columns(13).HeaderText = ""
  220.         grdBlock.Columns(14).HeaderText = ""
  221.         grdBlock.Columns(15).HeaderText = ""
  222.         grdBlock.Columns(16).HeaderText = ""
  223.         grdBlock.Columns(17).HeaderText = ""
  224.         grdBlock.Columns(18).HeaderText = ""
  225.         grdBlock.Columns(19).HeaderText = ""
  226.         grdBlock.Columns(20).HeaderText = ""
  227.     End Sub

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Дабы не плодить новые темы подскажите пожалуйста варианты поиска
Код - vb.net [Выбрать]
  1.         Dim F1(0) As Short
  2.         Dim F2(0) As Object
  3.         If tsBlock.Text <> "" Then
  4.             ' для выбора по блоку и по слою
  5.             ' F1(0) = 0 ' поиск по слою
  6.             ' F2(0) = "INSERT" ' "BLOCK"
  7.             ' F1(1) = 8 ' поиск по имени 2
  8.             ' F2(1) = tsLayer.Text ' tsBlock.Text ' F2(1) = "`*U*," & tsBlock.Text
  9.  
  10.             ' для выбора по блоку
  11.             F1(0) = 0 ' поиск по слою
  12.             F2(0) = "INSERT" ' "BLOCK"
  13.         Else
  14.             MsgBox("Блок не выбран, продолжеие не возможно", vbOKOnly + vbCritical, "Сбор данных")
  15.             Exit Sub
  16.         End If
  17.         CadSelectionSet.Select(AcSelect.acSelectionSetAll, , , F1, F2)
а именно - тут выборка элементов блоков "INSERT", для MText, я писал "MText", но вот как выбрать мультивыноски вообще не пойму. Писал и "Мультивыноска" и "MLeader" и в интернете искал хотя бы раскладку по элементам и доступным кодам выбора.

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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
я попробую Вас направить, все таки, на путь нормального .NET API.
Ниже небольшая заготовка или простой шаблон, надеюсь это Вам поможет
Код - vb.net [Выбрать]
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.EditorInput
  6. Imports Autodesk.AutoCAD.Geometry
  7. Imports Autodesk.AutoCAD.Runtime
  8.  
  9. <Assembly: CommandClass(GetType(ClassLibrary1.Commands))>
  10. Namespace ClassLibrary1
  11.     Public Class Commands
  12.         <CommandMethod("select")>
  13.         Public Shared Sub SelectObj()
  14.  
  15.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  16.             If doc Is Nothing Then Return
  17.  
  18.             Dim ed As Editor = doc.Editor
  19.             Dim db As Database = doc.Database
  20.  
  21.             Dim blackRefsIds As List(Of ObjectId) = New List(Of ObjectId)()
  22.             Dim mleaderIds As List(Of ObjectId) = New List(Of ObjectId)()
  23.  
  24.             'Собираем данные из текущего рабочего пространства
  25.             Using currentSpace = TryCast(db.CurrentSpaceId.Open(OpenMode.ForRead), BlockTableRecord)
  26.  
  27.                 For Each id As ObjectId In currentSpace
  28.  
  29.                     If id.ObjectClass = RXObject.GetClass(GetType(BlockReference)) Then
  30.                         blackRefsIds.Add(id)
  31.                     End If
  32.  
  33.                     If id.ObjectClass = RXObject.GetClass(GetType(MLeader)) Then
  34.                         mleaderIds.Add(id)
  35.                     End If
  36.                 Next
  37.             End Using
  38.  
  39.             'Найдя нужные объекты, перебираем их и читаем их свойства
  40.             For Each id In blackRefsIds
  41.  
  42.                 Using br = TryCast(id.Open(OpenMode.ForRead), BlockReference)
  43.  
  44.                     'если слой блока не такой, что нужен то переходим к следующему блоку
  45.                     If br.Layer <> "какой то слой" Then Continue For
  46.                     'По поводу эффективного имени блока, код уже приводил
  47.                     'тут читаем свойства нужных "блоков"
  48.                     '....
  49.                     If br.IsDynamicBlock Then
  50.                         'пребираем динимические свойства
  51.                         Dim dynProps = br.DynamicBlockReferencePropertyCollection
  52.                         For Each dynProp As DynamicBlockReferenceProperty In dynProps
  53.  
  54.  
  55.                         Next
  56.                     End If
  57.                 End Using
  58.             Next
  59.  
  60.             For Each id In mleaderIds
  61.  
  62.                 Using ml = TryCast(id.Open(OpenMode.ForRead), MLeader)
  63.                     'тут читаем свойства мультивыноски
  64.                     '....
  65.                 End Using
  66.             Next
  67.         End Sub
  68.     End Class
  69.  
  70. End Namespace
  71.  

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Спасибо, тут правда другой подход к выборке примитивов и потом идёт перебор и сравнение параметров.

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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Да, другой, более надежный и быстрый подход.
Выбор объектов с помощью         
CadSelectionSet.Select(AcSelect.acSelectionSetAll, , , F1, F2)
не вполне надежен, т.к. зависит от редактора и может не возвращать объекты находящиеся вне экрана, по крайней мере так было в VBA, который использует тот же подход.  Нужно ли рисковать и наступать на грабли, которые можно обойти?

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Код - vb.net [Выбрать]
  1. CadSelectionSet.Select(AcSelect.acSelectionSetAll, , , F1, F2)
Тут более гибкий поиск, я допустим сразу указывал слой, а перебор всех элементов по моему где то на форуме обсуждался и решили что медленно работает.

Но в принципе спасибо за код, я взял начало и считал всё что мне надо, а вот как записать в определённый объект какие либо данные, в частности мне хотелось бы Mtext и мультивыноска править настройки, так как когда настройки хранятся внутри текста, то он не реагирует ни на настройки стиля, ни на изменение текста, а когда собираешь чертежи разных исполнителей, а начальник требует что бы шрифт был везде одинаков приходится заходить в каждый примитив и заменять.
Код - vb.net [Выбрать]
  1. ObjectIdToObject
Я так понял так не обратиться к примитиву?

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

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Окрыть объект для чтения (это работает быстро):
Код - vb.net [Выбрать]
  1. Using ml = TryCast(id.Open(OpenMode.ForRead), MLeader)
  2.   'тут читаем свойства мультивыноски
  3.   '....
  4. End Using
Открыть объект для записи(работает медленнее):
Код - vb.net [Выбрать]
  1. Using ml = TryCast(id.Open(OpenMode.ForWrite), MLeader)
  2.     'тут пишем в объект
  3.     '....
  4. End Using

либо открыв для чтения и узнав, что объект нужно изменить, то можно обновить открытие объекта до записи:
Код - vb.net [Выбрать]
  1.  Using ml = TryCast(id.Open(OpenMode.ForRead), MLeader)
  2.   'тут читаем свойства мультивыноски
  3.   '....
  4.   ml.UpgradeOpen();
  5.   'тут пишем в объект
  6.   '......
  7. End Using

Все написанное выше работает без транзакции, т.е. то же самое можно сделать и при помощи транзакции.
Все это очень подробно расписано в справке.

ЗЫ.
От VB кровь из глаз... какой же он корявый... и многословный

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Спасибо попробую, я просто синтаксис не понимаю Using... что и зачем я использую. Про ненависть к VB на форуме я в курсе, но начинал с макросов очень давно и теперь переучиваться - тем более что это не профильное занятие вообще не охото. В справке наверное написано, но это когда знаешь где искать, а так там:
Код - Visual Basic [Выбрать]
  1. Dim splineObj As AcadSpline
  2. Dim objectID As Long
  3. objectID = splineObj.objectID
  4. Dim tempObj As AcadObject
  5. Set tempObj = ThisDrawing.ObjectIdToObject(objectID)
то есть ID созданного объекта записан в переменную, а потом использован.
Как бы то ни было я первые результаты (кода начал пробовать написание плагина) получил недели через две.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
а перебор всех элементов по моему где то на форуме обсуждался и решили что медленно работает.
Не медленнее, чем метод Select(AcSelect.acSelectionSetAll...). В большинстве случаев быстрее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Я пришёл с конкретным вопросом переменные для -
Код - vb.net [Выбрать]
  1. CadSelectionSet.Select(AcSelect.acSelectionSetAll, , , F1, F2)
и кстати не знаю в каких случаях он работает медленнее, так как здесь можно сразу задать фильтр, а там перебирать.
Я может не понимаю, но вот тут я не вижу где ObjectID для обращения к конкретному примитиву, а перебор (допустим у меня один из тестовых файлов вмещает 12 000 МТекстов и перебор даёт о себе знать.
Код - vb.net [Выбрать]
  1. Using ml = TryCast(id.Open(OpenMode.ForWrite), MLeader)
  2.     'тут пишем в объект
  3.     '....
  4. End Using
В данном случае мне по ходу проще заюзать SelectAtPoint это будет быстрее работать правда элемент возможно всё так же будет недоступен для редактирования.
Спасибо Ваш метод выбора мне понравился, я разом выбирал 4 типа примитивов - буду пробовать дальше.

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Всё разобрался более или менее
Код - vb.net [Выбрать]
  1.         cadMT = CadDoc.ObjectIdToObject(CLng(тут ранее считанный ObjectID.ToString))
  2.         cadMT.TextString = "Trex"
  3.         cadMT.color = ACAD_COLOR.acRed
  4.         cadMT.Update()
Изменяются свойства нужного объекта по его ObjectID полученного предоставленным Вами кодом ранее, теперь буду тестировать и раскидывать на остальные примитивы

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

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

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

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

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Ты не понимаешь, что в действительности код самого ядра AutoCAD, который реализует этот фильтр, выполняет перебор всех примитивов и отбирает их по фильтру?
Буду знать, пока всё равно пробую и предоставленные примеры и то что нахожу в справке.

Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Не рекомендую. Во-первых, если переданная точка вне видимой области чертежа, то ничего не выберется. Плюс есть еще некоторые нюансы, связанные с точностью выбора, зависящие от размера апертуры.
Спасибо, я этого не знал. Ну у меня вроде получилось обратиться через ObjectIdToObject правда тоже есть нюансы.