Blender 3D: Noob to Pro/Procedural object creation

Generating Elements with Python

A quick reference for commands to create elements through a Python script instead of manually. All of these scripts require the following code at the start:

import Blender from Blender import NMesh

We will also, for the tutorial, be working with an object, known as obj. To work with obj, after the import sequence, add the line

obj = NMesh.GetRaw()

If the name in quotes of an existing object is entered into the parentheses instead of left blank, it will use that object's mesh as a template. [edit] Vertices

The basic structure of the vertex generation command is:

v=NMesh.Vert(x.x,y.y,z.z)

Where v is the name of the vertex and x.x, y.y, and z.z are the X, Y, and Z coordinates of v, which must end in a decimal place.

For example, here is how one might create the three vertices of a triangle and attach them to obj's mesh:

v=NMesh.Vert(1.0,0.0,0.0) obj.verts.append(v) v=NMesh.Vert(0.0,1.0,0.0) obj.verts.append(v) v=NMesh.Vert(0.0,0.0,1.0) obj.verts.append(v)

Or, for vertices not created under the same name (v), it can be written thusly:

a=NMesh.Vert(1.0,0.0,0.0) b=NMesh.Vert(0.0,1.0,0.0) c=NMesh.Vert(0.0,0.0,1.0) obj.verts.append(a) obj.verts.append(b) obj.verts.append(c)

[edit] Faces

The basic structure of the face generation command is:

f=NMesh.Face()

Where f is the name of a given face to be created.

To append vertices (maximum 4) to a face, use the line

f.v.append(obj.verts[x ])

Where x is the order of the vertex around the perimeter (beginning with 0).

Let us mix the previous vertex assigning conventions in with our example of a creation and appendage of a face to more efficiently demonstrate the degree of flexibility had by the command. This code adds a square to Obj.

v=NMesh.Vert(1.0,1.0,0.0) obj.verts.append(v) v=NMesh.Vert(1.0,-1.0,0.0) obj.verts.append(v) a=NMesh.Vert(-1.0,-1.0,0.0) b=NMesh.Vert(-1.0,1.0,0.0) obj.verts.append(a) obj.verts.append(b) f.v.append(obj.verts[0 ]) f.v.append(obj.verts[1 ]) f.v.append(obj.verts[2 ]) f.v.append(obj.verts[3 ]) obj.faces.append(f)

[edit] Objects

All of this code hasn't so much modified or created a mesh. It's more like a blueprint for the changes. To actually construct the new object, insert the following line of code at the end of the blueprint:

NMesh.PutRaw(obj, "Square", 1)

The first argument is the name of the mesh to be used to create "square", the second argument, which is the name of the object. This can be anything you like. The third argument is the renormalization boolean. When set to 1 (true), this forces Blender to recalculate the mesh's normals before generating the object in 3D space. Finally, use this piece of code after all of your object creation and other visual modification scripts to tell Blender to refresh the screen:

Blender.Redraw()

[edit] Iterative Loops

Possibly the most important advantage of procedural object creation is the work it saves you when creating something with any sort of replicable quality. Here we will give the basic format of a loop in Python, then show some example scripts you can build on. The basic loop is thus:

for i in range(a,b,c):

   Four (more) spaces indentation marking all code contained in the loop

Same indententation level as "for i in range" line to exit loop

Where i is the iteration number, a is the start value of the iterations, b is the end value of the iterations, and c is the increment. Entering in c is not necessary if the increment is 1. If a is 0, b is 100, and c is 1, it will run the iterative loop 100 times, starting with the 1st iteration, where i=0. If c is 2, it will run the iterative loop, adding two to i each loop, until i=100.(50 times - for iteration 1 i=0, iteration 2 i=2, and iteration 50 i=98). Note that when i=b (end value of the iterations), the loop will end prior to executing the loop code.

If you nest loops, you can perform such tasks as placing a row of ten vertices in with one of the coordinates set to i, so that when i makes another iteration the nested loop makes another row of ten vertices in the new position given by i.

A loop that produces a vertex at the origin, (1,1,1), and (2,2,2)

for i in range(0,3,1):

   v=NMesh.Vert(i,i,i)
   obj.verts.append(v)

A square-producing loop:

for i in range(0,2,1):

   for j in range(0,2,1):
       v=NMesh.Vert(j,0,i)
       obj.verts.append(v)

A two-square-producing loop:

for i in range(0,2,1):

   for j in range(0,2,1)
       for k in range(0,2,1)
           v=NMesh.Vert(j,k,i)
           obj.verts.append(v)

[edit] Links

   * Blender tools:
         o http://www.makehuman.org/
         o http://www.geocities.com/blenderdungeon/lsystem/
   * Python:
         o http://www.alcyone.com/software/lsystem/
   * Other:
         o http://www.devx.com/Intel/Article/20333/2046 , "Procedural 3D Content Generation, Part 2"
         o ModelingCloudsShape --antont, Sun, 20 Mar 2005 03:33:07 +0200 reply http://www-evasion.imag.fr/Publications/2004/BN04/