# Creating many primitive objects quickly with Python

I'd like to be able to generate a bunch of primitive objects. All of them will be different sizes and have a material out of a random set.

What I'm having trouble with is the following:

• Creating 20,000 primitive objects quickly
• Creating a set of different materials where I can assign the primitive objects to

Here is my code so far:

import bpy, random
from random import randint

#Short hands for common calls
scene = bpy.context.scene
selected = bpy.context.selected_objects
mesh = bpy.ops.mesh
context = bpy.context
object = bpy.ops.object
selected_object = bpy.context.active_object

clouds = 500

def baseObject(x,y,z):
#Creates base cylinder
return

def clearScene():
#Clears the current scene
for selectedObj in bpy.context.scene.objects:
selectedObj.select= True
object.delete()
return

def ObjectCreation(clouds):
for attempts in range(clouds):
x = round(random.uniform(-4.0, 4.0), 10)
y = round(random.uniform(-4.0, 4.0), 10)
z = round(random.uniform(-4.0, 4.0), 10)
baseObject(x,y,z)
context.object.scale[0] = x/10   #X Scale
context.object.scale[1] = y/10   #Y Scale
context.object.scale[2] = z/10   #Z Scale

materialCreation()
return

def materialCreation():
#for attempts in range(scale):
randomRed = random.uniform(0.0, 1.0)    #Used for random color scale, need to adjust later for color mapping
randomGreen = random.uniform(0.0, 1.0)
randomBlue = random.uniform(0.0, 1.0)

material = bpy.data.materials.new("Material")    #Material properties
material.alpha = round(random.uniform(0.1, 1.0), 10)    #Opacity
material.use_transparency = True
context.object.show_transparent = True
context.object.data.materials.append(material)  #Applies material properties
context.object.color = (randomRed, randomGreen, randomBlue, 1)  #Changes objects color(RGB Opacity)
context.object.active_material.use_object_color = True
return

clearScene()
ObjectCreation(clouds)

• Adding 20,000 cubes will not be quick. – David Jun 15 '16 at 21:18
• Is there a way to optimize it? – John Pham Jun 15 '16 at 21:30
• Is every single object unique? Or are you going to have a bunch of different cubes, toruses, cones, etc. – Mike Belanger Jun 15 '16 at 23:33
• For now, it would be a bunch of cylinders with different sizes, positions, and materials. – John Pham Jun 16 '16 at 0:04
• You could always link some of them instead of making separate objects -- probably save some memory. – Mike Belanger Jun 16 '16 at 0:53

Instead of using the operator to create the mesh each time you can use a copy and link it to the scene. Try and avoid high amounts of operator calls Python performance with Blender operators . They have the tendency to bloat out because of the undo stack, for one thing.

The operator is called once to create the primitive, then a copy is used for each iteration.

Created a list of 10 random materials. Each object mesh will have one randomly selected material from the list.

import bpy, random
from random import randint

context = bpy.context
scene = context.scene

def base_object():
#Creates base cylinder
return

def clear_scene(scene):
#Clears the current scene
for obj in scene.objects:
bpy.data.objects.remove(obj)
return

def object_creation(scene, clouds):
base_object()
obj = scene.objects.active
mesh = obj.data
nummats = 10
random_mats = create_material_list(nummats) # create 10 random materials
for attempts in range(clouds):
x = round(random.uniform(-4.0, 4.0), 10)
y = round(random.uniform(-4.0, 4.0), 10)
z = round(random.uniform(-4.0, 4.0), 10)
obj.location = (x, y, z)
obj.scale = 0.1 * obj.location

red = random.uniform(0.0, 1.0)    #Used for random color scale, need to adjust later for color mapping
green = random.uniform(0.0, 1.0)
blue = random.uniform(0.0, 1.0)
obj.show_transparent = True
obj.active_material = random_mats[random.randint(0, nummats-1)] # random pick of random mats

obj.color = (red, green, blue, 1)  #Changes objects color(RGB Opacity)

# copy the next one
obj = obj.copy()
obj.data = mesh.copy() # a new mesh for each object.
return

def create_material_list(len):
#for attempts in range(scale):
mats = []
for i in range(len):
material = bpy.data.materials.new("Material")    #Material properties
material.alpha = round(random.uniform(0.1, 1.0), 10)    #Opacity
material.use_transparency = True
material.use_object_color = True
mats.append(material)

return mats

clear_scene(scene)
object_creation(scene, 1000)


A similar question answer How can I create many objects quickly?

Might also want to check this out https://blender.stackexchange.com/a/42232/15543

If you stick with CamelCase for class names you will get better formatting.

• Using your object_creation results in creating 2 objects at a time but it slows down the overall process. I tested with 50 objects with the old function which ran for 6 seconds compared to yours which ran for 2.39 seconds. Your function does have a linear speed compared to mine which drops the longer it runs which might be caused by memory. – John Pham Jun 16 '16 at 23:39
• And for 1000 objects? – batFINGER Jun 17 '16 at 15:58