Passing obj
to your function doesn't matter, because modifier_add
works on the active object. If you don't want that, see this answer for how to avoid bpy.ops
altogether.
bpy.ops.texture.new
doesn't return a value, nor does bpy.ops.object.modifier_add
, so you have to find tex1 some other way. You also have to assign your newly created texture to the modifier. Here is one way to do this, there are others. This code is verbose to make it clear what it is doing. It can be simplified a bit.
def displace():
bpy.ops.object.modifier_add(type='DISPLACE')
texture_set = set(bpy.data.textures.keys())
bpy.ops.texture.new()
new_texture_set = set(bpy.data.textures.keys()) - texture_set
texture_name = new_texture_set.pop()
texture = bpy.data.textures[texture_name]
texture.type = 'VORONOI'
bpy.context.active_object.modifiers[-1].texture = texture
This uses a common technique for find what an bpy.ops
operator has created:
- Create a set of all the things created by that op
- Execute the op
- Create a set of all the things created by that op and remove the old set from it.
This will leave you with a set that consists of the newly created things. In the case of a texture there is only one.
It also relies on modifier_add
adding the modifier to the end of the modifier stack, making it possible to find it with the index -1.
Often, there is a better approach because the op will set some contextual "active" data, and instead of constructing the sets you can just refer to whatever that is.
Also, Markus von Broady just reminded me in a comment that if the op adds one newly created thing to a list you can use the index -1 to retrieve it rather than the set operations. (In other words, I could use the same technique I used for finding the modifier to find the texture!) This leads to the shorter version:
def displace():
bpy.ops.object.modifier_add(type='DISPLACE')
bpy.ops.texture.new()
texture = bpy.data.textures[-1]
texture.type = 'VORONOI'
bpy.context.active_object.modifiers[-1].texture = texture