Archiman86 Posted November 10, 2009 Posted November 10, 2009 Hello all, I am looking for a lisp routine to create a new layer by selecting an object. The idea is this: I have a series of objects on corresponding layers that are going to be part of a "future" expansion of the overall design. For that reason, I want to create seperate layers with a suffix of "-future" so that I can set layer properties accordingly (half-tone, etc.) Ideally I would like it to give an option to select objects, then take the layer name from that object and create a new one with the suffix and then put that object on that layer. That way I can select the future objects, and it will create all the layers and put them on for me. Any help would be greatly appreciated. Regards, Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 Whipped this up real quick, let me know if it works: (defun c:obtol( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget)) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (foreach forVar ssEnts (if (member (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") (layer-list)) (vl-cmdf "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") (vl-cmdf "-layer" "make" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") ) ) (setvar "cmdecho" echo) (princ) ) (defun layer-list( / layLst) (vl-load-com) (vlax-for vFor (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) (setq layLst (cons (vla-get-name vFor) layLst))) ) *EDIT* Hold on, I missed something.. gimme a sec to re-do it. Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 That works great thanks. Now is there a way to set the properties for the layer when it creates it. Namely I would like to set the color to 252 and the linetype to "hidden" Thanks again! Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 I didn't filter out the objects that were already on a "* - FUTURE" layer, so it ended up putting them on a "* - FUTURE - FUTURE" layer.. I fixed that. Here's the updated code with the layer properties set, however you need to make sure that the "Hidden" linetype is loaded, otherwise I'm pretty sure it'll error out. (defun c:obtol( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget)) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (foreach forVar ssEnts (if (not (wcmatch (cdr (assoc 8 (entget forVar))) "* - FUTURE")) (if (member (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") (layer-list)) (vl-cmdf "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") (vl-cmdf "-layer" "new" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "Ltype" "Hidden" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "Color" "252" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") ) ) ) (setvar "cmdecho" echo) (princ) ) (defun layer-list( / layLst) (vl-load-com) (vlax-for vFor (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) (setq layLst (cons (vla-get-name vFor) layLst))) ) *EDIT* Yes, I'm well aware of how hack this is >>" *EDIT EDIT* Ugh, not changing the properties.. note to self: don't submit code unless it's awesome. *EDIT EDIT EDIT* Ok a mistake on my mistake.. it SHOULD work, as long as the layer doesn't already exist.. Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 hey, as long as it works, which it does. I greatly appreciate this! My goal for this is to create two buttons, oen to put on future and one to take back off future. That way, when it comes back around to the future stuff being implemented, I would liek to easily switch them back to the normal layers (without "-future" suffix). That would probably be easier to do, since the layers are already created, it would just be to move it to the other layer. So for instance, I have a transformer that i want to put on future. So I would use this to select it and move it to layer "transformer-future". Then later on in the prject I would like to move it back to layer "transformer."...etc. Thanks again! Edit:correct, if the layer already exists it does not change it. is this possible? Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 Anything is possible, it's just a question of how. (defun c:obtol( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget)) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (foreach forVar ssEnts (if (not (wcmatch (cdr (assoc 8 (entget forVar))) "* - FUTURE")) (if (member (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") (layer-list)) (vl-cmdf "-layer" "Ltype" "hidden" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "-layer" "Color" "252" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") (vl-cmdf "-layer" "new" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "-layer" "Ltype" "hidden" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "-layer" "Color" "252" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "" "chprop" forVar "" "LAYER" (strcat (cdr (assoc 8 (entget forVar))) " - FUTURE") "") ) ) ) (setvar "cmdecho" echo) (princ) ) (defun layer-list( / layLst) (vl-load-com) (vlax-for vFor (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) (setq layLst (cons (vla-get-name vFor) layLst))) ) ... of course, "How well?" plays a big part, for people who take the time to care.. >>" Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 how would I write a seperate routine to change them back to the original layers when I need to. (see above) Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 Quick and dirty: (defun c:ftoo( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget "_X" '((8 . "* - FUTURE")))) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (if ssEnts (mapcar (function (lambda (x) (vl-cmdf "chprop" x "" "layer" (substr (cdr (assoc 8 (entget x))) (- (strlen (cdr (assoc 8 (entget x)))) 9)) ""))) ssEnts) ) (setvar "cmdecho" echo) (princ) ) Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 when I tried runng this, this is what I got Cannot find layer "T - FUTURE".Invalid option keyword. Invalid option keyword. Invalid option keyword. Cannot find layer "T - FUTURE". Invalid option keyword. Invalid option keyword. Invalid option keyword. Cannot find layer "T - FUTURE". Invalid option keyword. Invalid option keyword. Invalid option keyword. Cannot find layer "T - FUTURE". I do not necassarily need it to change the layers back. All I am looking to do is start the app...select the objects that I want to change back to normal layers, then have it move them back to the non-future layer. Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 Sorry, I'm actually at work (sshh, don't tell anyone) so I'm trying to do this fast. (defun c:ftoo( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget '((8 . "* - FUTURE")))) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (foreach forVar ssEnts (if (member (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) (layer-list)) (vl-cmdf "chprop" forVar "" "LAYER" (substr (cdr (assoc 8 (entget forVar))) 0 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "") (vl-cmdf "-layer" "new" (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "" "chprop" forVar "" "LAYER" (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "") ) ) (setvar "cmdecho" echo) (princ) ) (defun layer-list( / layLst) (vl-load-com) (vlax-for vFor (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) (setq layLst (cons (vla-get-name vFor) layLst))) ) Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 Im sorry to keep bothering you at work. This still will not work. I am not sure why. I got: Command: FTOOSelect objects: Specify opposite corner: 432 found Select objects: ; error: bad argument value: positive 0 Thanks again. I really appreciate all your help! If nothing else I can just isolate the layers and change them back one by one... Quote
Freerefill Posted November 10, 2009 Posted November 10, 2009 Dammit, I missed a substr... (defun c:ftoo( / layLst ss ssEnts echo) (vl-load-com) (setq echo (getvar "cmdecho")) (setvar "cmdecho" 0) (setq ss (ssget '((8 . "* - FUTURE")))) (if ss (setq ssEnts (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))) (foreach forVar ssEnts (if (member (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) (layer-list)) (vl-cmdf "chprop" forVar "" "LAYER" (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "") (vl-cmdf "-layer" "new" (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "" "chprop" forVar "" "LAYER" (substr (cdr (assoc 8 (entget forVar))) 1 (- (strlen (cdr (assoc 8 (entget forVar)))) 9)) "") ) ) (setvar "cmdecho" echo) (princ) ) (defun layer-list( / layLst) (vl-load-com) (vlax-for vFor (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) (setq layLst (cons (vla-get-name vFor) layLst))) ) Just had to set a 0 to a 1.. little stuff like that.. gotta love the debugging process. >. Quote
Archiman86 Posted November 10, 2009 Author Posted November 10, 2009 That works! Thank you soo much again! Where do I send the check to!? I wish I had the time to learn this stuff. I know the basics but I have to refer to references all the time. I can't come up with it off the top of my head. Thanks Again! Quote
jalucerol Posted November 10, 2009 Posted November 10, 2009 Great work freerefill!!! really fast Quote
Archiman86 Posted November 30, 2009 Author Posted November 30, 2009 Ok, now I have one more request alonf these lines. How would I set up a command to delete any un-used layers with the suffix "- FUTURE"? Say for instance, I do the preliminary work and set some to future layers. The previous routines select objects and creates the necassary "future" layers. Then say I come back later int he project and change some of the objects back to the original layers, leaving some of the future layers empty. Either I would like to have the change back command check the layers, or have a seperate command, for when I am going through and cleaning up the files before issue that will check for un-used future layers. Any ideas would be greatly appreciated, as usual. Thanks in advance Quote
Archiman86 Posted November 30, 2009 Author Posted November 30, 2009 Well, not exactly. See I may want to keep some layers that are unused that dont have "- future" as a suffix. I am trying to figure out a way to incorporate it into the existing commands I have written by freerefill or a seperate command by itself that would jsut delete any layers with suffix of "- future" Quote
Lee Mac Posted November 30, 2009 Posted November 30, 2009 Surely just: -purge la *- FUTURE n But if you need the code: (defun c:lpurge ( ) (command "_.-purge" "_la" "*- FUTURE" "_N") (princ)) Lee Quote
Archiman86 Posted November 30, 2009 Author Posted November 30, 2009 thank you for the info. I am relatively new to Lisp, and I dont use it regularly, so I forget things/capabilities. That helps. Thanks again. 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.