Wait for operator to finish

@londo The issue I see though is that the remaining code of a script or something needs to go into the callback function otherwise is executed right away. For example I was trying to follow the above solution for my case where I need to repeatedly apply a remesher operator on multiple objects and when all objects are done to apply a cleanup and still I couldn’t make it work, check bellow:

import bpy

from quad_remesher_1_1 import QREMESHER_OT_remesh as op

def _cleanup():
    """ Cleanup the scene by removing the hidden objects"""
    _remove_hidden_objects()

def _remove_hidden_objects():
    """ Removes all objects of the current scene """
    # Select all
    bpy.ops.object.select_all(action='DESELECT')
    for obj in bpy.context.scene.objects:
        if obj.hide_get() == True:
            obj.hide_set(False)
            obj.select_set(True)
            # Delete selection
            bpy.ops.object.delete()


def remesh_object(obs):
    if obs:
        ob = obs.pop(0)
        bpy.ops.object.select_all(action='DESELECT') # Deselect all objects    
        #Set active object to variable
        bpy.context.view_layer.objects.active = ob
        if ob: ob.select_set(True)

        print("Object: {}".format(ob.name))

        # remesh object!!!!!    
        bpy.ops.qremesher.remesh()

# some callback function - here we put what shall be run after the modal is finished
def callback(ret):
    print('Callback triggered: {} !!'.format(ret))
    remesh_object(obs)
    
def modal_wrap(modal_func, callback):
    def wrap(self, context, event):
        ret, = retset = modal_func(self, context, event)
        if ret in {'FINISHED'}: # my plugin emits the FINISHED event on finish - yours might do FINISH or CANCELED, you might have to look it up in the source code, __init__.py , there look at the modal() function for things like return {'FINISHED'} or function calls that return things alike.
            print(f"{self.bl_idname} returned {ret}")
            callback(ret)
        return retset
    return wrap

op._modal_org = op.modal
op.modal = modal_wrap(op.modal, callback)    


obs = [o for o in bpy.data.objects
        if o.type == 'MESH']
        
remesh_object(obs)

############### <------------------TODO: WAIT HERE UNTILL ALL OBJECTS HAVE BEEN REMESHED AND THEN APPLY CLEANUP

# clean scene collection
_cleanup()
1 Like

I tried to use the modal wrap approach to wait for the bake operator to finish (bpy.ops.object.bake)
When I look for the type blender tells me it’s OBJECT_OT_bake but I can’t find that in the bpy.types.

Also using from bpy.ops.object import bake as op is telling me No module named 'bpy.ops.object'; 'bpy.ops' is not a package

How could I wrap the object bake method and execute a callback when baking is finished. It kind of sucks that such a simple thing as writing async code in a synchronious way (like javascript async/await) is not yet possible with python/blender.