Jump to content

Creating layers by selecting objects


Recommended Posts

Posted

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,

  • Replies 37
  • Created
  • Last Reply

Top Posters In This Topic

  • Archiman86

    16

  • Lee Mac

    12

  • Freerefill

    7

  • ronjonp

    2

Posted

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.

Posted

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!

Posted

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..

Posted

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?

Posted

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.. >>"

Posted

how would I write a seperate routine to change them back to the original layers when I need to. (see above)

Posted

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)
 )

Posted

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.

Posted

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)))
 )

Posted

Im sorry to keep bothering you at work. This still will not work. I am not sure why. I got:

 

Command: FTOO

Select 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...

Posted

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. >.

Posted

That works! Thank you soo much again! Where do I send the check to!? :D 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!

  • 3 weeks later...
Posted

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

Posted

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"

Posted

Surely just:

 

-purge
la
*- FUTURE
n

But if you need the code:

 

(defun c:lpurge ( )
 (command "_.-purge" "_la" "*- FUTURE" "_N")
 (princ))

Lee

Posted

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.

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...