# AttributeError when adding keyframes in draw function

I am trying to add add keyframes to an object from values in a csv file using python. It successfully reads the file and puts it into a list. However, it just gives me this error when adding the keyframes.

AttributeError: Writing to ID classes in this context is not allowed: Camera, Object datablock, error setting Object.<UNKNOWN>


This is the code that i have so far:

def draw(self, context):
results = []
layout = self.layout

obj = context.object

with open('record.txt', newline='') as inputfile:
results.append(row)
line = 0
for x in results:
line += 1
if line > 2:
currentFrame = str(x)
xRot, yRot, zRot,_,_ = currentFrame.split(';')
xRot = xRot.replace("['", "")
print(xRot + " " + yRot + " " + zRot)
obj.rotation_euler[0] += float(xRot)
obj.keyframe_insert(data_path="rotation_euler", frame= float(line), index=0)
obj.rotation_euler[1] += float(yRot)
obj.keyframe_insert(data_path="rotation_euler", frame= float(line), index=1)
obj.rotation_euler[2] += float(zRot)
obj.keyframe_insert(data_path="rotation_euler", frame= float(line), index=2)


I would appreciate suggestions in how to solve this issue.

• Can you post a sample line from the csv file? – Todd McIntosh Jul 12 '15 at 20:33
• Also see : blender.stackexchange.com/questions/17919/… it's related – zeffii Jul 13 '15 at 8:52
• @geooot i'm pretty sure the code as you wrote it - for adding keyframes - doesn't work as intended, a sample line (or several lines) of the record.txt file would let us give working solutions. – zeffii Jul 13 '15 at 9:06
• @zeffii Here is a line of the csv file pastebin.com/pygPSnRA – geooot Jul 13 '15 at 15:44
• @geooot I've adjusted my answer. care to share a file I could test it on - seems like fun. – zeffii Jul 14 '15 at 15:34

The draw function is for UI only (defining layout and visibility of properties, sliders etc). It's called multiple times per second, sometimes 20 or more times, as you move your mouse around

You can't change bpy.data (including keyframes) from inside draw, it is blocked by design. You probably don't want to repeatedly execute that code anyway. A standard approach is to Run it from Text Editor with or without an enclosing function.

If this represents the first and second line of the the dataset, and the next lines are all formatted like line 2.

dataset.txt

GYROSCOPE X (°/s);GYROSCOPE Y (°/s);GYROSCOPE Z (°/s);Time since start in ms ;YYYY-MO-DD HH-MI-SS_SSS
9.08;-1.04;-9.51;20;2015-07-03 14:17:34:206


code

import csv
import bpy

def some_function(fp):

obj = bpy.data.objects['Camera']

results = []
with open(fp, newline='') as inputfile:
next(row_gen) # skip first line.

for row in row_gen:
results.append(row[0].split(';'))

# start making frames at frame 1
for idx, frame_data in enumerate(results, 1):
xRot, yRot, zRot = frame_data[:3]
print(xRot, yRot, zRot)
obj.rotation_euler[0] += float(xRot)
obj.rotation_euler[1] += float(yRot)
obj.rotation_euler[2] += float(zRot)
obj.keyframe_insert(data_path="rotation_euler", frame=idx, index=-1)

some_function(fp='/home/zeffii/Desktop/zen/dataset.txt')


The -1 at the end indicates that the keyframe is to be added after the other existing keyframes.

For info about paths; whether to use back or forward slashes, see:

Adding this for completeness, because it differs across Operating Systems.