3
$\begingroup$

After reading some posts here, i try to avoid using operators in order to avoid useless scene.update slowdown.

Unfortunatly i still have a slowdown when creating multiple objects in blender, here is the 'test code' showing performance hit (seems to be linear and not exponential).

import bpy
from datetime import datetime

iter = 0
startTime = datetime.now()

def duplicate_object(scene, name, copyOb):
    global startTime
    global index

    mesh = bpy.data.meshes.new("tmp")
    ob_new = bpy.data.objects.new(name, mesh)

    ob_new.data = copyOb.data.copy()
    ob_new.data.name = name
    bpy.data.meshes.remove(mesh)
    scene.objects.link(ob_new)

    print(iter, datetime.now()-startTime)
    iter+=1
    startTime = datetime.now()

    return ob_new

for i in range(0,5000):
    duplicate_object(bpy.context.scene, "toto", bpy.data.objects['Cube'])

Not sure why script slowdown with object number, it doesn't seem to check for every object in scene to create a new one.. Is it only blender having bad time handling more and more objects (even before any scene.update()?)

Any help welcome ! :)

$\endgroup$
  • $\begingroup$ jasperge provided some good optimizations, but you might want to ask yourself: "do I really need a new mesh for each object?". wiki.blender.org/index.php/Doc:2.6/Manual/Modeling/Objects/… In many applications it's perfectly fine for a thousand objects to share a single mesh. Per-object (instead of per-data) materials make it feasible in even more situations. $\endgroup$ – Mutant Bob Oct 8 '14 at 18:10
  • $\begingroup$ And sometimes you don't even need an entire Object for your duplicate, and all you need to vary is position and orientation. Then DupliGroups become useful: wiki.blender.org/index.php/Doc:2.6/Manual/Modeling/Objects/… . I was introduced to that technique by IRC when having 1000+ gears started to bog down my UI. $\endgroup$ – Mutant Bob Oct 8 '14 at 18:12
1
$\begingroup$

I'm not sure, but I think it's mainly Blender having to deal with more and more meshes. In your case an extra slowdown is introduced by first creating a "tmp" mesh.

Here you have an improved version of your code, which is a little bit faster, but still slows down after duplicating more objects.

import bpy
from datetime import datetime


def duplicate_object(scene, name, copyOb, iter):
    startTime = datetime.now()

    mesh = copyOb.data.copy()
    mesh.name = name
    ob_new = bpy.data.objects.new(name, mesh)

    scene.objects.link(ob_new)

    print(iter, datetime.now() - startTime)

    return ob_new

for i in range(5000):
    duplicate_object(bpy.context.scene, "toto", bpy.data.objects['Cube'], i)
$\endgroup$
1
$\begingroup$

A variation which recycles a single mesh:

import bpy

def army(mesh):
    scn = bpy.context.scene
    for r in range(10):
        for c in range(4):
            obj = bpy.data.objects.new("army", mesh)
            obj.location = ( r*3, c*3, 2)
            scn.objects.link(obj)

army(bpy.data.meshes["Cube"])

And here's a fragment that uses dupligroup empties:

ob = bpy.data.objects.new(name, None)
ob.dupli_type = 'GROUP'
ob.dupli_group = bpy.data.groups['prototype cube']
ob.location = (x,y,z)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.