mesh fabrication

fabricating other objects

material slots

animation and fcurves

incorporating python libraries


shape keys

animating curve bevel


UV layers



video sequence editor (VSE)

images and textures

analytic geometry

node trees


import bpy
import random
import math

def action_z_spin():
    :return: the action for spinning on the Z axis with a period of 30 frames
    rval ="z spin")
    if rval is None:
        rval ="z spin")
        curve ="rotation_euler", 2)
        curve.extrapolation = 'LINEAR'
        p0 = curve.keyframe_points[0]
        p1 = curve.keyframe_points[1]
        p0.interpolation = 'LINEAR' = (1, 0) = (31, math.pi*2)
    return rval

def many_spinning_frogs(template, bounds, count, name, group):
    return a list of 'count' objects (not yet linked to the scene).
     Each object is an empty rigged to duplicate the group 'template'.
     Each object also has an NLA track which references the "z spin" action with a random time scale.
     Each object is added to 'group'.
     :param template: a group of objects for each empty to duplicate
     :param bounds: a list of the form [xmin, xmax, ymin, ymax, zmin, zmax]
     :param count: how many objects to create and return
     :param name: the name for newly created objects
     :param group: the group to which all newly created objects will be added
    rval = []
    for i in range(count):
        # pick a random coordinate in the bounds
        x = random.uniform(bounds[0], bounds[1])
        y = random.uniform(bounds[2], bounds[3])
        z = random.uniform(bounds[4], bounds[5])

        obj =, None)
        obj.location = (x, y, z)
        # rig the Empty to duplicate the template group
        obj.dupli_type = 'GROUP'
        obj.dupli_group = template

        # brand new objects don't have any animation_data, so we create it
        # create an NLA track
        track = = "spin"
        # create a new strip in that track with the z_spin() action
        strip ="spin", 1, action_z_spin())
        # The strip will pull values from the z_spin() action covering 20 to 100 seconds (random)
        strip.action_frame_start = 1
        freq = random.randrange(20, 100)
        if random.randrange(2) > 0:
            # this is a little trick to make half the frogs spin the opposite direction,
            # since you can't run NLAs in reverse.
            obj.rotation_euler[1] = math.pi
            obj.rotation_mode = 'ZXY'
        strip.action_frame_end = freq*30
        # the strip will scale that random span of time to 200 seconds
        strip.frame_end = 1+30*200

        # the order in which you set action_frame_end and frame_end are important.
        # Setting them in the "wrong" order can cause a recalculation
        # of the other value to something you don't want.

        # stuff the newly created object in the group
        if not group is None:


    return rval


frog =['frog']

group ="stars")
if group is None:
    group ="stars")

frogs = many_spinning_frogs(frog, [-15, 15, -10, 10, -20, -40], 100, "star", group)
for obj in frogs:

Blender python API quick-start

Syntax highlighting by Pygments.