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 math

def maybeDispose(name):
    obj =
    if not obj is None: = "discard"

def fakeData():
    rval = []
    for x in range(100+1):
        y = (x*x)/100 + 4*math.sin(x/2)
        rval.append( [ x,y] )
    return rval

def makeCurve(name, data):
    curve =, 'CURVE')
    spline ='BEZIER')
    spline.bezier_points.add(len(data) - 1)
    for i,xy in enumerate(data):
        xyz = [ xy[0], xy[1], 0 ]
        spline.bezier_points[i].co = xyz
        spline.bezier_points[i].handle_left = xyz
        spline.bezier_points[i].handle_right = xyz
    curve.bevel_object =["line"]
    return curve

def animateCurveBevel(obj, f1, f2):"bevel_factor_end", frame=f2) = 0"bevel_factor_end", frame=f1)
    anim =[0]
    anim.keyframe_points[0].interpolation = 'LINEAR'

def animateCurveBevelBad(obj, f1, f2):
    obj.keyframe_insert(data_path="data.bevel_factor_end", frame=f2) = 0
    obj.keyframe_insert(data_path="data.bevel_factor_end", frame=f1)
    anim = obj.animation_data.action.fcurves[0]
    anim.keyframe_points[0].interpolation = 'LINEAR'

def frameForX(idx, nPoints, f0, f9):
    return f0 + (f9-f0) *idx/(nPoints-1)

def setVisibility(obj, f1, f2):

    if not f2 is None:
        obj.keyframe_insert(data_path='hide', frame= bpy.context.scene.frame_end+10)
    obj.keyframe_insert(data_path='hide_render', frame=f1)
    obj.keyframe_insert(data_path='hide', frame=f1)
    obj.hide = True
    obj.hide_render = True
    obj.keyframe_insert(data_path='hide', frame=0)
    obj.keyframe_insert(data_path='hide_render', frame=0)
    if not f2 is None:
        obj.keyframe_insert(data_path='hide', frame=f2)
        obj.keyframe_insert(data_path='hide_render', frame=f2)

def makeText(text, loc, f1, f2):
    curve ="label", 'FONT')
    curve.body = text
    o1 ="label", curve)
    o1.location = loc
    if not f1 is None:
        setVisibility(o1, f1, f2)
    o1.parent =["font folder"]

    return o1

def make2Text(text1, text2, loc, f1, f2):
    o1 = makeText(text1, loc, f1, f2)
    o2 = makeText(text2, loc, f1, f2) = 'RIGHT'

    return (o1, o2)

def lookUp(data, f0, f9, frame):
    f1 = -1

    for i,xy  in enumerate(data):
        f2 = frameForX(i, len(data), f0, f9)
        f3 = frameForX(i+1, len(data), f0, f9)
        if frame<f3:
            return xy
        f1 = f2

    return data[-1]


name = "graph"

for obj in
    if[:5] == "label": = "discard"


data = fakeData()

obj =, makeCurve(name, data))
obj.scale = (0.1,0.1,0.1) = obj = True["graph"])

f0 = 31
f9 = f0+ 5*bpy.context.scene.render.fps

animateCurveBevel(obj, 31, f9)

if False:
    # animating text by creating hundreds of individual text objects that pop in and out
    f1 = -1
    for i,xy  in enumerate(data):
        f2 = frameForX(i, len(data), f0, f9)
        f3 = frameForX(i+1, len(data), f0, f9)
        if (i+1 >= len(data)):
            f3 = None
        if (f2>f1):
            make2Text("x=%d,"%xy[0], "y=%.1f"%xy[1], [4,6,1], f2, f3)
        f1 = f2
    # animating text by hooking into the frame_change_pre callback.

    # Thanks:

    # wipe out any preexisting handlers. Hope that doesn't ruin anyone's day.

    # make the two text objects.
    (t1, t2) = make2Text("x=?,", "y=?", [4,6,1], None, None)
    tdata1 =
    tdata2 =

    def adjustText(scene):
        Update the body on the text labels to be correct for each frame.
        xy = lookUp(data, f0, f9, scene.frame_current)
        tdata1.body = "x=%d,"%xy[0]
        tdata2.body = "y=%.1f"%xy[1]


Blender python API quick-start

Syntax highlighting by Pygments.