0
$\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$
0
$\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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.