1
$\begingroup$

I have default humanoid rig, and exported animation data using following code reference to csv file.

NOTE: I am not using blender's in-built copy animation data as I am planning to modify code further for custom use.

import bpy
sce = bpy.context.scene
ob = bpy.context.object
for f in range(sce.frame_start, sce.frame_end+1):
sce.frame_set(f)
print("Frame %i" % f)

for pbone in ob.pose.bones:
   print(pbone.matrix) //Saving this data to a csv file.

Now I, am I am trying to import this data by adding keyframes to other humnoid rig using following but cant get it working.

Keyframes are added but it doesn't animate.

import bpy
    import csv
    from mathutils import Matrix

    sce = bpy.context.scene
    ob = bpy.context.object


    with open('maximo_keys.csv', newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            sce.frame_set(int(row['frame']))
            cbone = ob.pose.bones[row['bone_name']]
            
            if(cbone.name == 'thigh.L'):
                print(row['rotZ'])
            
            cbone.matrix = Matrix([(float(row['locX']), float(row['locY']), float(row['locZ']), float(row['locW'])),
                   (float(row['rotX']), float(row['rotY']), float(row['rotZ']), float(row['rotW'])),
                   (float(row['ScaleX']), float(row['ScaleY']), float(row['ScaleZ']), float(row['ScaleW'])),
                   (0.0000, 0.0000, 0.0000, 0.1)])
            
            bpy.context.view_layer.update()
            
            cbone.keyframe_insert(data_path="location", index=-1)
            cbone.keyframe_insert(data_path="rotation_euler", index=-1)

Can someone direct me what is wrong i am doing?

This is simplest version, where I added 2 single bone armatures and added animation on 1 armature.

import bpy

sce = bpy.context.scene

ob1 = bpy.data.objects['Armature'] #object with animation
ob2 = bpy.data.objects['Armature.001'] #object to copy animation

for f in range(sce.frame_start, sce.frame_end+1):
        sce.frame_set(f)
       
        ob2bone =  ob2.pose.bones["Bone"] 
        ob2bone.matrix = ob1.pose.bones['Bone'].matrix
        ob2bone.keyframe_insert("location", frame=f)
$\endgroup$
7
  • $\begingroup$ In prior version (pre 2.8) this kind of thing would require a scene update (or update of sorts) on each iteration. The 2.8 equiv would be context.view_layer.update() or alternatively get the loc n rot from the matrix and set to cbone before keyframe insert. Could prob look at doing this with numpy and foreach_set the data directly into fcurves. $\endgroup$ – batFINGER Jan 24 at 14:09
  • $\begingroup$ @batFINGER - tried bpy.context.view_layer.update() but did not do anything. $\endgroup$ – VK321 Jan 24 at 14:22
  • $\begingroup$ Ok, tested and not the case, as this works Ok, pasteall.org/LD8U (on simple armature with bone "Bone") instead of assigning frame to scene try as kf insert arg. $\endgroup$ – batFINGER Jan 24 at 14:32
  • $\begingroup$ Hard to help with q's that rely on file IO, without seeing data. Could you please fix the indenting in question code. (quick way to markdown if using blender text editor is select all, tab, copy, paste here, shift tab in blender, one tab right is code markdown, or wrap above below with 3 backticks, or select in BSE text editor and hit code button (ctrl-K) $\endgroup$ – batFINGER Jan 24 at 14:39
  • $\begingroup$ @batFINGER just updated indenting, if it's working for you why its not for me? happy to share file data. $\endgroup$ – VK321 Jan 24 at 16:25

Your Answer

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

Browse other questions tagged or ask your own question.