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$
2
  • $\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, 2014 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, 2014 at 18:12

2 Answers 2

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$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .