Получить количество объектов модели

Автор Тема: Получить количество объектов модели  (Прочитано 8631 раз)

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

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Подскажите, возможно ли с помощью API AutoCAD
сразу получить количество примитивов ModelSpace
Т.е. не проходиться в цикле со счетчиком, а сразу получить количество.

SelectionSet.Count не подходит т.к. набора
как такового нет. есть только объект database

Может ответ на этот вопрос уже есть на форуме?


Отмечено как Решение Алексей (IdeaSoft) 27-09-2016, 21:27:48

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

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Подскажите, возможно ли с помощью API AutoCAD
сразу получить количество примитивов ModelSpace
Да.
Т.е. не проходиться в цикле со счетчиком, а сразу получить количество.
Нет.
Речь ведь идёт про количество примитивов в Пространстве Модели. Чем тебя итератор не устраивает? Быстрее всё равно не получишь.
Можно так с помощью LINQ:
Код - C# [Выбрать]
  1. using System.Linq;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6.  
  7. #pragma warning disable 0618
  8.  
  9. [assembly: CommandClass(typeof(CountModel.Utils))]
  10.  
  11. namespace CountModel
  12. {
  13.   public class Utils
  14.   {
  15.     [CommandMethod("CountModel")]
  16.     public void MyCommand()
  17.     {
  18.       Document doc = Application.DocumentManager.MdiActiveDocument;
  19.       if (doc == null) return;
  20.       Editor ed = doc.Editor;
  21.       using (BlockTable bt =
  22.         doc.Database.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
  23.       using (BlockTableRecord btr =
  24.         bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForRead) as BlockTableRecord) {
  25.          ed.WriteMessage("\nВсего в Пространстве Модели {0} примитивов.",   btr.Cast<object>().Count());
  26.       }
  27.     }
  28.   }
  29. }

Переписывать на VB.NET не буду. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
На VB net не нужно на С все понятно

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Чем тебя итератор не устраивает? Быстрее всё равно не получишь
А что вот эта конструкция "btr.Cast<object>().Count()"
работает точно с такой же скоростью, как если бы я пробежался по циклу таблицы?
Т.е. Count -это не свойство а метод класса? судя по скобкам Count()
Что где-нибудь в заголовке таблицы нет величины счетчика?

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

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
А что вот эта конструкция "btr.Cast<object>().Count()"
работает точно с такой же скоростью, как если бы я пробежался по циклу таблицы?
Думаю, что медленнее. Во всяком случае не быстрее, так как использует тот же итератор + возможны накладные расходы. Но можешь проверить если интересно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Но можешь проверить если интересно
Хотя да нужно проверить к примеру пробежался я по таблице с 50 000 примитивов - порядка 100 мс заняло.
а может и меньше во всяком случае долго ждать не пришлось.
Попробую позднее 500 000 объектов проверить.
Мне нужно знать заранее количество что бы один раз __malloc вызвать
А то выделять динамически память это очень дорогого стоит.
Я тут на днях провел эксперимент.
Вызвал тестовом примере 100 000 раз new для инстансов класса - 3 сек. ушло- Очень медленно.
А когда один раз сделал new <class>[100 000] разом выбрал мгновенно!
 

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

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Я тут на днях провел эксперимент.
Вызвал тестовом примере 100 000 раз new для инстансов класса - 3 сек. ушло- Очень медленно.
А когда один раз сделал new <class>[100 000] разом выбрал мгновенно!
Всё правильно. Важно, чтобы потом не нужно было этот массив увеличивать. Иначе накладные расходы на создание нового массива, удаление старого и перенос всех элементов из старого массива в новый.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Важно, чтобы потом не нужно было этот массив увеличивать
Я тут по этому поводу лекцию на Ютубе смотрел.
В компьютерных играх есть такая практика программирования.
В основном цикле игры, динамически выделяют больше памяти чем требуется.
На сколько больше все зависит от самой игры - решать программисту.
И потом пользуются этим куском памяти.
Получается не совсем экономно с памятью, но зато игра не тормозит.

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
btr.Cast<object>().Count()

Выражение перевести на VB NET не проблема

Код - vb.net [Выбрать]
  1. Dim obj As Object = btr.Cast(Of Object).Count

А вот на С++ :(

Код - C++ [Выбрать]
  1. CAD_DBS::BlockTable^ bt = (CAD_DBS::BlockTable^)(db->BlockTableId.Open(CAD_DBS::OpenMode::ForRead));
  2.  CAD_DBS::BlockTableRecord^ btr = (CAD_DBS::BlockTableRecord^)(bt[CAD_DBS::BlockTableRecord::ModelSpace].Open(CAD_DBS::OpenMode::ForRead));
  3. btr->Cast // ??? Пишет член Cast класса не найден.

IntelliSense: class "Autodesk::AutoCAD::DatabaseServices::BlockTableRecord" не содержит члена "Cast"

Я подключал сборки acad 2012 и Net FrameWork 4.5
В проекте поддержка CLR включена.




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

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот на С++
О Боже!!! Зачем это всё если на чистом ObjectARX это красивее, быстрее, понятнее...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
ObjectARX это красивее
Если это С++, то нужно на ObjectARX сделать.

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

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Это метод из LINQ
А теперь понятно - LinQ я не подключил.