New layer with block name

New layer with block name

Anonymous
Not applicable
1,612 Views
11 Replies
Message 1 of 12

New layer with block name

Anonymous
Not applicable

Hello Forum, I am not sure this is at all possible, but I figured you all would know.  I would like to write a comman/LISP routine where I can create a new layer with the same name as an already existing block.  For example, I have a block labeled "Frame_1" I then run this command, select this block and it creates a layer called "Frame_1".  I've been playing around with making layers from a few different ways, and I can't find a way to copy a name from a block...yet.  Any ideas?

0 Likes
Accepted solutions (1)
1,613 Views
11 Replies
Replies (11)
Message 2 of 12

pendean
Community Legend
Community Legend
Message 3 of 12

Kent1Cooper
Consultant
Consultant
Accepted solution

If they're not Dynamic Blocks, something like this [untested]:

(defun C:LBN ; = Layer with Block's Name
  (/ esel edata)
  (if
    (and
      (setq esel (entsel "\nSelect Block to create Layer with its Name: "))
      (member '(0 . "INSERT") (setq edata (entget (car esel))))
    ); and
    (command "_.layer" "_new" (cdr (assoc 2 edata)) "")
  ); if
  (princ)
); defun

That will use the defaults for the properties of the Layer [color, linetype, etc.], but you can add options to set those.  It won't care if the Layer already exists, i.e. if you run it and pick a Block you had already done it with.  Be aware that it will do the same even if you pick an Xref, or an associative Array object, or a WMF image, but it can be made to avoid those if necessary.

 

It could also be made to put the selected Block on the Layer named for it.

 

If you might ever do it with Dynamic Blocks, I assume it should be adjusted to get the "effective" name, rather than use the (assoc 2) Block name, which will be an "anonymous" type starting with *U.

Kent Cooper, AIA
Message 4 of 12

devitg
Advisor
Advisor

@Kent1Cooper  about DYN blocks , how to make the filter 

 

I try 

 

(setq blk-references-ss (ssget "X" '((0 . "insert")    (2 . "*U*"))))

 But it return NIL , 

 

It seem to be the * shall be treated in other way 

 

Please 

 

0 Likes
Message 5 of 12

Kent1Cooper
Consultant
Consultant

Try the reverse-apostrophe prefix "`*U*" to have it take the first asterisk literally, not as a wildcard.

 

But be aware that the same *U prefix is used for the "names" of associative Array objects, which are also of the "INSERT" variety.

Kent Cooper, AIA
0 Likes
Message 6 of 12

ВeekeeCZ
Consultant
Consultant

Here's another version that works with multiple selection.

 

(vl-load-com)

(defun c:BNamesToLayer (/ s i o n)
  
  (if (setq s (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength s))
      (setq o (vlax-ename->vla-object (ssname s (setq i (1- i))))
	    n (vlax-get-property o (if (vlax-property-available-p o 'EffectiveName) 'EffectiveName 'Name)))
      (if (tblsearch "LAYER" n)
	(princ (strcat "\nLayer '" n "' already exists."))
	(progn
	  (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 n) '(70 . 0)))
	  (princ (strcat "\nLayer '" n "' created."))))))
  (princ)
  )

 

0 Likes
Message 7 of 12

devitg
Advisor
Advisor

@Kent1Cooper Thanks for the "reverse".

How can avoid to not select such others *u* , "as  associative Array objects?"

 

0 Likes
Message 8 of 12

Kent1Cooper
Consultant
Consultant

@devitg wrote:

@Kent1Cooper Thanks for the "reverse".

How can avoid to not select such others *u* , "as  associative Array objects?"

 


I think [I'm not sure this is foolproof] that if the "effective name" is different from the (assoc 2) name, it's a Dynamic Block, but if they are the same, it's an associative Array.  If 'ent' is the entity name:

 

(if (= (vla-get-EffectiveName (vlax-ename->vla-object ent)) (cdr (assoc 2 (entget ent))))

  (.... then -- it's an associative Array ....)

  (.... else -- it's a Dynamic Block ....)

)

 

There are probably other ways to tell the difference, but I haven't dug into it.

Kent Cooper, AIA
Message 9 of 12

devitg
Advisor
Advisor

@Kent1Cooper So there is no way to get it by filter list . 

Ok . Thanks . 

 

0 Likes
Message 10 of 12

Kent1Cooper
Consultant
Consultant

@devitg wrote:

@Kent1Cooper So there is no way to get it by filter list . 

....


Array objects have this kind of thing in their entity data:

 

(102 . "{ACAD_REACTORS") (330 . <Entity name: 2af43f20>) (102 . "}")

 

which Blocks don't.  So it should be possible to filter for things without (102) entries.

Kent Cooper, AIA
Message 11 of 12

Anonymous
Not applicable

Thank you, I must not have looked for the right tag words.  

0 Likes
Message 12 of 12

Anonymous
Not applicable

@Kent1Cooper I have been playing around with this LISP and added a part to put the block on the newly created layer, but now I am trying to change that layer color to a random color.  I have been doing research and am at a sticking point.  Based on what I have read and my understanding, the below lisp SHOULD work, but it clearly isn't.  Any advice?  I saw a couple of posts where you helped with random number generation especially pertaining to color and I don't think I care about repeating colors.  It would be nice to not include dark colors as I saw you did with another lisp, but not necessary.  Thank you!

 

 

(defun C:LBN ; = Layer with Block's Name

  (if
    (and
      (setq esel (entsel "\nSelect Block to create Layer with its Name: "))
      (member '(0 . "INSERT") (setq edata (entget (car esel))))
    ); and
    (command "_.layer" "_new" (cdr (assoc 2 edata)) "")
 
  ); if
(command "-laymch" "l" "" "N" (cdr (assoc 2 edata)))
(defun LM:rand ( / a c m )
		(setq	m	4294967296.0
			a	1664525.0
			c	1013904223.0
			$xn	(rem (+ c (* a (cond ($xn) ((getvar 'date))))) m))
		(/ $xn m)
	)
	(defun LM:randrange ( a b )
		(+	(min a b)	(fix (* (LM:rand) (1+ (abs (- a b))))))
	)
  (/ esel edata)
(command "-layer" "c" (SETQ num (LM:randrange 1 200)) (cdr (assoc 2 edata)) "")

  (princ)
); defun
0 Likes