I’m trying to create drivers for some material and texture settings. A typical application is facial expressions, where wrinkles are made with a bump map. However, drivers for materials and textures evidently work differently from ordinary drivers. But how?
The following program creates drivers for three properties of the default cube: an object setting (visibility), a material setting (use_textures), and a texture setting (noise depth) are all driven by object properties of an armature.
import bpy def run(): bpy.ops.object.armature_add() bpy.ops.transform.translate(value=(0, -2, 0)) rig = bpy.context.object rig["Hide"] = False rig["Tex"] = True rig["Depth"] = 4 tex = bpy.data.textures.new("Tex", type = "CLOUDS") mat = bpy.data.materials.new("Mat") mtex = mat.texture_slots.add() mtex.texture = tex cube = bpy.data.objects["Cube"] cube.data.materials = mat fcu = cube.driver_add("hide", -1) setDriver(fcu, rig, '["Hide"]') fcu = cube.material_slots[mat.name].material.driver_add("use_textures", 0) #fcu = cube.driver_add("material_slots[\"%s\"].material.use_textures" % mat.name, 0) setDriver(fcu, rig, '["Tex"]') fcu = cube.material_slots[mat.name].material.texture_slots[tex.name].texture.driver_add("noise_depth", -1) #fcu = cube.driver_add("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.noise_depth" % (mat.name, tex.name), -1) setDriver(fcu, rig, '["Depth"]') return def setDriver(fcu, rig, datapath): drv = fcu.driver drv.type = "SCRIPTED" drv.expression = "x" drv.show_debug_info = True var = drv.variables.new() var.name = "x" var.type = "SINGLE_PROP" targ = var.targets targ.id = rig targ.data_path = datapath return run()
The object setting works fine; the object is hidden when the armature property is set. However, the material and texture drivers are dead. The drivers are there (cf picture) and the corresponding settings are purple, but the driver values do not react when I change the armature properties.
However, I can add working drivers in the viewport. Weirdly enough, the working drivers turn out to belong to the object itself, and not to the material and textures. Also I note that the driven settings do not turn purple. Anyway, the driven data_path can be read off from the picture below.
However, if I change the program accordingly (comment/uncomment the driver_add lines), the following error appears:
Traceback (most recent call last): File "\matdriver.py", line 45, in <module> File "\matdriver.py", line 22, in run ValueError: bpy_struct.driver_add(): path spans ID blocks
Does anyone have an idea how to get around this. The logged operator when I add working drivers is bpy.ops.anim.driver_button_add(all=False), but that is of little use to me since I don’t know how to select a button from python.