from typing import Any, Dict, Sequence
import bpy
[docs]def set_keyframe(
bpy_struct: Any, frame: int, property_name: str, value: Any, action_group: str = ""
) -> bool:
"""Add a keyframe value a frame to a property of a bpy_struct.
Parameters
----------
bpy_struct : A Blender bpy_struct object which properties to animate.
frame : An Integer.
The frame at which the value will get inserted.
property_name : A String representing the name of property to change.
value : Any value the property should get at this frame.
action_group : A String.
Name of the ActionGroup the F-Curve of the animation should be added to.
Returns
-------
True if the keyframe was set successfully, else False.
"""
setattr(bpy_struct, property_name, value)
return bpy_struct.keyframe_insert(property_name, frame=frame, group=action_group)
[docs]def animate_property(
bpy_struct: Any,
property_name: str,
frames: Sequence[int],
values: Sequence[Any],
action_group: str = "",
) -> bool:
"""Add keyframes to a property of a bpy_struct.
Parameters
----------
bpy_struct : A Blender bpy_struct object which properties to animate.
frames : A Sequence of integers.
Correspond to the frames at which the values will get inserted.
values : A Sequence.
The values the property should take for each corresponding frame.
action_group : A String.
Name of the ActionGroup the F-Curve of the animation should be added to.
Returns
-------
True if all keyframes were set successfully, else False.
"""
# Check if the sequences of values have the right length.
if len(values) != len(frames):
raise ValueError(
"Values sequence must have the same length as the frames "
"sequence. Found values sequence of length "
f'{len(values)} for property "{property_name}", '
f"but frames sequence has length {len(frames)}.",
)
return_values = (
set_keyframe(bpy_struct, frame, property_name, value, action_group=action_group)
for value, frame in zip(values, frames)
)
return all(return_values)
[docs]def animate_properties(
bpy_struct: Any,
frames: Sequence[int],
animation: Dict[str, Sequence[Any]],
action_group: str = "",
) -> bool:
"""Add keyframes to multiple properties of a bpy_struct.
For each frame in frames, each property from bpy_struct listed in the keys
of animation gets assigned a value corresponding to that frame.
Parameters
----------
bpy_struct : A Blender bpy_struct object which properties to animate.
frames : A Sequence of integers.
Correspond to the frames at which the values will get inserted.
animation : Dict[str, Sequence[Any]].
Associates a property_name to a sequence of values.
action_group : A String.
Name of the ActionGroup the F-Curve of the animation should be added to.
Returns
-------
True if all keyframes were set successfully, else False.
"""
return_values = (
animate_property(
bpy_struct,
property_name,
frames,
values_sequence,
action_group=action_group,
)
for property_name, values_sequence in animation.items()
)
return all(return_values)
[docs]def clear_animation_data(bpy_struct: Any) -> None:
bpy_struct.animation_data_clear()
[docs]def set_end_frame(frame: int) -> None:
bpy.context.scene.frame_end = frame
[docs]def animate_opacity(
material,
fade_in_start,
fade_in_stop,
fade_out_start,
fade_out_stop,
opacity_outer=0,
opacity_inner=1,
):
"""Animate the transparency/opacity of a BSDF material
Parameters
----------
material: bpy.types.Material using a BSDF Node.
Material for which the transparency will be animated.
fade_in_start: int
Frame of the start of the fade-in of the opacity.
fade_in_stop: int
Frame of the end of the fade-in of the opacity.
fade_out_start: int
Frame of the start of the fade-out of the opacity.
fade_out_stop: int
Frame of the end of the fade-out of the opacity.
value_outer: float between 0 and 1 (default=0)
Value of the opacity after fade-in and before fade-out.
value_inner: float between 0 and 1 (defaul=1)
Value of the opacity before fade-in and after fade-out.
See Also
--------
ddg.blender.material.transparent_material
"""
alpha = material.node_tree.nodes["Principled BSDF"].inputs["Alpha"]
values = [opacity_outer, opacity_inner, opacity_inner, opacity_outer]
frames = [fade_in_start, fade_in_stop, fade_out_start, fade_out_stop]
animate_properties(alpha, frames, {"default_value": values})