I'm writing a tool that would allow me to modify meshes within a circle of certain radius. I'd like to be able to change this radius with a mouse wheel, just like with proportional editing tool:
Here's the relevant part of my code. It blocks zooming by mouse wheel and use it to change the radius instead. Circle selection is called in the cursor position in order to select faces I want to modify.
import bpy
class ModalWheelTest(bpy.types.Operator):
"""Operator which runs its self from a timer"""
bl_idname = "wm.modal_wheel_test"
bl_label = "Test mouse wheel"
_timer = None
_radius = 10
def set_wheel_zoom_state(self, state):
"""
Disable or enable zooming by mouse wheel
"""
for key_map_item in bpy.context.window_manager.keyconfigs.default.keymaps["3D View"].keymap_items:
if key_map_item.name == 'Zoom View' and key_map_item.type in {'WHEELINMOUSE', 'WHEELOUTMOUSE'}:
key_map_item.active = state
def modal(self, context, event):
if event.type in {'RIGHTMOUSE', 'ESC'}:
self.cancel(context)
return {'CANCELLED'}
if event.type == 'MOUSEMOVE':
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
override = bpy.context.copy()
override['area'] = area
override['region'] = area.regions[4]
bpy.ops.view3d.select_circle(
override,
x=event.mouse_region_x,
y=event.mouse_region_y,
radius=self._radius,
gesture_mode = 3
)
break
if event.type in {'WHEELUPMOUSE'}:
self._radius = min(20, self._radius+1)
print("radius: {}".format(self._radius))
if event.type in {'WHEELDOWNMOUSE'}:
self._radius = max(5, self._radius-1)
print("radius: {}".format(self._radius))
return {'PASS_THROUGH'}
def execute(self, context):
if context.area.type != 'VIEW_3D':
print("Must use in a 3d region")
return {'CANCELLED'}
self.set_wheel_zoom_state(False)
wm = context.window_manager
self._timer = wm.event_timer_add(0.1, context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
self.set_wheel_zoom_state(True)
wm = context.window_manager
wm.event_timer_remove(self._timer)
def register():
bpy.utils.register_class(ModalWheelTest)
def unregister():
bpy.utils.unregister_class(ModalWheelTest)
if __name__ == "__main__":
register()
My question is: how can I draw a white circle in the 3D view window so I can actually see what I am selecting? I'm expecting that I'd clear it on every modal
method call and then redraw it with actualized radius and cursor position.