Blender and Python molecules visualization

2012-04-11
#blender #python

Blender is a free software for 3D graphics. In old virsions many operations were binded to hotkeys, so it was believed that Blender is very hard to master. Now it has more userfriendly interface with button in addition to hotkeys.

One of the most useful features of Blender is scripting. Below I provide python script for drawing molecules with cylinders and spheres.

Command to draw a sphere:

bpy.ops.mesh.primitive_uv_sphere_add()

To draw a cylinder, you need to specify cylinder center and rotation. Rotation is described via rotation axis and rotation angle.

Trivial cylinder after creation is aligned with Z axis: z = (0,0,1). If you need to connect two points r1 and r2 with cylinder, its center coordinate is r3 = (r1+r2)/2. Cylinder must be aligned with z_desired = (r1-r2).normalized(), so rotation axis is rot_axis = z.cross(z_desired) and angle angle = acos(z.dot(z_desired)).

Wrapping up, code:

from math import degrees, acos
from mathutils import Vector

spheres = (Vector((2,3,3)),Vector((1,1,2)),Vector((2,3,4)),Vector((4,5,3)))
edges = ((0,1),(1,2),(2,3))

for i in range(0, len(spheres)):
  r1 = spheres[i]
  bpy.ops.mesh.primitive_uv_sphere_add(location=(r1.x, r1.y, r1.z))

for i in range(0,len(edges)):
  r1 = spheres[edges[i][0]]
  r2 = spheres[edges[i][1]]
  r3 = (r1+r2)/2
  z = Vector((0,0,1))
  z_desired = (r1-r2).normalized()
  rot_axis = z.cross(z_desired)
  angle = acos(z.dot(z_desired))
  bpy.ops.mesh.primitive_cylinder_add(radius=0.3, depth=(r2-r1).length,location=(r3.x,r3.y,r3.z))
  bpy.ops.transform.rotate(value=(angle,), axis=rot_axis)

After copy-paste to blender console you will see the similar image:

blender_python