Problems reading existing Action data

I have an armature created by an imported motion capture “running” BVH file whose Action I’m still trying to append to a human armature of similar structure. I’m getting the right values but the joints bend the wrong ways, possibly because of improper Euler axis order. I’ve decided to export the current data so I can manipulate it as needed to analyze the problem and perhaps modify it before importing it into the human armature. My first test script reading the properly running BVH Action looks like this (Note: on the preview this is almost unreadable light gray on white but you can click in the code box and hit Ctrl_A to select it and it becomes much more readable. Maybe the final display will be better.)


for sceneObj in bpy.context.scene.objects:
    if sceneObj.type != 'ARMATURE':
        continue
    armName = sceneObj.name
    print ("Found armature: " + armName + "
")
    armature = bpy.data.objects[armName]
    startCurve = armature.animation_data.action.fcurves[0]
    keyFrames = startCurve.keyframe_points;
    print ("Processing " + str(keyFrames.__len__()) + " keyframes...")
    keyCounter = 0
    for keyframe in keyFrames:
        thisFrame = keyFrames[keyCounter].co[0]
        print ("
Processing keyframe: " + str(keyCounter) + " at frame: " + str(thisFrame))
        bpy.ops.anim.change_frame(frame = thisFrame)
        counter = 0
        for curve in armature.animation_data.action.fcurves:
            dataPath = curve.data_path
            strings = str.split(dataPath, '"')        
            print("Found curve handling bone: " + strings[1] + " for: " + strings[2][2:])
            obj = armature.path_resolve(dataPath)
            if type(obj) == Vector:
                print ("Vector X, Y, Z values are: [" + str(obj.x), ", ", str(obj.y), ", ", str(obj.z) + ']')
            if type(obj) == Euler:
                print ("Euler value order: " + obj.order)
                if (obj.order == "ZYX"):        
                    print ("Euler X, Y, Z values are:  [" + str(obj.z), ", ", str(obj.y), ", ", str(obj.x) + ']')
                else:
                    Print ("Order is not ZYX")
            counter = counter + 1
            if counter > 6:
                break
        keyCounter = keyCounter + 1
        if keyCounter >= 4:
            break
    print ("
End of keyframes tested.")

The results for the first bone (and a peek at the second that doesn’t actually change) for the first four keyframes looks like this:

Found armature: RunningAnimation

Processing 12 keyframes…

Processing keyframe: 0 at frame: 1.0
{‘FINISHED’}
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Hips for: location
Vector X, Y, Z values are: [0.0 , 0.0 , 0.0]

Processing keyframe: 1 at frame: 3.0
{‘FINISHED’}
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Hips for: location
Vector X, Y, Z values are: [0.0 , 0.0 , 0.0]

Processing keyframe: 2 at frame: 5.0
{‘FINISHED’}
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Hips for: location
Vector X, Y, Z values are: [0.0 , 0.0 , 0.0]

Processing keyframe: 3 at frame: 7.0
{‘FINISHED’}
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: location
Vector X, Y, Z values are: [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Root for: rotation_euler
Euler value order: ZYX
Euler X, Y, Z values are: [0.04436017945408821 , 0.008516216650605202 , 0.07332903891801834]
Found curve handling bone: b_Hips for: location
Vector X, Y, Z values are: [0.0 , 0.0 , 0.0]

End of keyframes tested.

Given these results I have the following questions:

  • The first problem here is that by actually moving the Armature through the keyframes of the Action I thought the values for each keyframe would change, but they dont–each keyframe provides the same results. The script runs fast enough that I can’t see the armature move but is always ends up on frame 7 as expected. So, for this type of query, what must I do to move from keyframe to keyframe picking up the values unique to each?
  • The location values for the b_Root bone are coming up as:
    [0.0007030908018350601 , -1.1276321411132812 , 0.0026783025823533535]
    but the values given in the UI for the X, Y and Z locations of b_Root are
    [3.60806, -1.97762, and -646.202].
    If these are in millimeters the UI values sound better as the Z location should be much larger then the X and Y positions. So why should the location be so different between the UI and the Python code?
  • The UI shows three entries in the Graph Editor for location and for Euler Rotations–one for each dimension. The output here also shows three entries for each location and rotation but provides the same three position array for each one. Is that right or am I missing something here?
  • I’m guessing the rotations are degrees in the UI and radians in Python but there must be a significant amount of rounding for the degrees as the values vary noticeably, though usually not until the third of fourth significant digit. I’m guessing that’s okay. Is that probably okay?

Thanks in advance to anyone who can help be get the right values in the output so I can turn around and apply them, possibly in different order, possibly with sign changes, and possibly with additional data for the more detailed human armature (like fingers and hands). Oh, and BTW, I’m normally a Java users so please pardon my camel-back capitalization on some of the variables in the code–I’m not terribly smooth with Python yet.