How To Make My Addon Support “Undo” In Blender

GOAL

Today’s goal is to implement “Undo” in my Blender addon.

Environment

Blender 2.83
Windows10

Method

Add bl_options “UNDO” or “UNDO_GROUPED” into the your custom operator. It’s easy.

UNDO Undo: Push an undo event (needed for operator redo).
UNDO_GROUPED: Grouped Undo, Push a single undo event for repeated instances of this operator.

from Blender2.93.2 Python API Documentation

The following is an example.

class ADDMATRIX_add_cube(bpy.types.Operator):
    bl_idname = 'add_matrix_obj.add_cube'
    bl_label = "Add matrix cube"
    bl_options = {'REGISTER', "UNDO"} # Add "UNDO" option here

    input1: bpy.props.IntProperty()
    input2: bpy.props.IntProperty()

    def execute(self, context):
        for xi in range(self.input1):
            x = xi*1.2
            for yi in range(self.input2):
                y = yi*1.2
                bpy.ops.mesh.primitive_cube_add(size=0.5, enter_editmode=False, align='WORLD', location=(x, y, 0))
        return {'FINISHED'}

Postscript

be aware of the error where Blender crashed when undo after executing script in python console. (Reference: Fix T86293: crash undoing after executing the python console in certain)

That was fixed in Blender 2.93, the latest version. And You can fix the error by adding bl_options “UNDO_GROUPED” into the ConsoleExec operation in C:/Program Files/Blender Foundation/Blender 2.83/2.83/scripts/startup/bl_operators/console.py.

class ConsoleExec(Operator):
    """Execute the current console line as a python expression"""
    bl_idname = "console.execute"
    bl_label = "Console Execute"
    bl_options = {"UNDO_GROUPED"} # add undo here

    interactive: BoolProperty(
        options={'SKIP_SAVE'},
    )

    @classmethod
    def poll(cls, context):
        return (context.area and context.area.type == 'CONSOLE')