cloning
link-mesh-array.py
link-mesh.py

mesh fabrication
staircase.py
triangle-donut.py
vertexAccumulator.py
randomSquareArray.py
meshFromBathymetry.py
cylinders-from-list-of-radii.py
binary-image-to-mesh.py
sphere-minecraft-schematic.py
spikify.py
add-to-mesh.py
mobius-strip.py
split-copy-mesh.py

fabricating other objects
create-text.py
text-from-file.py
create-camera.py
create-bezier.py
helix-bezier.py

material slots
cube-copy-blue.py
cube-turns-red.py
red-blue-per-object.py

animation and fcurves
csv-to-fcurve-loc-rot.py
csv-to-fcurve.py
pop-in-material.py
spike-wiggle-2.py
spike-wiggle.py
sweep-animate-size.py
animate-cycles-lamp-strength.py

incorporating python libraries
exec-text-library.py
exec-external-python.py
import-python.py

constraints
camera-track-object.py
text-track-camera.py

shape keys
explore-shape-keys.py
shape-key-fin.py
docking-tube.py

animating curve bevel
data-graph.py

drivers
scan-drivers.py
copy-drivers.py
driver-fin.py
driver-multi-chain.py

UV layers
barber-pole.py
expand-uv-to-fit.py
uv-from-geometry-cubic.py
flip-texture-v-coordinate.py

modifiers
hook-modifier-curve.py
rounded-prisms.py
make-tile.py
remove-action-modifiers.py

NLAs
explore-NLAs.py
spinning-frogs.py

video sequence editor (VSE)
create-vse-image-strips.py
slide-show.py
vse-strip-gap.py

images and textures
image-on-mesh.py
image-to-material-node.py
load-image-texture.py
texture-one-cube-face.py
condense-duplicate-images.py

analytic geometry
animate-random-spin.py
camera-cone-exp-2.py
camera-cone-exp.py
compute-circle-center.py
dihedral-angle-from-xy.py
extrude-edge-along-custom-axis.py
orientation-matrix.py
two-spheres.py
bezier-interpolate.py
rotate-to-match.py

node trees
change-diffuse-to-emission-node.py

etc
add-plane-from-selected-vertices.py
adjust-all-materials.py
all-nodes-cycles-materials.py
bit_shift.py
bone-orientation-demo.py
cannonball-packing.py
comb.py
convert-quaternion-keyframes-to-euler.py
copy-location-from-vertex-group.py
create-cycles-material.py
demonstrate-decomposition-instability.py
dump-point-cache.py
dump-screen-layout-info.py
expand-nla-strips.py
explore-edge-bevel-weight.py
find-action-users.py
find-green-rectangle.py
find-new-objects.py
fix-scene-layers.py
generate-makefile.py
link-external-data-blocks.py
list-referenced-files.py
material-readout.py
movie-card-stack.py
movies-on-faces.py
next-file-name.py
object-font-from-regular-font.py
operator-mesh-gridify.py
particle-animator.py
particle_loop.py
pose-match.py
pose-sequence-to-fbx.py
prepare-texture-bake.py
raining-physics.py
random-pebble-material.py
reverse-keyframes.py
scale-parallelogram.py
screenshot-sequence.py
select-objects-in-modifiers.py
select-vertices.py
shift-layers.py
snapshot-keyframes-as-mesh.py
sphere-project-texture.py
squish-mesh-axis.py
subdivide-fcurve.py
thicken-texture.py
transform-selected.py
voronoi-madness.py

# let's create animations showcasing the effects of various particle system parameters

import bpy


def grass_group():
    return bpy.data.groups.get("grasses")

def make_PS_dupli(name):
    ps = bpy.data.particles.new(name)
    set_PS_dupli(ps)

def set_PS_dupli(ps):
    ps.type = 'HAIR'
    ps.render_type = 'GROUP'
    ps.dupli_group = grass_group()
    print(ps.dupli_group)
    ps.use_advanced_hair = True
    ps.child_type = 'INTERPOLATED'
    ps.count=100
    ps.material_slot = 'grass 1'

def set_PS_path(ps):
    ps.type = 'HAIR'
    ps.render_type = 'PATH'
    ps.use_advanced_hair = True
    ps.child_type = 'INTERPOLATED'
    ps.count=100
    ps.material_slot = 'grass 1'

def particle_mesh():
    name = "particle emitter"
    mesh = bpy.data.meshes.get(name)
    if mesh is None:
        mesh = bpy.data.meshes.new(name)
        verts = ( [8,8,0],
        [-8,8,0],
        [-8,-8,0],
        [8,-8,0])
        mesh.from_pydata(verts, [], [ [0,1,2,3] ])
        mesh.materials.append(bpy.data.materials.get("dirt"))
        mesh.materials.append(bpy.data.materials.get("grass 1"))
    obj = bpy.data.objects.new(name, mesh)
    return obj


def set_flash_keyframes(hide, fr):
    # the curve started out empty, let's add 4 points
    hide.keyframe_points.add(4)
    kp = hide.keyframe_points
    # start hidden
    kp[0].co = (1, True)
    # appear at fr
    kp[1].co = (fr, False)
    # disappear at fr+1
    kp[2].co = (fr + 1, True)
    # make all the objects reappear at frame 999 (well beyond the animation end)
    kp[3].co = (999, False)

    for bt in kp:
        bt.interpolation = 'CONSTANT'
    if fr==1:
        # in this case, the object starts visible, not hidden, so we remove a conflicting point
        kp.remove(kp[0])


def get_flash_action(fr):
    """
    :param fr: what frame should the object appear at (and disappear immediately after?
    :return: an action datablock to make the object appear at the targeted frame and disappear immediately afterward
    """

    name = "action flash %d"%fr
    rval = bpy.data.actions.get(name)
    # it is not very commmon for objects to reuse actions outside of an NLA context,
    # but since I'm making a lot of animations that have text armies that
    # appear and disappear in a similar manner, I decided to reuse the actions.
    if rval is None:
        # the action I want does not exist yet.  Make it.
        rval = bpy.data.actions.new(name)
        # this curve will control the object's visibilty in the 3D view
        h1 = rval.fcurves.new("hide")
        # this curve will control the object's visibility in the rendered scene
        h2 = rval.fcurves.new("hide_render")

        set_flash_keyframes(h1, fr)
        set_flash_keyframes(h2, fr)

    return rval


def label_material():
    rval = bpy.data.materials.get("label")
    if rval is None:
        rval = bpy.data.materials.new("label")
        rval.emit = 1
        rval.diffuse_intensity = 0
        rval.specular_intensity = 0
        rval.diffuse_color = (1,1,1)
    return rval

def value_overlay(msg, fr, scn):
    """
    create a text message that appears at fr and disappears immediately after
    :param msg: the body of the text
    :param fr: frame number for the text object to appear
    :param scn: the scene the object will be linked to.
    """
    curve = bpy.data.curves.new("value_overlay", 'FONT')
    curve.body = msg
    curve.size = 0.5
    curve.materials.append(label_material())

    obj = bpy.data.objects.new("value_overlay", curve)
    obj.animation_data_create()
    obj.animation_data.action=get_flash_action(fr)

    cns = obj.constraints.new("CHILD_OF")
    cns.target= scn.camera
    obj.location = (-4.3, 1.8, -10)

    scn.objects.link(obj)


def animate_parameter(ps, data_path, keyframes, extra = {}):

    for key, value in extra.items():
        setattr(ps, key, value)

    ps.animation_data_create()
    ac = bpy.data.actions.new("ps action %s" % data_path)
    ps.animation_data.action = ac
    fc = ac.fcurves.new(data_path=data_path)

    fc.keyframe_points.add(len(keyframes))
    for i in range(len(keyframes)):
        bt = fc.keyframe_points[i]
        bt.co = keyframes[i]
        bt.interpolation = 'LINEAR'

    return fc


def fabricate_text_animation(scn, ps, fc, extra={}):

    # clobber old text
    for obj in scn.objects:
        if obj.type=='FONT':
            scn.objects.unlink(obj)

    extra_msg = ""
    data_path = fc.data_path
    for key, value in extra.items():
        extra_msg = extra_msg + "\n" + key + "=" + str(value)
    for fr in range(scn.frame_start, scn.frame_end + 1):
        value_overlay("%s=%.2f%s" % (data_path, fc.evaluate(fr), extra_msg), fr, scn)


def find_particle_system_settings(scn):
    """scan the objects to find one with a particle system"""

    for obj in scn.objects:
        if obj.particle_systems is None:
            continue
        print ( len(obj.particle_systems))
        return obj.particle_systems[-1].settings
    return None

def make_scene_for(name, data_path, keyframes, ps_func, extra={}):
    scn = bpy.data.scenes.get(name)
    if scn is not None:
        print("not creating scene %s"%name)
        return
    scn = bpy.data.scenes.new(name)
    scn.frame_end = keyframes[-1][0]

    s2= bpy.data.scenes.get("lights camera")
    for obj in s2.objects:
        scn.objects.link(obj)
        if obj.type == 'CAMERA':
            scn.camera = obj
    scn.world = s2.world
    scn.render.tile_x = 64
    scn.render.tile_y = 64
    scn.render.use_overwrite = False
    scn.render.image_settings.compression=100

    obj = particle_mesh()
    scn.objects.link(obj)

    scn.update()
    print(scn.camera)

    bpy.context.screen.scene = scn

    scn.objects.active = obj
    bpy.ops.object.particle_system_add()
    ps = obj.particle_systems[-1].settings
    ps_func(ps)

    scn.render.filepath = "/var/tmp/blender/%s/%s/"%(ps.render_type,name)

    #

    fc = animate_parameter(ps, data_path, keyframes, extra)

    fabricate_text_animation(scn, ps, fc, extra)

    return scn

#
#

def child_parameters_1(ps_func=set_PS_dupli):
    global KF_10
    KF_10 = [[1, 0], [60, 1], [120, 4], [180, 10]]
    KF_1_0 = [[1, 1], [60, 0]]
    KF_1 = [[1, 0], [60, 1]]

    # this can not be keyframed
    # make_scene_for("hair_length", "hair_length", [ [1,4], [60,0], [61,4], [75,4], [135,10]], set_PS_dupli)

    make_scene_for("length_random", "length_random", KF_1, ps_func)

    make_scene_for("clump_factor", "clump_factor", [[1, -1], [61, 0], [120, 1]], ps_func)
    make_scene_for("clump_shape", "clump_shape", [[1, -1], [60, 0],  [76, 0], [135, 1]], ps_func, {"clump_factor":-1})

    make_scene_for("child_length", "child_length", KF_1_0, ps_func)
    make_scene_for("child_length_threshold", "child_length_threshold", KF_1_0, ps_func,
                   {"child_length": 0.3})

    # parting?

    make_scene_for("roughness_1", "roughness_1", [[1, 0], [60, 0.2], [120, 1], [180, 4]], ps_func)
    make_scene_for("roughness_1_size", "roughness_1_size", KF_10, ps_func, {"roughness_1": 1})

    make_scene_for("roughness_endpoint", "roughness_endpoint", [[1, 0], [60, 1], [120, 4]], ps_func)
    make_scene_for("roughness_end_shape", "roughness_end_shape", KF_10, ps_func,
                   {"roughness_endpoint": 1})

    make_scene_for("roughness_2", "roughness_2", KF_10, ps_func)
    make_scene_for("roughness_2_size", "roughness_2_size", KF_10, ps_func, {"roughness_2":1})
    make_scene_for("roughness_2_threshold", "roughness_2_threshold", KF_1, ps_func, {"roughness_2":1})

Blender python API quick-start

Syntax highlighting by Pygments.