I took another 3D day today, and started getting practical with my script-based modelling plans. And it wasn’t very easy, since not much documentation exists for stuff like that.
First of all, what is it exactly I wanted to do? What I wanted was a way to define the location of every vertex and every face in the model myself, in my script code, and then create a Blender object from that. I’m pretty sure not many people (or perhaps no one?) do that, thus I had to work a little to find how to do that.
The basic problem was that the Blender scripting API does not provide a simple way to add and remove vertices or faces. To circumvent that, I thought about creating a grid mesh with the number of vertices I’ll want, and then place the vertices wherever I want. But then I had a problem – how do I create the faces? What do I do with the initial faces? That would have been a mess, if at all possible.
I actually started thinking about creating a non-Blender 3d file in my own code and then importing it to Blender. I saw that PLY is a simple file format I could work with. But that gave me an idea – my impression from Blender so far was that something like importing an external file might be done in a Python script. If I could see their script for importing PLY, I’ll know how to create an object from a list of vertices.
Indeed, that was the way. So how do you do it? Let’s create a cube for example.
First of all, create a mesh:
mesh = bpy.data.meshes.new(name="Test")
Add 8 vertices with the “add” method of mesh.vertices, and define the coordinates of each vertex:
mesh.vertices.add(8) mesh.vertices.co.x = -1 mesh.vertices.co.y = -1 mesh.vertices.co.z = -1 ... mesh.vertices.co.x = 1 mesh.vertices.co.y = 1 mesh.vertices.co.z = 1
Now add 6 faces and define the vertices they connect:
mesh.faces.add(6) mesh.faces.vertices_raw = (0,2,6,3) mesh.faces.vertices_raw = (5,1,4,7) mesh.faces.vertices_raw = (0,1,5,3) mesh.faces.vertices_raw = (4,2,6,7) mesh.faces.vertices_raw = (1,0,2,4) mesh.faces.vertices_raw = (5,3,6,7)
Important note – make sure the vertex order is correct. You can start at any vertex and go clockwise or counterclockwise, but make sure you don’t put two vertices that aren’t supposed to have an edge between them, in adjacent places. For example, if I would have written:
mesh.faces.vertices_raw = (0,2,3,6)
I would have made an edge between 2 and 3, which are diagonal vertices, so the face would be all messed up.
After defining the vertices and faces, we can complete the mesh and create an object based on it:
mesh.validate() mesh.update() scn = bpy.context.scene obj = bpy.data.objects.new("Test", mesh) scn.objects.link(obj)
So what am I doing with my new power? I have great plans for the future, but as a first test, I went with a rather obvious choice for an art-loving programmer – the Menger sponge.
It’s basically the same cube creation I just showed, just repeated many times recursively. Since renderings of the Menger sponge are everywhere, with some beautiful variations on it, I wanted to play with it a little and make something more special. Here’s what I got:
Indeed, 3D is fun.