Lee Mac Posted January 21, 2009 Posted January 21, 2009 Good Evening All - (or Morning for some...) , Ok, so this is my first real attempt at Visual LISP - I have always stuck to Common LISP as much as possible until now, but I am trying to delve into the world of VL.... Below is my first VL attempt. Please critisize/praise it all you like.... I need feedback to know if I am doing things right or wrong. (defun c:layupd (/ ent obj) (while (setq ent (car (entsel))) (setq obj (vlax-ename->vla-object ent)) (if (not (vl-catch-all-error-p (vla-put-layer obj "2"))) (princ "\nLayer Updated.") (princ "\nError Updating Layer.") ) (vlax-release-object obj) ) (princ) ) I thought I'd start off easy, just a LISP to change the layer of a selected object to layer 2. Any improvements, critisisms are welcome. Cheers Lee Quote
ASMI Posted January 21, 2009 Posted January 21, 2009 (defun c:layupd (/ ent obj) (while (setq ent(entsel)) (setq obj (vlax-ename->vla-object(car ent))) (if(not(vl-catch-all-error-p (vl-catch-all-apply 'vla-put-layer (list obj "2")))) (princ "\nLayer Updated.") (princ "\nError Updating Layer.") ) ) (princ) ) 1. (setq ent(entsel)) because (car nil) will generate an error in case of empty input. 2. Only vl-catch-all-apply function will generate error object 3. vlax-release-object no need with active document objects. Quote
Lee Mac Posted January 21, 2009 Author Posted January 21, 2009 Many thanks for your time ASMI in pointing out my mistakes - it is much appreciated. 1. (setq ent(entsel)) because (car nil) will generate an error in case of empty input. I really should've known this anyway - its not even specific to VL - but thanks for pointing it out. 2. Only vl-catch-all-apply function will generate error object OK, so I should use the functions: "vl-catch-all-error-p" and "vl-catch-all-apply" in pairs - nice. 3. vlax-release-object no need with active document objects. Ahh, ok, I spoke with CAB about this a while back and so just put it in just in case - but thanks for pointing it out. Quote
CarlB Posted January 21, 2009 Posted January 21, 2009 1. (setq ent(entsel)) because (car nil) will generate an error in case of empty input. Just to not confuse anyone, this point is not true, try it. Maybe ASMI was thinking of "entget" on a nil which would give an error. Quote
Lee Mac Posted January 21, 2009 Author Posted January 21, 2009 Good Point Carl, just tried typing (car nil) in my command prompt - returns nil Well spotted - good man. :wink: Quote
Lee Mac Posted January 21, 2009 Author Posted January 21, 2009 Using knowledge gained from ASMI's post: Second real attempt: (defun Make_Reactor () (vl-load-com) (if (not vport:reactor) (setq vport:reactor (vlr-command-reactor nil '((:vlr-commandWillStart . vpPrompt))))) (princ)) (Make_Reactor) (defun vpPrompt (Reac args / ss i vp ent obj) (if (and (= (car args) "QSAVE") (setq ss (ssget "X" '((0 . "VIEWPORT")))) (not (zerop (setq i (sslength ss))))) (progn (setq vp i) (while (not (minusp (setq i (1- i)))) (setq ent (ssname ss i) obj (vlax-ename->vla-object ent)) (if (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-put-DisplayLocked (list obj 1)))) (princ))) (princ (strcat "\n" (rtos vp) " Viewport(s) Locked.")))) (princ)) Quote
ASMI Posted January 22, 2009 Posted January 22, 2009 1. (setq ent(entsel)) because (car nil) will generate an error in case of empty input. Sorry, I would say (vlax-ename-> vla-object nil) will generate an error. Quote
ASMI Posted January 22, 2009 Posted January 22, 2009 (defun vpPrompt (Reac args / ss sCnt eCnt ent obj) (if (and (= (car args) "QSAVE") (setq ss (ssget "X" '((0 . "VIEWPORT")))) (not(zerop (setq i (sslength ss))))) (progn (setq sCnt 0 eCnt 0) (foreach vp [color="Blue"](mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr(ssnamex ss)))) ; transforms set to list[/color] (if(vl-catch-all-error-p (vl-catch-all-apply 'vla-put-DisplayLocked(list vp [color="#0000ff"]:vlax-true[/color]))) [color="#0000ff"](setq eCnt(1+ eCnt)) (setq sCnt(1+ sCnt))[/color] ); end if ); end foreach [color="#0000ff"](princ(strcat "\n" (itoa sCnt) " Vieport(s) locked" (if(/= 0 eCnt) (strcat ", " (itoa eCnt) " were on locked layer! ") "." ); end if ); end strcat ); end princ[/color] ); end progn ); end if (princ) ) 1. If you go on a more serious level is not much sense to work with selection sets. LISP - a language of processing lists and convertion the selection set to list just get you a lot of new features. For example work with FOREACH, MAPCAR, APPLY, LAMBDA functions instead of the standard and dull entities extraction using SSNAME. 2. Of course, you can use integers as constants of the system, but still recommended to use the full name. :vlax-true more informative than 1, but if you look at the other constants is difficult to imagine for example that corresponds to 12 acAlignmentMiddleRight. 3. Every time you tell that all viewport locked, in fact, some may be locked layer. So I completed your prompt. Quote
Lee Mac Posted January 22, 2009 Author Posted January 22, 2009 1. If you go on a more serious level is not much sense to work with selection sets. LISP - a language of processing lists and convertion the selection set to list just get you a lot of new features. For example work with FOREACH, MAPCAR, APPLY, LAMBDA functions instead of the standard and dull entities extraction using SSNAME. Thanks for this pointer - I must admit, having a list of all the entities would be a hell of a lot more convenient than having to manually step through the set one by one. But I have one more question regarding the piece of code you inserted: (mapcar 'vlax-ename->vla-object ; [b][color=Blue]Produce a List of VL-Objects.[/color][/b] (vl-remove-if 'listp ; [b][color=Blue]Why do you need this here? Surely there are only Entity Names in the List?[/color][/b] (mapcar 'cadr (ssnamex ss)) ; [b][color=Blue]Creates a List of all the Entity Names (enames)[/color][/b] ) ) My question being, why do you need to have "vl-remove-if 'listp...." in there? Surely the original list generated by (mapcar 'cadr (ssnamex ss)) will only contain the entity names? 2. Of course, you can use integers as constants of the system, but still recommended to use the full name. :vlax-true more informative than 1, but if you look at the other constants is difficult to imagine for example that corresponds to 12 acAlignmentMiddleRight. This is a great point. I suppose :vlax-true is much less ambiguous. Thanks 3. Every time you tell that all viewport locked, in fact, some may be locked layer. So I completed your prompt. Thanks for this - much more professional. - I hadn't accounted for that circumstance. I am very grateful to you ASMI for pointing these things out - I can learn from them. Cheers Lee Quote
ASMI Posted January 22, 2009 Posted January 22, 2009 My question being, why do you need to have "vl-remove-if 'listp...." in there? Surely the original list generated by (mapcar 'cadr (ssnamex ss)) will only contain the entity names? Not only enames. Look for the end members of list - it may be points of selection poligon (depends on selection method). vl-remove-if 'listp - removes lists of points. Quote
Lee Mac Posted January 22, 2009 Author Posted January 22, 2009 I have one more query regarding VL: If I want to change the property of a list of VL entities, would I use "foreach" or "mapcar"? i.e. Changing every Entity in a list to Red: (foreach ent entlst (vla-put-color ent "1")) Or (mapcar 'vla-put-color entlst '("1")) What would you recommend? Quote
ASMI Posted January 22, 2009 Posted January 22, 2009 (foreach ent entlst (vla-put-color ent [color="Blue"]1[/color]) ); end foreach or (mapcar [color="#0000ff"]'(lambda(x)(vla-put-color x 1))[/color]entlst) There isn't a big difference, but it is thought that MAPCAR faster function (is whether or not I do not know). Main is the correct syntax. Please note that the argument of Color property is the integer (not a string) and function MAPCAR supports only one function for this ase you should use LAMBDA. Quote
Lee Mac Posted January 22, 2009 Author Posted January 22, 2009 Cheers for the heads up ASMI - I am trying to use the VL more and more - things are easier with it. I thought I may have to use a lambda function - mapcar and lambda seem to pair up quite regularly. Thanks once again Lee 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.