Выбор одного объекта при помощи Editor.GetSelection

Автор Тема: Выбор одного объекта при помощи Editor.GetSelection  (Прочитано 6725 раз)

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
AutoCAD 2009 SP3 x64 Enu

Нужно выбрать один примитив, соответствующий заданному фильтру. Т.е. выбор объекта должен осуществляться точечно, а не рамкой выбора и выбран должен быть только один.
Код - C# [Выбрать]
  1. using Ed = Autodesk.AutoCAD.EditorInput;
  2. ...
  3. Ed.SelectionFilter filter = new Ed.SelectionFilter(tv);
  4. Ed.PromptSelectionOptions pso = new Ed.PromptSelectionOptions();
  5. pso.MessageForAdding = String.Format("Укажите вхождение блока '{0}'",
  6.         BlockRiseMarkExtension.AnchorBlockName);
  7. pso.SingleOnly = true;
  8. pso.SinglePickInSpace = true;
  9. pso.AllowSubSelections = false;
  10. pso.AllowDuplicates = false;
  11. ...
  12. Ed.PromptSelectionResult psr = ed.GetSelection(pso, filter);
  13. ...

Однако, обозначенный выше код позволяет выбрать рамкой сколько угодно объектов... Если в качестве альтернативы использовать Editor.GetEntity, то нет возможности указать фильтр выбора.

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

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Свойство SelectEverythingInAperture не помогает?
Спасибо, помогло - теперь выделение не рамкой, а точечно, как и нужно. Только если промахиваюсь мимо вхождения блока, повторного запроса на выбор объекта не происходит (влияет свойство SingleOnly = true). Если SingleOnly отключить, то запрос объектов продолжается (что мне не нужно). Это реализовать как-то можно, чтобы не засовывать код в цикл?

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

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Нет, т.к. это почти аналог Editor.GetEntity.
Ладно, а как-то присобачить SelectionFilter к Editor.GetEntity можно?

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В общем, остановился на таком варианте:

Код - C# [Выбрать]
  1. ...
  2. using Db = Autodesk.AutoCAD.DatabaseServices;
  3. using Ed = Autodesk.AutoCAD.EditorInput;
  4. ...
  5. Ed.PromptEntityOptions peo = new Ed.PromptEntityOptions(
  6.         String.Format("Укажите экземпляр блока '{0}'",
  7.         BlockRiseMarkExtension.AnchorBlockName));
  8. peo.AllowNone = false;
  9. peo.AllowObjectOnLockedLayer = true;
  10. // Перед тем, как вызвать метод AddAllowedClass, нужно обязательно
  11. // вызвать метод SetRejectMessage, иначе в AutoCAD 2009 получим Fatal
  12. // Error, а в более новых - Exception.
  13. peo.SetRejectMessage("\nНеобходимо указать вхождение блока якоря.\n");
  14. peo.AddAllowedClass(typeof(Db.BlockReference), true);
  15.  
  16. using (doc.LockDocument()) {
  17.         using (Db.Transaction tr = db.TransactionManager
  18.                 .StartTransaction()) {
  19.                 Ed.PromptEntityResult per = null;
  20.                 Boolean isAnchor = false;
  21.                 // Запрашиваем выбор до тех пор, пока либо не будет выбран,
  22.                 // якорь, либо не будет нажата клавиша Esc (отмена).
  23.                 do {
  24.                         per = ed.GetEntity(peo);
  25.                         if (per.Status != Ed.PromptStatus.OK) {
  26.                                 ed.WriteMessage("Не был указан якорь. Операция" +
  27.                                         "прервана.\n");
  28.                                 return;
  29.                         }
  30.                         Db.BlockReference br = tr.GetObject(per.ObjectId,
  31.                                 Db.OpenMode.ForRead) as Db.BlockReference;
  32.                         Db.ObjectId bdefId = br.IsDynamicBlock ?
  33.                                 br.DynamicBlockTableRecord : br.BlockTableRecord;
  34.                         Db.BlockTableRecord btr = tr.GetObject(bdefId,
  35.                                 Db.OpenMode.ForRead) as Db.BlockTableRecord;
  36.                         isAnchor = String.Equals(btr.Name,
  37.                                 BlockRiseMarkExtension.AnchorBlockName,
  38.                                 StringComparison.CurrentCultureIgnoreCase);
  39.                         if (!isAnchor) ed.WriteMessage("\nУказанный примитив" +
  40.                                 " не является якорем.\n");
  41.                 } while (!isAnchor);
  42.  
  43.  
  44.                 // Возвращаем обратно предварительный выбор, чтобы отметки остались
  45.                 // выбранными по завершению операции назначения якоря
  46.                 ed.SetImpliedSelection(risemarks);
  47. ...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ладно, а как-то присобачить SelectionFilter к Editor.GetEntity можно?
Нет конечно. Это же обертка для acedEntsel(), которая никаких фильтров не понимает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Я не уверен, что сработает в полном объеме, но для варианта SelectionSet можно указать и фильтр, и то, что "выбирать только один объект" (ключ в лиспе - "_.:S"). Может, стоит порыть в эту сторону?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

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

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Понял, умолк :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!