KRBeckman Posted February 17, 2010 Posted February 17, 2010 Hey Everybody, Lot of time when I'm surfacing the objects I'm drawing my surfaces share one edge (and 2 verticies), so instead of having to pick these points twice, I would like a lisp that takes the points selected for verticies 3 and 4 and save them to be used later as verticies 2 and 1 respectively. Here's what I've got so far: (defun c:sfs () (if (eq rst "") (setq rst "Yes") (progn (initget "Yes No") (setq rst (getkword "\nWould you like to reset this macro? (Y, <N>)")))) (if (eq rst "Yes") (progn (setq art "" pt1 "" pt2 "" pt3 "" pt4 "" px1 "" px2 "" px3 "" px4 "" py1 "" py2 "" py3 "" py4 "" pz0 "" edh "") (initget 1 "Rectangular Circular") (setq art (getkword "\nWhat type of Array?< Rectangular Circular >: ")) (command "_.pline" pause pause pause pause "cl")) (progn (command "_.pline" pt1 pt2 pause pause "cl"))) (setq pl1 (mapcar 'cdr(vl-remove-if '(lambda(x)(/= 10(car x)))(entget(entlast)))) px1 (car (nth 0 pl1)) py1 (cadr (nth 0 pl1)) pz0 (nth 0 (mapcar 'cdr(vl-remove-if '(lambda(x)(/= 38(car x)))(entget(entlast))))) px2 (car (nth 1 pl1)) py2 (cadr (nth 1 pl1)) px3 (car (nth 2 pl1)) py3 (cadr (nth 2 pl1)) px4 (car (nth 3 pl1)) py4 (cadr (nth 3 pl1)) pt1 (list px1 py1 pz0) pt2 (list px2 py2 pz0) pt3 (list px3 py3 pz0) pt4 (list px4 py4 pz0)) (command "_.erase" "l" "") (entmake (list (cons 0 "3DFACE") (cons 8 "Temp") (cons 100 "AcDbEntity") (cons 100 "AcDbFace") (cons 10 pt1) (cons 11 pt2) (cons 12 pt3) (cons 13 pt4) (cons 70 15)))) (cond (eq art "Rectangular") (progn (setq pt1 (list px4 py4 pz0) pt2 (list px3 py3 pz0))) (eq art "Circular") (progn (setq pt1 (list px1 py1 pz0) pt2 (list px4 py4 pz0)))) ) I am so close, its just not changing pt1 and pt2's coordinates in the end. Any help would be greatly appriciate. Quote
Lee Mac Posted February 17, 2010 Posted February 17, 2010 I seriously don't recommend this: (setq art "" pt1 "" pt2 "" pt3 "" pt4 "" px1 "" px2 "" px3 "" px4 "" py1 "" py2 "" py3 "" py4 "" pz0 "" edh "") Just localise the variables. Quote
KRBeckman Posted February 17, 2010 Author Posted February 17, 2010 Why? What could go wrong? The problem with localizing the variable is that I want to preserve the values of points 1 and 2 for the next time I run the lisp. That's the whole point of storing those values, that way I don't have to click on each point twice. Quote
Lee Mac Posted February 17, 2010 Posted February 17, 2010 Why? What could go wrong? The problem with localizing the variable is that I want to preserve the values of points 1 and 2 for the next time I run the lisp. That's the whole point of storing those values, that way I don't have to click on each point twice. Many things, they could clash with other programs, and you are setting them all to an empty string for some reason...? You can preserve points 1 and 2 as global variables, but all the rest can be localised. Quote
Lee Mac Posted February 17, 2010 Posted February 17, 2010 How about something like this: (defun c:sfs (/ 3DFace ent z ptLst) (defun 3DFace (p1 p2 p3 p4) (entmakex (list (cons 0 "3DFACE") (cons 8 "Temp") (cons 10 p1) (cons 11 p2) (cons 12 p3) (cons 13 p4) (cons 70 15)))) (if (and *pt1 *pt2 *art (not (initget "Yes No")) (eq "No" (cond ((getkword "\nWould you like to reset this macro? (Y, <N>)")) ("No")))) (command "_.pline" *pt1 *pt2 pause pause "_C") (progn (initget 1 "Rectangular Circular") (setq *art (getkword "\nWhat type of Array?< Rectangular Circular >: ")) (command "_.pline" pause pause pause pause "_C"))) (if (eq "LWPOLYLINE" (cdr (assoc 0 (entget (setq ent (entlast)))))) (progn (setq z (cond ((cdr (assoc 39 (entget ent)))) (0.0))) (apply '3DFace (setq ptLst (mapcar (function (lambda (x) (append x (list z)))) (mapcar (function cdr) (vl-remove-if-not (function (lambda (x) (= 10 (car x)))) (entget ent)))))) (entdel ent) (cond ( (eq *art "Rectangular") (setq *pt1 (nth 3 ptLst) *pt2 (nth 2 ptLst))) ( (eq *art "Circular") (setq *pt1 (nth 0 ptLst) *pt2 (nth 3 ptLst)))))) (princ)) Quote
KRBeckman Posted February 17, 2010 Author Posted February 17, 2010 Yeah, that works great... But I'm still wondering why my way didn't work. Any insight? Quote
Lee Mac Posted February 17, 2010 Posted February 17, 2010 Yeah, that works great... But I'm still wondering why my way didn't work. Any insight? Your COND statement didn't have properly defined text expressions. Quote
KRBeckman Posted February 17, 2010 Author Posted February 17, 2010 Gotcha, thanks a ton again for your help. Quote
Lee Mac Posted February 17, 2010 Posted February 17, 2010 Gotcha, thanks a ton again for your help. You're welcome Quote
KRBeckman Posted February 23, 2010 Author Posted February 23, 2010 Hey Lee, I just realized a problem with this... it only creates the 3-d face on the top ucs... and at elevation of "0". I would like this to create the 3-d face where ever and on what ever ucs I draw the polyline. I'm thinking this has to do with using a LWPOLYLINE, but I don't know how to change it. Any suggestions? Quote
Lee Mac Posted February 23, 2010 Posted February 23, 2010 Perhaps use a Polyline? (defun c:sfs (/ 3DFace vlax-list->3D-point ent ptLst) (defun 3DFace (p1 p2 p3 p4) (entmakex (list (cons 0 "3DFACE") (cons 8 "Temp") (cons 10 p1) (cons 11 p2) (cons 12 p3) (cons 13 p4) (cons 70 15)))) (defun vlax-list->3D-point (lst) (if lst (cons (list (car lst) (cadr lst) (caddr lst)) (vlax-list->3D-point (cdddr lst))))) (if (and *pt1 *pt2 *art (not (initget "Yes No")) (eq "No" (cond ((getkword "\nWould you like to reset this macro? [Yes/No] <No>)")) ("No")))) (command "_.3DPoly" *pt1 *pt2 pause pause "_C") (progn (initget 1 "Rectangular Circular") (setq *art (getkword "\nWhat type of Array? [Rectangular/Circular] : ")) (command "_.3DPoly" pause pause pause pause "_C"))) (if (eq "POLYLINE" (cdr (assoc 0 (entget (setq ent (entlast)))))) (progn (apply '3DFace (setq ptLst (vlax-list->3D-point (vlax-get (vlax-ename->vla-object ent) 'Coordinates)))) (entdel ent) (cond ( (eq *art "Rectangular") (setq *pt1 (nth 3 ptLst) *pt2 (nth 2 ptLst))) ( (eq *art "Circular") (setq *pt1 (nth 0 ptLst) *pt2 (nth 3 ptLst)))))) (princ)) Quote
KRBeckman Posted February 23, 2010 Author Posted February 23, 2010 Didn't realize it'd be that easy... Worked great... If you don't mind, how would you loop it so that once you select a rectangular or cicular array you keep making polylines/faces? Quote
Lee Mac Posted February 23, 2010 Posted February 23, 2010 Didn't realize it'd be that easy... Worked great... If you don't mind, how would you loop it so that once you select a rectangular or cicular array you keep making polylines/faces? "Didn't realize it'd be that easy."... I approached it using Visual LISP, and used a recursive function to convert the point list to a list of 3D points - I wouldn't say it was an 'easy' transition. Use the While function to loop the program. Quote
KRBeckman Posted March 19, 2010 Author Posted March 19, 2010 Hey Lee... I changed this up just a little bit and now I'm having problems... I added a default value for *art and made it so that when prompted for the type of array the user can just hit enter to either use the default if this is the first time its ran or use the last entry used: (defun c:sfs (/ 3DFace vlax-list->3D-point ent ptLst) (setq *art (if (not *art) "Rectangular" *art) old_art *art) (defun 3DFace (p1 p2 p3 p4) (entmakex (list (cons 0 "3DFACE") (cons 8 "Temp") (cons 10 p1) (cons 11 p2) (cons 12 p3) (cons 13 p4) (cons 70 15)))) (defun vlax-list->3D-point (lst) (if lst (cons (list (car lst) (cadr lst) (caddr lst)) (vlax-list->3D-point (cdddr lst))))) (if (and *pt1 *pt2 *art (not (initget "Yes No")) (eq "No" (cond ((getkword "\nWould you like to reset this macro? [Yes/No] <No>)")) ("No")))) (command "_.3DPoly" *pt1 *pt2 pause pause "_C") (progn (initget "Rectangular Circular") (setq art_r (if (= *art "Rectangular") "<Rectangular>" "Rectangular") art_c (if (= *art "Circular") "<Circular>" "Circular") art_pmt (strcat "\nWhat type of Array? [" art_r "/" art_c "]: ") *art (getkword art_pmt) *art (if (= *art "") old_art *art)) (command "_.3DPoly" pause pause pause pause "_C"))) (if (eq "POLYLINE" (cdr (assoc 0 (entget (setq ent (entlast)))))) (progn (apply '3DFace (setq ptLst (vlax-list->3D-point (vlax-get (vlax-ename->vla-object ent) 'Coordinates)))) (entdel ent) (cond ( (eq *art "Rectangular") (setq *pt1 (nth 3 ptLst) *pt2 (nth 2 ptLst))) ( (eq *art "Circular") (setq *pt1 (nth 0 ptLst) *pt2 (nth 3 ptLst)))))) (princ)) But now after I run it once, its not asking me if I'd like to reset the macro or using the points from the previous use. Any ideas? Quote
KRBeckman Posted March 19, 2010 Author Posted March 19, 2010 ok, so it only does this when I try to do a Rectangular Array???? What the heck is going on? Quote
KRBeckman Posted March 19, 2010 Author Posted March 19, 2010 Got it to work, but not sure why.... I got rid of declaring the local variable in the first line and now it works, but I don't get how that would effect it. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.