I tried to add a driver to the color influence of a texture.
But that seems to be the wrong string. Also I’m not sure where exactly to add the driver, like: object.driver_add()
Any help appreciated
If you add it from the UI you get a driver added to the object with datapath (path from object to property) of
If you try and add this using script it will spit the dummy… You can add a dummy driver like location and then overwrite the data_path later.
>>> C.object.driver_add('material_slots["Material"].material.texture_slots.diffuse_color_factor') Traceback (most recent call last): File "<blender_console>", line 1, in <module> ValueError: bpy_struct.driver_add(): path spans ID blocks >>> driver = C.object.driver_add('location',0) >>> driver bpy.data.objects['Cube']...FCurve >>> driver.data_path = 'material_slots["Material"].material.texture_slots.diffuse_color_factor'
You can also add the driver to the material… this is my prefered method. This way the material is driven for any object that uses it
>>> bpy.data.materials['Material'].driver_add('texture_slots.diffuse_color_factor') bpy.data.materials['Material']...FCurve
Thank you very much, that worked well
One other question:
if you do something in the viewport, the python code gets displayed in the info window. But only the “global” command gets shown, which automatically refers to the active object.
Is there an easy way to “convert” this code to do it with some other object?
I mean just so I can look it up more quickly in general, not to actually use this in a script
Have you really managed to create drivers for the material directly? There is something special about material and texture drivers that make them work differently from other drives. Run the program below with the default setup.
If test = 1, the first texture slot turns purple but the driver does not work.
If test = 2, I get the error message “path spans ID blocks”.
If test = 3, the first texture slot does not turn purple but the driver works.
Unfortunately, in my specific problem I dont have access to the mesh when I want to create material drivers, at least not without a rather massive recoding. That I dont get visual feedback is ok, but I really want to create material drivers before I create the objects.
import bpy test = 3 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["UseTex"] = True cube.data.materials = mat if test == 1: fcu = mat.driver_add("use_textures", 0) elif test == 2: fcu = cube.driver_add("data.materials.use_textures", 0) elif test == 3: fcu = cube.driver_add("location", 0) fcu.data_path = "data.materials.use_textures" fcu.array_index = 0 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 = cube targ.data_path = '["UseTex"]'
Yeah i see what you mean… haven’t paid too much attention to the values, glad you pointed this out.
This piece of code makes method 1 work
def matfix(scene): for mat in bpy.data.materials: if mat.animation_data is not None: for driver in mat.animation_data.drivers: prop = mat.path_resolve(driver.data_path) #print(prop) prop[driver.array_index] = driver.evaluate(scene.frame_current) bpy.app.handlers.frame_change_pre.append(matfix)
Is it bug-reportworthy?
EDIT: couple of checks for specific case
def matfix(scene): dlist = [(driver, mat) for mat in bpy.data.materials if mat.animation_data is not None for driver in mat.animation_data.drivers if driver.data_path == "use_textures"] for driver, mat in dlist: prop = mat.path_resolve(driver.data_path) #print(prop) cls = type(prop).__name__ if cls == "bpy_prop_array": prop[driver.array_index] = driver.evaluate(scene.frame_current) bpy.app.handlers.frame_change_pre.append(matfix)
Thanks a lot! Your matfix function resolves a long-standing problem for me, although I invoke it from a explicit update button rather than on frame change.
I already filed a bug report half a year ago. Somebody, probably Aligorith, explained that material and texture drivers were handled differently from other drivers, but I did not understand how it worked.