Sometimes I get embarrassingly excited about being able to do things in Python that I will probably never need to do again. This is one of those times.
I had a mesh—a plane that I had turned into an a spiral walk-way. And I had the thought, this thing can’t have walls. Eventually I want the walk-way to be the center of a large arena that’s coated in fog. And the only way you’d really be able to see that it’s a spiral is if it’s semi-transparent and lined in lights.
I then had a 20 minute argument with myself about how to proceed. You can apply a texture with transparency and set the non-transparent parts to an emission material. I think. But getting all the circles to be the same size and repeat in a uniform fashion in Gimp might actually require that I return to Scheme, and I would rather chew my arm off than attempt that again. I could run a loop to create a line of spheres along the grid and then just duplicate that for each line, rotating and trimming spheres as necessary. But that got frustrating because my computer slows down considerably when I have more than about 100 objects in a scene. The gif above was made with a Blender model that has about a thousand lights, so that’s a no go.
Then it occurred to me that if I loop-divided it enough, I’d have vertices evenly split along each edge. Then it would just be a matter of pulling the coordinates from the mesh to get some x and y values going.
How is that done?
Super easy. You just select the mesh and then Python the selected object into a variable. Like so:
obj = bpy.context.scene.objects.active
I’m sure there’s Blender documentation explaining this part, but I just took it from this dump() function on StackExchange.
mesh = obj.data for vert in mesh.vertices: #Within this for loop, these represent the coordinates of each vertex vert.co.x vert.co.y vert.co.z
That’s it. Since my plane was oriented along the x and y axes, I modified my script to loop through six times, each time upping the z value by .5 to get another set of lights at an evenly divided height. By lights, I mean a sphere with an emission material. I prefer those to actual lights in Blender, but you can throw any object into the loop to create one at each vertex position.
Keep in mind, if you have a slow computer, this still takes a while. I left Blender running for about 5 minutes before it unfroze with all my spheres. And I had to put them into a different layer so that I could turn them off and modify the other layers at a normal speed.
import bpy obj = bpy.context.scene.objects.active z=0 mesh = obj.data for index in range(6): for vert in mesh.vertices: x = vert.co.x y = vert.co.y bpy.ops.mesh.primitive_uv_sphere_add(size=.05,location=(x,y,z)) z+=.5