Conditions for Layers?

Conditions for Layers?

amber.baysinger
Contributor Contributor
1,097 Views
16 Replies
Message 1 of 17

Conditions for Layers?

amber.baysinger
Contributor
Contributor

I posted in general, and Patchy suggested I come over here and ask, so I guess this is a cross post.

 

I was curious, I think the answer might be no, if you can have one layer control another layer. For example, if I turn on the girder layer, it will turn off the balcony layer without manually turning it off? If this is possible, it would greatly help our production.

 

Thanks!

 

Original Post: Re: Conditions for Layers? - Autodesk Community - AutoCAD

0 Likes
1,098 Views
16 Replies
Replies (16)
Message 2 of 17

ronjonp
Mentor
Mentor

Give this a try:

 

(defun c:foo (/ a b)
  (cond	((and (setq a (tblobjname "LAYER" "GIRDER")) (setq b (tblobjname "LAYER" "BALCONY")))
	 (vlax-put (vlax-ename->vla-object a) 'layeron -1)
	 (vlax-put (vlax-ename->vla-object b) 'layeron 0)
	)
  )
  (princ)
)

Or to toggle:

(defun c:foo (/ a b)
  (cond	((and (setq a (tblobjname "LAYER" "GIRDER")) (setq b (tblobjname "LAYER" "BALCONY")))
	 (setq a (vlax-ename->vla-object a))
	 (setq b (vlax-ename->vla-object b))
	 (if (= 0 (vlax-get a 'layeron))
	   (progn (vlax-put a 'layeron -1) (vlax-put b 'layeron 0))
	   (progn (vlax-put a 'layeron 0) (vlax-put b 'layeron -1))
	 )
	)
  )
  (princ)
)

 

0 Likes
Message 3 of 17

Kent1Cooper
Consultant
Consultant

Layer STATES might be able to do what you want.  No code required, and you could put commonly-used ones into simple Tool Palette button command macros.

Kent Cooper, AIA
Message 4 of 17

amber.baysinger
Contributor
Contributor

Copy and paste in notepad, save as .lsp?

0 Likes
Message 5 of 17

amber.baysinger
Contributor
Contributor

I'll look into that too, thanks!

0 Likes
Message 6 of 17

CodeDing
Advisor
Advisor

@amber.baysinger ,

 

In short, No there is not a way to do exactly as you describe.

 

We can get close with custom routines (such as ronjonp suggests), layer states (such as Kent suggests), and even Layer Groups (described here).

 

But perhaps to get the layers to AUTOMATICALLY adjust the way you desire, I would have to look into Reactors a little bit more. There MAY be a way that way, but I don't experiment with them much.

 

Best,

~DD

0 Likes
Message 7 of 17

ronjonp
Mentor
Mentor

@amber.baysinger wrote:

Copy and paste in notepad, save as .lsp?


Yup. Or you can paste the code directly into the command line and run using 'foo'.

0 Likes
Message 8 of 17

Kent1Cooper
Consultant
Consultant

Another way to toggle the relationship is to just change the sign on the color entry in entity data for the two Layer objects, since that is what defines the on/off difference:

(defun C:FLO (/ ldata) ; = Flip Layers On-off condition
  (foreach lay '("GIRDER" "BALCONY")
    (setq ldata (entget (tblobjname "layer" lay)))
    (entmod (subst (cons 62 (- (cdr (assoc 62 ldata)))) (assoc 62 ldata) ldata))
  )
  (princ)
)

If you start with either of those two Layers on and the other off, the command will flip their on-off relationship.  Any Layer in the list [you can add as many as you like] will be turned on if it's off, and vice versa.

Kent Cooper, AIA
0 Likes
Message 9 of 17

ronjonp
Mentor
Mentor

For fun, here's another that will toggle on off between the two layers (ie swaps states).

(defun c:foo (/ a b)
  (cond	((and (setq a (tblobjname "LAYER" "GIRDER")) (setq b (tblobjname "LAYER" "BALCONY")))
	 (setq a (vlax-ename->vla-object a))
	 (setq b (vlax-ename->vla-object b))
	 (vlax-put a 'layeron (~ (vlax-get a 'layeron)))
	 (vlax-put b 'layeron (~ (vlax-get a 'layeron)))
	)
  )
  (princ)
)

 

0 Likes
Message 10 of 17

amber.baysinger
Contributor
Contributor

@ronjonp & @Kent1Cooper I've tried what you both have said, but nothing is working. I assume I am doing something wrong, but I'm not sure what.

 

@CodeDing I will look into the reactors as well as layer states, thanks!

0 Likes
Message 11 of 17

ronjonp
Mentor
Mentor

The only way I'd think that the code would not work is if the two layers do not exist in the drawing you run the code in.

Example for my second code posting:

2021-09-14_8-37-36.gif

The first code example only turns on the girder layer then turn off the balcony layer.

 

0 Likes
Message 12 of 17

amber.baysinger
Contributor
Contributor

I'll attach my test file, and the second example. Those are the two files I'm trying it with now, and it still doesn't seem to do anything. I started with the GIRDER layer off (light bulb icon), and the BALCONY on. If I turn off the balcony, the girder does not come on, or if I turn on the girder, the balcony does not come on. I still think I am probably misunderstanding something. Sorry.

0 Likes
Message 13 of 17

ronjonp
Mentor
Mentor

It is not automatic, you have to call the command "foo" after you load it.

Message 14 of 17

dgorsman
Consultant
Consultant

Reactors could do it, but it would have to be very carefully planned out to avoid unintended sequences i.e. turning off layer A results in Layer B and C turning on; layer C turning on results in layer D turning off; layer D turning off results in Layer A turning on (turning B and C off, and D on, so A is turned off...).  It's extremely easy to end up with an endless loop, locking up AutoCAD.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 15 of 17

hak_vz
Advisor
Advisor

@amber.baysinger 

 

I have another proposal. You can create set of helper functions that will turn on or off set  of layer (one or more of them separated with ",". For each set of layers you should have on and off function

 

 

(defun c:loff( / string_to_list collectLayerObjects getlayernames acad _off layercollection layernames eo str)
(defun string_to_list ( str del / pos )
	(if (setq pos (vl-string-search del str))
		(cons (substr str 1 pos) (string_to_list (substr str (+ pos 1 (strlen del))) del))
		(list str)
	)
)
(defun collectLayerObjects ( / ret) (reverse (vlax-for lay (vlax-get (vla-get-activedocument (vlax-get-acad-object)) 'Layers) (setq ret (cons (cons (vlax-get lay 'Name) lay)ret)))))
(defun getlayernames nil (mapcar 'car (collectLayerObjects)))
(setq acad (vla-get-activedocument (vlax-get-acad-object)))
(setq _off (string_to_list "GIRDER,test1,test2" ","));PUT LAYERNAMES HERE - CASE SENSITIVE
(setq layercollection (collectLayerObjects))
(setq str "")
(setq layernames(getlayernames))
	(foreach e _off
		(cond 
			((member e layernames)
				(setq eo (cdr (assoc  e layercollection)))
				(vlax-put eo 'LayerOn 0)
				(setq str (strcat str e " "))
			)
		)
	)
(princ (strcat "\nLayers " str "have been turned off!"))
(princ)
)

(defun c:lon( / string_to_list collectLayerObjects getlayernames acad _on layercollection layernames eo str)
(defun string_to_list ( str del / pos )
	(if (setq pos (vl-string-search del str))
		(cons (substr str 1 pos) (string_to_list (substr str (+ pos 1 (strlen del))) del))
		(list str)
	)
)
(defun collectLayerObjects ( / ret) (reverse (vlax-for lay (vlax-get (vla-get-activedocument (vlax-get-acad-object)) 'Layers) (setq ret (cons (cons (vlax-get lay 'Name) lay)ret)))))
(defun getlayernames nil (mapcar 'car (collectLayerObjects)))
(setq acad (vla-get-activedocument (vlax-get-acad-object)))
(setq _on (string_to_list "GIRDER,test1,test2" ",")) ;PUT LAYERNAMES HERE - CASE SENSITIVE
(setq layercollection (collectLayerObjects))
(setq str "")
(setq layernames(getlayernames))
	(foreach e _on
		(cond 
			((member e layernames)
				(setq eo (cdr (assoc  e layercollection)))
				(vlax-put eo 'LayerOn -1)
				(setq str (strcat str e " "))
			)
		)
	)
(princ (strcat "\nLayesrs " str "have been turned on!"))
(princ)
)

 

 

 

To create functions with another name just change function name for example change c:lon c:loff to c:bon c:boff  (ie. function name after c:)

In each On OF  function you have to change a line

 

 

"GIRDER,test1,test2" 

 

 

with desired names of layers

 

 

"LAYER1,layer2,SOME_LAYER"

 

 

 

If you use standard layers name this can speed up your work

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 16 of 17

Kent1Cooper
Consultant
Consultant

It works for me:

FLO.gif

Are you sure you have the Layer names spelled exactly the same way in the drawing and in the list in the code?

Kent Cooper, AIA
0 Likes
Message 17 of 17

Sea-Haven
Mentor
Mentor

Like the others having a list of pairs (("GIRDER" "BALCONY")("TILES" "WOOD")....) so would look for layer names.

 

It is possible with a reactor to say type in  "LGIRDER" on the command line CAD will return "Unknown command", but its possible to grab the error and pull it apart the "L" at the start is required just a letter as I use C O F already, but the remainder "GIRDER" will be pulled out and then the on/off applied to "Girder" and 2nd layer "Balcony" note would add a Case check to stop problems.

 

The other way depending on how many you have is to use a DCL and choose either a list or for me a radio button lisp so just click I have around 20 can be entered, screen size dependant, Pretty sure it was RLX and he has a grid dcl so could do even more. This would be 3 lines of code for the dcl plus a call to the on/off functions already provided.

 

SeaHaven_0-1631685438535.png

It could be Multi toggles dcl also perhaps show on / off for 1st layer

SeaHaven_1-1631685984574.png

 

0 Likes