I’ve just started trying my hand at python scripting in Blender 2.77a on Xubuntu 16.04.
I wrote a script to mess about with the ‘frame_change_pre’ handler - the callback function creates a new object every frame.
The problem is that the script fails with the linux terminal displaying ‘TypeError: addBlock() takes 0 positional arguments but 1 was given’ when the frame is changed, but if I call the addBlock() function directly in the script it works without a problem. I have hunted for hours but I can’t see what the problem is. I saw a reference to class methods requiring a ‘self’ parameter in the declaration, but I tried that and it didn’t make any difference.
This is the complete script:
import bpy
import math
from mathutils import Vector
from mathutils import Euler
scn = bpy.context.scene
def createBlock(name='Block', scale=(1,1,1), rotn=(0,0,0), locn=(0,0,0)):
verts = [(1, 1, 1),
(1, -1, 1),
(-1, -1, 1),
(-1, 1, 1),
(1, 1, -1),
(1, -1, -1),
(-1, -1, -1),
(-1, 1, -1)]
faces = [(0, 1, 2, 3),
(4, 5, 6, 7),
(0, 4, 5, 1),
(1, 5, 6, 2),
(2, 6, 7, 3),
(3, 7, 4, 0)]
v_len = len(verts)
for v in range(0, v_len):
if scale != (1,1,1):
verts[v] = tuple(v1 * v2 for v1, v2 in zip(verts[v], scale))
if rotn != (0,0,0):
vec = Vector(verts[v])
eul = Euler(rotn, 'XYZ')
vec.rotate(eul)
t = vec.to_tuple(4)
verts[v] = t
me = bpy.data.meshes.new(name+'Mesh')
ob = bpy.data.objects.new(name, me)
ob.location = locn
ob.show_name = True
# Link object to scene and make active
scn.objects.link(ob)
scn.objects.active = ob
ob.select = True
me.from_pydata(verts, [], faces)
me.update(calc_edges=True)
def addBlock():
frame = scn.frame_current
angle = math.radians(frame * 30)
x = frame * math.cos(angle)
y = frame * math.sin(angle)
z = frame * 0.5
name = 'Slab{0:03d}'.format(frame)
createBlock(name, scale=(1,1,0.1), rotn=(0,0,angle), locn=(x,y,z))
# This produces an error when the frame is changed
bpy.app.handlers.frame_change_pre.append(addBlock)
# This works
addBlock()