Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

blender

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.

like image 631
JaredTS486 Avatar asked Nov 21 '12 03:11

JaredTS486


2 Answers

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

like image 105
jesterKing Avatar answered Oct 26 '22 10:10

jesterKing


I would suggest you use either greenlets or spawn a new process. Greenlets are generally easier to use because you don't need to worry about locks and race conditions, but they cannot be used in every situation. Using the multiprocess or threading module would certainly deal with the problem.

like image 33
aquavitae Avatar answered Oct 26 '22 12:10

aquavitae