# context.frame_set() not updating every time

I am trying to build a tool for calculating the IK pole angle of a constraint, I already posted a question here, but no answers. So I decided to go for brute force. Running a for loop and trying angles between -180 and 180 and seeing the difference with the rest position of the bone.

But the script does't works i returns too many angles supposed to be the right one when the truth is that only have one exact angle.

Here is the evaluating function, the full operator is a bit longer, so I put on PasteAll

# context is the bpy.context,
# p_bone is the pose bone with the constraint
# ik is the Inverse kinimatics constraint on the p_bone
# angle is the angle to try and score
def ik_test(context, p_bone, ik, angle):
# mute constraint for getting original vectors of the bone
ik.mute = True
# then update the scene
context.scene.frame_set(context.scene.frame_current)
# get some vecotrs
v1 = p_bone.vector
x1 = p_bone.x_axis
z1 = p_bone.z_axis

# unmute the constraint
ik.mute = False
# set the pole_angle for the test
ik.pole_angle = angle
# update the scene again
context.scene.frame_set(context.scene.frame_current)
# get the new vectors
v2 = p_bone.vector
x2 = p_bone.x_axis
z2 = p_bone.z_axis

# lets see the diferences..
v_point = (v1 - v2).magnitude
x_point = (x1 - x2).magnitude
z_point = (z1 - z2).magnitude
# lets get the total score
total = v_point + x_point + z_point
# with better score total sould be smaller,
# but it returns zero at multiple angles
# this only can happen if the scene does't update.
print(angle, total)
return (angle, total)

• Could you please fix your indenting. Can use blender text editor. Select all, hit tab, (tabs all one to the right, the formatting needed for bse) copy .. paste here. shift-tab tabs back. – batFINGER Sep 9 '17 at 16:36
• oops, I fixed now. – Jeacom Sep 9 '17 at 17:46
• Try scene.update() I think frame_set does update, but maybe not for scene.frame_current – batFINGER Sep 9 '17 at 17:52
• Still getting many zero scores, as if the values didn't change. – Jeacom Sep 9 '17 at 18:11

Run this example on a sample start up file, with cube selected. What result to you expect to get.

import bpy
from mathutils import Vector
context = bpy.context
scene = context.scene
obj = context.object

v1 = obj.location
# move the object
obj.location += Vector((1, 1, 1))
#update the scene
scene.update()
# get the new location
v2 = obj.location
# print the result.
print(v1, v2, v2 - v1)


The result

<Vector (1.0000, 1.0000, 1.0000)> <Vector (1.0000, 1.0000, 1.0000)> <Vector (0.0000, 0.0000, 0.0000)>


The context object clearly moves, but the vectors v1 and v2 both have the same value. This is because v1 is a reference to obj.location and not to the value when set. To get the value when set:

Use Vector.copy()

"use this to get a copy of a wrapped vector with no reference to the original data"

Use Vector.copy() whenever you want to get a snapshot of a Vector value. Otherwise v1 = p_bone.vector will always equal v2 = p_bone.vector as it is a reference to the value, p_bone.vector. This is one (major) reason you are always getting 0s.

Also worth noting: blender natively uses radians as a measure of angle. 180 as radians is degrees(180) or 10313.24 degrees, which is rather nonsensical.

• Even, the same pattern of zeros. Look: postimg.org/image/dzyimsgk5 – Jeacom Sep 10 '17 at 1:56
• Oh well that's that then. Simply wiriting no it still doesn't work is somewhat annoying, given that code as was with reference to vector would give zero on for each of (v2 - v1) , (x2 - x1), (z2 - z1). Ever thought about posting a link to changed code, , and a sample file to run it on. You do know that blender uses radians natively for angles? You could add descriptive print statements to make it easier to debug. – batFINGER Sep 10 '17 at 7:21