import bpy
import math
class Dropper:
def __init__(self, nx, dx, ny, dy, x0=0, y0=0, z0=40):
self.nx = nx
self.dx = dx
self.ny = ny
self.dy = dy
self.x0 = x0
self.y0 = y0
self.z0 = z0
def location_for(self, i):
u = i % self.nx
i_ = math.floor(i / self.nx)
v = i_ % self.ny
i_ = math.floor(i_ / self.ny)
print("%d, %d" % (u, v))
x = self.x0 + u * self.dx
y = self.y0 + v * self.dy
loc = (x, y, self.z0 + i_ * 2)
return loc
def drop_location_for(self, i):
layer=1;
while True:
if (i<layer*layer):
return self.drop_location_for_layer(layer, i)
i = i -layer*layer
layer = layer+1
def drop_location_for_layer(self, layer, i):
u = i%layer
v = math.floor(i/layer)
x = self.x0 + (u-layer/2)*self.dx
y = self.y0 + (v-layer/2)*self.dy
return (x,y,10)
def drop(self, template, n, preexisting):
scn = bpy.context.scene
name = "pileable"
for i in range(n):
if i < len(preexisting):
obj = preexisting[i]
else:
obj = bpy.data.objects.new(name, template.data)
scn.objects.link(obj)
#
obj.select = True
scn.objects.active = obj
bpy.ops.rigidbody.objects_add(type='ACTIVE')
obj.select = False
obj.location = self.location_for(i)
#
frame = i*3+3
frame = 30+7*math.sqrt(i)
frame = 30+ 20*math.pow(i, 0.3333)
fc1 = get_fcurve(obj.animation_data.action, "rigid_body.kinematic")
set_keyframe_points(fc1, 'CONSTANT', [1,True], [frame-1,False])
fc2 = get_fcurve(obj.animation_data.action, "rigid_body.enabled")
set_keyframe_points(fc2, 'CONSTANT', [1, False], [frame, True])
drop_loc = self.drop_location_for(i)
for ai in range(3):
fc3 = get_fcurve(obj.animation_data.action, "location", ai)
set_keyframe_points(fc3, 'LINEAR', [1, obj.location[ai]], [frame-3, drop_loc[ai]])
def get_fcurve(action, data_path, index=0):
for curve in action.fcurves:
if (curve.data_path == data_path and index==curve.array_index):
return curve
return action.fcurves.new(data_path, index)
def set_keyframe_points(fcurve, ipo, *kps):
l1 = len(fcurve.keyframe_points)
l2 = len(kps)
while (l1 > l2):
fcurve.keyframe_points.remove(fcurve.keyframe_points[0])
l1 = len(fcurve.keyframe_points)
if (l1 < l2):
fcurve.keyframe_points.add(l2-l1)
for i in range(l2):
fcurve.keyframe_points[i].co = kps[i]
fcurve.keyframe_points[i].interpolation = ipo
#
scn = bpy.context.scene
d = Dropper(6, 2, 5, 2)
d.drop(bpy.data.objects["stackable"], 1000, [ obj for obj in scn.objects if obj.name[:8] == "pileable"])
|
Blender python API quick-start
Syntax highlighting by Pygments.