Learning about Operators #1
.start
Today, I finally got to learn the basics of Operators, thanks to the following links.
I wrote the program above in 4 steps as presented below
import bpy
class MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
def execute(self, context):
self.report({'INFO'}, 'Hello')
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
class MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
x = bpy.props.IntProperty()
y = bpy.props.IntProperty()
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
class MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
x = bpy.props.IntProperty()
y = bpy.props.IntProperty()
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
split = layout.split()
column1 = split.column()
column1.label(self.bl_idname)
column2 = split.column()
row = column2.row(align=True)
row.prop(self, 'x')
row.prop(self, 'y')
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
import bpy
class MousePositionOperator(bpy.types.Operator):
# operators python name with namespace bpy.ops.
# Upon registering this class, a type called 'WM_OT_mouse_position' is created under bpy.types
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
bl_description = "Displays the mouse coordinates in the Info header"
x = bpy.props.IntProperty(name='mX', description='X position of mouse')
y = bpy.props.IntProperty(name='mY', description='Y position of mouse')
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
split = layout.split()
column1 = split.column()
# Python name of the operator (bpy.ops)
column1.label(self.bl_idname)
# Type name of the operator (Dynamically created upon registration of this class)
column1.label(self.__class__.__name__)
column2 = split.column()
row = column2.row(align=True)
row.prop(self, 'x')
row.prop(self, 'y')
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
operator = layout.operator('wm.mouse_position')
operator.x = -1
operator.y = -1
Next step was to introspect the operator in the Console.
And also the Operator's type
.end
satishgoda at gmail dot com
Today, I finally got to learn the basics of Operators, thanks to the following links.
- blender_python_api_2_65_release/bpy.ops.html
- blender_python_api_2_65_release/bpy.types.Operator.html
- blender_python_api_2_65_release/bpy.props.html
Based on some examples from the above links, I made a version for myself
A quick overview of my setup. |
First
In this version, we are creating a new operator by sub-classing bpy.types.Operator and implementing a very basic execute method. Once the custom operator class is registered with Blender, its available to us.
class MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
def execute(self, context):
self.report({'INFO'}, 'Hello')
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
The operator is available from the Operator search menu in all contexts. We could implement a poll classmethod on Operators to make the operator locked to certain contexts. More on that later. |
Second
import bpyclass MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
x = bpy.props.IntProperty()
y = bpy.props.IntProperty()
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
Third
import bpyclass MousePositionOperator(bpy.types.Operator):
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
x = bpy.props.IntProperty()
y = bpy.props.IntProperty()
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
split = layout.split()
column1 = split.column()
column1.label(self.bl_idname)
column2 = split.column()
row = column2.row(align=True)
row.prop(self, 'x')
row.prop(self, 'y')
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
Fourth
Now we are providing a description for the operator and naming/describing the operator properties. Some comments are also being added.
class MousePositionOperator(bpy.types.Operator):
# operators python name with namespace bpy.ops.
# Upon registering this class, a type called 'WM_OT_mouse_position' is created under bpy.types
bl_idname = 'wm.mouse_position'
bl_label = 'Mouse Position'
bl_description = "Displays the mouse coordinates in the Info header"
x = bpy.props.IntProperty(name='mX', description='X position of mouse')
y = bpy.props.IntProperty(name='mY', description='Y position of mouse')
def invoke(self, context, event):
self.x, self.y = event.mouse_x, event.mouse_y
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
split = layout.split()
column1 = split.column()
# Python name of the operator (bpy.ops)
column1.label(self.bl_idname)
# Type name of the operator (Dynamically created upon registration of this class)
column1.label(self.__class__.__name__)
column2 = split.column()
row = column2.row(align=True)
row.prop(self, 'x')
row.prop(self, 'y')
def execute(self, context):
self.report({'INFO'}, "mX: {0} mY: {1}".format(self.x, self.y))
return {'FINISHED'}
bpy.utils.register_class(MousePositionOperator)
Changes made to Info Header
if hasattr(bpy.types, 'WM_OT_mouse_position'):operator = layout.operator('wm.mouse_position')
operator.x = -1
operator.y = -1
As you can see, we can update the operator property values after creating an instance of it in the user interface.
Operator in Action |
Tried to execute the operator from the Console. |
Based on the bl_idname, when we register the class, Blender creates a type called WM_OT_mouse_position under bpy.types |
Errors Encountered
Some of the errors encountered while developing the wm.mouse_position operator.Function.result expected a set
location: <unknown location>:-1
RuntimeError: class WM_OT_mouse_position, function execute: incompatible return value , str(, Function.result expected a set, not a NoneType)
I just scratched the surface for today, and am looking forward to writing more Operators. But, if you want to get your hands dirty with the code, you can leverage on the templates provided in the Blender distribution and which can be accessed from the Text Editor Templates menu.
.end
satishgoda at gmail dot com
Comments
Post a Comment
Your comments are very much appreciated. Thank You.