0
$\begingroup$

I'm struggling with a rather straight forward operation - rotating a bone. There are tons of examples but can't seem to get it working.

I need to rotate the bone in edit mode (if it's mode specific please share the method too).

I think my selection isn't working. Below is my code:

bpy.context.object.data.bones.active = bpy.context.object.pose.bones["lowerarm_l"].bone
bpy.context.object.pose.bones["lowerarm_l"].bone.select=True
bpy.data.objects['Armature'].pose.bones["lowerarm_l"].bone.select=True
print(bpy.data.objects['Armature'].pose.bones["lowerarm_l"].bone.select)
bpy.ops.transform.rotate(value=1.72994)
bpy.context.object.data.bones.active.hide = True

Console

$\endgroup$
2
  • $\begingroup$ Right now, I cannot answer your question. As far as I can tell you're executing all these lines one by one via the Python command line. Please try to understand what each line is supposed to do first, identify where (i.e. at which of these lines) your code behaves differently than you'd expect and then ask a more specific question. $\endgroup$ – TheBeautifulOrc Jun 10 '20 at 13:54
  • $\begingroup$ You're using the bones in pose mode, use ob.data.bones. $\endgroup$ – Frederik Steinmetz Jun 10 '20 at 14:05
1
$\begingroup$

Rotate an edit bone

To define a rotation require the angle to rotate, the axis to rotate around and a point that the axis goes thru. To code transforms in 3D the sooner we get our heads around linear algebra, ie vectors and matrices the easier it becomes.

Following test script rotates the edit bone (in edit mode) named "Bone" 30 degrees around the bones local X axis, using its head as the pivot point.

One translation matrix moves such that the head is (0, 0, 0) our pivot point. Rotate this with rotation matrix. Move back with negated transform matrix.

import bpy
from mathutils import Matrix
from math import radians

context = bpy.context

bone_name = "Bone" # change to suit

ob = context.edit_object
arm = ob.data

#bone = context.active_bone
bone = arm.edit_bones.get(bone_name)

if bone:
    # local axes of the bone
    x, y, z = bone.matrix.to_3x3().col
    # rotation matrix 30 degrees around local x axis thru head
    R = (Matrix.Translation(bone.head) @
         Matrix.Rotation(radians(30), 4, x) @
         Matrix.Translation(-bone.head)
        )
    #bone.matrix = R @ bone.matrix
    bone.transform(R) 

adjust the angle, the axis, the pivot point to demo how it works. Using y for axis should "roll" the bone.

$\endgroup$
1
  • $\begingroup$ Thanks, however it doesn't work with the Z axis instead of X, the bone is going crazy. $\endgroup$ – lucky3 Sep 29 '20 at 17:30
0
$\begingroup$

From @batFinger code, fix to make it work with all axes:

import bpy
from mathutils import Matrix
from math import radians    

bone = bpy.context.selected_editable_bones[0]

if bone:
    old_head = bone.head.copy()
    R = Matrix.Rotation(radians(30), 4, bone.x_axis.normalized())   
    bone.transform(R, roll=True) 
    offset_vec = -(bone.head - old_head)
    bone.head += offset_vec
    bone.tail += offset_vec
$\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.