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

ADN Club => AutoCAD .NET API => Тема начата: Luca от 04-11-2019, 05:52:43

Название: Как получить коллекцию блоков по имени?
Отправлено: Luca от 04-11-2019, 05:52:43
Уважаемые форумчане, как, используя AC .NET API,  получить коллекцию блоков зная имя блока?

Начни с этих статей:
https://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html
https://adn-cis.org/vyibor-vstavok-blokov-s-ispolzovaniem-filtra.html
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 09:43:26
Luca,
Статьи помогли?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 04-11-2019, 09:54:53
Статьи помогли?
надеюсь помогут. сегодня только начал ещё. вчера 14 часов работал и под конец уже мало что понимал. сегодня буду разбирать.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Lemieux от 04-11-2019, 12:32:59
Уважаемые форумчане, как, используя AC .NET API,  получить коллекцию блоков зная имя блока?

Начни с этих статей:
https://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html
https://adn-cis.org/vyibor-vstavok-blokov-s-ispolzovaniem-filtra.html
Может стоит копать в сторону OwnerID?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 12:34:43
Может стоит копать в сторону OwnerID?
Уточни что ты имеешь в виду и как предлагаешь это реализовать.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Lemieux от 04-11-2019, 13:11:07
Может стоит копать в сторону OwnerID?
Уточни что ты имеешь в виду и как предлагаешь это реализовать.
Если я правильно понимаю, то автор хочет получить список ссылок блоков (BlockReference) в чертеже определённого описания блока, зная имя этого описания блока (BlockTableRecord). Я бы сначала получил бы все ссылки блоков в чертеже, например через SelectionSet, а потом бы через цикл сравнивал с именем OwnerID и добавлял в массив.

Так, меня особо не пинать, этот способ работал на AutoLisp, на .NET пока не было возможности попробовать этот способ на практике  :)
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 13:13:39
Lemieux,
Идею понял. Только OwnerID с чьим ObjectId сравнивать будешь?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Lemieux от 04-11-2019, 13:17:15
Lemieux,
Идею понял. Только OwnerID с чьим ObjectId сравнивать будешь?
BlockTableRecord. Судя по хелпу всё должно работать.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 13:21:48
BlockTableRecord. Судя по хелпу всё должно работать.
Ошибаешься. OwnerID для BlockReference вернет ObjectId той BlockTableRecord, куда этот BlockReference вставлен. Т.е. например, BlockTableRecord Пространства модели или Пространства листа, если вставлен в них или BlockTableRecord какого-нибудь блока, если это вложенный блок.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Lemieux от 04-11-2019, 13:30:01
BlockTableRecord. Судя по хелпу всё должно работать.
Ошибаешься. OwnerID для BlockReference вернет ObjectId той BlockTableRecord, куда этот BlockReference вставлен. Т.е. например, BlockTableRecord Пространства модели или Пространства листа, если вставлен в них или BlockTableRecord какого-нибудь блока, если это вложенный блок.
Это фиаско ©  ;D

Через это свойство нужно получать ObjectID BlockTableRecord? https://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_BlockReference_BlockTableRecord
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 13:50:19
Через это свойство нужно получать ObjectID BlockTableRecord? https://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_BlockReference_BlockTableRecord
Да - если это блок статический (не динамический) или нужно получить BlockTableRecord именно этой вставки. Если нужно получить BlockTableRecord основного описания динамического блока, то свойство DynamicBlockTableRecord: https://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_BlockReference_DynamicBlockTableRecord
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 04-11-2019, 14:58:09
Luca,
Статьи помогли?
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices; // Application
  2. using Autodesk.AutoCAD.DatabaseServices; // Database
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD;
  5. using Autodesk.AutoCAD.Runtime;
  6. // types
  7. using Transaction = Autodesk.AutoCAD.DatabaseServices.Transaction;
  8. using Database = Autodesk.AutoCAD.DatabaseServices.Database;
  9.  
  10. namespace Automation{
  11.     public class AFS
  12.     {
  13.        
  14.         [CommandMethod("getAllBlockByName")]
  15.         public void getAllBlocksByName()
  16.         {
  17.             Document document = Application.DocumentManager.MdiActiveDocument;
  18.             Editor   editor   = Application.DocumentManager.MdiActiveDocument.Editor;
  19.             Database database = document.Database;
  20.             try
  21.             {
  22.                 using (document.LockDocument())
  23.                 {
  24.                     using (Transaction transaction = database.TransactionManager.StartTransaction())
  25.                     {
  26.                         BlockTable blockTable = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
  27.                         foreach (ObjectId blockId in blockTable)
  28.                         {
  29.                             BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockId, OpenMode.ForRead);
  30.                             /* В таблице
  31.                              * как здесь проверить, что это именно тот блок? методах
  32.                              *
  33.                             if ()
  34.                             {
  35.  
  36.                             }
  37.                             */
  38.                         }
  39.                     }
  40.  
  41.                 }
  42.             }
  43.             catch (Exception exc)
  44.             {
  45.                 editor.WriteMessage("{0}\n", exc.Message);
  46.             }
  47.         }
  48.     }
  49. }
  50.  
Вопросов несколько:
1. Где посмотреть правила форматирования?
2. Правильно ли я понимаю, что
в BlockTable хранятся все  блоки, если можно так сказать, а в BlockTableRecord хранятся ссылки на конкретные экземпляры?
3. Как нужный мне блок отличить от ненужных?  здесь https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-__MEMBERTYPE_Properties_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord (https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-__MEMBERTYPE_Properties_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord) я не увидел такого... Имя же должно быть у блока?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 04-11-2019, 15:15:11
1. Где посмотреть правила форматирования?
У меня в подписи. А также в Правилах форума - п. 4.5
2. Правильно ли я понимаю, что
в BlockTable хранятся все  блоки, если можно так сказать, а в BlockTableRecord хранятся ссылки на конкретные экземпляры?
BlockTable - это таблица описаний всех блоков, а BlockTableRecord - это описание конкретного блока.
3. Как нужный мне блок отличить от ненужных?  здесь https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-__MEMBERTYPE_Properties_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord я не увидел такого... Имя же должно быть у блока?
Ты не обратил внимание, что класс BlockTableRecord - наследник класса SymbolTableRecord, у которого есть свойство Name: https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_SymbolTableRecord_Name
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Владимир Шу от 05-11-2019, 09:54:10
Я бы начал от сюда: https://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 05-11-2019, 11:43:35
Владимир Шу,
Я как раз эту ссылку и давал. :)
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 10-11-2019, 10:22:02
Возникли вопросы:
Как при выборе блоков по имени учесть ещё два фактора:
1. Блок выделен (обычное выделение)
2. Находится на определенном слое
3. Хранить получаемые блоки в массиве - верно?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 10-11-2019, 13:45:21
1. Блок выделен (обычное выделение)
Предварительный выбор? Тогда Editor.SelectImplied()  - у команды должен быть установлен флаг CommandFlags.UsePickSet иначе при запуске команды предварительный набор сбрасывается.
2. Находится на определенном слое
Фильтровать по DXF-коду 8 - имя слоя.
3. Хранить получаемые блоки в массиве - верно?
Я предпочитаю хранить их ObjectId.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 10-11-2019, 14:15:03
Предварительный выбор? Тогда Editor.SelectImplied()  - у команды должен быть установлен флаг CommandFlags.UsePickSet иначе при запуске команды предварительный набор сбрасывается.
не понимаю что значит предварительный выбор...
просто на чертеже всего много и цепи, линии и пр. могут быть совсем из разных "участков". я хочу выбрать и применять команды только к выделенному, те чтобы команда составления графа или нумерации блоков работала только с выделенными блоками и полилиниями.
посмотрел и нашел вот такой класс - Autodesk.AutoCAD.EditorInput.SelectionSet и у этого класса методы GetObjectIds  и  GetEnumerator
возник вопрос:
а между командами результаты будут сохраняться и так, чтобы из следующей команды данные были доступны, например, я отключаю все слои, кроме того, на котором расположены блоки, выделяю  то, с чем хочу работать, выполняю команду NumberBlocks и блоки пронумерованы (кстати, я так и не понял можно ли вызывать команду с параметрами? типа NumberBlocks 1 2 3), затем я выключаю слой с блоками и включаю слой с полилиниями - "связями", выделяю нужный мне участок и выполняю команду GetLinks и получаю все связи, затем (полагаю, что данные с предыдущих команд сохранились) строю граф, на основе массива или списка устройств и связей, выполняю расчет и оформляю в виде таблицы.  так можно ведь?

Я предпочитаю хранить их ObjectId.
SelectionSet.GetObjectIds
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 10-11-2019, 14:25:49
не понимаю что значит предварительный выбор...
А я не понимаю что такое "выделенное".
я хочу выбрать и применять команды только к выделенному
Научись пользоваться терминами AutoCAD. Те объекты чертежа, которые ты выделил до запуска какой-либо команды - это и есть предварительный выбор (PickFirst)
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 10-11-2019, 14:27:38
а между командами результаты будут сохраняться и так, чтобы из следующей команды данные были доступны
Если сохранишь - сохранятся, если нет - не сохранятся.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 10-11-2019, 14:35:33
Если сохранишь - сохранятся, если нет - не сохранятся.
куда сохранять то?
я понимаю как что-то сохранить в БД, но в данном случае как это сохраняется?
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 10-11-2019, 14:39:32
куда сохранять то?
Куда хочешь - туда и сохраняешь. Тут главное понять что именно ты хочешь сохранить. Пока же это всё полная абстракция.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Luca от 10-11-2019, 15:07:05
Куда хочешь - туда и сохраняешь. Тут главное понять что именно ты хочешь сохранить. Пока же это всё полная абстракция.
а если я хочу сохранить  массив или список ссылок на блоки или полилинии, те сначала выделяю блоки, считываю, потом выделяю полилинии считываю и потом запускаю команду построения графа.
Название: Re: Как получить коллекцию блоков по имени?
Отправлено: Александр Ривилис от 10-11-2019, 16:42:29
Куда хочешь - туда и сохраняешь. Тут главное понять что именно ты хочешь сохранить. Пока же это всё полная абстракция.
а если я хочу сохранить  массив или список ссылок на блоки или полилинии, те сначала выделяю блоки, считываю, потом выделяю полилинии считываю и потом запускаю команду построения графа.
Во-первых, это всё можно сделать в одной команде - так что сохранять ничего не понадобится.
Во-вторых, массив ObjectId выбранных объектов можно сохранить в глобальной переменной.