Making changes to objects in scene before exporting using custom exporter addon I'm writing a custom exporter that ultimately exports a FBX file and a set of render images.

Before that happens, the exporter traverses through the scene and modifies specific objects. For example, it applies rotations on the camera, moves meshes to world origin, modifies meshes. After that, it exports the FBX and calls to render stills.

After exporting and rendering, it undoes all the changes in the scene.

The problem is duplicating and effectively undoing all the changes has been difficult to maintain. The second problem is that the names of the exported objects must be the same as the objects in the scene; not "Cube.001".

I have so far:

with DuplicateScene(root_obj) as dup_root_obj:
    modify_cameras(dup_root_obj)
    modify_meshes(dup_root_obj)
    export_model(dup_root_obj)
    export_stills(dup_root_obj)


The problem, again, is that the exported FBX doesn't contain the original name as in the scene.
I thought a little about what @batFINGER mentioned in the comments, and it got me thinking:

class DuplicateScene2():
    _file_stack = []

    def __init__(self):
        if not bpy.data.is_saved:
            raise ValueError("Save .blend file before exporting")
        # Push filepath onto stack
        if len(DuplicateScene2._file_stack) == 0:
            DuplicateScene2._file_stack.append(bpy.data.filepath)
            bpy.ops.wm.save_mainfile(filepath = bpy.data.filepath,
                                     check_existing = False)
        else:
            filepath, fileext = os.path.splitext(bpy.data.filepath)
            DuplicateScene2._file_stack.append("%s.copy.%02i.blend" % (filepath, DuplicateScene2._unique_id))
            DuplicateScene2._unique_id += 1
            # Save file
            filepath = DuplicateScene2._file_stack[-1]
            bpy.ops.wm.save_as_mainfile(filepath = filepath,
                                        check_existing = False,
                                        copy = True)

    def __enter__(self):
        # Return new context override
        context = bpy.context
        window = context.window_manager.windows[0]
        screen = window.screen
        scene = context.scene
        area_view3d = [area for area in screen.areas if area.type == 'VIEW_3D'][0]
        space_view3d = [space for space in area_view3d.spaces if space.type == 'VIEW_3D'][0]
        return {'window': window,
                'screen': screen,
                'area': area_view3d,
                'space': space_view3d,
                'context': context,
                'scene': scene}

    def __exit__(self, type, value, traceback):
        filepath = DuplicateScene2._file_stack.pop()
        bpy.ops.wm.open_mainfile(filepath = filepath,
                                 load_ui = True,
                                 use_scripts = False)
        if len(DuplicateScene2._file_stack) &gt; 0:
            os.remove(filepath)


Using it like so:

try:
    with DuplicateScene2 as override_context:
        ...
except ValueError as e:
    self.report({'ERROR'}, "%s" % (e))
    return {'CANCELLED'}


With this, checking if the file has been saved or not will warn the user about needing to save before exporting. Any exceptions thrown will still allow the file to be reverted.

If there are "cleaner" methods, or suggestions, please do post!

Edit: This doesn't work nested, which is what I realized that I also need.

Edit: Added supported with nesting.