# How to Add and Render Many Columns

I would like to render many buildings (say, about 50000) as simple columns on a flat plain in Blender. I have values for location (X,Y) and a height value. However, if I try to add more than a couple of thousand columns, I run out of memory.

I think that I want to use the particle / hair system since each building is not independent. they are all simple 4 sided columns, so they can use the same textures, etc. I can add 50,000 columns, using the techniques discussed in the video http://www.youtube.com/watch?v=mCEQYyesxLg. However, I need to be able to set the location and scale of each one based on my data. How can I do this?

The end result should be something like: http://ekisto.sq.ro/ which is a beautiful visualization of stack overflow data.

Update: I'm close! The following updates my particle locations and scales:

scalesize = 10
scalexy = 50

object = bpy.context.object
cols = object.particle_systems[0].particles

def setColumn(index, name, xval, yval, heightval):
cols[index].location.x = float(xval) / scalexy
cols[index].location.y = float(yval) / scalexy
cols[index].location.z = 0
cols[index].size = float(heightval) / scalesize

ii = 0
f = open('input.data', 'r')
for line in f:
values = line.split()
setColumn(ii, values[0], values[1], values[2], values[3])
ii = ii + 1
f.close()


However, when I hit 'F12' to do the render, the particle system updates all the locations and un-does the setting of the locations. How do I tell the particle system to not update?

• Related: blender.stackexchange.com/q/7581/599. Try adding the columns all inside a single object (there is a difference between 50000 individual objects and 50000 cubes inside the same mesh). Also try instancing (dupli objects) or linked data. – gandalf3 Mar 24 '14 at 19:55
• Thanks Gandalf3. the link has a number of good suggestions, as does blender.stackexchange.com/questions/7358. – cedorman Mar 24 '14 at 20:59

I was unable do this using the technique above, because I could not figure out how to prevent re-setting of the location. Therefore, I used the following technique: create a single object, copy it with ob.copy, put copies into scene object list, and then update the scene.

bpy.ops.mesh.primitive_cylinder_add(vertices=numVertices, radius=columnSize,
depth=height,location=loc)
ob = bpy.context.object
obs = []
sce = bpy.context.scene

f = open('input.data', 'r')
for line in f:
values = line.split()

x = float(values[1]) / scaleXY
y = float(values[2]) / scaleXY
height = float(values[3]) / scaleHeight

copy = ob.copy()
copy.location += Vector((x,y, 0))
# copy.data = copy.data.copy()
copy.scale.x = copy.scale.x * height / 2
copy.scale.y = copy.scale.y * height / 2
copy.scale.z = copy.scale.z * height
obs.append(copy)

for ob in obs: