PoseBones and Python

Hi everybody. I have a small problem. I’m trying to get a bone in Armature Bones by name and move it, but I don’t know how.
Right now, I can move with bone with this:

armatura_obj = Blender.Object.Get(‘mblenrig’)
poz = armatura_obj.getPose()
pbones = poz.bones.values()

and set up move by
pbones[10].quat[:] = 1.000,0.1000,0.2000,0.2000

is it possible to make it diferent way. Not using the number of bone (10), but use the name of bone (forearm)?

Tk everybody for any help.

Wont this work?
poz.bones[“forearm”].quat[:] = 1.000,0.1000,0.2000,0.2000

it works :slight_smile: tk

Hi all

Here is a little function in python to rotate bone(s) …

####################################

SetBoneRotXYZ

python function to rotate bone(s)

version 0.00

Marabout 10/05/2009

####################################

import Blender
from Blender import Scene, Object, Armature, Window
from math import *
from Blender import Mathutils
from Blender.Mathutils import *

#----------------------------------------

frame = frame number where to rot (num)

armaName = name of the armature (string)

boneName = name of the bone in the armature (string)

rotXYZ = tuple [rotx,roty,rotz]

#----------------------------------------
def SetBoneRotXYZ(frame,armaName,boneName,rotXYZ):
arm_obj = Blender.Object.Get(armaName)
action = arm_obj.getAction()
if not action: # Add a pose action if we dont have one yet
action = Armature.NLA.NewAction()
action.setActive(arm_obj)

pose = arm_obj.getPose()
pose_bones = pose.bones
pose_bone = pose_bones[boneName]

pose_bone.quat[:] = Euler(rotXYZ).toQuat()
pose_bone.insertKey(arm_obj, frame, Object.Pose.ROT)
pose.update()

#----------------------------------------

main : test setting some bones …

#----------------------------------------
armaName = ‘Armature’
boneName1 = ‘Bone01’
boneName2 = ‘Bone02’

Window.EditMode(1)
#**********

clear bones in frame 1

#**********
frame = 1
SetBoneRotXYZ(frame,armaName,boneName1,[0,0,0])
SetBoneRotXYZ(frame,armaName,boneName2,[0,0,0])
#**********

set bones in frame 50

#**********
frame = 50
SetBoneRotXYZ(frame,armaName,boneName1,[0,45,0])
SetBoneRotXYZ(frame,armaName,boneName2,[45,0,0])

Window.EditMode(0)

@Marabout: Some formatting was lost in your code post.

Did you mean?


def SetBoneRotXYZ(frame,armaName,boneName,rotXYZ):
    arm_obj = Blender.Object.Get(armaName)
    action = arm_obj.getAction()
    
    if not action: 
        # Add a pose action if we dont have one yet
        action = Armature.NLA.NewAction()
        action.setActive(arm_obj)

    pose = arm_obj.getPose()
    pose_bones = pose.bones
    pose_bone = pose_bones[boneName]

    pose_bone.quat[:] = Euler(rotXYZ).toQuat()
    pose_bone.insertKey(arm_obj, frame, Object.Pose.ROT)
    pose.update()

Hi

Yes, it seems my code was loosing some format …:cool:
Marabout

Hi everybody,

how can I do the same, move individual bones within an armature from Game Engine??? Can’t find any post about this,

Apollo

You need to set up a dummy action with keys for all bones that you indend to move and then attach an action actuator to a controller that runs a Python script. A single frame with locrot keys for all bones will do the job.

You can then use the new and undocumented functionality to getChannel() and setChannel(location, scale, rotation) on the action actuator.

I had to make extensive use of “print dir(action)” to figure out how to use it. If you want to mess about then use the dir() function to print out all methods of any Python object. Not recommended for beginners until it’s documented, but pretty interesting to play with.

edit: If you don’t know how to use the dir() function then start with this:

import GameLogic
print GameLogic.__doc__
print dir(GameLogic)

cont = GameLogic.getCurrentController()
print cont.__doc__
print dir(cont)

Edit: ideasman42 added access to action channels in Blender 2.49a and you will need at least this version of Blender to use this.