2

When I run this script:

import bpy, time
t0 = time.time()

for i in range(1000):
    bpy.ops.mesh.primitive_uv_sphere_add()

    if i % 100 == 0:
        print(time.time()-t0)
        t0 = time.time()

This is the output (exponential growth vs. time):

1.1920928955078125e-05
0.44658803939819336
0.46373510360717773
0.5661759376525879
0.7258329391479492
0.9994637966156006
1.381392002105713
1.8257861137390137
2.4634311199188232
3.2817111015319824

Why does this happen? Is there a better approach?

I am running this on a server with ample memory, and I know Blender can expand to use most of it (it does in rendering).

PattimusPrime
  • 867
  • 8
  • 21
  • Did you try to move your spheres, or add them to a currently invisible layer? My wild guess is that a redraw may be somehow triggered by adding spheres, and redrawing 1000 spheres maybe slowing the process down. – 9000 Jun 26 '12 at 20:09
  • That's definitely a good guess, but I don't think that's what's happening. The spheres only draw when the script completes, and I see the same behavior for selected and invisible layers. – PattimusPrime Jun 28 '12 at 22:12

1 Answers1

1

The quick answer:

bpy.ops.object.select_all(action='DESELECT')
bpy.ops.mesh.primitive_uv_sphere_add()
sphere = bpy.context.object

for i in range(1000):
    ob = sphere.copy()
    ob.data = sphere.data.copy()
    bpy.context.scene.objects.link(ob)
bpy.context.scene.update()

Explanation:

Anything in bpy.ops.* causes a scene redraw with each call. You want to avoid calling these in loops. The above script calls lower-level copy() methods, which don't redraw. If you want linked duplicates, you can remove the sphere.data.copy() line.

This solution is not my own. Kudos go to CoDEmanX over at BlenderArtists for this answer!

PattimusPrime
  • 867
  • 8
  • 21