I am writing a simple Python script that creates an animation. In order to do this, I am using the following code:

def RotateBone(boneName,rotDegrees,rotAxis):
    boneSelect = bpy.context.object.data.bones[boneName]
    boneSelect.select = True
    bpy.ops.transform.rotate(value = radians(rotDegrees),axis = rotAxis)
    boneSelect.select = False

It rotates a bone and then I use lock key frame command.

My problem is that if I run it twice, it will re-apply the rotations on the animation sequence. That makes the process of development tedious. I am deleting the human model and re-loading it from disk by using the UI, then I use Run script command.

I've also checked this answer, it does the same - relative rotation. I've also tried setting the rotation_euler property of the bone directly, but it does not seem to do anything. Any of these might solve my problem:

  • Find a command that resets all rotations in all key frames that I did.
  • Set the bone rotation values in an absolute way
  • Find a command that deletes an object and a command that loads .mhx object from disk.

Any idea?


2 Answers 2


Your problem was using the edit bones, not pose bones.

A function I used was like the following:

set_rotation(ob, bone_name, rot, axis='X'):
     mat_rot = mathutils.Matrix.Rotation(radians(rot), 4, axis)
     bone = ob.pose.bones[bone_name]
     bone.matrix = mat_rot

This has the added benefit of using a quaternion I believe. I will need to look into that. axis can also be a Vector.

  • $\begingroup$ Thanks for your answer. What is the difference between edit bones and pose bones? $\endgroup$ Commented Aug 10, 2015 at 14:26
  • 1
    $\begingroup$ edit bones is like selecting / moving / scaling bones in edit mode. Pose bones would be the same in pose mode. In edit mode the changes are permanent. In pose mode they just affect the pose and can be "reset". $\endgroup$
    – beiller
    Commented Aug 10, 2015 at 14:58

I think I managed to find a solution. rotation_euler property does seem to work (and it is absolute). It didn't work before because rotation_mode was quarternion, so it didn't affect them.

Thus, the solution is:

def SetBoneRotationDeg(human,boneName,rotEulerDeg):
    lastMode = human.pose.bones[boneName].rotation_mode
    human.pose.bones[boneName].rotation_mode = 'XYZ'    
    human.pose.bones[boneName].rotation_euler[0] = radians(rotEulerDeg[0])
    human.pose.bones[boneName].rotation_euler[1] = radians(rotEulerDeg[1])
    human.pose.bones[boneName].rotation_euler[2] = radians(rotEulerDeg[2])
    human.pose.bones[boneName].rotation_mode = lastMode

You must log in to answer this question.

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