Duplicating a Material (in a for loop)

I have a script I adapted from BlenderDiplom and it works except for one key problem. I want to offset the keyframe of the material texture per object. Which I realize now means I need to make a duplicate material for each object as currently it is just offsetting the same material again and again.

I’m brand new to blender python (and python) and I’m stuck figuring out how to achieve this - would appreciate any help.



import random 
import bpy

loops = 5
distanceX = 0
distanceY = 1
distanceZ = 0
offset = .1

for i in range(loops):
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate = {"linked":False})
    obj = bpy.context.active_object
    randx = (0.5 - random.random()) * 10 
    randy = (0.5 - random.random()) * 10
    randz = (0.5 - random.random()) * 10
    obj.delta_location[0] += (distanceX + 0)
    obj.delta_location[1] += (distanceY + randy)
    obj.delta_location[2] += (distanceZ + 0)
    #worked up to here
    randt = random.random()
    newOffset = -(239 * randt)

    curMat   = bpy.context.object.active_material
    emitStr = curMat.node_tree.nodes['Emission'].inputs[1]
    fcurves = curMat.node_tree.animation_data.action.fcurves

    for curve in fcurves:
        keyframePoints = curve.keyframe_points

        for keyframe in keyframePoints:
            keyframe.co[0] += newOffset
            keyframe.handle_left[0] += newOffset
            keyframe.handle_right[0] += newOffset

And to clarify it would need to be a copy of the original material I just realize otherwise the keyframe offset would get very far off.

I ended up solving this, so I’m posting the final code - it’s got some placeholders in it, but I didn’t want to start editing what worked in case I messed something up in the process.



import random #at the top of the script
import bpy


loops = 40
distanceX = 10
distanceY = 0
distanceZ = 0
offset = .1
mat = bpy.data.materials['Filament']




for i in range(loops):
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate = {"linked":False})
    obj = bpy.context.active_object
    DupMat = mat.copy()
    obj.data.materials[2] = DupMat
    randx = (0.5 - random.random()) * offset 
    randy = (0.5 - random.random()) * offset
    randz = (0.5 - random.random()) * offset
    obj.delta_location[0] += (distanceX + 0)
    obj.delta_location[1] += (distanceY + 0)
    obj.delta_location[2] += (distanceZ + 0)
    #worked up to here
    randt = random.random()
    newOffset = -(239 * randt)




    curMat   = bpy.context.object.active_material
    emitStr = curMat.node_tree.nodes['Emission'].inputs[1]
    fcurves = curMat.node_tree.animation_data.action.fcurves


    for curve in fcurves:
        keyframePoints = curve.keyframe_points




        for keyframe in keyframePoints:
            keyframe.co[0] += newOffset
            keyframe.handle_left[0] += newOffset
            keyframe.handle_right[0] += newOffset





1 Like