Пустой ввод при выполнении entsel.
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Пустой ввод при выполнении entsel.

Пустой ввод при выполнении entsel.

Ответ
Поиск в этой теме
Непрочитано 13.03.2006, 15:52 #1
Пустой ввод при выполнении entsel.
Tramp
 
Регистрация: 12.01.2006
Сообщений: 114

Уважаемые, а как можно предотвратить пустой ввод при выполнении функции entsel? (initget 1) результата не даёт.
Просмотров: 4743
 
Непрочитано 13.03.2006, 15:58
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


В каком смысле? Примерно так, например, можно:
Код:
[Выделить все]
(while (not (setq ent (entsel "\nУкажите примитив : ")))
  (princ "\nНичего не выбрано!")
  ) ;_ end of while
Можно также проверять значение errno, если такой подход больше нравится...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 13.03.2006, 16:12
#3
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Если нужно отделить пустой выбор (промахнулся) от нажатия клавиши ввод (выход)

Код:
[Выделить все]
(defun get_entt ( / Bl e1 errno)
 (setq BL t)
 (while BL
  (setq e1 (entsel "\nВыберите объект <выход>:"))
  (if e1
    (progn
      (alert (strcat "Вы выбрали " (cdr(assoc 0 (entget (car e1))))))
    )
    (progn
      (setq errno (getvar "ERRNO"))
      (cond 
           ((= errno 7) ;;;Пустой выбор
             (alert "Ничего не выбрано")
             (setq BL t)
            )
           ((= errno 52) ;;;Клавиша Ввод(выход)
             (setq BL nil e1 nil)
            )
          (t (alert "Необходимо выбрать примитив")
             (setq BL t)
          )
      )
    )
   )
  );_while
)
VVA вне форума  
 
Автор темы   Непрочитано 13.03.2006, 16:15
#4
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


Так проверять конечно можно, но беда в том, что мне нужна проверка на соответствие типа выбранного объекта типу "LINE". Делаю это через проверку точечной пары с меткой "0".
Код:
[Выделить все]
(cdr (assoc 0 (entget selected_object)))
В случае пустого ввода такая проверка даёт ошибку.
Tramp вне форума  
 
Непрочитано 13.03.2006, 16:18
#5
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Тогда можно так:
Код:
[Выделить все]
(while (and (not (setq ent (entsel "\nSelect the line : ")))
	    (/= (cdr (assoc 0 (car ent))) "LINE")
	    ) ;_ end of and
  (princ "\nНи шиша не выбрали, либо не отрезок это!")
  ) ;_ end of while
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 13.03.2006, 16:31
#6
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


2 Kpbic
Не работает. Пустой ввод отсеивает, а ошибочный пропускает.

2 VVA
Тип-то выбранного объекта оно определяет, а как прервать этот цикл, когда наконец будет выбран верный?

Ребята, вы уж извините меня за хронический тупизм, сам чувствую, что решение где-то рядом, но тяжко в конце дня думается, да и не программер я :-)
Tramp вне форума  
 
Непрочитано 13.03.2006, 16:38
#7
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Код:
[Выделить все]
;;;prmpt - приглашение
;;;myfilter - фильтр объетков '("LWPOLYLINE" "ARC" "POLYLINE" "LINE" "ELLIPSE" "SPLINE")
;;; sps - список объектов,чтобы не выбирали дважды один и тот же или nil
;;; Точку выбора заносит в LASTPOINT

(defun _MIP_GET_ENTT ( prmpt myfilter sps / Bl e1 prname str aa e2 pt)
 (setq BL t)  ;_Признак выхода
 (while BL
  (setvar "ERRNO" 0)
  (setq e1 (entsel (strcat "\n" prmpt " <выход>:")))  ;_Выбор примитива
  (setq pt (cadr e1) e1 (car e1))  ;_pt - точка выбора e1 - имя примитива
  (if pt (setvar "LASTPOINT" pt))  ;_pt в LASTPOINT
  (if (member e1 sps)              ;_Есть e1 в списке?
  (progn
    (alert "Примитив уже выбран")  ;_Да Повторный выбор
  )
  (progn                           ;_Нет Анализируем дальше
   (if e1                          ;_А вообще что-то выбрано?
    (progn                                     ;_Да
      (setq prname (cdr(assoc 0 (entget e1)))) ;_Берем тип примитива (LINE ARC и т.д.)
      (if myfilter                             
	(progn
	  (if (member prname myfilter)     ;_Есть ли тип в фильтре?
	    (setq BL nil)                  ;_Да Bl-nil while прекращается
	    (progn                         ;_Нет
	      (setq str "\nПримитив должен быть типа\n") ;_Сообщение
	      (foreach aa myfilter
		(setq str (strcat str aa " "))
	      )
	      (alert str)
	    )  
	  )  
	)
	(setq BL nil)     ;_Фильтра нет. while прекращаем
      )	
    )
    (progn     ;_А вообще что-то выбрано? НЕТ
               ;_Анализируем почему
      (setq e2 (getvar "ERRNO"))  ;_Берем код ошибки
      (cond 
           ((= e2 7) ;;;Пустой выбор
             (alert "Ничего не выбрано")
             (setq BL t)    ;_while продолжаем
            )
           ((= e2 52) ;;;Клавиша Ввод(выход)
             (setq BL nil e1 nil);_while прекращаем
            )
          (t (alert "Необходимо выбрать примитив")
             (setq BL t);_что-то другое while продолжаем
          )
      )

    )
   )
 )
)    
  );_while
  e1              ;_Возвращаем имя примива
)

;;;Пример
(setq SPS nil)
(setq E1 (_MIP_GET_ENTT "Выберите 1-й отрезок" '("LINE") sps))
(if E1   (setq SPS (append SPS (list E1))))
(setq E2 (_MIP_GET_ENTT "Выберите 2-й отрезок" '("LINE") sps))
(if E2 (setq SPS (append SPS (list E2))))
VVA вне форума  
 
Автор темы   Непрочитано 13.03.2006, 16:45
#8
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


Спасибо, работает :-) Теперь попробую понять, как :-)
Tramp вне форума  
 
Непрочитано 13.03.2006, 17:03
#9
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


>Tramp Лисп №7 снабдил комментариями, может будет полегче
VVA вне форума  
 
Непрочитано 13.03.2006, 22:53
#10
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от Tramp
Спасибо, работает :-) Теперь попробую понять, как :-)
Вот попроще...
Код:
[Выделить все]
(while (not (setq ent (ssget ":S" '((0 . "LINE"))))))
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 13.03.2006, 22:57
#11
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


Да, так действительно понятнее :-)
Я в конце концов эту задачу тоже решил, примерно вот так
Код:
[Выделить все]
(setq FLine nil)
(setq Flag 0)
(while (= Flag 0)
  (setq FLine (car (entsel "\nSelect line")))
  (if (/= Fline nil)
    (if (= (cdr (assoc 0 (entget FLine))) "LINE")
      (setq Flag 1)
      (alert "Incorrect input"); else
    ); if
    (alert "Incorrect input"); else
  ); if
); while
Но твой вариант универсальнее.
Tramp вне форума  
 
Автор темы   Непрочитано 13.03.2006, 23:10
#12
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


2 Елпанов Евгений
Интересный вариант... Никогда раньше не сталкивался с selection set'ами.
Tramp вне форума  
 
Непрочитано 14.03.2006, 07:50
#13
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Для хорошего выбора единичного примитива надо делать изощреннее.

1. Отделить промах от отказа с помощью анализа ERRNO (прячется в отдельную функцию)

2. Ограничить типы выбираемых примитивов (прячется в отдельную функцию)

3. Иметь возможность в момент выбора факультативно передавать опции командной строки (прячется в функцию)

4. По аналогии с entsel получать такой же список (примитив и точка указания). Точка часто тоже нужна, если не нужна то ее можно отбрасывать, но уже в программе.

5. Факультативно предотвращать выбор примитива на блокированном слое.

Все это формируется из маленьких низкоуровневых функций, но в результате из них можно сформировать свой постоянный заменитель entsel.

Подменять entsel на ssget не хорошо. Пользователю надо ясно указать на выбор одного примитива, а ssget будет сбивать с толку своим приглашением выбрать объекты. Хотя такой подход тоже может быть, только реальный код будет сложнее, чем фрагмент показанный Евгением Елпановым.

В ruCAD чаще всего используется две функции:

Код:
[Выделить все]
(defun ru-get-entsel (message)
  ;; (ru-get-entsel "Выбери объект, но не промахнись!")
  ;; Применять при отсутствии требований к блокирове и типам
  ;; примитивов
  ;; Возвращает список (примитив  точка_указания)
  (_ru-get-ent-default message "Выход" '_ru-get-entsel-no-error)
)
и


Код:
[Выделить все]
(defun ru-get-entsel-by-type
                             (message     msg_err_types
                              list_types  no_locked   /
                              ent         ent_type    bad_type
                              locked      do
                             )
;|
Выбор примитива с воможностью задать допустимые типы
 и выбор на не блокированном слое с возможностью выхода 
и с блокировкой ESC

Аргументы:

message - сообщение

msg_err_types - сообщение о неверном типе если задан список типов,
 иначе ""

list_types - список допустимх типов или NIL

no_locked  - выбор на не блокированном слое -T, на любом -NIL

Примеры:
 (ru-get-entsel-by-type 
   "Выбери отрезок или полилинию" 
   "Это не ОТРЕЗОК и не ПОЛИЛИНИЯ" 
   (list "LINE" "LWPOLYLINE") T)

 (ru-get-entsel-by-type 
  "Выбери объект на неблокированном слое" "" nil  T)

 (ru-get-entsel-by-type 
  "Выбери отрезок или полилинию - можно на блокированном" 
  "Это не ОТРЕЗОК и не ПОЛИЛИНИЯ" 
  (list "LINE" "LWPOLYLINE") nil)
Возвращает имя примитива и точку указания или nil при отказе
 |;

  (setq do t)
  (while do
    (setq bad_type t
          locked t
    ) ;_ end of setq
    (if (setq ent (ru-get-entsel message))
      (progn
        (setq ent_type (cdr (assoc 0 (entget (car ent)))))
        (if (and list_types
                 (not (member ent_type list_types))
            ) ;_ end of and
          (princ (strcat "\nОШИБКА: Указан объект типа '"
                         ent_type
                         "'. "
                         msg_err_types
                 ) ;_ end of strcat
          ) ;_ end of princ
          (setq bad_type nil)
        ) ;_ end of if
        (if (and no_locked
                 (ru-layer-is-lock (cdr (assoc 8 (entget (car ent)))))
            ) ;_ end of and
          (princ "\nОШИБКА: Объект на заблокированном слое!")
          (setq locked nil)
        ) ;_ end of if
        (setq do (or bad_type locked))
      ) ;_ end of progn
      (setq do nil)
    ) ;_ end of if
  ) ;_ end of while
  ent
) ;_ end of defun
Тексты используемых внутри функций не привожу (они есть в книге "САПР на базе AutoCAD..."). Здесь важен принцип.
ShaggyDoc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Пустой ввод при выполнении entsel.