Giter VIP home page Giter VIP logo

blender-scripting's Introduction

blender-scripting

This is a collection of simple to more involved examples to scripting in Blender with Python.

Table of Contents

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

utils

Some frequently used functions in blender, which will be used in most of the scripts.

Simple Sphere

simple_sphere.py

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))

Simple Sphere

Parametric Torus

parametric_torus.py

Parametric generation of a torus. The torus is created with the following parameterization of a grid of the variables u, v

Torus Formula

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.

Parametric Torus

Metaballs

metaballs.py

Generate random metaballs in Blender inspired by this tutorial.

Metaballs

Voronoi Landscape

voronoi_landscape.py

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.

Voronoi Landscape

Tetrahedron Fractal

tetrahedron_fractal.py

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)

Tetrahedron Fractal

Phyllotaxis Flower

phyllotaxis_flower.py

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.

Phyllotaxis Flower

Rugged Donut

rugged_donut.py

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)

Rugged Donut

Fisher Iris Visualization

fisher_iris_visualization.py

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.

Fisher Iris Visualization

Voronoi Sphere

voronoi_sphere.py

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.

Voronoi Sphere

blender-scripting's People

Contributors

billmanh avatar milochen0418 avatar njanakiev avatar tomashubelbauer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blender-scripting's Issues

utils package outdated in blender2.8

def setAmbientOcclusion(ambient_occulusion=True, samples=5, blend_type='ADD'):
    # blend_type options: 'ADD', 'MULTIPLY'
    bpy.context.scene.world.light_settings.use_ambient_occlusion = ambient_occulusion
    bpy.context.scene.world.light_settings.ao_blend_type = blend_type
    bpy.context.scene.world.light_settings.samples = samples
def target(origin=(0,0,0)):
    tar = bpy.data.objects.new('Target', None)
    bpy.context.scene.objects.link(tar)
    tar.location = origin

    return tar
def simpleScene(targetCoord, cameraCoord, sunCoord, lens=35):
    print('createSimpleScene called')

    tar = target(targetCoord)
    cam = camera(cameraCoord, tar, lens)
    sun = lamp(sunCoord, 'SUN', target=tar)

    return tar, cam, sun

Materials broken in blender 4.0 (solution)

If you can't properly see materials you need to change create_material() in utils/init.py to

def create_material(base_color=(1, 1, 1, 1), metalic=0.0, roughness=0.5):
    mat = bpy.data.materials.new('Material')

    if len(base_color) == 3:
        base_color = list(base_color)
        base_color.append(1)

    mat.use_nodes = True
    bsdfnode = mat.node_tree.nodes["Principled BSDF"]
    bsdfnode.inputs[0].default_value = base_color
    bsdfnode.inputs[1].default_value = metalic
    bsdfnode.inputs[2].default_value = roughness

    return mat

fail in run_script.py "'TextCurve' object has no attribute 'align_x'"

Hi, I got a failure when run the "run_script.py"

found bundled python: /home/qiang/zq/blender-2.71-linux-glibc211-x86_64/2.71/python createSimpleScene called createLamp called Traceback (most recent call last): File "/home/qiang/zq/git-space/blender-scripting/run_script.py", line 22, in <module> exec(compile(open(file).read(), scriptFile, 'exec')) File "fisher_iris_visualization.py", line 186, in <module> createLabels(X, y, labels, cameraObj) File "fisher_iris_visualization.py", line 128, in createLabels fontCurve.align_x = 'CENTER' AttributeError: 'TextCurve' object has no attribute 'align_x'
I wonder if there exists a problem about the version of the blender or python. Thanks for your attention.

Changing backgrounds

Hi, thanks for this amazing project. I want to change the background image of the render animations as follows:

filepath = "ground.jpeg"
img = bpy.data.images.load(filepath)
cam = bpy.context.scene.camera
cam.data.show_background_images = True
bg = cam.data.background_images.new()
bg.image = img

But it doesn't work. I only know how to change the color of background now. Could you help me fix this?

Depth Maps

I want to create a depthmap using python and blender. Can someone please help me on that as soon as possible

Can't install Scipy and Utils

Perhaps these are old scripts but anytime I try to use some of these I get ModuleNotFound errors. Can't install with pip as that errors out. I have tried every which way to hack around it but keep getting hung up on that. Any tips?

[Bug] no attribute default_value

Context
I am a first time user to blender scripting. I am working with Blender 2.82 (sub 7) (2.82.a+dfsg-1). I am on Ubuntu 20.04.

Whats Wrong
When running several of the scripts following the Readme, including simple_sphere.py and fisher_iris_visualization.py, I am getting an Attribute Error on default_value.

AttributeError: 'NodeSocketShader' object has no attribute 'default_value'

Expected Behavior
When I checkout 8359200, I am able to run the script successfully.

Looks like this is a recent change so I assume I am doing something wrong, I made sure blender was updated and ran it using the command given on the readme, but I am not sure what I might be doing wrong.

bpy.ops.object.select_by_layer could not be found

While calling most of the utility functions I get errors like the following. I use NixOS so it might be due to unusual libraries locations, but shouldn't really.

Any ideas?

Traceback (most recent call last):
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<blender_console>", line 1, in <module>
  File "/home/mix/repos/blender-scripting/scripts/utils/__init__.py", line 129, in removeAll
  File "/nix/store/lbd3a6hzkjkljyy03y5rsfaf9ih325dp-blender-2.80/share/blender/2.80/scripts/modules/bpy/ops.py", line 201, in __call__
    ret = op_call(self.idname_py(), None, kw)
AttributeError: Calling operator "bpy.ops.object.select_by_layer" error, could not be found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/nix/store/lbd3a6hzkjkljyy03y5rsfaf9ih325dp-blender-2.80/share/blender/2.80/scripts/modules/console_python.py", line 168, in execute
    is_multiline = console.push(line_exec)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/code.py", line 258, in push
    more = self.runsource(source, self.filename)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/code.py", line 74, in runsource
    self.runcode(code)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/code.py", line 94, in runcode
    self.showtraceback()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/code.py", line 142, in showtraceback
    lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 121, in format_exception
    type(value), value, tb, limit=limit).format(chain=chain))
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 508, in __init__
    capture_locals=capture_locals)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 363, in extract
    f.line
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 285, in line
    self._line = linecache.getline(self.filename, self.lineno).strip()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 16, in getline
    lines = getlines(filename, module_globals)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 47, in getlines
    return updatecache(filename, module_globals)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 137, in updatecache
    lines = fp.readlines()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x91 in position 3495: invalid start byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/nix/store/lbd3a6hzkjkljyy03y5rsfaf9ih325dp-blender-2.80/share/blender/2.80/scripts/startup/bl_operators/console.py", line 55, in execute
    return execute(context, self.interactive)
  File "/nix/store/lbd3a6hzkjkljyy03y5rsfaf9ih325dp-blender-2.80/share/blender/2.80/scripts/modules/console_python.py", line 172, in execute
    stderr.write(traceback.format_exc())
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 167, in format_exc
    return "".join(format_exception(*sys.exc_info(), limit=limit, chain=chain))
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 121, in format_exception
    type(value), value, tb, limit=limit).format(chain=chain))
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 521, in __init__
    self._load_lines()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 533, in _load_lines
    self.__context__._load_lines()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 531, in _load_lines
    frame.line
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/traceback.py", line 285, in line
    self._line = linecache.getline(self.filename, self.lineno).strip()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 16, in getline
    lines = getlines(filename, module_globals)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 47, in getlines
    return updatecache(filename, module_globals)
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/linecache.py", line 137, in updatecache
    lines = fp.readlines()
  File "/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x91 in position 3495: invalid start byte

location: <unknown location>:-1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.