So I am trying to make a custom brush size similar to Sculpt mode:
This is for visualizing the Brush Proximity for an object with Dynamic Paint modifier.
I have this example which draws a rectangle on the viewport. I’d like this rectangle to be a circle & have its location where the cursor is when called.
Okay, I found a better example. This script lets you draw a circle & change its radius by mouse scrolling. But it only works in Blender 2.79 & I’d like to get it working on 2.8…
import bpy
import bgl
import blf
import math
def draw_circle_2d(color, cx, cy, r, num_segments):
theta = 2 * 3.1415926 / num_segments
c = math.cos(theta) #precalculate the sine and cosine
s = math.sin(theta)
x = r # we start at angle = 0
y = 0
bgl.glColor4f(*color)
bgl.glBegin(bgl.GL_LINE_LOOP)
for i in range (num_segments):
bgl.glVertex2f(x + cx, y + cy) # output vertex
# apply the rotation matrix
t = x
x = c * x - s * y
y = s * t + c * y
bgl.glEnd()
def draw_callback_px(self, context):
bgl.glEnable(bgl.GL_BLEND)
# ...api_current/bpy.types.Area.html?highlight=bpy.types.area
header_height = context.area.regions[0].height # 26px
npanel_width = context.area.regions[1].width
transorm_panel_width = context.area.regions[3].width
width = context.area.width - npanel_width - transorm_panel_width
height = context.area.height + header_height
# draw text
bgl.glLineWidth(4)
draw_circle_2d((1.0, 1.0, 1.0, 0.8), self._mouse_pos_x, self._mouse_pos_y, self._radius, 360)
# restore opengl defaults
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
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 = 50
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):
context.area.tag_redraw()
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':
self._mouse_pos_x = event.mouse_region_x
self._mouse_pos_y = event.mouse_region_y
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(200, self._radius+5)
print("radius: {}".format(self._radius))
if event.type in {'WHEELDOWNMOUSE'}:
self._radius = max(5, self._radius-5)
print("radius: {}".format(self._radius))
return {'RUNNING_MODAL'}
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
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
self.set_wheel_zoom_state(True)
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
wm = context.window_manager
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
# the arguments we pass the the callback
args = (self, context)
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
context.window_manager.modal_handler_add(self)
self._mouse_pos = []
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "View3D not found, cannot run operator")
return {'CANCELLED'}
def register():
bpy.utils.register_class(ModalWheelTest)
def unregister():
bpy.utils.unregister_class(ModalWheelTest)
if __name__ == "__main__":
register()