4
$\begingroup$

This question/answer (Control Cycles material nodes and material properties in Python) has been very useful, so I know now how to enter a keyframe for a given material node using keyframe_insert(). But I would also like to update these keyframe points at a later time: I have created a node group, which I would like to duplicate (multiple times), to reuse it as is, but for the keyframe points --the number of keyframe points will remain the same, only their values are to change.

If accessing and updating the keyframe points is not possible (like position, scale...), I could at least delete them via keyframe_delete() and then insert new ones. If this is the only way, what's the data_path to one of these node properties?

$\endgroup$

1 Answer 1

3
$\begingroup$

I don't know if this is the best way to do it, but it does exactly what I want it to do.

I have a Group of nodes. As part of this Group, there is a Value input node. I want to keyframe the default value of this Value node. So this is how it works.

Inserting a new keyframe point

1- Get a reference to the Group node:

group = bpy.data.materials['Material'].node_tree.nodes['Group']

2- Get a reference to the Value node within the Group:

node = group.node_tree.nodes['ValueNodeName']

3- Set the default value of the output of the Value node, and insert a keyframe (in this example, the value to insert is 1, and the frame number is 21)

node.outputs['Value'].default_value = 1
node.outputs['Value'].keyframe_insert('default_value', frame = 21)

Repeat step 3 for each new keyframe point to insert.

Overwriting an existing keyframe point

If I needed to overwrite an existing keyframe point, I could enter another keyframe point for the very same frame number. For example, if I wanted to update the keyframe point at frame 21 from value 1 to value 33:

node.outputs['Value'].default_value = 33
node.outputs['Value'].keyframe_insert('default_value', frame = 21)

Accessing a Keyframe Point from an F-Curve

Instead of adding, deleting and overwriting keyframe points from the node's output properties, we could get a reference to the F-Curve used to animate those properties and modify them that way. If material is a reference to the material containing our value node, this is how we could proceed:

action = material.node_tree.animation_data.action
if action:
    fc = action.fcurves.find(data_path)
        if fc:
            for kfp in fc:
                print(kfp.co)

The previous snippet would print the coordinates of all the keyframe points belonging to the F-Curve stored under data path data_path. For example, if the name of our value node were MyValueNode, the data path would be

data_path = 'nodes['MyValueNode'].outputs[0].default_value'
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .