3
$\begingroup$

I get the error

line 60, in return_rotation
TypeError: bpy.struct.keyframe_insert()
property "constraints["FollowPath"].offset_factor" not found

I really dont get what should be the problem and was hoping you guys could help out.

This is the code:

import bpy
import re
import os
import math
import linecache

cube = bpy.data.objects['Cube'] # defining the cube (TestObject)


armature = bpy.data.objects['Armature'] # Defining the armature
bpy.context.scene.objects.active = armature # Selecting the armature
bpy.ops.object.mode_set(mode='POSE') # Setting the mode to POSE
footBone = armature.pose.bones['foot'] # Defining the footBone (the big one)
toesBone = armature.pose.bones['toes'] # Defining the toesBone (the small one)
footBone.rotation_mode = 'XYZ' # Set rotation mode to Euler XYZ, easier to understand
toesBone.rotation_mode = 'XYZ' # Set rotation mode to Euler XYZ, easier to understand


bpy.ops.object.mode_set(mode='OBJECT')
# insert a keyframe


def file_len(fname): # A function which returns the number of lines in a file.
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1 


numberOfLines = file_len('somestuff\Python Test/usedata.csv')#Getting number of lines - 10 to be safe, but safe limit will be removed later.
steps = 1/numberOfLines # How much, is needed to be increased in the followPath modifier, given that only one cycle is needed.
cube.constraints['Follow Path'].offset_factor = 0 #Setting offset to 0, Todo find the right offset. Find how much a cycle is.

def return_rotation(start_value, end_value):
    steps = 1 / (end_value-start_value) # this ensures a complete cycle when all the lines are read
    counter = 0 # This is the frameNumber
    i = start_value # The line number from which to start reading from
    while i < end_value: #end_value is the line to be read to
        line = linecache.getline('somestuff\Python Test/usedata.csv', i).split(',') # fetching a single line

        # setting rotation angles. It only accepts radians, hence the conversion.
        angleX = math.radians(float(line[0]))
        angleY = math.radians(float(line[1]))
        angleZ = math.radians(float(line[2]))
        print(angleX)



        # TODO: check if toesBone is under the floor

        #----------------FootBone-------------------------------------------------------------------------------------------------#
        # Rotate Bones
        footBone.rotation_euler.rotate_axis('X', angleX)
        footBone.rotation_euler.rotate_axis('Y', angleY)
        footBone.rotation_euler.rotate_axis('Z', angleZ)

        # keyframe everything
        footBone.keyframe_insert(data_path="rotation_euler" ,frame = counter) #Insert rotation keyframe
        footBone.constraints["Follow Path"].offset_factor += steps # increasing offset factor

The problem

        footBone.keyframe_insert(data_path= 'constraints["Follow Path"].offset_factor', frame = counter) # Keyframing the offset factor.

End of problem

        # Checking if the offset_factor is above 1 or below zero, and correts this
        if(footBone.constraints['Follow Path'].offset_factor >= 1 or footBone.constraints['Follow Path'].offset_factor < 0): 
            footBone.constraints['Follow Path'].offset_factor = 0

        #----------------cube-----------------------------------------------------------------------------------------------------#
        cube.rotation_mode = 'XYZ'

        cube.rotation_euler[0] += angleX
        cube.rotation_euler[1] += angleY
        cube.rotation_euler[2] += angleZ
        print(float(line[0]))
        print(cube.rotation_euler[0])

        cube.keyframe_insert(data_path='rotation_euler',frame = counter)
        cube.constraints["Follow Path"].offset_factor += steps #Stepping through cycle
        cube.keyframe_insert(data_path= 'constraints["Follow Path"].offset_factor', frame=counter) # Keyframing the offset factor.

        #Checking if the follow path cycle is above one. Might be removed, if not using offset_factor from 0-1 but instead -99999 - 99999
        if(cube.constraints['Follow Path'].offset_factor >= 1 or cube.constraints['Follow Path'].offset_factor < 0): 
            cube.constraints['Follow Path'].offset_factor = 0


        i += 1
        counter += 1
    linecache.clearcache()

return_rotation(1,280)
$\endgroup$
2
$\begingroup$

If I add an armature manually, add a Follow Path constraint in Pose mode, enable Fixed Position and keyframe the offset slider, the data_path of the created f-curve is:

'pose.bones["Bone"].constraints["Follow Path"].offset_factor'

So it's referenced by the "owning" object, and the data path fully qualifies the pose bone and its constraint.

| improve this answer | |
$\endgroup$
  • $\begingroup$ I have a problem when I want to enable this script, someone can to help me? Thank you i.stack.imgur.com/YKqkU.png $\endgroup$ – Laurent Mlanao Dec 28 '16 at 10:52
  • $\begingroup$ I can't see any relation to the post. It looks like an addon called KeyFrameConstraints is throwing an error because it tries to access data during initialization, when it is not allowed to read from bpy.data and bpy.context. This has to be resolved by the plugin author. $\endgroup$ – CodeManX Dec 28 '16 at 16:20

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.