An Edmonton.py presentation byChris Want / cjwant@gmail.com / @cwant
From the Blender website:
“Blender is a free and open source 3D animation suite. It supports the entirety of the 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, even video editing and game creation”Three ways to access python
We'll run our scripts through the text editor
Execute with Alt-P while your mouse is in the editor
Most of the modeling is done through the menus or through hot keys. These execute bits of code called "operators". The Python API maps well to these operators.
Check out the tooltips
An object is defined by the type of data it points to, e.g., mesh, camera, lamp, curve, text ...
>>> ob = bpy.data.objects["Profile"] >>> ob.data bpy.data.meshes["Plane"]
>>> ob2 = bpy.data.objects["Camera"] >>> ob2.data bpy.data.cameras["Camera"]
Typically meshes are modeled in "Edit Mode".
Meshes are made of vertices, edges, and faces
Think of vertices as a zero-based list of coordinates
Think of faces/edges as pointers into the list of vertices
# A list of 3D coordinates verts = [ [1, 1, 0], [1, -1, 0], [-1, -1, 0], [-1, 1, 0] ]
# List the verts to connect edges = [ [0, 1], [1, 2] ]
# List the verts to span faces = [ [0, 2, 3] ]
# The magic is done by: # bpy.types.Mesh.from_pydata me = bpy.data.meshes.new("me") me.from_pydata(verts, edges, faces) ob = bpy.data.objects.new("ob", me) scn = bpy.context.scene scn.objects.link(ob) # Not needed scn.objects.active = ob ob.select = True
To create the shape, we must specify:
Copy numverts vertices mulitple times, based on resolution
Old edges become new faces.
Exploit the fact that we are connecting vertices who's indices are numverts apart.
import bpy from math import sin, cos, pi num_cycles = 4 resolution = 64 radius = 5 amplitude = 1
def main(): oldob = bpy.data.objects["Profile"] if oldob == None: return oldme = oldob.data numvert = len(oldme.vertices) numedge = len(oldme.edges) numface = len(oldme.polygons) verts = [] faces = []
###### ... main() cont'd for i in range(resolution): for j in range(numvert): # Duplicate and transform vertices vold = oldme.vertices[j].co vnew = transform_vert(vold, i) verts.append(vnew) # Extrude old edges into new faces for j in range(numedge): if oldme.edges[j].is_loose: e = oldme.edges[j].vertices f = edge_to_face(e, i, numvert) faces.append(f)
###### ... main() cont'd me = bpy.data.meshes.new("thingy") me.from_pydata(verts, [], faces) ob = bpy.data.objects["thingy"] ob.data = me
def transform_vert(v, i): prop = float(i) / float(resolution) a = 2*pi*prop b = a * num_cycles cosa = cos(a) sina = sin(a) sinb = sin(b) x = (v[0] + radius) * cosa + v[1] * sina y = -(v[0] + radius) * sina + v[1] * cosa z = v[2] + sinb * amplitude return [x, y, z]
def edge_to_face(e, i, numvert): i1 = i i2 = (i + 1) % (resolution) f = [e[0] + i1*numvert, e[1] + i1*numvert, e[1] + i2*numvert, e[0] + i2*numvert] return f
main()
The interior must be clearly defined
The subdivision surface modifier is your friend!
From the File/Export menu ...
Recommendations:
I use ShapeWays, because: