Blender Python scripting, trying to prevent UI lock up while doing large calculations

blender, python

Solution

If you want to do large calculations in Blender, and still have a responsive UI you might want to check out model operators with python timers.

It would be something like this:

class YourOperator(bpy.types.Operator):
    bl_idname = "youroperatorname"
    bl_label = "Your Operator"

    _updating = False
    _calcs_done = False
    _timer = None

    def do_calcs(self):
        # would be good if you can break up your calcs
        # so when looping over a list, you could do batches
        # of 10 or so by slicing through it.
        # do your calcs here and when finally done
       _calcs_done = True

    def modal(self, context, event):
        if event.type == 'TIMER' and not self._updating:
            self._updating = True
            self.do_calcs()
            self._updating = False
        if _calcs_done:
            self.cancel(context)

        return {'PASS_THROUGH'}

    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._updating = False
        self._timer = context.window_manager.event_timer_add(0.5, context.window)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        self._timer = None
        return {'CANCELLED'}

You'll have to take care of proper module imports and operator registration yourself.

I have a Conways Game Of Life modal operator implementation to show how this can be used: https://www.dropbox.com/s/b73idbwv7mw6vgc/gol.blend?dl=0

Problem

I am working in blender doing a script for N number of objects. When running my script, it locks up the user interface while it is doing its work. I want to write something that prevents this from happening so i can see what is happening on the screen as well as use my custom UI to show a progress bar. Any ideas on how this is doable in either python or blender? Most of the calculations only take a few minutes and i am aware that this request might make them take longer than normal. Any help would be appreciated. The function that is doing most of the work is a for a in b loop.

Original source