Author Topic: setting initget within while  (Read 7706 times)

0 Members and 1 Guest are viewing this topic.

daron

  • Guest
setting initget within while
« on: August 06, 2004, 04:27:44 PM »
Can this be done?

First I tried this:
Code: [Select]
(defun c:aet (/ lpnt pmpt)
(setq lpnt (getvar "lastpoint"))
(defun cont ()
(initget "Undo")
(setq pmpt (getpoint lpnt "\nSelect end point Undo or [Enter] to exit: "))
)
(while pmpt   ;;;I even tried cont here.
(cond ((or (/= pmpt nil) (/= pmpt "Undo"))
(command ".arc" "@" "e" pmpt "d" pause)
(setq lpnt pmpt)
     )
     ((= pmpt "Undo")
(command ".erase" "l" "")
(command ".arc" "@" "e" pmpt "d" pause)
(setq lpnt pmpt)
     )
)
)
(princ)
)


but I can't get the defun to repeat or something. I've also tried it as a lambda instead of defun.

This was a last resort.
Code: [Select]
(defun c:aet (/ lpnt pmpt)
(setq lpnt (getvar "lastpoint"))
(while     (initget "Undo")
(setq pmpt (getpoint lpnt "\nSelect end point Undo or [Enter] to exit: "))
(cond ((or (/= pmpt nil) (/= pmpt "Undo"))
(command ".arc" "@" "e" pmpt "d" pause)
(setq lpnt pmpt)
     )
     ((= pmpt "Undo")
(command ".erase" "l" "")
(command ".arc" "@" "e" pmpt "d" pause)
(setq lpnt pmpt)
     )
)
)
(princ)
)


What do I need to do to use initget before getpoint and use getpoint as a while condition?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
setting initget within while
« Reply #1 on: August 06, 2004, 05:03:43 PM »
Try This...
Code: [Select]
(defun c:aet (/ lpnt pmpt)
(setq lpnt (getvar "lastpoint"))
(initget "Undo")
(while (setq pmpt (getpoint lpnt "\nSelect end point Undo or [Enter] to exit: "))
   (cond ((or (/= pmpt nil) (/= pmpt "Undo"))
          (command ".arc" "@" "e" pmpt "d" pause)
          (setq lpnt pmpt)
         )
         ((= pmpt "Undo")
          (command ".erase" "l" "")
          (command ".arc" "@" "e" pmpt "d" pause)
          (setq lpnt pmpt)
         )
   )
  (initget "Undo")
)
(princ)
)
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.

sinc

  • Guest
setting initget within while
« Reply #2 on: August 07, 2004, 12:45:48 AM »
Or This...
Code: [Select]
(defun c:aet (/ lpnt pmpt)
(setq lpnt (getvar "lastpoint"))
(while
   (progn
         (initget "Undo")
         (setq pmpt (getpoint lpnt "\nSelect end point Undo or [Enter] to exit: "))
   )
   (cond ((or (/= pmpt nil) (/= pmpt "Undo"))
          (command ".arc" "@" "e" pmpt "d" pause)
          (setq lpnt pmpt)
         )
         ((= pmpt "Undo")
          (command ".erase" "l" "")
          (command ".arc" "@" "e" pmpt "d" pause)
          (setq lpnt pmpt)
         )
   )
)
(princ)
)

The (progn ...) can be extended with as many functions as desired.

SMadsen

  • Guest
setting initget within while
« Reply #3 on: August 07, 2004, 07:28:19 AM »
Code: [Select]

...
(while (or (initget "Undo")(setq pmpt (getpoint ...)))
  ...
)


.. is yet another

sinc

  • Guest
setting initget within while
« Reply #4 on: August 07, 2004, 09:54:33 AM »
Personally, I don't like using OR when I mean PROGN.  It's confusing.

Sometimes, I might use OR or AND that way, because it works like a short-circuit operator (functions in the statement are evaluated until one of them is false for an AND or true for an OR, at which point the AND/OR terminates without executing any remaining instructions).  But because of the syntax of Lisp, using AND or OR in this way also greatly reduces code readability, so I still don't really like it.  It's probably better to use COND in this case - it makes intent clearer, even though it means extra parentheses (another Lisp syntax-decision that decreases readability).

YMMV.

JohnK

  • Administrator
  • Seagull
  • Posts: 10638
setting initget within while
« Reply #5 on: August 07, 2004, 10:35:36 AM »
Modualr programing my friend. Think on the conceptual level, not the level of process'.

How do functions like OR and AND take away from the readability of code when they are bacic  logical functions of the language?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

sinc

  • Guest
setting initget within while
« Reply #6 on: August 07, 2004, 11:54:26 AM »
In Stig's example, the OR works exactly like a PROGN, but only because the initget always returns nil.  You have to know that initget always returns nil for the intent of the code to be clear.  The intent of PROGN, on the other hand, is obvious.  The difference may not mean much to experienced programmers, but it can mean a world of difference to a less-experienced programmer trying to read the code, or even to an experienced programmer new to the environment.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
setting initget within while
« Reply #7 on: August 07, 2004, 12:14:57 PM »
I have to agree with sinc's basic premise -- clear intent is preferable to "clever" code.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

daron

  • Guest
setting initget within while
« Reply #8 on: August 09, 2004, 08:15:59 AM »
Well, I think they are all interesting in the sense that it was a road I hadn't considered. Neither the OR nor the PROGN had I ever used for WHILE nor did I think it were possible. Both examples have broadened my horizons. Thanks.

CAB, (initget...) before the while would work the first time, but with each successive run through while will not call initget. That is why I was hoping to use the defun to make the successive calls. Thanks, though.

JohnK

  • Administrator
  • Seagull
  • Posts: 10638
setting initget within while
« Reply #9 on: August 09, 2004, 09:03:50 AM »
Daron, Take another look at CAB's code. Its very good; The last thing in the while loop is an initget. *Wink* His code is the reason why i didnt post mine. (His was better then mine. )
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

daron

  • Guest
setting initget within while
« Reply #10 on: August 09, 2004, 09:31:10 AM »
Thanks Se7en. I missed that. Sorry CAB. It's too early in the morning to catch all that.

I have another question related to the same code. I can't think of a good way to get the undo portion working. I'll repost what improvements I've come up with on this code. I'm thinking something recursive to append all the points selected to be able to undo and move the lastpoint to the correct point, but I don't want this to get bogged down or out of hand. Recursive or not, I think append is the direction I want to go, but I'm sure many of you guys have dealt with creating undo functions in this manner, I thought I'd just throw it out at you and see what more I can learn from you.
Code: [Select]
(defun c:aet (/ ptpnt endpnt lpnt pmpt)
(setq cmde (getvar "cmdecho")
           omod (getvar "orthomode")
)
(setvar "cmdecho" 0)
(setvar "orthomode" 0)
(initget "Continue")
(setq stpnt  (getpoint "\nSelect start point of arc or [<C>ontinue]: "))
(cond ((or (= stpnt "Continue") (= stpnt nil))
(setq lpnt (getvar "lastpoint"))
     )
     ((or (/= stpnt "Continue") (/= stpnt nil))
(setq endpnt (getpoint stpnt "\nSelect end point of arc: "))
(command ".arc" stpnt "e" endpnt "d" pause)
(setq lpnt endpnt)
     )
)
(while
(progn (initget "Undo")
      (setq pmpt (getpoint lpnt "\nSelect end point, Undo or [Enter] to exit: "))
)
(cond ((or (/= pmpt nil) (/= pmpt "Undo"))
      (command ".arc" "@" "e" pmpt "d" pause)
      (setq lpnt pmpt)
     )
     ((= pmpt "Undo")
      (command ".erase" "l" "")
     )
)
)
(setvar "cmdecho" cmde)
(setvar "orthomode" omod)
(princ)
)

Regardless of the undo portion not working correctly here, I get an error message that doesn't make sense.
Code: [Select]
Select end point, Undo or [Enter] to exit:
Select end point, Undo or [Enter] to exit: u
Invalid 2D point.
; error: Function cancelled

u should be a valid point with the initget call, but it's acting like it's not. I don't understand what's going on there. I tried or as well.

SMadsen

  • Guest
setting initget within while
« Reply #11 on: August 09, 2004, 11:06:01 AM »
Daron, use AND instead of OR in the not-equal-to-Undo condition

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
setting initget within while
« Reply #12 on: August 09, 2004, 11:06:56 AM »
Two suggestions:

(Fast solution) Look into bit 7 (value 128) for initget calls; trap non coordinate input and branch accordingly.

(Better solution) Consider a different approach than wrapping calls to command, .i.e. a function that gathers points etc. then calling entmake or vla-add-lwpolyline / arc / whatever as appropriate given a succesful selection of points / instructions.

My 2¢ :)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

daron

  • Guest
setting initget within while
« Reply #13 on: August 09, 2004, 11:29:51 AM »
I'll look into all suggestions. The only problem I have with using entmake or vla-... is that I don't remember being able to have the arc visible when drawing it. I need to use pause to achieve that and command is the only way I'm aware to get that. Prove me wrong please!!! I'd love to not use command.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
setting initget within while
« Reply #14 on: August 09, 2004, 12:06:12 PM »
Quote from: Daron
I'll look into all suggestions. The only problem I have with using entmake or vla-... is that I don't remember being able to have the arc visible when drawing it. I need to use pause to achieve that and command is the only way I'm aware to get that. Prove me wrong please!!! I'd love to not use command.

Without resorting to kludges (grdraw etc.) or 3rd party tools, the dynamic drawing (or ghosting) of the "budding" arc is not a practical avenue (imo) to mimic the arc command given the effort required. You're basically on the right track given your requirements (now that I better understand it), all you need to do is idiot (oops, bullet) proof the wrapper so it anticipates all potential inut and branches (sometimes ignoring) input accordingly. If I had time, and I apologise for participating here when I really don't, I'd push some bits for you. I'll try to help out here and there though. Cheers, M.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

SMadsen

  • Guest
setting initget within while
« Reply #15 on: August 10, 2004, 06:19:41 AM »
Daron, I would use the ARC command as you do it, also. About the undo option, I would build a list of points as the command progresses and use those points to backtrace during undo sessions.

Below is my suggestion for implementing the undo mechanism. I'll let the comments take over further explanation:

Code: [Select]
(defun c:aet (/ ptpnt endpnt lpnt stpnt pmpt undolst cmde init omod pmp)
  (setq cmde (getvar "cmdecho")
        omod (getvar "orthomode")
  )
  (setvar "cmdecho" 0)
  (setvar "orthomode" 0)
  ;; instead of LASTPOINT (which can be set by numerous actions), I'd
  ;; suggest that you use a dedicated global point to continue from.
  ;; first, check if the global holds a point list
  (cond ((vl-consp *aet_pt*)
         ;; ok, global point exists (highly probable at least)
         ;; go set up the prompt and initget option .. also set
         ;; lpnt to the global point
         (setq pmp  "\nSelect start point of arc or [<C>ontinue]: "
               init "Continue"
               lpnt *aet_pt*
         )
        )
        ;; no global exists .. just ask for initial point with no
        ;; initget options
        ((setq pmp  "\nSelect start point of arc: "
               init 0
         )
        )
  )
  ;; go ask for point or option
  (initget init)
  (setq stpnt (getpoint pmp))
  ;; check result
  ;; if "Continue" or nothing then simply jump right into the loop
  (cond ((or (not stpnt) (= stpnt "Continue")))
        ;; if not the above, get endpoint and start to build the
        ;; undo data list. Because CMDECHO is off, help the user
        ;; by issuing the standard prompt at the user input
        ((setq endpnt (getpoint stpnt "\nSelect end point of arc: "))
         (princ
           "\nSpecify tangent direction for the start point of arc: "
         )
         (command ".arc" stpnt "e" endpnt "d" pause)
         (setq lpnt    endpnt
               undolst (list stpnt)
         )
        )
  )
  ;; initialize the loop prompt
  (setq pmp "\nSelect end point or [Undo]: ")
  (while
    (progn (initget "Undo")
           (setq pmpt (getpoint lpnt pmp))
    )
     ;; if Undo, then first check the undo data and see if it's
     ;; even possible to undo (otherwise do nothing but tell there
     ;; is nothing to undo)
     (cond ((= pmpt "Undo")
            (cond ((not undolst) (princ "Nothing to undo"))
                  ;; if undo data exists: go erase the last arc,
                  ;; reset lpnt to first occurence in the undo list
                  ;; and chop off the "undid" point from the undo list
                  (T
                   (command ".ERASE" "Last" "")
                   (setq lpnt    (car undolst)
                         undolst (cdr undolst)
                   )
                  )
            )
           )
           ;; if point is received: go draw the arc, append point
           ;; to the undo list and set lpnt to the new point.
           ;; again, help the user by issuing the standard prompt
           (pmpt
            (princ
              "\nSpecify tangent direction for the start point of arc: "
            )
            (command ".ARC" lpnt "E" pmpt "D" pause)
            (setq undolst (cons lpnt undolst)
                  lpnt    pmpt
            )
           )
     )
     ;; adjust prompt to reflect the status of the undo data
     (setq pmp (if undolst
                 "\nSelect end point or [Undo]: "
                 "\nSelect end point: "
               )
     )
  )
  ;; put last point up for later continuance
  (setq *aet_pt* lpnt)
  (setvar "cmdecho" cmde)
  (setvar "orthomode" omod)
  (princ)
)

daron

  • Guest
setting initget within while
« Reply #16 on: August 10, 2004, 07:51:00 AM »
Thank you Stig. I'll go test it and learn to better understand it.

SMadsen

  • Guest
setting initget within while
« Reply #17 on: August 10, 2004, 08:17:02 AM »
You're welcome. Now to the home assignment: Implement a redo mechanism :)

daron

  • Guest
setting initget within while
« Reply #18 on: August 10, 2004, 02:18:18 PM »
Now that's something I hadn't even considered, but I'm not sure I see the need. I'll see what I can do though.

SMadsen

  • Guest
setting initget within while
« Reply #19 on: August 10, 2004, 03:55:58 PM »
Who needs a need?

I was just trying to be amusing. Hope you can use the code I posted, Daron.

daron

  • Guest
setting initget within while
« Reply #20 on: August 10, 2004, 04:20:36 PM »
The code you posted is awesome. I've been using it all day. As far as a need goes, I'm going to try and improve on it by adding a line function and better than a redo function, I'd like to add a close function to it. I hope others find it useful, too.

Thanks again, Stig.

CADaver

  • Guest
setting initget within while
« Reply #21 on: August 11, 2004, 10:56:26 AM »
A possible refinement maybe???

Build a selection set as you go, then PEDIT the whole thing into a single pline when you're done?

daron

  • Guest
setting initget within while
« Reply #22 on: August 11, 2004, 02:42:27 PM »
Good idea. I'd like to get the line portion worked out before attempting that though. If you want to write a module for doing that, it might be a good exercise.

CADaver

  • Guest
setting initget within while
« Reply #23 on: August 11, 2004, 04:17:35 PM »
Quote from: Daron
Good idea. I'd like to get the line portion worked out before attempting that though. If you want to write a module for doing that, it might be a good exercise.
umm... remember who yer talking to??  ...the thief/hack/cad-slug?? ...the only reason I kin rite my name is mom has it stenciled on my boxers.

daron

  • Guest
setting initget within while
« Reply #24 on: August 12, 2004, 08:11:37 AM »
Mmm. I thought you knew a little. No activeX here. All unleaded lisp. We're even using command.