1
$\begingroup$

How can I set my scene's visible layers from Python? I'd like to make layers 0 and 4 visible. Here's what I've tried:

for i in range(20):
    bpy.context.scene.layers[i] = False

bpy.context.scene.layers[0] = True
bpy.context.scene.layers[4] = True
$\endgroup$
  • $\begingroup$ Please edit your question to include an explanation of what result this current code is producing and, if necessary, why this result isn't what you want. $\endgroup$ – Ray Mairlot Feb 11 '18 at 21:03
  • $\begingroup$ I couldn't identify a reproducible pattern in my code, but Haunt_House has it figured out in his answer $\endgroup$ – ajwood Feb 11 '18 at 23:47
  • $\begingroup$ Took me a while as well, but once I saw that always the last visible layer remained, it was easy. How about you put the improved code as an edit in your question? My code might be ugly and too long, but it is readable. $\endgroup$ – Haunt_House Feb 12 '18 at 0:20
  • $\begingroup$ I'd do it like this: visible=[0,4]; for i in range(20): bpy.context.scene.layers[i] = i in visible $\endgroup$ – ajwood Feb 12 '18 at 0:28
  • $\begingroup$ Try it with visible = [3,4] and only layer 0 turned on.. It'll still keep layer 0. It'll work if layer 0 is always the one to be switched on. $\endgroup$ – Haunt_House Feb 12 '18 at 0:38
1
$\begingroup$

My code may be awful (abeit easily readable), but I think the problem you have is this: it's impossible to turn all layers off. One must be turned on, so a loop to disable them all doesn't work. It seems that Blender is checking anytime you try to disable a layer whether it's the last man standing.

I simply turned it around by first switching the desired layers on and then disabling all others.

import bpy

visible = [0,4]
for b in visible:
    bpy.context.scene.layers[b] = 1

a  = 0
while a < 20:
    if a not in visible:
        bpy.context.scene.layers[a]= 0
    a += 1

edit: batFINGER reduced it to two lines, so give his comment an upvote (:

import bpy

visible = [3,6,9]
scene.layers = [l in visible for l in range(20)]

Creating the full list before assigning it is a smart move.

$\endgroup$
  • 4
    $\begingroup$ scene.layers = [l in visible for l in range(20)] as long as visible has one valid index. Else does nothing. $\endgroup$ – batFINGER Feb 12 '18 at 10:44
  • $\begingroup$ @batFINGER Now that's good code. Eight lines reduced to 2 ( : $\endgroup$ – Haunt_House Feb 12 '18 at 12:30
  • $\begingroup$ @batFINGER What makes me wonder a bit is that at least superficially 'l' gets used before being defined and it still works. Seems like I need more books. $\endgroup$ – Haunt_House Feb 12 '18 at 18:26
  • $\begingroup$ Yep, python list comprehension is a bit tricky at first. $\endgroup$ – batFINGER Feb 12 '18 at 18:38
  • 1
    $\begingroup$ @Amir I already had a look at your question. But It's not my specialty. Answering python questions is rare for me. Just look at how much better samblers answer is. $\endgroup$ – Haunt_House Mar 7 '18 at 20:50
1
$\begingroup$

The layers visibility (for both object and scene) is a list of boolean values, you can generate a list of bools by multiplying a single bool array -

bpy.context.scene.layers = [True]+[False]*2+[True]+[False]*16

You just need to make sure the length of the list is 20.

You can also use list comprehension -

bpy.context.scene.layers = [x in [0,4] for x in range(20)]
$\endgroup$
  • $\begingroup$ I want to do rendering from specific layers and import an object into another layer simultaneously. Do you know how to do that possibly? If so, could you please take a look at my question here and see if you can offer a solution? $\endgroup$ – Amir Mar 7 '18 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.