1
$\begingroup$

I am trying to use blender (2.79b) for batch visualization of data on Windows 10. Unfortunately, blender gets very slow after creating a certain amount of objects. I tried to improve things by "flushing" the geometry to a file every so often. My concept was:

while more_data:
  add_geometry()
  if number_of_objects > limit:
    save_file()
    delete_all_objects()

Alas, this doesn't seem to help. As more data is processed blender gets slower and slower. I wrote a benchmark test program that creates a simple polygon object (in actual use they would all be different, not the same):

import sys, bpy, time
from mathutils import Vector

verts = [Vector((0, 0, 0)),  Vector((1, 0, 0)),  Vector((1, 1, 0))]
faces = [ (0, 1, 2) ]

def build_geometry():
    for obj_number in range(5000):
        base_name ='object_%d' % obj_number
        mesh = bpy.data.meshes.new(base_name)
        mesh.from_pydata(verts, [], faces)
        mesh.update()    
        obj = bpy.data.objects.new(base_name, mesh)
        bpy.context.scene.objects.link(obj)

def remove_geometry():
    for o in bpy.data.objects:
        bpy.data.objects.remove(o, do_unlink=True)
    for m in bpy.data.meshes:
        bpy.data.meshes.remove(m, do_unlink=True)

remove_geometry()
for i in range(10):
    sys.stdout.write('%d' % i)

    start = time.perf_counter()
    build_geometry()
    stop = time.perf_counter()
    sys.stdout.write(' build time = %g' % (stop - start))
    #  could save the file here, but not relevant
    start = time.perf_counter()
    remove_geometry()
    stop = time.perf_counter()
    sys.stdout.write(' cleanup time = %g\n' % (stop - start))

Running the benchmark gives:

blender.exe -b --python D:\python\build_objs.py

0 build time = 1.8863 cleanup time = 6.83109
1 build time = 2.35458 cleanup time = 7.93244
2 build time = 2.89152 cleanup time = 10.4506
3 build time = 3.74924 cleanup time = 11.1356
4 build time = 4.25657 cleanup time = 12.8942
5 build time = 5.38783 cleanup time = 14.2254
6 build time = 5.90367 cleanup time = 16.2433
7 build time = 6.89383 cleanup time = 18.2199
8 build time = 7.97026 cleanup time = 21.7214
9 build time = 9.24869 cleanup time = 23.8938

The 10th iteration is really slow compared to the first.
Is there anything I can do to get a more constant "build" and "cleanup" time? Can the "cleanup" time (deleting most objects) be reduced?

$\endgroup$
  • $\begingroup$ A modest improvement can be achieved by adding: bpy.context.user_preferences.edit.use_global_undo=False at the outset $\endgroup$ – IRayTrace Apr 2 at 4:10
1
$\begingroup$

Clean Factory Settings Operator

Using the method outlined in How to completely remove all loaded data from Blender? particularly the accepted answer

replacing iterative object and mesh removal with operator, has a marked improvement in keeping times consistent between benchmark loops.

def remove_geometry():
    bpy.ops.wm.read_factory_settings(use_empty=True)
    return

Other minor change suggestions

  • Have a feeling can remove mesh update
  • Zero pad base name base_name = 'object_%04d' % obj_number
  • Somewhat pedantic Calling remove_geometry first in loop will require one less call.

Related

Object creation slows over time

$\endgroup$
  • $\begingroup$ This results in AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead DAG zero... not allowed to happen! addon_utils.reset_all unloading object_print3d_utils addon_utils.reset_all unloading io_scene_gltf_ksons errors in the output. In addition, this presumes the goal is to completely wipe the slate clean. Admittedly I could work with that by re-creating materials and other assets that need to be present in all files. $\endgroup$ – IRayTrace Apr 3 at 18:21
  • $\begingroup$ Not errors. The DAG zero is a warning. Others are info messages from reloading triggered by the operator. Could link in assets from a library. The other one that comes to mind is writing a shell script to loop blender -b weighing up blender load time vs slow down displayed in question. $\endgroup$ – batFINGER Apr 3 at 18:54
0
$\begingroup$

So it doesn't seem like there is a way to clean the existing blender scene.

Loading factory settings has certain issues for me. What I found is that I can create a "prototype" file with things like materials, and visual references (floor), and save it.

Now go reading in the data. Each time the scene gets full and I need to save off, I do it to a new file, and then reload the "prototype" file. This gets me the flush of memory allocations needed to get performance back to where it should be, and the "common" objects are available to start the next section of data.

$\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.