3D Scientific Visualization with Blender

Chapter 7

Python scripting

The Blender API can be used in Python scripts to automate tasks and read in scientific data. The API allows the user to create and manipulate objects and data, edit properties and groupings, and control the animation sequence of a scientific visualization.

7.1 Scripting in blender

The Blender scripting interface is shown in figure . When a new script is started, a ‘Run Script’ button appears in the GUI—pressing this button will run the script. In addition, Blender scripts can be run from the command line via:

image

Figure 7.1. The editor and command line allow the user to control the Blender interface and functions via the Blender Python API.

blender - -python myscript.py

7.1.1 Blender and Python libraries

The following libraries will be commonly used with Blender scripts for scientific visualization. These typically will appear in the script preamble with ‘import’.

bpy. Application modules that allow control over the context, data types, operators and GUI applications.

bmesh. A standalone module giving access to mesh objects, vertices and connecting segments.

csv. A useful Python module for reading formatted data.

glob. A standard Python module for traversing directory structure and obtaining lists of files to load.

os. An operating system interface useful for loading/finding paths where required libraries might be needed.

math. Basic mathematical operations and functions.

7.1.2 Example: reading formatted ASCII data into blender

There are many different methods for reading formatted text into a Python dictionary. We employ dictionaries here for their clarity and convenience in terms of defining a Python data construct. The data for this short example will be in the following format:

 

#Name X Y Z

Point001 4.2 2.3 5.6

Point002 1.2 9.3 6.4

Point003 4.3 2.3 7.4

...

We can then read in the specified data with the following short Python script.

 

import bpy

import bmesh

import csv

 

'''Read in the data according to the defined list of fields

   Remove the final header if needed.

   Define the table as an empty list

'''

fields = ['Name', 'X', 'Y', 'Z']

csvin = csv.reader(open(f))

data=[row for row in csvin]

header=data.pop(0)

table = []

 

'''For each row in the data list, map the fields and

   data elements to a dictionary

   Append the dictionary to the table list.

'''

for row in data:

   datarow = map(float,row[0].split())

   rowdict=dict(zip(fields, datarow))

   table.append(rowdict)

7.1.3 Example: adding data points to an object as vertices

For this example we create a cube object mesh (actually, any mesh will work) and remove all but one vertex. That vertex will then be duplicated at all the positions of the imported ASCII text file.

  • Create a UV-cube mesh by clicking Add → Mesh → Cube. Alternatively, the keyboard shortcut SHIFT–A can be used.
  • Press TAB to enter Mesh Edit mode. CTRL–right-click on all vertices but one and press X to delete them.
  • Run the following script, which will switch the GUI to Edit mode and duplicate the vertex at each X, Y, Z point loaded from the ASCII table:

 

import bpy

import bmesh

import csv

#Switch to edit mode

bpy.ops.object.mode_set(mode = 'EDIT')

obj = bpy.data.objects['Cube']

mesh = obj.data

bm = bmesh.from_edit_mesh(obj.data)

rowcount = 0

for i in range(0,len(bm.verts)-1):

 try:

    bm.verts[i].co.x = table[rowcount]['X']

    bm.verts[i].co.y = table[rowcount]['Y']

    bm.verts[i].co.z = table[rowcount]['Z']

    rowcount += 1

    bmesh.update_edit_mesh(obj.data)

 except:

    pass

7.1.4 Example: animating multiple time steps

For simulations where the data may be a changing 3D time-series, inserting keyframes between each time step can animate the data. Keyframe insertion and the animation playback toolbar can also be controlled via the Blender API. This example reads in a series of formatted ASCII text files, putting together the previous two code blocks.

 

import bpy

import bmesh

import csv

import glob

'''This line will change depending on whether Linux,

Mac OS, or Windows is used

'''

files = glob.glob(mydirectory + '/*')

for f in files:

   #Switch to edit mode

   bpy.ops.object.mode_set(mode = 'EDIT')

   print(Frame: + str(f))

   bpy.context.scene.frame_set(framecount)

   fields = ['Name', 'X', 'Y', 'Z']

   csvin = csv.reader(open(f))

   data=[row for row in csvin]

   header=data.pop(0)

   table = []

for row in data:

   datarow = map(float,row[0].split())

    rowdict=dict(zip(fields, datarow))

    table.append(rowdict)

obj = bpy.data.objects['Cube']

mesh = obj.data

bm = bmesh.from_edit_mesh(obj.data)

rowcount = 0

for i in range(0,len(bm.verts)-1):

   try:

       bm.verts[i].co.x = table[rowcount]['X']

       bm.verts[i].co.y = table[rowcount]['Y']

       bm.verts[i].co.z = table[rowcount]['Z']

       rowcount += 1

       bmesh.update_edit_mesh(obj.data)

except:

       pass

bpy.ops.anim.keyframe_insert(type='Location')

Показать оглавление

Комментариев: 0

Оставить комментарий