How to run methods without freezing animation?

Hey all,

First of all, thanks for this amazing community! I have learned a lot from those q and a’s.

I’m building a VR app prototype in Blender and using bpy.app.handlers.frame_change_pre for event updates.

Some methods take few seconds to calculate and they stops animation. Is it possible to run them in parallel without freezing animation flow? (some kind of callbacks of multiprocessing?)

I simplified the code to show what I’m trying to achieve

import bpy
import time
list = []
def calculate_new_location():
    # after a lot of vector math and matrix transformations
    # this method updates the list of locations for per frame animation
    time.sleep(5)
    list.append((0.0, 0.0, 0.0))
    list.append((0.5, 0.0, 0.0))
    list.append((1.0, 0.0, 0.0)) 
def run_main_loop(scene): 
    current_frame = scene.frame_current +1
    # let's pretend that user did something on frame 5 
    # and we need to recalculate some object location 
    if current_frame == 5:
        calculate_new_location()
    # if list is updated we animate a new object location for the next frame
    if len(list) > 0:
        obj = bpy.data.objects['Cube']
        obj.location = list[0]
        obj.keyframe_insert(data_path="location", frame=current_frame + 1)
        list.pop(0)  
bpy.app.handlers.frame_change_pre.append(run_main_loop)
bpy.ops.screen.animation_play()

Or maybe there is a different way to achieve the same functionality?

Were I attempting this, I’d probably run the math heavy operations in a separate process and have that managed by an asyncio loop. The Blender Cloud addon is a decent reference for using asyncio with Blender. There’s a blog entry on the official site explaining the thought process when writing the addon.

That said I really don’t think you should be attempting any form of VR with Blender. There’s way too much latency, particularly if you intend to do calculations with Python.
Why not use Unreal or Unity?

Thanks for the reply, Ben.
I will investigate the Blender Cloud add-on solution.
Truth to say I never expected to develop a full prototype in Blender, but since I start doing it I kind of fall in love with Python and the neatness of Blender API. I can prototype things and test new ideas really fast. Our main platform is Unity, but to do the same things there takes a lot longer for me (and Unity interface and C# makes me want to hate all living creatures which I don’t like to do).

I hear you about loving Python, but I fear you’ll waste a lot of time trying to make Blender do things it’s not designed for without ever getting a reasonable level of performance to full explore your ideas. Happy to be proved wrong though :stuck_out_tongue:

I don’t know what the state of Python is in Unity, but Unreal now has what looks to be a pretty robust Python API. Still an awful UI though (except for their node interface, which I like).

The great thing that it’s possible to “make Blender do things it’s not designed for”. For example, I query RDF graph from DBpedia in Blender. And it’s exciting.
I spend a lot of time trying to emulate real-world physics. But now I know on a deep level how to calculate object collisions, repulsion, bouncing, gravitation, etc. Of course it all available in game engines. Knowing how to make it from scratch gives me that super feeling :slight_smile:
But you right. I after testing in Blender I have to move things to a game engine.

Small question.
Did you mean this blog entry from 2016?

I have trouble finding any documentation or code snippets on this topic

That’s it.
The most important part is the asyncio event loop paragraph explaining how they use the asyncio event loop within blender. Mainly that you they run a modal operator with a single update per main thread tick. As for code details, the addon is here.

If you’re not familiar with asyncio (and parallelizing/concurrency) then you’d best start with understanding that before bothering with a specific implementation. There are plenty of presentations on Youtube explaining concurrency in Python, and asyncio is modern way to do it.

1 Like

Thanks a lot, Ben.
Yes, sure, I started from non-Blender-specific implementations.