2
$\begingroup$

This is very similar to another question today about setting bones in python for use with ManuelBastioniLab and may have the same answer, but Im setting bone roll values in edit mode and he is setting location values in pose mode.

Im trying to import animations including pre done mocap data and animations I make myself (possably fk and ik rigs) from Blender to Unreal (UE4). This is using the manuelbastionilab addon to create human characters and create an ik skeleton and load bvh mocap data. I have spent about 100 hours or more trying to do this and Ive come to the conclusion the only way to do it is to reset the bone roll values to some kind of default for each animation / skeleton. Otherwise the mesh becomes incredibly twisted in many different ways in UE4.

So Ive started to write a python script to set all the values. This is my first python script so its fair to say I dont know what Im doing, but I have got it to set the bone roll values using 2 slightly different methods and they both give the same results. Im having this problem using a fk skeleton (forward kinematics) (no ik on this one). So for setting the bone roll on the little finger I set pinky01_R to 37 but blender sets it to 2636, and the other pinky03_R is set to -47,but blender sets it to -2693. I don't know in what universe 37 == 2636, but Id like to know if its a bug or if there is some way to set the bone roll to the value I give it. The blender scene is set to metric and degrees and scene scale 0.01

If you want to re create this you will can use the manuelbastionilab addon click initcharacter then finalize, then run my script (press space type MBSetDefaultBoneRolls)

Here is my code so far

bl_info = {
   "name": "Setup bone rolls",
   "category": "Rigging"
}

import bpy
import math


class MBBoneRollsSet(bpy.types.Operator):
    """Sets  bone roll values to default for Manuelbastionilab ik and fk     skel"""
    bl_idname = 'rigging.mbbonerollsetter'
    bl_label = 'MBSetDefaultBoneRolls'
    bl_options = {'REGISTER', 'UNDO'}
    bl_category = 'Rigging'

    def execute(self, context):
        Armat = None
        for obj in bpy.context.selected_objects:
            if obj.type == 'MESH' and obj.parent and obj.parent.type == 'ARMATURE':
                Armat = obj.parent
                break
            if obj.type == 'ARMATURE' :
                Armat = obj
                break


        if Armat == None:
            for obj in bpy.data.objects:
                if obj.type == 'MESH' and obj.parent and obj.parent.type == 'ARMATURE':
                    Armat = obj.parent
                    break

        for obj in bpy.context.selected_objects:
            obj.select = False

        if Armat != None:
            Armat.select = True
            bpy.context.scene.objects.active = Armat
            bpy.ops.object.mode_set(mode = 'EDIT')

            Armat.select = True
            #Armat.data.edit_bones:
            bpy.context.object.data.edit_bones['pinky01_R'].roll =46.0
            for EBone in Armat.data.edit_bones:
                if EBone.name == 'pinky03_R':
                   EBone.roll = -47
            bpy.context.scene.update()
            bpy.ops.object.mode_set(mode='OBJECT') 

        return {'FINISHED'}


def register():
    bpy.utils.register_class(MBBoneRollsSet)

def unregister():
    bpy.utils.unregister_class(MBBoneRollsSet)


if __name__ == "__main__":
    register()

Anyway if there is anyone who knows why its setting such a wrong value and or what can be done about it, that would be great!

$\endgroup$
  • 2
    $\begingroup$ To add to answer below: Blender uses the radian natively. (Except occasionally in VSE) I like using math.radians(-47) and its cohort math.degrees(radians) . $\endgroup$ – batFINGER Jun 20 '18 at 9:14
2
$\begingroup$

Python always sets rotation in Radians, not degrees.

$2\pi$ radians is equal to $360^\circ$. This explains your issue, since

$$37 \text{ radians} = (37\cdot 180/\pi)^\circ \approx -2693^\circ$$

You'll need to convert degrees to radians by multiplying by $\pi\approx 3.14...$ and dividing by $180$.

$\endgroup$
0
$\begingroup$

Just import math, and use math.degrees(...) to get right 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.