Как задать уже выбранные ранее объекты при множественном выборе объектов?

Автор Тема: Как задать уже выбранные ранее объекты при множественном выборе объектов?  (Прочитано 15130 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Здравствуйте!
Есть необходимость выбора объектов, но с уже известным заранее набором объектов. Этакий вариант изменения предыдущего выбора.
То есть, должно быть такое поведение:
- запускается метод выбора
- подсвечивается переданный набор объектов как будто их только что уже выбрали
- далее уже можно продолжать работать с этим выбором - выбирать новые или удалять из выбора объекты.
По поведению, это должно быть похоже на выбор объектов для операций в динамическом блоке:
https://screencast.autodesk.com/main/details/391e256b-00e9-45ce-a2de-1d4b4e372a25
Может быть, у кого-то есть идеи как такое можно сделать? Или уже знаете как сделать такое? Поделитесь, пожалуйста!
Я уже вроде все возможности метода Editor.GetSelection на пару с событиями объекта Editor исследовал и не нашел как такое сделать можно.


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Итак. Допустим у тебя есть уже набор, в котором содержатся примитивы.
1) Запускаешь команду _SELECT и передаешь ей этот набор. Завершаешь команду. Теперь в предыдущем наборе будут эти примитивы. Их можно выбрать в команде выбора при помощи ключевого слова "_P"
2) Запускаешь асинхронно (наверное через Document.SendStringToExecute) "_P " - команда сразу не выполнится, а выполнится только после запроса к AutoCAD. Про пробел после _P не забудь.
3) Запускаешь Editor.GetSelection() - в этот момент как раз и должно попасть "_P", т.е. сначала отработает ввод предыдущего набора, а затем будет запрос к пользователю.
На 100% не уверен, но думаю что сработает. 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
German, интересное предположение! Но проверка показала, что не работает такой вариант. Если есть предварительный выбор, при запуске метода Editor.GetSelection просто он же и возвращается без всякой возможности выбора вручную. По крайней мере, в моем коде именно так это работает.
Александр Наумович, ой как не хочется командные методы использовать... К тому же, набора первоначального как такового нет - есть только коллекция ObjectId объектов. Ее как-то передать в _SELECT возможно?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
К тому же, набора первоначального как такового нет - есть только коллекция ObjectId объектов. Ее как-то передать в _SELECT возможно?
Конечно. Создаешь SelectionSet из коллекции ObjectId и передаёшь его (SelectionSet) в команду. Т.е.:
Код - C# [Выбрать]
  1. SelectionSet ss = SelectionSet.FromObjectIds(ids);  // ids - коллекция ObjectId
  2. ed.Command("_SELECT", ss, ""); // Код условный - зависит от того каким образом ты будешь синхронно запускать команду
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
По поведению, вот этот код делает то, что нужно:
Код - C# [Выбрать]
  1. SelectionSet sSet = SelectionSet.FromObjectIds(ids);
  2. ed.Command("_.select", sSet);
Но как потом получить выбранные объекты?
Как добавить фильтр выбора?
Как задать сообщения при выборе/удалении из выбора объектов?
Цитировать
2) Запускаешь асинхронно (наверное через Document.SendStringToExecute) "_P " - команда сразу не выполнится, а выполнится только после запроса к AutoCAD. Про пробел после _P не забудь.
Вызов асинхронной команды с помощью ed.CommandAsync выполняется уже после завершения всего моего командного метода, когда это уже совершенно не нужно...

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

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

Отмечено как Решение Дмитрий Загорулькин 17-11-2014, 19:14:09

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй такой вариант. Я тестировал его только в AutoCAD 2015, но есть все предпосылки, что он будет работать и в предыдущих версиях:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.Internal; // Нужно для Utils.SelectObjects
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12. using AcEd = Autodesk.AutoCAD.EditorInput;
  13. using AcIt = Autodesk.AutoCAD.Internal;
  14.  
  15. [assembly: CommandClass(typeof(TestSelectionSet.MyCommands))]
  16.  
  17. namespace TestSelectionSet
  18. {
  19.   public class MyCommands
  20.   {
  21.     [CommandMethod("TestAddSelection")]
  22.     public void TestAddSelection()
  23.     {
  24.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  25.       if (doc == null) return;
  26.       AcEd.Editor ed = doc.Editor;
  27.       ObjectId[] ids = GetObjectIdFromUser();
  28.       if (ids != null && ids.Length != 0) {
  29.         // Устанавливаем предварительный набор
  30.         // (вместо команды _SELECT)
  31.         AcIt.Utils.SelectObjects(ids);
  32.         // Первое запрос фальшивый - только для того, чтобы "проглотить"
  33.         // набор предварительного выбора
  34.         AcEd.PromptSelectionResult resSel = ed.GetSelection();
  35.         doc.SendStringToExecute("_P ", false, false, false);
  36.         // Тут возможен вариант и с фильтром
  37.         resSel = ed.GetSelection();
  38.         if (resSel.Status == PromptStatus.OK)
  39.         {
  40.           ed.WriteMessage("\nВыбрано {0} объектов.", resSel.Value.Count);
  41.         }
  42.       }
  43.     }
  44.     /// Тестовая функция, которая возвращает массив ObjectId
  45.     public ObjectId[] GetObjectIdFromUser()
  46.     {
  47.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  48.       if (doc == null) return null;
  49.       AcEd.Editor ed = doc.Editor;
  50.       AcEd.PromptSelectionResult resSel = ed.GetSelection();
  51.       if (resSel.Status == PromptStatus.OK && resSel.Value.Count != 0)
  52.         return resSel.Value.GetObjectIds();
  53.       else
  54.         return null;
  55.     }
  56.   }
  57. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да! Все работает как надо и в 2014 и в 2015 версиях! И с фильтром и с сообщениями! Гениально! Спасибо большое! :)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Погонял код и так и эдак, поэкспериментировал. Выяснил, что Utils.SelectObjects можно заменить на ed.SetImpliedSelection - работает одинаково. Ну а в остальном - из песни слов не выкинешь, работает только в таком варианте :)
Я еще думал, что получится adoc.SendStringToExecute("_P ", false, false, false) заменить на ed.SelectPrevious() - но не вышло, хотя, вроде бы одинаковые функции выполняют. А  не, понял в чем разница :)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я еще думал, что получится adoc.SendStringToExecute("_P ", false, false, false) заменить на ed.SelectPrevious() - но не вышло, хотя, вроде бы одинаковые функции выполняют.
Функции выполняет как раз разные. Первое просто вводит в командную строку "_P ", причем именно тогда, когда AutoCAD ожидает от пользователя выбор примитивов или ключевое слово. Второе же просто возвращает набор предыдущего выбора.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да, я понял, спасибо :)
Цитировать
причем именно тогда, когда AutoCAD ожидает от пользователя выбор примитивов или ключевое слово
Кстати, даже если бы не было этой особенности, можно было бы подписаться на событие ed.PromptingForSelection (или ed.PromptedForSelection) и в нем запустить (sender as Editor).Document.SendStringToExecute.