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()