8
$\begingroup$

I have the following code which generates an object:

mesh = bpy.data.meshes.new("Raw Curve")  
mesh.from_pydata(self.rawCurve, edges, [])  # verts, edges, faces
mesh.update()  

profile_object = bpy.data.objects.new("Raw Curve", mesh)  
profile_object.data = mesh  # this line is redundant .. it simply overwrites .data  

scene = bpy.context.scene  
scene.objects.link(profile_object)

How can I add this object to a specific layer (e.g. to layer 2)?

$\endgroup$
11
$\begingroup$
#add to layer 2 first - needs to be on at least one layer
profile_object.layers[1] = True

#wipe other layers
for i in range(20):
    profile_object.layers[i] = (i == 1)
$\endgroup$
  • $\begingroup$ Here is my current code: pastebin.com/bruT7f3r But it still draws the new object into the 1st layer. What can be wrong? $\endgroup$ – Endre Jul 21 '15 at 19:08
  • $\begingroup$ You need to make sure, that if you set a layer to False, there is at least one other layer the object is part of. It is not allowed to set all layers to False since the user could not select the object anymore in the viewport (he might use the outliner - but this prevents the user from accidently clearing all layers). Thus the first line is mandatory, you have to add it to another layer before you can wipe it from the others. In your script you are probably trying to remove it from layer 1 before adding it to layer 3. $\endgroup$ – pink vertex Jul 21 '15 at 19:31
  • 1
    $\begingroup$ I found the problem. scene.objects.link(obj) have to be executed before the layout stuff. $\endgroup$ – Endre Jul 21 '15 at 19:42
  • 1
    $\begingroup$ Just checked the source code - if you link an object to a scene the active/visible layers of the scene get copied to the object's layers. $\endgroup$ – pink vertex Jul 21 '15 at 19:53
  • 1
    $\begingroup$ You added it to Layer 1, then tried to first set [1] to false and then to the layer you needed to True. So say you try to set it to layer 3. profile_object.layers[1] = False fails because it is the only True at that time. I edited the code to set layer 19 to true initially. This should now work because 19 is the last layer to be set in the for loop. $\endgroup$ – ntg Sep 7 '16 at 15:43
4
$\begingroup$

small utility function I use:

put_on_layers = lambda x: tuple((i in x) for i in range(20))
obj.layers[:] = put_on_layers({2,6,5,11})

{2,6,5,11} is a set, can be 1 or more values, starting from 0 ending at 19.

$\endgroup$
2
$\begingroup$

My favorite syntax is

obj.layers = [ i==2 for i in range(len(obj.layers)) ]

or if you want the flexibility of zeffi's solution

obj.layers = [ i in {2,6,5,11} for i in range(len(obj.layers)) ]

You could also just write range(20) instead of range(len(obj.layers)) assuming blender never changes the number of layers.

The most important thing to remember is don't try to set the layers before the object has been linked to a scene. The last time I made that mistake my layers assignment had no effect (I assume the scene.link reset the layers value somehow; I am not sure if that has changed in recent blender versions).

$\endgroup$
  • $\begingroup$ I want to import an object directly into a specific layer. I wonder, do you know a solution for that? If so, could you please check out my question here and see if you can offer a solution? $\endgroup$ – Amir Mar 7 '18 at 20:02

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.