Author Topic: double while loop in routine  (Read 9042 times)

0 Members and 1 Guest are viewing this topic.

jaydee

  • Guest
double while loop in routine
« on: September 20, 2011, 01:53:48 AM »
How to provide a while loop to continue entsel, if missed, try again.
at the same time allow to continue to select until right click to exit (what im only manage is Esc to exit)

Code: [Select]
(defun c:test (/ en)

;;;how to provide another
;(while here

  (while
    (not (setq en (car (entsel))))
    (prompt "\n Missed, try again")
  )
  (command "_chprop" en "" "c" "1" "")

;)
(princ)
)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: double while loop in routine
« Reply #1 on: September 20, 2011, 02:22:33 AM »
I don't think right-click (since you can only get that using grread, which then means entsel doesn't happen). Unfortunately only space/enter would stop entsel without erroring out like esc does. So you could go and use initget with a keyword and 128 as the code. Then also add that keyword as a default (i.e. in between <> in the message). If you do so, then entsel would return the keyword string when the user pressed Enter/Space.

As a sample:
Code: [Select]
(defun EntSelChk (msg init chk / en err)
  (while (and (progn
                (if init
                  (apply 'initget init)
                )
                (setq en (entsel msg))
              )
              (listp en)
              (setq err (apply chk (list en)))
         )
    (princ err)
  )
  en
)

(defun c:Test (/ en check)
  (defun check (en / )
    (if (not (wcmatch (cdr (assoc 0 (entget (car en)))) "LINE,LWPOLYLINE"))
      "\nThat's not a line / polyline, please try again."
    )
  )
  (while (and (setq en (EntSelChk "\nSelect line / polyline <Exit>: " '("Exit" 128) 'check))
              (not (eq en "Exit")))
    (princ "\nYou've picked an acceptable entity")
  )
  (princ "\nYou've selected to exit.")
  (princ)
)
Edit: scratch that, just realised it still doesn't do as intended. Will look a bit further and come back.
« Last Edit: September 20, 2011, 02:26:48 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: double while loop in routine
« Reply #2 on: September 20, 2011, 08:22:20 AM »
No Right Click exit but an old subroutine of mine that allows Enter Exit.

Code: [Select]
(defun getEntity (msg enttype / picked ent return)
  ;;  enttype may be nil
  (setvar "ErrNo" 0) ; reset variable
  (while
    (not
      (cond
        ((and (null (setq picked (entsel msg)))
              (/= 52 (getvar "ErrNo")) ; <Enter> was not hit
         )
         (prompt "\nMissed, Try Again.")
        )
        ((null picked) t) ; [ENTER] pressed, exit loop, return nil
        ((progn
           (setq ent (car picked))
           (cond
             ((null enttype) (setq return ent))
             ((= (strcase enttype) (cdr (assoc 0 (entget ent))))
              (setq return ent)
             )
             (t (prompt "\nWrong entity type, Try Again."))
           )
         )
        )
      )
    )
  )
  return
)


A more elaborate routine can be found here:
http://www.theswamp.org/index.php?topic=21655.msg262245#msg262245
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: double while loop in routine
« Reply #3 on: September 20, 2011, 08:32:56 AM »
I have always liked (ssget) for these kind of selections.  It's built in.  -David
R12 Dos - A2K

kruuger

  • Swamp Rat
  • Posts: 637
Re: double while loop in routine
« Reply #4 on: September 20, 2011, 08:52:13 AM »
do you want something like this ?
Code: [Select]
(defun c:TEST (/ OB DT)
  (while
    (progn
      (initget "Exit  ")
      (if (setq OB (entsel "\nSelect line [Exit]: "))
        (cond
          ( (or (= OB "Exit") (= OB ""))
            (princ "\n>> Exit TEST routine. <<")
            nil
          )
          ( (/= (setq DT (cdr (assoc 0 (entget (car OB))))) "LINE")
            (princ "\n** Wrong object selected **")
            T
          )
          ( (= DT "LINE")
            (princ "\n>> You select a line. <<")
            nil
          )
        )
        (progn
          (princ "\n** Nothing selected **")
           T
        )
      )
    )
  )
  (princ)
)
k.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: double while loop in routine
« Reply #5 on: September 20, 2011, 08:57:48 AM »

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: double while loop in routine
« Reply #6 on: September 20, 2011, 12:54:15 PM »
Probably, most approximately to what you wanted :
(only one while loop is needed)

Code: [Select]
(defun c:test (/ en)

(while (or (setq en (car (entsel))) (listp (cadr (grread nil 2))) )

  (if (not en)
    (prompt "\n Missed, try again")
    (command "_chprop" en "" "c" "1" "")
  )

)
(princ)
)

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: double while loop in routine
« Reply #7 on: September 20, 2011, 03:30:23 PM »
And this is even worse, but more logical :

Code: [Select]
(defun or2 (exp1 exp2)
(if (and (eq exp1 T) (eq exp2 T)) T
(if (and (eq exp1 T) (eq exp2 nil)) T
(if (and (eq exp1 nil) (eq exp2 T)) nil
(if (and (eq exp1 nil) (eq exp2 nil)) nil
))))
)

(defun c:test (/ en)
(while (or2 (listp (cadr (grread nil 2))) (if (setq en (car (entsel))) T) )
  (if (not en)
    (prompt "\n Missed, try again")
    (command "_chprop" en "" "c" "1" "")
  )
)
(princ)
)

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: double while loop in routine
« Reply #8 on: September 20, 2011, 03:58:44 PM »
Marko,

Isn't this:
Code: [Select]
(defun or2 (exp1 exp2)
(if (and (eq exp1 T) (eq exp2 T)) T
(if (and (eq exp1 T) (eq exp2 nil)) T
(if (and (eq exp1 nil) (eq exp2 T)) nil
(if (and (eq exp1 nil) (eq exp2 nil)) nil
))))
)

Just:
Code: [Select]
(defun or2 ( exp1 exp2 ) (and exp1))
Since the expression returns T irrelevant of the value of exp2.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: double while loop in routine
« Reply #9 on: September 20, 2011, 04:02:36 PM »
Marko,

Isn't this:
Code: [Select]
(defun or2 (exp1 exp2)
(if (and (eq exp1 T) (eq exp2 T)) T
(if (and (eq exp1 T) (eq exp2 nil)) T
(if (and (eq exp1 nil) (eq exp2 T)) nil
(if (and (eq exp1 nil) (eq exp2 nil)) nil
))))
)

Just:
Code: [Select]
(defun or2 ( exp1 exp2 ) (and exp1))
Since the expression returns T irrelevant of the value of exp2.
I was about to ask the same thing.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: double while loop in routine
« Reply #10 on: September 20, 2011, 05:00:06 PM »
Yes, you're probably wright... Now I swapped exp1 and exp2 in hope to get some different results, but no success...  :|

Code: [Select]
(defun or2 (exp1 exp2)
(if (and (eq exp1 T) (eq exp2 T)) T
(if (and (eq exp1 T) (eq exp2 nil)) nil
(if (and (eq exp1 nil) (eq exp2 T)) T
(if (and (eq exp1 nil) (eq exp2 nil)) nil
))))
)

(defun c:test (/ en)
(while (or2 (if (setq en (car (entsel))) T) (listp (cadr (grread nil 2))) )
  (if (not en)
    (prompt "\n Missed, try again")
    (command "_chprop" en "" "c" "1" "")
  )
)
(princ)
)

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: double while loop in routine
« Reply #11 on: September 20, 2011, 05:52:19 PM »
I'm not exactly sure what you are trying to accomplish Marko?  GrRead will wait for any user input, so the user would be prompted by entsel, then the program would pause until the user provided another input.

I believe the OP's request is satisfied by CAB's, Kruuger's or my example...

jaydee

  • Guest
Re: double while loop in routine
« Reply #12 on: September 20, 2011, 08:36:00 PM »
Thankyou all for your help.
I need to test it in actual function (chprop just a simple example) to see which one suit me best.
the code provide by Lee seems promising with minor mod, Lee i hope you dont mind i repost the mod version here.
This code will allow continuous to pick entity until right click to exit, also handle missed pick.
Code: [Select]
(defun c:test1 ( / entity )

(while
  (if
    (setq entity
      (car
        (LM:SelectIf "\nSelect a Line: "
          (lambda ( x ) (eq "LINE" (cdr (assoc 0 (entget (car x)))))) entsel nil
        )
      )
    )

    (progn
      (command "_chprop" entity "" "c" "1" "")
      (princ)
;     (princ (strcat "\nHandle of Selected Line: " (cdr (assoc 5 (entget entity)))))
    )
  )
)
  (princ)
)

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: double while loop in routine
« Reply #13 on: September 21, 2011, 01:20:55 AM »
Here is my final result, and it's working fine :

Code: [Select]
(defun c:test (/ pt ss en)
(while (listp (setq pt (cadr (grread nil (+ 2 4) 2))))
  (setq ss (ssget pt))
  (if ss
    (progn
      (setq en (ssname ss 0))
      (command "_chprop" en "" "c" "1" "")
    )
    (prompt "\n Missed, try again")
  )
)
(princ)
)

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Ketxu

  • Newt
  • Posts: 109
Re: double while loop in routine
« Reply #14 on: September 21, 2011, 10:33:51 AM »
Here is my final result, and it's working fine :

Code: [Select]
(defun c:test (/ pt ss en)
(while (listp (setq pt (cadr (grread nil (+ 2 4) 2))))
  (setq ss (ssget pt))
  (if ss
    (progn
      (setq en (ssname ss 0))
      (command "_chprop" en "" "c" "1" "")
    )
    (prompt "\n Missed, try again")
  )
)
(princ)
)

M.R.
So strange, it's working fine if I type TEST and run command. But, if i used up arrow to call it again from history command, it done nothing..