How To Pass Arguments To Custom Operator In Blender Python

GOAL

Today’s goal is to create operator that takes arguments in Blender Python.

The following is a custom operator that takes 2 argument “count_x” and “count_y”, and add cube object in the form of count_x rows and count_y columns.

Environment

Blender 2.83(LTS)
Windows10

Method

1. Create operator with properties

Pass the argument values through the properties to custom operator. Use “:” to add property in Blender custom operator as below. Check “Operator Example” in Blender manual for details.

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

    input1: bpy.props.IntProperty() # add argument1 as property "input1"
    input2: bpy.props.IntProperty() # add argument2 as property "input2"

    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'}

You can execute operator with passing values of arguments “input1” and “input2” as below.

bpy.ops.add_matrix_obj.add_cube(input1 = 3, input2 = 2)

2. Add property

Register properties in register() function. Be sure to delete the registered property in unregister().

def register():
    bpy.types.Scene.count_x = bpy.props.IntProperty()
    bpy.types.Scene.count_y = bpy.props.IntProperty()
    bpy.utils.register_class(ADDMATRIX_add_cube)

def unregister():
    del bpy.types.Scene.count_x
    del bpy.types.Scene.count_y
    bpy.utils.unregister_class(ADDMATRIX_add_cube)

3. Add UI to change property

Create UI as below.

Add a button to execute operator with bpy.types.UILayout.operator function.

class ADDMATRIX_panel(bpy.types.Panel):
    bl_label = "Add Matrix Obj"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        layout = self.layout
        col = layout.column(align=True)
        # add prop
        col.prop(context.scene, "count_x")
        col.prop(context.scene, "count_y")

        #pass properties to the operator
        ops = col.operator("add_matrix_obj.add_cube", text="Add Cube")
        ops.input1 = context.scene.count_x
        ops.input2 = context.scene.count_y

Pass argument from UI

It is unable to pass arguments in bpy.types.UILayout.operator, so set values into input1 and input2 after adding operator.

#pass properties to the operator
ops = col.operator("add_matrix_obj.add_cube", text="Add Cube")
ops.input1 = context.scene.count_x
ops.input2 = context.scene.count_y

Complete code

Here’s the full source code of this addon.

bl_info = {
        "name": "Add Matrix Object",
        "description": "test addon to pass properties to custom operator",
        "version": (1, 0),
        "blender": (2, 80, 0),
        "category": "3D View",
        }

import bpy

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

    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'}

class ADDMATRIX_panel(bpy.types.Panel):
    bl_label = "Add Matrix Obj"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        layout = self.layout
        col = layout.column(align=True)
        # add prop
        col.prop(context.scene, "count_x")
        col.prop(context.scene, "count_y")

        #pass properties to the operator
        ops = col.operator("add_matrix_obj.add_cube", text="Add Cube")
        ops.input1 = context.scene.count_x
        ops.input2 = context.scene.count_y

classs = [
    ADDMATRIX_add_cube, ADDMATRIX_panel
]


def register():
    bpy.types.Scene.count_x = bpy.props.IntProperty()
    bpy.types.Scene.count_y = bpy.props.IntProperty()
    for c in classs:
        bpy.utils.register_class(c)

def unregister():
    del bpy.types.Scene.count_x
    del bpy.types.Scene.count_y
    for c in classs:
        bpy.utils.unregister_class(c)


if __name__ == '__main__':
    register()