How to use modal operator with export fbx?

What’s the proper way to use bpy.ops.export_scene.fbx() in a modal operator? I tried like this but no fbx were saved.

class Export(Operator):
    bl_idname = 'test.export'
    bl_label = 'Export'
    bl_options = {'REGISTER'}

    filepath: StringProperty(subtype='FILE_PATH')
    filename_ext: StringProperty(default='.fbx')

    @classmethod
    def poll(cls, context):
        return context.selected_objects is not None

    def modal(self, context, event):
        bpy.ops.export_scene.fbx(filepath=self.filepath, use_selection=True)
        return {'FINISHED'}

    def execute(self, context):
        do_other_things(objects)
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

I also tried with context.window_manager.modal_handler_add(self) instead of context.window_manager.fileselect_add(self) and with bpy.ops.export_scene.fbx('INVOKE_DEFAULT') but the execute function runs immediately with the export.

Basically I want to export the selected objects as FBX with the export dialog window and wait for it to finish and after that I want to do other things with the objects, but all within one operator.

your code doesn’t add the modal handler, so modal() does nothing, it’s just a function that never gets called- thus, nothing happens.

if you call bpy.ops.export_scene.fbx(‘INVOKE_DEFAULT’) from your own invoke, and put your ‘do_other_things’ stuff in your invoke (get rid of execute altogether) it should work.

yes, but I mentioned below the code that I tried with modal handler too. If I put both the export.fbx() and the do_other_things() in the invoke, what’s gonna be in the modal()? It’s just execute the export and the do_other_things() immediately.

Tried like this but same result, the do_other_things() executes immediately.

class Export(Operator):
    bl_idname = 'test.export'
    bl_label = 'Export'
    bl_options = {'REGISTER'}

    def modal(self, context, event):
        bpy.ops.export_scene.fbx('INVOKE_DEFAULT')
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.modal_handler_add(self)
        do_other_things(objects)
        return {'RUNNING_MODAL'}

oh, i see what you’re trying to do now- try this:

class Export(bpy.types.Operator):
    bl_idname = 'test.export'
    bl_label = 'Export'
    bl_options = {'REGISTER'}

    filepath: bpy.props.StringProperty(subtype='FILE_PATH')
    filename_ext: bpy.props.StringProperty(default='.fbx')

    @classmethod
    def poll(cls, context):
        return context.selected_objects # this is a list, it can be empty but it will never be "None".

    def execute(self, context):
        # this will happen after the file select dialog is confirmed
        bpy.ops.export_scene.fbx(filepath=self.filepath, use_selection=True)
        return {'FINISHED'}
    
    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)        
        return {'RUNNING_MODAL'}