А если получить таблицу блоков, взять от туда описания блоков и для каждого описания получить вхождения?1. Не думаю, что это будет быстрее, так как всё-равно идёт сканирование базы данных. Причем не только Пространства Модели, а и всех блоков (в том числе и относящихся к Layout).
Или так не прокатит и есть подводные камни?
Полученные ObjectId придётся отфильтровывать на предмет принадлежности к Пространству Модели. А это уже требует получения объекта на основе его ObjectId.
То есть данный перебор объектов происходит по всем объектам чертежа и даже листов?Да. И не только по ним, но и по всем блокам. Пространство модели - это блок с именем "*Model_Space". Кроме него в чертеже может быть еще куча разных блоков (описаний блоков - BlockTableRecord), которые также будут просмотрены. И это явно не то, что тебе нужно.
Обалдеть, так это, мне бы потом не помешало бы научиться перебирать объекты внутри блоков тоже )Ну если у тебя вместо:
Получается, если у меня будут блоки с одинаковыми именами, то перебирать он будет по всем блокам с одинаковыми именами? Правильно понимаю?Или я не понял вопроса или ты не понимаешь сути блоков в AutoCAD. Есть "описания блоков" (класс BlockTableRecord) - запись таблицы блоков, которая содержит все примитивы, содержащиеся внутри блока. А есть "вставки блоков" (класс BlockReference) - примитив, ссылающийся на "описание блока". Так вот "описание блока" с одним именем в чертеже может быть только одно, а "вставок блоков" с одним именем может быть сколько угодно, а может и вообще не быть ни одного. И "вставки блоков" могут быть внутри любых других "описаний блоков". В том числе и внутри Пространства модели - "описания блока" с именем "*Model_Space". В отличие от других "описаний блоков" Пространство модели не может иметь никаких вставок в другие "описания блоков".
4. Исходя из Ваших слов, я понял, что с помощьюДа. Но только с "исходным" состоянием этого динамического блока.
Код - vb.net: [Выделить]
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(acBlkTbl("Рамка_v4"), OpenMode.ForRead)
я смогу определять внутри блока примитивы, из которого он состоит.
5. Перебирая объекты внутри блока, хочется определять их видимость, а затем и размеры. И так для каждой рамки в пространстве модели (в моем примере 6 штук).Для этого лезть в этот (!!!) блок не нужно. В зависимости от параметров видимости и других динамических свойств "вставки блока" будут иметь реально разные имена.
6. Сейчас мне нужно понять как сделать так, чтобы не пробегать все до единого объекты (к ним я отношу линии, дуги, окружности, размеры, тексты, таблицы и т.д.) в пространстве модели, а только блоки (DXF код которых "INSERT").Как это сделать я тебе уже выше написал здесь: http://adn-cis.org/forum/index.php?topic=2964.msg11191#msg11191
реально разные имена
Но похоже ты не читаешь или не понимаешь что я тебе пишу
так что быстрее не будет
Попробуй оба варианта, сравни и выбери нужный.
Оба, в смысле перебор и выбор с фильтром.
Типа *U80, *U81 и т.д?Да.
Александр, не поймите меня неправильно, но в этом коде я вижу как перебираются все объекты (допустим, что их 25 006 объектов), у меня даже 10324 объекта долго перебираются (и этот чертеж всего 650 килобайт), а что если мне принесут на тест чертеж 13 Мб (я уже боюсь представить, что такой модуль просто где-нибудь встанет)Это очень быстрая операция. Просто возьми и проверь. Не нужно теоретизировать. У меня есть программы, которые перебирают все объекты в чертеже (не только в пространстве модели), да еще и модифицируют его (REMOVEALLPROXY). И работает это единицы секунд на чертежах размером в десятки мегабайт. Быстрее можно только если все нужные тебе блоки видны на экране. И тогда можно их отфильтровать (но не по имени).
Код - vb.net: [Выделить]
For Each acObjId As ObjectId In acBlkTblRec ' Здесь перебираются все объекты
If acObjId.ObjectClass().DxfName = "INSERT" Then
' здесь обработка только блоков
End If
Next
Я уже это делать умею, но время на перебор затрачивается достаточно большое. А я хочу обойти это с другой стороны.
А давайте попробуем обойти это ограничение.Ну-ну. Хочу посмотреть как это тебе удастся сделать.
Ну-ну. Хочу посмотреть как это тебе удастся сделать
Дело в том, что вывожу в командную строку информацию об объекте. Может это мешает.Именно это и мешает.
Но всё становится еще хуже, когда, я использую форму и отображаю процесс выполнения задачи.Попробуй ProgressMeter. Пример использования: http://adndevblog.typepad.com/autocad/2013/02/return-to-command-prompt-when-escape-is-pressed-using-net.html
Судя по вот этому AcDbBlockReference, хочется задать вопрос, а Вы на .NET пишите?Ну точно не на C++ с использованием ObjectARX. :) Это он имя класса получает при помощи COM/ActiveX.
Это он имя класса получает при помощи COM/ActiveX.Так я вот именно про это, что он не методы .net api использует...
Надеюсь, что завтра все получится.Я проверил скорость обработки твоего чертежа-примера. Только при помощи команды _ARRAY увеличил количество рамок в сто раз (объектов в чертеже стало около 500000). REMOVEALLPROXY отработала менее чем за секунду. Делай выводы.
но в этом коде я вижу как перебираются все объекты (допустим, что их 25 006 объектов), у меня даже 10324 объекта долго перебираются (и этот чертеж всего 650 килобайт), а что если мне принесут на тест чертеж 13 Мб (я уже боюсь представить, что такой модуль просто где-нибудь встанет)Долго получать объект и проверять его, а проверить его указатель (ObjectId) - это очень быстрая опреация и не забывайте, что через COM - вы не только получаете объект, но и пересылаете его целиком на каждой операции получения - .Net же работает "изнутри" автокада.
Я проверил скорость обработки твоего чертежа-примера. Только при помощи команды _ARRAY увеличил количество рамок в сто раз (объектов в чертеже стало около 500000). REMOVEALLPROXY отработала менее чем за секунду. Делай выводы.
Долго получать объект и проверять его, а проверить его указатель (ObjectId) - это очень быстрая опреация и не забывайте, что через COM - вы не только получаете объект, но и пересылаете его целиком на каждой операции получения - .Net же работает "изнутри" автокада.
Dim FT(0) As Short ' Здесь была запарка (в документации здесь стоял Integer)Документация написана для VBA. А Integer в VBA - это Short в VB.NET (и в C#).
Документация написана для VBA. А Integer в VBA - это Short в VB.NET (и в C#).
в 26 строке nInserts вне зоны видимости, или я что то опять перепутал.Ничего не перепутал. Это я в FAR'е правил текст и само-собой его не проверял. Ну бывает и на старуху проруха...
Тоже быстро! Этот модуль действительно перебирает все объекты? Или у меня глюки?Перебирает все, но считает только вставки блоков. А ты думаешь что Editor.SelectAll() с фильтром работает иначе? Нет конечно. Проход по всем и сравнение с фильтром.