If you are making a Blender plugin, you will want to handle events from the mouse and keyboard and provide more interactive features. The function to change the size of an object just by moving the mouse when pressing the S key in Object mode is just an example of handling an event from the mouse, and the operation feeling is good.
So this time, I will show you how to handle mouse and keyboard events in Blender script with samples.
Again, the sample is shown first. This sample allows you to scale the object according to the mouse position. We have dealt with the following events so that you can understand the pattern of input events in Blender.
mouse_keyboard_event_test.py
import bpy
bl_info = {
"name" : "Mouse/Keyboard event test",
"author" : "Nutti",
"version" : (0,1),
"blender" : (2, 7, 0),
"location" : "UV > Mouse/Keyboard event test",
"description" : "Mouse/Keyboard event test.",
"warning" : "",
"wiki_url" : "",
"tracker_url" : "",
"category" : "UV"
}
running = False #True if event acquisition is in progress
class MouseKeyboardEventTest(bpy.types.Operator):
"""Mouse/Keyboard event test."""
bl_idname = "uv.mouse_keyboard_event_test"
bl_label = "Mouse/Keyboard event test"
bl_description = "Mouse/Keyboard event test"
bl_options = {'REGISTER', 'UNDO'}
obj_scale = 1.0 #Object magnification
orig_x = 0.0 #X coordinate when the button is pressed
orig_scale = [] #Object magnification when the button is pressed
def modal(self, context, event):
global running
#Exit if not working
if running is False:
return {'PASS_THROUGH'}
#Apply magnification to objects
active_obj = bpy.context.active_object
active_obj.scale[0] = self.orig_scale[0] * self.obj_scale
active_obj.scale[1] = self.orig_scale[1] * self.obj_scale
active_obj.scale[2] = self.orig_scale[2] * self.obj_scale
#############################################
#mouse/Processing to handle keyboard events
#############################################
#Mouse movement-Set the magnification of the object based on the X coordinate of the mouse
if event.type == 'MOUSEMOVE':
factor = 1.0 / 100.0
self.obj_scale = 1.0 + (event.mouse_x - self.orig_x) * factor
return {'RUNNING_MODAL'}
#When you press the spacebar-Return the magnification when the button is pressed
elif event.type == 'SPACE':
if event.value == 'PRESS':
self.orig_x = event.mouse_x
return {'RUNNING_MODAL'}
#When right click is pressed-Confirm the changed enlargement ratio and end the operation
if event.type == 'RIGHTMOUSE':
if event.value == 'PRESS':
running = False
return {'FINISHED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
global running
if context.area.type == 'VIEW_3D':
#Accept each event if the button is pressed while it is not running
if running is False:
running = True
#Initial state setting
self.obj_scale = 1.0
self.orig_x = event.mouse_x
active_obj = bpy.context.active_object
self.orig_scale = [
active_obj.scale[0],
active_obj.scale[1],
active_obj.scale[2]
]
#modal handler settings
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
return {'CANCELLED'}
# 'N'Place a button in the menu that appears on the right side of VIEW 3D when you press a key
class OBJECT_PT_MKET(bpy.types.Panel):
bl_label = "Mouse/Keyboard Event Test"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
sc = context.scene
layout = self.layout
#Button placement
layout.operator(MouseKeyboardEventTest.bl_idname, text="Start", icon="PLAY")
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
Follow the steps below to install the script. Blender Wiki
If you click the "Start" button in "Mouse / Keyboard Event Test" of the menu displayed on the right side when you press the'N'key in View 3D, the following operations will be accepted.
operation | Behavior on objects |
---|---|
Mouse movement | Move the mouse to the right of the screen from where you clicked the button to enlarge the selected object, and move it to the left of the screen to zoom out. |
Space bar | Restores the size of the object when the button is clicked. |
right click | Confirm the size of the changed object and finish the operation. |
The basic explanation of the Blender script is introduced in the following article, so here we will focus on the explanation of the newly added elements. [\ Blender ] How to make a Blender plugin
Add a button to the menu on the right that appears when you press the'N'key in View 3D. Button registration is beyond the scope of this article, so think of it like this for now.
# 'N'Place a button in the menu that appears on the right side of VIEW 3D when you press a key
class OBJECT_PT_MKET(bpy.types.Panel):
bl_label = "Mouse/Keyboard Event Test"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
#Button placement
# ...
** A method that is called when the class is called **. In this sample, it is called when the button is clicked.
def invoke(self, context, event):
global running
if context.area.type == 'VIEW_3D':
#Accept each event if the button is pressed while it is not running
if running is False:
running = True
#Initial state setting
# ....
#modal handler settings
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
return {'CANCELLED'}
We have specified a handler (an object with a modal
method) in the context.window_manager.modal_handler_add
function to accept mouse events after clicking the button.
Here, specify self
because the class has both ʻinvoke and
modal` methods at the same time. In addition, various initial state settings are also made.
If you set a handler here, the modal method will continue to be called ** after **, so we have prepared a running
variable to eliminate operations on the object even if an event occurs at the time of stop.
If you register a handler with the context.window_manager.modal_handler_add
function in the ʻinvoke` method, it will be called ** when an event occurs from the mouse or keyboard **.
def modal(self, context, event):
global running
#Exit if not working
if running is False:
return {'PASS_THROUGH'}
# ....
#Mouse movement-Set the magnification of the object based on the X coordinate of the mouse
if event.type == 'MOUSEMOVE':
factor = 1.0 / 100.0
self.obj_scale = 1.0 + (event.mouse_x - self.orig_x) * factor
return {'RUNNING_MODAL'}
#When you press the spacebar-Return the magnification when the button is pressed
elif event.type == 'SPACE':
if event.value == 'PRESS':
self.orig_x = event.mouse_x
return {'RUNNING_MODAL'}
#When right click is pressed-Confirm the changed enlargement ratio and end the operation
if event.type == 'RIGHTMOUSE':
if event.value == 'PRESS':
running = False
return {'FINISHED'}
return {'RUNNING_MODAL'}
The modal
method handles each event as follows.
Event | processing |
---|---|
Mouse movement | Gets the current position and calculates the lateral difference between the current position and the initial position to set the magnification of the object. afterwards, {'RUNNING_MODAL'} Is returned and processing continues. |
right click | {'FINISHED'} Returns and finishes the process. |
Space bar | Change the enlargement ratio of the object to the initial value. afterwards, {'RUNNING_MODAL'} Is returned and processing continues. |
Other | {'RUNNING_MODAL'} Is returned and processing continues. |
I introduced how to handle events from the mouse and keyboard in Blender scripts. By knowing keyboard and mouse events, I think that ** more things can be achieved with scripts **, so why not try using it?
Recommended Posts