TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: David Hall on August 21, 2014, 03:36:06 PM

Title: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 21, 2014, 03:36:06 PM
I cant seem to find where I can change a variant if I use vla-getpoint.  In VBA, I have a point called InsPT1, and I can change the Z value using InsPT1(2) = WhateverNumber.  How can I do something similiar in Vlisp? 


Actually, let me tell you what I have done, so you can see the nasty version of poor code.
Code: [Select]
(setq INSPT (getpoint "INSERTION POINT: "))
      (setq INSPT (vlax-3d-point  (list (car INSPT) (cadr INSPT) (atof BUSHEIGHT))
  )
      )
      (setq ROT (vla-getangle UTIL INSPT "SELECT ROTATION: "))
The only way I could figure it out was to use getpoint, then pull car and cadr out, and put my Z in and then make a vlax-3d-point
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: ronjonp on August 21, 2014, 03:53:19 PM
Use (vlax-get (vlax-ename->vla-object (car (entsel))) 'insertionpoint) it will return a point list.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 21, 2014, 04:50:14 PM
But is there a way to use vla-getpoint and pull out the Z value?
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Kerry on August 21, 2014, 05:37:32 PM
But is there a way to use vla-getpoint and pull out the Z value?

Try something like this David

Code - Auto/Visual Lisp: [Select]
  1.  
  2.       doc     (vla-get-activedocument acadobj)
  3. )
  4.  
  5. (setq ppt     (vla-getpoint (vla-get-utility doc) nil "Enter a point: ")
  6.       mypoint (vlax-variant-value ppt)
  7.       zvalue  (vlax-safearray-get-element mypoint 2)
  8. )
  9.  
  10. (vlax-safearray-put-element mypoint 2 1.66)
  11.  
  12. (setq new-zvalue (vlax-safearray-get-element mypoint 2))
  13.  
  14.  
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 09:53:14 AM
Thanks Kerry, That was the missing piece I was looking for.  I kept seeing references to safe arrays, but wasn't sure what to do with it.  I 'm off to try this out.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 11:01:17 AM
Perfect Kerry, that was what I needed!  As a test I used addline to text the variables, and it worked perfectly
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Kerry on August 22, 2014, 11:04:49 AM
Most excellent!
In that case, I'll go to bed now.
g'night.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 03:23:28 PM
So now I'm stuck trying to make a region.  I used this code
Code - Auto/Visual Lisp: [Select]
  1.         DOC     (vla-get-activedocument ACADOBJ)
  2.         UTIL    (vla-get-utility DOC)
  3.         MSPACE  (vla-get-modelspace DOC)
  4.   )
  5.   (setq WALL_LENGTH
  6.          (vla-getreal
  7.            UTIL
  8.            "Enter Wall Length: "
  9.          )
  10.   )
  11.   (setq WALL_LENGTH_IN (cvunit WALL_LENGTH "ft" "in"))
  12.   (if (/= (rem WALL_LENGTH_IN 8) 0)
  13.     (setq WALL_LENGTH_IN
  14.            (+ WALL_LENGTH_IN (- 8 (rem WALL_LENGTH_IN 8)))
  15.     )
  16.   )
  17.   (setq WALL_WIDTH
  18.          (vla-getreal
  19.            UTIL
  20.            "Enter Wall Width: "
  21.          )
  22.   )
  23.   (setq WALL_WIDTH_IN (cvunit WALL_WIDTH "ft" "in"))
  24.   (if (/= (rem WALL_WIDTH_IN 8) 0)
  25.     (setq WALL_WIDTH_IN (+ WALL_WIDTH_IN (- 8 (rem WALL_WIDTH_IN 8))))
  26.   )
  27.   (setq WALL_HEIGHT
  28.          (vla-getreal
  29.            UTIL
  30.            "Enter Wall Height: "
  31.          )
  32.   )
  33.   (setq WALL_HEIGHT_IN (cvunit WALL_HEIGHT "ft" "in"))
  34.   (if (/= (rem WALL_HEIGHT_IN 8) 0)
  35.     (setq WALL_HEIGHT_IN
  36.            (+ WALL_HEIGHT_IN (- 8 (rem WALL_HEIGHT_IN 8)))
  37.     )
  38.   )
  39.  
  40.  
  41.   (setq INSPT (getpoint "Pick Upper Left Wall Corner: "))
  42.   (setq WALLULO (list (car INSPT) (cadr INSPT))
  43.         WALLULI
  44.                 (list (+ (car INSPT) 8) (- (cadr INSPT) 8))
  45.  
  46.  
  47.         WALLURO
  48.                 (list (+ (car INSPT) WALL_LENGTH_IN) (cadr INSPT))
  49.  
  50.  
  51.         WALLURI
  52.                 (list (- (+ (car INSPT) WALL_LENGTH_IN) 8)
  53.                       (- (cadr INSPT) 8)
  54.  
  55.  
  56.                 )
  57.  
  58.  
  59.         WALLLLO
  60.                 (list (car INSPT) (- (cadr INSPT) WALL_WIDTH_IN))
  61.  
  62.  
  63.         WALLLLI
  64.                 (list (+ (car INSPT) 8)
  65.                       (+ (- (cadr INSPT) WALL_WIDTH_IN) 8)
  66.  
  67.  
  68.                 )
  69.  
  70.  
  71.         WALLLRO
  72.                 (list (+ (car INSPT) WALL_LENGTH_IN)
  73.                       (- (cadr INSPT) WALL_WIDTH_IN)
  74.  
  75.  
  76.                 )
  77.  
  78.  
  79.         WALLLRI
  80.                 (list (- (+ (car INSPT) WALL_LENGTH_IN) 8)
  81.                       (+ (- (cadr INSPT) WALL_WIDTH_IN) 8)
  82.  
  83.  
  84.                 )
  85.  
  86.   )

to make a list of points.  Then trying to figure out how to make a region, I made this list

Code - Auto/Visual Lisp: [Select]
  1. (setq A (list WALLULO WALLURO WALLLRO WALLLLO))

But now I'm stuck with what to do next.  I tried making a safearray with this

Code - Auto/Visual Lisp: [Select]
  1.  (setq sa (vlax-make-safearray vlax-vbdouble '(1 . 2) '(1 .4)))
  2.   (setq sa (vlax-safearray-fill sa (list WALLULO WALLURO WALLLRO WALLLLO)))

which seemed to work, meaning no error was returned, but when I tried to make a region, it fails

Code - Auto/Visual Lisp: [Select]
  1. (setq OW (vla-addregion (list MSPACE sA) ))
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 04:41:52 PM
David,

The ActiveX addregion method requires one or more objects from which the region will be created, therefore, you would need to construct a temporary polyline perhaps, and then create the region from the polyline, before deleting the polyline.

Lee
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 04:44:41 PM
I tried that too, but to no avail.  I cant seem to get the syntax correct
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 04:50:38 PM
I tried that too, but to no avail.  I cant seem to get the syntax correct

Give me a minute, I'll post an example for you   :-)
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 04:52:28 PM
thanks Lee, I am struggling with learning this VLisp syntax.  I read the VBA examples (oh this is so easy in VBA) but cant seem to translate it to VLisp
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 05:10:18 PM
No worries David :-)

Try the following:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / *error* roundup8 doc hgt len lli llp lri lrp pl1 pl2 rg1 rg2 spc uli ulp uri urp wid )
  2.  
  3.     (defun *error* ( msg )
  4.         (foreach obj (list pl1 pl2 rg1 rg2)
  5.             (if (and obj (vlax-write-enabled-p obj)) (vla-delete obj))
  6.         )
  7.         (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
  8.             (princ (strcat "\nError: " msg))
  9.         )
  10.         (princ)
  11.     )
  12.  
  13.     (defun roundup8 ( n / r )
  14.         (setq r (rem n 8))
  15.         (if (or (equal 0.0 r 1e-8) (equal 8.0 r 1e-8)) (atof (rtos n 2 0)) (+ n (- 8 r)))
  16.     )
  17.           spc (vla-get-modelspace doc)
  18.     )
  19.     (initget 6)
  20.     (if (setq len (getdist "\nEnter wall length: "))
  21.         (progn
  22.             (setq len (roundup8 (* len 12.0)))
  23.             (initget 6)
  24.             (if (setq wid (getdist "\nEnter wall width: "))
  25.                 (progn
  26.                     (setq wid (roundup8 (* wid 12.0)))
  27.                     (initget 6)
  28.                     (if (setq hgt (getdist "\nEnter wall height: "))
  29.                         (progn
  30.                             (setq hgt (roundup8 (* hgt 12.0)))
  31.                             (if (setq ulp (getpoint "\nPick upper-left wall corner: "))
  32.                                 (progn
  33.                                     (setq ulp (list (car ulp) (cadr ulp))
  34.                                           lrp (mapcar '+ ulp  (list len (- wid)))
  35.                                           uli (mapcar '+ ulp '( 8 -8))
  36.                                           lri (mapcar '+ lrp '(-8  8))
  37.                                           urp (list (car lrp) (cadr ulp))
  38.                                           llp (list (car ulp) (cadr lrp))
  39.                                           uri (list (car lri) (cadr uli))
  40.                                           lli (list (car uli) (cadr lri))
  41.                                           pl1 (vlax-invoke spc 'addlightweightpolyline (append ulp urp lrp llp))
  42.                                           pl2 (vlax-invoke spc 'addlightweightpolyline (append uli uri lri lli))
  43.                                     )
  44.                                     (vla-put-closed pl1 :vlax-true)
  45.                                     (vla-put-closed pl2 :vlax-true)
  46.                                     (setq rg1 (car (vlax-invoke spc 'addregion (list pl1)))
  47.                                           rg2 (car (vlax-invoke spc 'addregion (list pl2)))
  48.                                     )
  49.                                     (vla-delete pl1)
  50.                                     (vla-delete pl2)
  51.                                     (vla-boolean rg1 acsubtraction rg2)
  52.                                     (vlax-invoke spc 'addextrudedsolid rg1 hgt 0.0)
  53.                                     (vla-delete rg1)
  54.                                 )
  55.                             )
  56.                         )
  57.                     )
  58.                 )
  59.             )
  60.         )
  61.     )
  62.     (princ)
  63. )

Feel free to ask if you have any questions about the code  :-)

EDIT: Changed the point calculations.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 05:23:10 PM
much appreciated!!!  But why/How this -  pl1 (vlax-invoke spc 'addlightweightpolyline (append ins uro lro llo))
instead of vla-addlightweightpolyline?
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 05:28:36 PM
much appreciated!!!  But why/How this -  pl1 (vlax-invoke spc 'addlightweightpolyline (append ins uro lro llo))
instead of vla-addlightweightpolyline?

You're welcome  :-)

I use the undocumented vlax-invoke function (there is also vlax-get/vlax-put for properties, though, vlax-put can be temperamental) to avoid the use of variants & safearrays - these functions accept arguments in native AutoLISP data types, such as lists.

I'll post another example using variants/safearrays for comparison.

Lee
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 05:35:00 PM
Using variants/safearrays:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / *error* roundup8 list->variant doc hgt len lli llp lri lrp pl1 pl2 rg1 rg2 spc uli ulp uri urp wid )
  2.  
  3.     (defun *error* ( msg )
  4.         (foreach obj (list pl1 pl2 rg1 rg2)
  5.             (if (and obj (vlax-write-enabled-p obj)) (vla-delete obj))
  6.         )
  7.         (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
  8.             (princ (strcat "\nError: " msg))
  9.         )
  10.         (princ)
  11.     )
  12.  
  13.     (defun roundup8 ( n / r )
  14.         (setq r (rem n 8))
  15.         (if (or (equal 0.0 r 1e-8) (equal 8.0 r 1e-8)) (atof (rtos n 2 0)) (+ n (- 8 r)))
  16.     )
  17.  
  18.     (defun list->variant ( typ lst )
  19.         (vlax-make-variant
  20.             (vlax-safearray-fill
  21.                 (vlax-make-safearray typ (cons 0 (1- (length lst))))
  22.                 lst
  23.             )
  24.         )
  25.     )
  26.    
  27.           spc (vla-get-modelspace doc)
  28.     )
  29.     (initget 6)
  30.     (if (setq len (getdist "\nEnter wall length: "))
  31.         (progn
  32.             (setq len (roundup8 (* len 12.0)))
  33.             (initget 6)
  34.             (if (setq wid (getdist "\nEnter wall width: "))
  35.                 (progn
  36.                     (setq wid (roundup8 (* wid 12.0)))
  37.                     (initget 6)
  38.                     (if (setq hgt (getdist "\nEnter wall height: "))
  39.                         (progn
  40.                             (setq hgt (roundup8 (* hgt 12.0)))
  41.                             (if (setq ulp (getpoint "\nPick upper-left wall corner: "))
  42.                                 (progn
  43.                                     (setq ulp (list (car ulp) (cadr ulp))
  44.                                           lrp (mapcar '+ ulp  (list len (- wid)))
  45.                                           uli (mapcar '+ ulp '( 8 -8))
  46.                                           lri (mapcar '+ lrp '(-8  8))
  47.                                           urp (list (car lrp) (cadr ulp))
  48.                                           llp (list (car ulp) (cadr lrp))
  49.                                           uri (list (car lri) (cadr uli))
  50.                                           lli (list (car uli) (cadr lri))
  51.                                           pl1 (vla-addlightweightpolyline spc (list->variant vlax-vbdouble (append ulp urp lrp llp)))
  52.                                           pl2 (vla-addlightweightpolyline spc (list->variant vlax-vbdouble (append uli uri lri lli)))
  53.                                     )
  54.                                     (vla-put-closed pl1 :vlax-true)
  55.                                     (vla-put-closed pl2 :vlax-true)
  56.                                     (setq rg1 (car (vlax-safearray->list (vlax-variant-value (vla-addregion spc (list->variant vlax-vbobject (list pl1))))))
  57.                                           rg2 (car (vlax-safearray->list (vlax-variant-value (vla-addregion spc (list->variant vlax-vbobject (list pl2))))))
  58.                                     )
  59.                                     (vla-delete pl1)
  60.                                     (vla-delete pl2)
  61.                                     (vla-boolean rg1 acsubtraction rg2)
  62.                                     (vla-addextrudedsolid spc rg1 hgt 0.0)
  63.                                     (vla-delete rg1)
  64.                                 )
  65.                             )
  66.                         )
  67.                     )
  68.                 )
  69.             )
  70.         )
  71.     )
  72.     (princ)
  73. )
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 06:01:16 PM
Here's another quick example for a general wall outline:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:wall ( / *error* ent hgt obj off pt1 rg1 rg2 spc thk )
  2.  
  3.     (defun *error* ( msg )
  4.         (foreach obj (vl-list* obj rg1 (append rg2 off))
  5.             (if (and obj (vlax-write-enabled-p obj))
  6.                 (vla-delete obj)
  7.             )
  8.         )
  9.         (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
  10.             (princ (strcat "\nError: " msg))
  11.         )
  12.         (princ)
  13.     )
  14.  
  15.     (setq thk 8.0) ;; Wall thickness
  16.  
  17.     (if (setq pt1 (getpoint "\nPick start point: "))
  18.         (progn
  19.             (setq spc (vlax-get-property (LM:acdoc) (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
  20.                   ent (entlast)
  21.             )
  22.             (vl-cmdf "_.pline" "_non" pt1)
  23.             (while (= 1 (logand 1 (getvar 'cmdactive))) (vl-cmdf "\\"))
  24.             (if (and (not (eq ent (setq ent (entlast))))
  25.                      (= "AcDbPolyline" (vla-get-objectname (setq obj (vlax-ename->vla-object ent))))
  26.                      (progn
  27.                          (vla-put-closed obj :vlax-true)
  28.                          (initget 6)
  29.                          (setq hgt (getdist "\nSpecify wall height: "))
  30.                      )
  31.                 )
  32.                 (progn
  33.                     (if (not (LM:listclockwise-p (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) (entget ent)))))
  34.                         (setq thk (- thk))
  35.                     )
  36.                     (if (setq off (LM:catchapply 'vlax-invoke (list obj 'offset thk)))
  37.                         (if (setq rg1 (car (LM:catchapply 'vlax-invoke (list spc 'addregion (list obj)))))
  38.                             (if (setq rg2 (LM:catchapply 'vlax-invoke (list spc 'addregion off)))
  39.                                 (progn
  40.                                     (foreach reg rg2 (vla-boolean rg1 acsubtraction reg))
  41.                                     (vla-addextrudedsolid spc rg1 hgt 0.0)
  42.                                 )
  43.                                 (princ "\nUnable to create internal region.")
  44.                             )
  45.                             (princ "\nUnable to create external region.")
  46.                         )
  47.                         (princ "\nWall outline too small for wall thickness.")
  48.                     )
  49.                 )
  50.             )
  51.         )
  52.     )
  53.     (*error* nil) (princ)
  54. )
  55.  
  56. ;; List Clockwise-p  -  Lee Mac
  57. ;; Returns T if the point list is clockwise oriented
  58.  
  59. (defun LM:ListClockwise-p ( lst )
  60.     (minusp
  61.         (apply '+
  62.             (mapcar
  63.                 (function
  64.                     (lambda ( a b )
  65.                         (- (* (car b) (cadr a)) (* (car a) (cadr b)))
  66.                     )
  67.                 )
  68.                 lst (cons (last lst) lst)
  69.             )
  70.         )
  71.     )
  72. )
  73.  
  74. ;; Catch Apply  -  Lee Mac
  75. ;; Applies a function to a list of parameters and catches any exceptions.
  76.  
  77. (defun LM:catchapply ( fnc prm / rtn )
  78.     (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply fnc prm))))
  79.         rtn
  80.     )
  81. )
  82.  
  83. ;; Active Document  -  Lee Mac
  84. ;; Returns the VLA Active Document Object
  85.  
  86. (defun LM:acdoc nil
  87.     (LM:acdoc)
  88. )

Quick demo:

(http://lee-mac.com/swamp/generalwall.gif)
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 22, 2014, 06:09:11 PM
OMG, I can now see why I was having so much trouble.  I like your first method much better.  Thanks Lee, your awesome!!!
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 22, 2014, 06:18:03 PM
OMG, I can now see why I was having so much trouble.  I like your first method much better.  Thanks Lee, your awesome!!!

Thanks David - I agree, its usually much easier to avoid variants/safearrays if possible.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: ribarm on August 23, 2014, 02:37:54 AM
@Lee, I would suggest that you use (initget 7) instead of (initget 6) to avoid nil result after user presses enter while (getdist)...
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 23, 2014, 08:25:06 AM
@Lee, I would suggest that you use (initget 7) instead of (initget 6) to avoid nil result after user presses enter while (getdist)...

This is not necessary as the null input is accounted for by the various if statements; furthermore, if (initget 7) were to be used, the user would have no way of exiting the program without pressing Esc & forcing an error.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 27, 2014, 01:54:34 PM
Lee, using your code from above, I am trying to cut a hole in the wall.  I have gotten this far
Code - Auto/Visual Lisp: [Select]
  1. (defun DRAW_GATE (/ *ERROR* ROUNDUP8 DOC SPC LEN REFCORNER)
  2.   (defun *ERROR* (MSG)
  3.     (foreach OBJ (list PL1 PL2 RG1 RG2)
  4.       (if (and OBJ (vlax-write-enabled-p OBJ))
  5.    (vla-delete OBJ)
  6.       )
  7.     )
  8.     (if   (not (wcmatch (strcase MSG t) "*break,*cancel*,*exit*"))
  9.       (princ (strcat "\nError: " MSG))
  10.     )
  11.     (princ)
  12.   )
  13.  
  14.   (defun ROUNDUP8 (N / R)
  15.     (setq R (rem N)
  16.     (if   (or (equal 0.0 R 1e-8) (equal 8.0 R 1e-8))
  17.       (atof (rtos N 2 0))
  18.       (+ N (- 8 R))
  19.     )
  20.   )
  21.    SPC (vla-get-modelspace DOC)
  22.   )
  23.  
  24.   (initget 6)
  25.   (if (setq LEN (getdist "\nEnter Distance from corner >= 15.333: "))
  26.     (progn
  27.       (setq LEN (ROUNDUP8 (* LEN 12.0)))
  28.       (if (setq REFCORNER (getpoint "\nPick reference corner: "))
  29.    (progn
  30.      (if (setq
  31.       REFANGLE (getangle REFCORNER
  32.                "\nPick reference point on wall: "
  33.           )
  34.          )
  35.        (setq INSPT       (polar REFCORNER REFANGLE LEN)
  36.         BOX       (vlax-invoke SPC 'ADDBOX INSPT 240 240 360)
  37.         SEL       (ssget '((0 . "3DSOLID")))
  38.         WALL       (car (entget (ssname SEL 0)))
  39.         WALLPIECE (vla-boolean WALL acsubtraction BOX)
  40.  
  41.        )
  42.  
  43.  
  44.      )
  45.    )
  46.       )
  47.     )
  48.   )
  49. )

but it errors out after creating the box.

Any Ideas?

Also, from code above, you set rg1 equal to the region created using car, when I try the same, it errors.


Also it should be noted that the error function needs updating, but I'm not quite sure what you were doing, so I haven't tried to change it yet.
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: David Hall on August 27, 2014, 06:04:59 PM
I was able to ake this work
Code: [Select]
    (setq INSPT     (polar REFCORNER REFANGLE LEN)
  BOX     (vlax-invoke SPC 'ADDBOX INSPT 240 240 360)
;;;   SEL     (ssget '((0 . "3DSOLID")))
  WALL      (car (entsel "\nPick wall: "))
  wall (vlax-ename->vla-object wall)
;;;   (vla-boolean WALL acintersection BOX)
  WALLPIECE (vla-boolean wall acsubtraction box)

    )
but I thought that the acintersection created a new piece of 3dsolid, not erase everything but the intersection
Title: Re: Change Z value of point after using VLA-GetPoint
Post by: Lee Mac on August 27, 2014, 06:41:04 PM
I was about to suggest converting the entity to a vla-object before issuing the boolean method, but it looks like you've got it  :-)

Yes, the acintersection operation will return only the intersection of the two solids.