4
$\begingroup$

I have already did a dummy test and all the rest of my code works. The only thing that fails is calling bpy.ops.anim.keyframe_insert_menu(type = 'LocRotScale'), which is what appears if you press I and doing it manually. The error I am getting is:

File "D:\Blender\2.79\scripts\modules\bpy\ops.py", line 189, in call ret = op_call(self.idname_py(), None, kw) TypeError: Converting py args to operator properties: enum "location" not found in ('Location', 'Rotation', 'Scaling', 'BUILTIN_KSI_LocRot', 'LocRotScale', 'BUILTIN_KSI_LocScale', 'BUILTIN_KSI_RotScale', 'BUILTIN_KSI_DeltaLocation', 'BUILTIN_KSI_DeltaRotation', 'BUILTIN_KSI_DeltaScal)

The idea of my script is simple, there are 8 coordinates in a list that I want to loop through and apply each coordinate to a cube.

Pseudo code would be:

  1. Frame_set the current frame on the timeline so starting frame would be at 0
  2. I would take the coordinate[i] in the list and apply it to the cube
  3. I would then key the location of the cube for animation
  4. update the current_frame by =+ 4 each time. S0 frame 0, 4, 8... would be the keyframes.

All other steps works, if I comment out step number 3 I would see my cube moving from 1 location to the other, I just need to know how to key each location for animation!

My code is below:

current_frame = 0

for i in range( 0, len( selected_loc ) ): # selcted_loc contains 8 xyz vectors 

    bpy.data.scenes["Scene"].frame_set( current_frame )
    moving_object.location = selected_loc[i] #moving_object is just a cube

    #bpy.ops.anim.keyframe_insert_menu(type = 'location') #line that fails

    current_frame += 4  
$\endgroup$

1 Answer 1

7
$\begingroup$

You should avoid ops functions and use the object's attributes and method to achieve your goal. (Ops is slow and can even be context dependant.)

To insert a location keyframe, use the keyframe_insert method of bpy_structs with data_path parameter set to location.

Use the same method for scale, setting the data_path to scale.

In order to keyframe the rotation, you need to know the rotation mode. An objects rotation_mode can either be set to QUATERNION or EULER. The respective parameter values for the data_path parameter are rotation_quaternion or rotation_euler.

Below is a fully working example, given there is an object named Cube.

import bpy
import mathutils

selected_loc = [mathutils.Vector((x, 0, abs(x-5))) for x in range(8)]
moving_object = bpy.data.objects['Cube']

for i, loc in enumerate(selected_loc):
    bpy.data.scenes["Scene"].frame_set(i * 4 + 1)
    moving_object.location = loc
    moving_object.keyframe_insert(data_path = 'location')
    if moving_object.rotation_mode == "QUATERNION":
        moving_object.keyframe_insert(data_path = 'rotation_quaternion')
    else:
        moving_object.keyframe_insert(data_path = 'rotation_euler')
    moving_object.keyframe_insert(data_path = 'scale')
$\endgroup$

You must log in to answer this question.

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