Controlling IK chain with Python ?

Hello Blenderheads,

I’ve tested some features of the blender Python API, like rotating bones, recording actions and so on…

My problem is: When grabbing (G Key) the “ik solving bone” (on top of the chain) the rest is following sufficently.

Now, I want to controll the chain through python - but I couldn’t find out how to affect the whole chain. Rotating the ik-solv. bone doesn’t affect the rest.

I’ll paste my script below. pbone[4] is the IK solv. bone.

I hope you can help me. Cheers, Florian


# ------ Imports -------
import tty, termios
import os
import re
import time
import sys
from threading import Thread
import Blender
from Blender import Armature
from Blender.Mathutils import *
from Blender import *
from Blender.Draw import *

# ------ Defines ---------

global toggle

toggle = 1
    
def event(evt,val):
    #print "event : " evt,val
    if (evt == ESCKEY and not val): toggle = 0
    if (evt == ESCKEY and not val): Exit()
    
    Register(event)

        
# ------ Logic goes here -------

print "----- NEW START ----"

arms = Armature.Get()
scn= Scene.GetCurrent()
#
arm_data= Armature.Get("Armature")
print arm_data
#arm_ob = scn.objects.new(arm_data)
arm_ob = scn.objects.active
print "which is active", arm_ob

# The initial angles of the DOF's of the robot
qInitial = [0, 0, 0, 0, 0, 0]
# The end angles of the DOF's of the robot
qEnd = [90, 90, -90, 90, -90, 90]
    
q = qInitial
# Every movement takes 40 frames
addFrames = 40
# Set current frame to 1
Blender.Set("curframe", 1)
currentFrame = 1

# adding an action

act = arm_ob.getAction()
if not act: # Add a pose action if we dont have one
    act = Armature.NLA.NewAction()
    act.setActive(arm_ob)




pose = arm_ob.getPose()

xbones=arm_ob.data.bones.values()
pbones = pose.bones.values()
print xbones
print "BONES",pbones

print "IK BONE",pbones[4]

frame = 1
for pbone in pbones: # set bones to no rotation
    pbone.loc[:] = 0.000,0.000,0.000
    #pbone.quat[:] = 1.000,0.000,0.000,0.0000
    pbone.insertKey(arm_ob, frame, Object.Pose.LOC)

    # Set a different rotation at frame 25
pbones[4].loc[:] = 1.000,0.000,0.000
#pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
#pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000
#pbones[3].quat[:] = 1.000,0.1000,0.3000,0.40000
#pbones[4].quat[:] = 0.500,-0.2000,-0.5000,0.30000
#pbones[5].quat[:] = 0.500,-0.2000,-1.5000,0.30000

frame = 25
for i in xrange(5):
    pbones[i].insertKey(arm_ob, frame, Object.Pose.LOC)
    
pbones[4].loc[:] = -4.000,1.000,0.000
#pbones[0].quat[:] = 1.000,0.000,0.000,0.0000
#pbones[1].quat[:] = 1.000,0.000,1.000,0.0000
#pbones[3].quat[:] = 1.000,0.000,0.000,0.0000
#pbones[4].quat[:] = 0.300,-0.700,-0.200,0.0000
#pbones[5].quat[:] = 0.500,-0.2000,-0.5000,0.30000

frame = 50
for i in xrange(5):
    pbones[i].insertKey(arm_ob, frame, Object.Pose.LOC)
    
pbones[4].loc[:] = 0.000,-4.000,3.000
#pbones[0].quat[:] = 1.000,0.000,2.000,0.0000
#pbones[1].quat[:] = 1.000,2.000,0.000,0.0000
#pbones[3].quat[:] = 1.000,0.000,0.000,0.0000
#pbones[4].quat[:] = 1.000,-0.100,0.400,0.0000
#pbones[5].quat[:] = 1.500,-0.700,-0.400,0.7000

frame = 75      
for pbone in pbones: # set bones to no rotation
    pbone.loc[:] = 0.000,0.000,0.000
    #pbone.quat[:] = 1.000,0.000,0.000,0.0000
    pbone.insertKey(arm_ob, frame, Object.Pose.LOC)


#for pbone in pbones: # set bones to no rotation
    #pbone.quat[:] = 1.000,0.000,0.000,0.0000
    #pbone.insertKey(arm_ob, frame, Object.Pose.ROT)


#while (toggle):
    #print "bla"

    #pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
    #pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000
    #pbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000
    #pbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000
    #pbones[4].quat[:] = 1.000,-0.2000,-0.3000,0.30000
    #pbones[5].quat[:] = 1.000,-0.2000,-0.3000,0.30000    


    #pbones[0].quat[:] = 1.000,0.000,0.000,0.0000
    #pbones[1].quat[:] = 1.000,0.000,0.000,0.0000
    #pbones[2].quat[:] = 1.000,0.000,0.000,0.0000
    #pbones[3].quat[:] = 1.000,0.000,0.000,0.0000
    print "exiting loop"

print "f00"

for arm in arms.values():
   arm.drawType = Armature.STICK #set the draw type
   #arm.makeEditable() #enter editmode


blubb = pbones[4].hasIK 
print "Has q5 an IK Chain?",blubb

location = pbones[4].loc
print "location", location

print "------------------------------"

localmatrix = pbones[4].localMatrix
print "localmatrix",localmatrix

#pbones[4].loc[:] = 0.000,0.000,0.000

bla = arm.bones['q5']

print "Name of Bone:"
print bla.name 
print "Has Parents?" 
print bla.hasParent()
print "Has Children?"
print bla.hasChildren()


pose.update()

# ------- Proper End -------
print "Script Ends here"

I dont really understand what you are wanting your script to do exactly. Could you explain it some more. One suggestion i could think of is to use an Empty for an IK solver and then just move the Empty.

That’s the solution. Sorry for the late answer.

Search the bf-python list for more info (Blender python mailing list)

cheers, Florian