blender-scripting
This is a collection of simple to more involved examples to scripting in Blender with Python.
Table of Contents
- Requirements
- Resources
- Utils
- Simple Sphere
- Parametric Torus
- Metaballs
- Voronoi Landscape
- Tetrahedron Fractal
- Phyllotaxis Flower
- Rugged Donut
- Fisher Iris Visualization
- Voronoi Sphere
Requirements
Blender 2.8+
To run the examples, open your favorite console in the example folder. Make sure to edit in run_script.py the scriptFile
variable to the Python script in the scripts folder you want to execute.
blender -b -P run_script.py
Another option is to open the script in Blender and run run_script.py inside Blender, which is a nice way to test and tweak the files and to see and play with the generated result before rendering.
To create videos from frames, you can use ffmpeg as follows:
ffmpeg \
-r 15 \ # frame rate
-i frames/phyllotaxis_flower%04d.png \ # input path
-c:v libx264 \ # video codec (H.246)
-c:a aac -ar 44100 \ # audio codec (AAC with 44100 Hz)
-pix_fmt yuv420p \ # pixel format and color sampling
phyllotaxis_flower.mp4 # output path
Resources
Utils
Some frequently used functions in blender, which will be used in most of the scripts.
Simple Sphere
Simple rendering of a smooth sphere. First an icosphere is added with
import bpy
bpy.ops.mesh.primitive_ico_sphere_add(location=(0, 0, 0))
obj = bpy.context.object
Then the subdivision surface modifier is added to the object to increase the resolution of the mesh and afterwards all the faces of the object are set to a smooth shading
modifier = obj.modifiers.new('Subsurf', 'SUBSURF')
modifier.levels = 2
modifier.render_levels = 2
mesh = obj.data
for p in mesh.polygons:
p.use_smooth = True
Alternatively the icosphere can be subdivided with the subdivisions
argument in the function
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, location=(0, 0, 0))
Parametric Torus
Parametric generation of a torus. The torus is created with the following parameterization of a grid of the variables u, v
where the values u, v are between 0 and 1 and are then mapped to x, y, z coordinates. In parametric_torus.py, the function torusSurface(r0, r1)
returns the surface parameterization function for a torus which is then used in createSurface(surface, n, m)
as the first argument, which creates the object from a n by m grid. The function createSurface(surface, n, m)
can be also used for other parameterizations such as surfaces of revolution or other parametric surfaces.
Metaballs
Generate random metaballs in Blender inspired by this tutorial.
Voronoi Landscape
This is a more advanced example for using a Voronoi diagram. The Voronoi diagram is implemented with the module scipy.spatial
which can be added with Scipy, or can be found in the Python distribution Anaconda. The steps to use Anaconda as the Interpreter in Blender 2.77 are shown in this solution.
Tetrahedron Fractal
This is an example for a fractal tetrahedron, where each tetrahedron is subdivided into smaller pieces with a recursive function. In order to create a material for the tetrahedron the material is assigned as shown here:
color = (0.5, 0.5, 0.5)
mat = bpy.data.materials.new('Material')
# Diffuse
mat.diffuse_shader = 'LAMBERT'
mat.diffuse_intensity = 0.9
mat.diffuse_color = color
# Specular
mat.specular_intensity = 0
obj.data.materials.append(mat)
Phyllotaxis Flower
This script implements a Phyllotaxis Flower which aranges leaves or the petals according to the golden angle. Additionally The flower is animated by appending an application handler for frame change by
def handler(scene):
frame = scene.frame_current
# Create new geometry for new frame
# ...
# Append frame change handler on frame change for playback and rendering (before)
bpy.app.handlers.frame_change_pre.append(handler)
In order to render all frames you can run
bpy.ops.render.render(animation=True)
The animation is inspired by the mesmerizing sculptures by John Edmark.
Rugged Donut
This script implements a number of different things available in Blender. For one it applies a Displace modifier to a torus which displaces the object with a texture as follows.
# Create musgrave texture
texture = bpy.data.textures.new('Texture', 'MUSGRAVE')
# Create displace modifier and apply texture
displace = obj.modifiers.new('Displace', 'DISPLACE')
displace.texture = texture
Further we can control the texture by an object such as an Empty object
# Create Empty to control texture coordinates
empty = bpy.data.objects.new('Empty', None)
bpy.context.scene.objects.link(empty)
# Take the texture coordinates from empty’s coordinate system
displace.texture_coords = 'OBJECT'
displace.texture_coords_object = empty
Additionally we want to add a material with additional bump map to our torus object which is done in the following way.
# Create bump map texture
bumptex = bpy.data.textures.new('BumpMapTexture', 'CLOUDS')
# Create material
mat = bpy.data.materials.new('BumpMapMaterial')
# Add texture slot for material and add texture to this slot
slot = mat.texture_slots.add()
slot.texture = bumptex
slot.texture_coords = 'GLOBAL'
slot.use_map_color_diffuse = False
slot.use_map_normal = True
# Append material to object
obj.data.materials.append(mat)
Now we want to animate the empty in order to animate the texture. We can achieve this by inserting keyframes for the location of our empty as shown in this quick tutorial and in the next snippet.
for frame in range(1, num_frames):
t = frame / num_frames
x = 0.7*cos(2*pi*t)
y = 0.7*sin(2*pi*t)
z = 0.4*sin(2*pi*t)
empty.location = (x, y, z)
empty.keyframe_insert(data_path="location", index=-1, frame=frame)
Fisher Iris Visualization
This script implements a visualization of the famous Fisher's Iris data set. The data set consists of 50 samples for each of three flower species of Iris setosa, Iris virginica and Iris versicolor. Each sample consists of four features (sepal length, sepal width, petal length and petal width). In order to visualize the data set in three dimensions we apply dimensionality reduction by using Principal Component Analysis. The data set and PCA are both included in the scikit-learn library for Python. This script works both with or without sklearn which is not part of the Blender Python distribution. You can use sklearn by using Anaconda in Blender which I show in this quick tutorial.
from sklearn import datasets
from sklearn import decomposition
# Load Dataset
iris = datasets.load_iris()
X = iris.data
y = iris.target
labels = iris.target_names
# Reduce components by Principal Component Analysis from sklearn
X = decomposition.PCA(n_components=3).fit_transform(X)
The data set in /scripts/data/iris/ is downloaded from the UCI Machine Learning Repository and PCA is implemented manually with the help of the included Numpy library. If sklearn is not in the current Python distribution the Iris data set is loaded as in the next code snippet.
path = os.path.join('data', 'iris', 'iris.data')
iris_data = np.genfromtxt(path, dtype='str', delimiter=',')
X = iris_data[:, :4].astype(dtype=float)
y = np.ndarray((X.shape[0],), dtype=int)
# Create target vector y and corresponding labels
labels, idx = [], 0
for i, label in enumerate(iris_data[:, 4]):
if label not in labels:
labels.append(label); idx += 1
y[i] = idx - 1
# Reduce components by implemented Principal Component Analysis
X = PCA(X, 3)[0]
The data set is loaded into the scene as a 3D scatter plot with different shape primitives for each class of flower from the BMesh Operators. Additionally each collection of shapes in a class has different materials assigned to them. Each class has corresponding labels which are rotated toward the camera by a Locked Track Constraint.
Voronoi Sphere
This is another example using the Voronoi diagram, but this time in the 3rd dimension. It is implemented as well with the module scipy.spatial
which can be added with Scipy and it is even used in a similar way as the previous Voronoi example in 2D.