creation of thousands of objects

Hi all:

I’m working on a script to create a bunch of spheres. My aim is to create about 10.000 or more. The way I am creating this spheres is this:


esfera = bpy.ops.mesh.primitive_ico_sphere_add

ballna=[None]*Nball  #here I create the object ball

for i in range(0,Nball):
   #this conditional checks how long does it take to create the balls
   if i/50==int(i/50):
        print('ball',i,"time", clock())
   #here I create the object icosphere 
   esfera(subdivisions=2,size=r0, location=(0,0,0))
   #finally I save the icosphere in the object ballna for further operations
   ballna[i] = bpy.context.object

The problem I have has to do with time. I have noticed that it takes more to create the last 50 spheres than the 50 first ones.

Is this something connected with the way Blender works or am I doing something wrong?

Thanks!


www.enriquesahagun.es

try to remove the history recording !

should be faster!

salutations

Thanks Ricky:

You mean the undo history? I did it days ago… now the problem is somewhere else. For example, I have just discovered that the if statement slows down the execution in an absurd way… I’ll go on debugging! :slight_smile:

Here is how I would approach this.


import bpy

def returnScene (passedIndex = 0):
    try:
        return bpy.data.scenes[passedIndex]
    except:
        return None
    
def returnICOSphere ():
    bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, size=1.0, view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
    ob = bpy.context.active_object
    return ob

def returnNameForNumber(passedFrame):
    frame_number = str(passedFrame)
    l = len(frame_number)
    post_fix = frame_number
    if l == 1: 
        post_fix = "000" + frame_number
    if l == 2: 
        post_fix = "00" + frame_number
    if l == 3: 
        post_fix = "0" + frame_number
    return post_fix


ob = returnICOSphere()      # NOTE: We only mess with the context one time.
ob.name = "ico_Original"
me = ob.data
me.name = "MasterMeshForSpheres"
print(me.name)
localScene = returnScene()

object_count = 10   # Set your count as high as you like.
for i in range(object_count):
    tempObjectName = "ico_" + returnNameForNumber(i)
    ob_temp = bpy.data.objects.new(tempObjectName, me)
    localScene.objects.link(ob_temp)

Set your object count as high as you like.

NOTE: This code links all objects to a single mesh which is more memory efficient than creating 10,000 meshes all the same linked to 10,000 objects. But if you need each mesh to be unique, you will have to modify this approach.

Thank you very much Atom!!

My approach was to make different objects, because I am animating them. So in principle seemed obvious to make objects with their own associated time lines. It works but it is slow. I’m increasing the speed by making the dynamic calculations in fortran so the python script “only” has to read massive amounts of data.

On the other hand, I never thought that “a single mesh which is more memory efficient than creating 10,000 meshes”. So I will explore that way. Then instead of standard keyframing I will have to do shape keying, isnt it?

Thanks again!

can you remind me how to stop the history recording

thanks

In users preference, edit, you can define the undo steps you want or totally disconect it. Is that what you mean? and by the way, are you also dealing with similar programming issues?

no - there is an API command to do that too!
but never been able to make it work!

thanks

I don’t think shape keys will work in this scenario. Because they affect the mesh and there really is only one mesh. Any shape changing of the mesh would be synchronous across all objects that were linked to it if you use my code approach.

was this issue solved? I’m finding that Blender likes to slow down after a it has tens of thousands of faces happening…a hundred hi-res spheres would start to crap out your runtime as the objects are linked to the scene. The solution is to link them all at the end, but then the linking would slow down after the first 50…anyway slight improvement…

Another approach might be to create a few proxy spheres. The proxy spheres could range from low poly to high poly. Then determine how far away from the camera each sphere is and assign a optimized sphere mesh for each distance or zone the sphere reside within. So only the spheres closest to the camera would need to be high poly.

Thats a clever idea! but I dont see how to handle it because I define the quality of the sphere at the very begining… I have to explore that proxy thing!

With my approach I’m handling about 3000 thousand icospheres (subdivision=3) in reasonable times

I meant link all of your objects in a separate for loop, so the last line in your post would be outside of that loop. That means that you have to create them as meshes internally in one loop, then link them in the next one. I found that once the faces appear in the window, all functions are slowed