TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: jlogan02 on August 26, 2022, 01:23:21 PM

Title: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: jlogan02 on August 26, 2022, 01:23:21 PM
Trying to use Lee Mac's PJ routine by changing the selection to a crossing window
to eliminate user input.

Getting a syntax error.

I also need to verify that the lines I'm selecting aren't already polylines.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:pj ( / *error* bl1 bl2 bl3 bl4 sel1 sel2 val var )
  2.    
  3.     (defun *error* ( msg )
  4.         (mapcar '(lambda ( a b ) (if b (setvar a b))) var val)
  5.         ;;(LM:endundo (LM:acdoc))
  6.         (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
  7.             (princ (strcat "\nError: " msg))
  8.         )
  9.         (princ)
  10.     )
  11.  
  12.   (if
  13.  
  14.     (setq
  15.       bl1 '(0.0 0.0)  ;;lower left white border corner
  16.             bl2 '(-1.0 -1.0)
  17.       bl3 '(34.00 22.00)  ;;Upper Right white border corner
  18.             bl4 '(34.0625 22.0625)
  19.     )
  20.  
  21.     (setq dim (getvar 'dimscale)
  22.       bl1 (mapcar '* bl1 (list dim dim))
  23.             bl2 (mapcar '* bl2 (list dim dim))
  24.             bl3 (mapcar '* bl3 (list dim dim))
  25.             bl4 (mapcar '* bl4 (list dim dim))
  26.   )
  27.    
  28.     (setq sel1 (list (car bl1) (cadr bl2)))
  29.     (setq sel2 (list (car bl3) (cadr bl4)))
  30.        
  31.         (progn
  32.             (setq var '(cmdecho peditaccept)
  33.                   val  (mapcar 'getvar var)
  34.             )
  35.             (mapcar '(lambda ( a b c ) (if a (setvar b c))) val var '(0 1))
  36.             (command "_.pedit" "_m" sel1 sel2 "" "_j" "" "")
  37.         )
  38.   )
  39.  
  40.     (*error* nil)
  41.     (princ)
  42. )
  43. ;; ssget  -  Lee Mac
  44. ;; A wrapper for the ssget function to permit the use of a custom selection prompt
  45. ;; msg - [str] selection prompt
  46. ;; arg - [lst] list of ssget arguments
  47.  
  48. (defun LM:ssget ( msg arg / sel )
  49.     (princ msg)
  50.     (setvar 'nomutt 1)
  51.     (setq sel (vl-catch-all-apply 'ssget arg))
  52.     (setvar 'nomutt 0)
  53.     (if (not (vl-catch-all-error-p sel)) sel)
  54. )
  55.  
  56. ;; Start Undo  -  Lee Mac
  57. ;; Opens an Undo Group.
  58.  
  59. (defun LM:startundo ( doc )
  60.     (LM:endundo doc)
  61.     (vla-startundomark doc)
  62. )
  63.  
  64. ;; End Undo  -  Lee Mac
  65. ;; Closes an Undo Group.
  66.  
  67. (defun LM:endundo ( doc )
  68.     (while (= 8 (logand 8 (getvar 'undoctl)))
  69.         (vla-endundomark doc)
  70.     )
  71. )
  72.  
  73. ;; Active Document  -  Lee Mac
  74. ;; Returns the VLA Active Document Object
  75.  
  76. (defun LM:acdoc nil
  77.     (LM:acdoc)
  78. )
  79.  


   
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: ribarm on August 26, 2022, 02:39:47 PM
Perhaps, untested, though...

Code: [Select]
(command "_.pedit" "_m" (LM:ssget "SELECTED..." (list "_W" sel1 sel2)) "" "_j" "" "")
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Lee Mac on August 26, 2022, 03:18:38 PM
Perhaps try something along the lines of the following:
Code - Auto/Visual Lisp: [Select]
  1. ;; Polyline Join  -  Lee Mac
  2. ;; Attempts to join all lines, arcs and polylines in a selection.
  3.  
  4. (defun c:pj ( / *error* dim sel val var )
  5.    
  6.     (defun *error* ( msg )
  7.         (mapcar '(lambda ( a b ) (if b (setvar a b))) var val)
  8.         (LM:endundo (LM:acdoc))
  9.         (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
  10.             (princ (strcat "\nError: " msg))
  11.         )
  12.         (princ)
  13.     )
  14.  
  15.     (setq dim (getvar 'dimscale))
  16.     (LM:startundo (LM:acdoc))
  17.     (if
  18.         (setq sel
  19.             (ssget "_C"
  20.                 (mapcar '* (list dim dim) '(34.0 22.0625))
  21.                 (mapcar '* (list dim dim) '( 0.0 -1.0000))
  22.                '(
  23.                     (-4 . "<OR")
  24.                          (0 . "LINE,ARC")
  25.                          (-4 . "<AND")
  26.                              (0 . "LWPOLYLINE")
  27.                              (-4 . "<NOT")
  28.                                  (-4 . "&=") (70 . 1)
  29.                              (-4 . "NOT>")
  30.                          (-4 . "AND>")
  31.                      (-4 . "OR>")
  32.                 )
  33.             )
  34.         )
  35.         (progn
  36.             (setq var '(cmdecho peditaccept)
  37.                   val  (mapcar 'getvar var)
  38.             )
  39.             (mapcar '(lambda ( a b c ) (if a (setvar b c))) val var '(0 1))
  40.             (command "_.pedit" "_m" sel "" "_j" "" "")
  41.         )
  42.     )
  43.     (*error* nil)
  44.     (princ)
  45. )
  46.  
  47. ;; Start Undo  -  Lee Mac
  48. ;; Opens an Undo Group.
  49.  
  50. (defun LM:startundo ( doc )
  51.     (LM:endundo doc)
  52.     (vla-startundomark doc)
  53. )
  54.  
  55. ;; End Undo  -  Lee Mac
  56. ;; Closes an Undo Group.
  57.  
  58. (defun LM:endundo ( doc )
  59.     (while (= 8 (logand 8 (getvar 'undoctl)))
  60.         (vla-endundomark doc)
  61.     )
  62. )
  63.  
  64. ;; Active Document  -  Lee Mac
  65. ;; Returns the VLA Active Document Object
  66.  
  67. (defun LM:acdoc nil
  68.     (LM:acdoc)
  69. )
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 26, 2022, 04:35:48 PM
Aren't lines 35-39--and 7--a bit obfuscated? I mean, I feel this should be moved to a separate procedure call to clarify what is happening (-i.e. make more readable). I have this in one of my lib routines.
Code - Auto/Visual Lisp: [Select]
  1. (defun #Error_Push_Vars ( lst / push->lst)
  2.   ;; This procedure will generate a list of
  3.   ;; variables and their orig. value before
  4.   ;; changing them to a desired value
  5.   ;;
  6.   ;; By: John K
  7.   ;;     11.28.06
  8.   ;;
  9.   ;; Example Use: (#Error_Push_Vars
  10.   ;;                  '(("CMDECHO" 0) ("BLIPMODE" 1)
  11.   ;;                    ("SNAPANG" 45) ("OSMODE" 0)))
  12.   ;;
  13.   ;; The syntax of the list members is as follows:
  14.   ;;  ( <Variable name to change/save>  <setting desired> )
  15.   ;;
  16.   ;; The variables orig value will be saved for later
  17.   ;; restoration.
  18.   ;;
  19.   ;;
  20.   ;; Note: This procedure is part of the
  21.   ;;       an ERROR trap set of procedures.
  22.   ;;
  23.   (defun push->lst (sym lst)
  24.     (set lst (cons sym (eval lst))) )
  25.   (mapcar
  26.     '(lambda (x)
  27.        (push->lst (list 'setvar (car x) (getvar (car x))) '#Error_Lst#)
  28.        (if (cadr x)
  29.          (setvar (car x) (cadr x)))
  30.        )
  31.     lst
  32.     )
  33.   )
  34.  

Which would then also make line 7 become: (mapcar 'eval #Error_Lst#)
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Lee Mac on August 26, 2022, 04:56:58 PM
FWIW, I find mine more readable; also, what if the system variable isn't available in the version in which your function is evaluated?
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 26, 2022, 05:19:54 PM
The problem is that people will obviously copy paste code without understanding it so, *you* may find it more readable but *someone else* may not with out proper understanding; I was speaking more towards the black-box methodology.

It will error out, of course. -i.e. I understand yours will generate a nil list but which is worse for a programmer that may never notice they misspelled a variable: 1. blindly (re)set values assuming all is well or 2. code errors out upon load/run?

Code: [Select]
Command: (#Error_Push_Vars '(("CDECHO" 0)))
; error: AutoCAD variable setting rejected: "CDECHO" 0

Command: (setq var '(cdecho)
(_>       val  (mapcar 'getvar var))
(nil)
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Lee Mac on August 26, 2022, 06:01:54 PM
It will error out, of course. -i.e. I understand yours will generate a nil list but which is worse for a programmer that may never notice they misspelled a variable: 1. blindly (re)set values assuming all is well or 2. code errors out upon load/run?

A programmer mispelling a variable is just bad code; my point is that not all system variables are available in all versions of AutoCAD or on all platforms supporting a LISP API, hence if code is to be compatible across a wide range of releases, such differences need to be accounted for to avoid errors. For example, I believe the PEDITACCEPT system variable was introduced in 2004, so earlier versions would result in an error.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 27, 2022, 10:00:34 AM
Misspellings are a great portion of the compiler’s complainants about my code (but jokes aside). Precisely my point. Code should be maintained; if the procedure or developer needs a variable which isn’t available the rule is to “fail fast” because these errors are typically easier to find and fix.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Lee Mac on August 29, 2022, 08:21:43 AM
...if the procedure or developer needs a variable which isn’t available the rule is to “fail fast” because these errors are typically easier to find and fix.

This means that the code would only be compatible with a small range of releases, erroring in others.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: rkmcswain on August 29, 2022, 09:00:05 AM
Quote from: Lee Mac
....my point is that not all system variables are available in all versions of AutoCAD or on all platforms supporting a LISP API, hence if code is to be compatible across a wide range of releases, such differences need to be accounted for to avoid errors.

Just wanted to "like" this.  :angel:
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 29, 2022, 09:46:03 AM
I don't think I understand the argument; if the code needs a variable--and it's not available--you want it to continue until after you've changed the end-user's environment?

If the variable is not actually required -i.e. the code can run without it- why would you add it in the first place?
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Tharwat on August 29, 2022, 10:54:13 AM
If a variable ( that retrieved from sys_var ) has a value, then that means the system variable is available then set the new desired value otherwise ignore the setting and resetting on exit.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 29, 2022, 12:09:44 PM
If a variable ( that retrieved from sys_var ) has a value, then that means the system variable is available then set the new desired value otherwise ignore the setting and resetting on exit.

Right. But again, if your code can operate without that variable then why set/reset it in the first place?
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Tharwat on August 29, 2022, 12:57:29 PM
Of course there is a goal behind using system variables to perform a certain process and of course you have the choice to use it or to leave it behind.

So you can ignore the use of CMDECHO then the history statements of the command used will be printed on the command line so we need it for a better presentation and performance of codes in this case.

Suppose the CMDECHO was not supported into your AutoCAD release and we want to use it, then how to know without testing out the return value of that sys_var to decide to set then reset ? So the main point resides here.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 29, 2022, 01:18:22 PM
Of course there is a goal behind using system variables to perform a certain process and of course you have the choice to use it or to leave it behind.

So you can ignore the use of CMDECHO then the history statements of the command used will be printed on the command line so we need it for a better presentation and performance of codes in this case.

Suppose the CMDECHO was not supported into your AutoCAD release and we want to use it, then how to know without testing out the return value of that sys_var to decide to set then reset ? So the main point resides here.

Meh! I'm not sold; the code prohibits the use of current AutoCAD on MACs so it's not that big of an issue to limit the use of an 18+ year old AutoCAD release as well.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: jlogan02 on August 29, 2022, 06:19:41 PM

Edit: ...thought pattern.

Thanks for all the discussion. It helps seeing more accomplished ppl discuss varying ideas that us lesser beings might not ever see or understand.

I did question what lines 7 and 39 were doing. Totally as an assumption/guess I took it to mean if the variable exists as line 7 states, error, because it should really be as line 39 states. I certainly didn't take into account versions or platforms beyond my simple though pattern.

J. Logan 
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 30, 2022, 04:06:03 PM

Edit: ...thought pattern.

Thanks for all the discussion. It helps seeing more accomplished ppl discuss varying ideas that us lesser beings might not ever see or understand.

I did question what lines 7 and 39 were doing. Totally as an assumption/guess I took it to mean if the variable exists as line 7 states, error, because it should really be as line 39 states. I certainly didn't take into account versions or platforms beyond my simple though pattern.

J. Logan

Those lines (36, 37, 38) in Lee's code are a slightly modified version of a wonderful generic error handler skeleton ElpanovEvgeniy posted years ago. I didn't save the link but I'll paste the text below.

Essentially, what the code below does is gather up the variables and their initial values and store them in a list. This list is then evaluated later during the error handler run (very nice, clean system by ElpanovEvgeniy).

The discussion was (in a nut-shell):
Lee introduced a feature in his version. I questioned the need for that feature.

ElpanovEvgeniy's error hander:
Code: [Select]
In the beginning of function I establish a list of the necessary environment variables,
list variable always miscellaneous:
Code:
(SETQ
  ERROR-LST-
  '("AUTOSNAP" "OSMODE" "APERTURE" "HPSPACE" "HPASSOC"
    "MIRRTEXT" "AUPREC" "LUPREC" "DIMZIN" "cecolor") 
  ERROR-LST- (mapcar '(lambda (a) (list 'setvar a (getvar a))) ERROR-LST-)
  )

Function *error*
Code:
(defun *error* (msg)
  (MAPCAR 'eval ERROR-LST-))

It is a universal *error* function *smile*
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: VovKa on August 30, 2022, 05:26:07 PM
The discussion was (in a nut-shell):
Lee introduced a feature in his version. I questioned the need for that feature.
Evgeniy's example contains the answer to the question
it will crash on Acad2000 ;)
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: Lee Mac on August 30, 2022, 05:41:36 PM
I did question what lines 7 and 39 were doing. Totally as an assumption/guess I took it to mean if the variable exists as line 7 states, error, because it should really be as line 39 states. I certainly didn't take into account versions or platforms beyond my simple though pattern.

Analysing lines 36-39:
Code - Auto/Visual Lisp: [Select]
  1. (setq var '(cmdecho peditaccept)
  2.       val  (mapcar 'getvar var)
  3. )
  4. (mapcar '(lambda ( a b c ) (if a (setvar b c))) val var '(0 1))

Here we have:
Code - Auto/Visual Lisp: [Select]
  1. ;; Define a variable storing a list of symbols (this could also be strings) representing system variables
  2. var '(cmdecho peditaccept)
Code - Auto/Visual Lisp: [Select]
  1. ;; Retrieve the current values of those system variables (some of which may be nil if the system variable doesn't exist)
  2. val  (mapcar 'getvar var)
Code - Auto/Visual Lisp: [Select]
  1. ;; Here, mapcar iterates over every item in the lists 'val', 'var' and (0 1)
  2. ;; Within the lambda function:
  3. ;;    'a' = Current system variable value (which may be nil if the system variable doesn't exist)
  4. ;;    'b' = System variable symbol
  5. ;;    'c' = New system variable value
  6. ;; Within the lambda function, the 'if' statement just says, if the system variable has a value (i.e. it exists), set it to this new value
  7. (mapcar '(lambda ( a b c ) (if a (setvar b c))) val var '(0 1))

Those lines (36, 37, 38) in Lee's code are a slightly modified version of a wonderful generic error handler skeleton ElpanovEvgeniy posted years ago.

For the record, the code is not a modification of any existing function...
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: JohnK on August 30, 2022, 06:48:38 PM
Great post, Lee.
Title: Re: Modifying Lee Mac's PolyTools "PJ" routine without success.
Post by: jlogan02 on August 31, 2022, 03:54:27 PM
Well done Lee. If I can understand that explanation, anyone can.

Thanks.