2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
import bpy
|
|
|
|
|
|
|
|
from bpy.props import (IntProperty, EnumProperty, BoolProperty)
|
|
|
|
from bpy.types import (AddonPreferences, GizmoGroup, Operator, Gizmo)
|
2024-02-26 14:13:43 +01:00
|
|
|
import gpu
|
2022-04-06 10:12:32 +02:00
|
|
|
from mathutils import Vector, Matrix, Euler
|
2024-02-26 14:13:43 +01:00
|
|
|
from gpu_extras.batch import batch_for_shader
|
|
|
|
|
|
|
|
from .constants import PICKERS, SHADERS
|
2023-11-09 10:29:56 +01:00
|
|
|
from .core.picker import Picker
|
2024-02-26 14:13:43 +01:00
|
|
|
from .core.geometry_utils import bounding_rect
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
class RP_OT_simple_operator(bpy.types.Operator):
|
|
|
|
"""Tooltip"""
|
|
|
|
bl_idname = "object.simple_operator"
|
|
|
|
bl_label = "Simple Object Operator"
|
|
|
|
|
|
|
|
|
|
|
|
def invoke(self, context, event):
|
|
|
|
|
|
|
|
context.window_manager.modal_handler_add(self)
|
|
|
|
|
|
|
|
print('Invoke RP_OT_simple_operator')
|
|
|
|
bpy.ops.node.rp_box_select('INVOKE_DEFAULT', tweak=True)
|
|
|
|
|
|
|
|
#bpy.ops.node.select_box('INVOKE_DEFAULT', wait_for_input=True, tweak=True)
|
|
|
|
|
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def modal(self, context, event):
|
|
|
|
print('modal op', event.type, event.value)
|
|
|
|
|
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
print('Select Shape')
|
|
|
|
return {'FINISHED'}
|
|
|
|
'''
|
2024-02-26 14:13:43 +01:00
|
|
|
'''
|
|
|
|
class RP_OT_box_select(Operator):
|
|
|
|
"""Box Select bones in the picker view"""
|
|
|
|
bl_idname = "node.rp_box_select"
|
|
|
|
bl_label = "Picker Box Select"
|
|
|
|
|
|
|
|
mode: EnumProperty(items=[(i, i.title(), '') for i in ('SET', 'EXTEND', 'SUBSTRACT')])
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
|
|
|
if not is_picker_space(context.space_data):
|
|
|
|
return
|
|
|
|
|
|
|
|
ob = context.object
|
|
|
|
return ob and ob in PICKERS
|
|
|
|
|
|
|
|
def draw_callback(self):
|
|
|
|
#print('draw callback border')
|
|
|
|
if not self.draw_border:
|
|
|
|
return
|
|
|
|
|
|
|
|
gpu.state.blend_set('ALPHA')
|
|
|
|
|
|
|
|
#print('DRAW BORDER')
|
|
|
|
|
|
|
|
self.color_shader.bind()
|
|
|
|
self.color_shader.uniform_float("color", self.bg_color)
|
|
|
|
self.bg_batch.draw(self.color_shader)
|
|
|
|
|
|
|
|
self.dash_shader.bind()
|
|
|
|
matrix = gpu.matrix.get_projection_matrix()
|
|
|
|
|
|
|
|
self.dash_shader.uniform_float("color", self.border_color)
|
|
|
|
self.dash_shader.uniform_float("viewMatrix", matrix)
|
|
|
|
self.dash_shader.uniform_float("dashSize", 5)
|
|
|
|
self.dash_shader.uniform_float("gapSize", 4)
|
|
|
|
|
|
|
|
self.contour_batch.draw(self.dash_shader)
|
|
|
|
|
|
|
|
gpu.state.blend_set('NONE')
|
|
|
|
|
|
|
|
def invoke(self, context, event):
|
|
|
|
#print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
|
|
|
|
|
|
|
|
if context.object.mode != 'POSE':
|
|
|
|
bpy.ops.object.posemode_toggle()
|
|
|
|
|
|
|
|
self.timer = None
|
|
|
|
#self.mode = self.mode_from_event(event)
|
|
|
|
#self.invoke_event = event.copy()
|
|
|
|
self.region = context.region
|
|
|
|
self.draw_border = False
|
|
|
|
|
|
|
|
self.picker = PICKERS[context.object]
|
|
|
|
|
|
|
|
self.start_mouse = event.mouse_region_x, event.mouse_region_y
|
|
|
|
#self.shader = line_strip_shader
|
|
|
|
self.border_color = [1, 1, 1, 1]
|
|
|
|
self.bg_color = [1, 1, 1, 0.05]
|
|
|
|
|
|
|
|
#args = (self, context)
|
|
|
|
self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR')
|
|
|
|
self.dash_shader = SHADERS['dashed_line']
|
|
|
|
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
|
|
|
|
|
|
|
|
context.window_manager.modal_handler_add(self)
|
|
|
|
|
|
|
|
self.picker.press_event(self.mode)
|
|
|
|
self.region.tag_redraw()
|
|
|
|
|
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def modal(self, context, event):
|
|
|
|
|
|
|
|
self.mouse = event.mouse_region_x, event.mouse_region_y
|
|
|
|
|
|
|
|
self.border = bounding_rect((self.start_mouse, self.mouse))
|
|
|
|
|
|
|
|
self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border})
|
|
|
|
self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border})
|
|
|
|
|
|
|
|
self.draw_border = True
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
self.region.tag_redraw()
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
if event.value == 'RELEASE':
|
|
|
|
return self.release_event(context)
|
|
|
|
|
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def release_event(self, context):
|
|
|
|
scn = context.scene
|
|
|
|
|
|
|
|
if scn.rig_picker.use_pick_bone:
|
|
|
|
self.picker.assign_bone_event()
|
|
|
|
|
|
|
|
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
|
|
|
|
self.picker.border_select(self.border, self.mode)
|
|
|
|
else:
|
|
|
|
self.picker.move_event(self.mouse)
|
|
|
|
self.picker.release_event(self.mode)
|
|
|
|
|
|
|
|
bpy.ops.ed.undo_push(message="Box Select")
|
|
|
|
|
|
|
|
return self.exit(context)
|
|
|
|
|
|
|
|
def exit(self, context):
|
|
|
|
bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW')
|
|
|
|
context.region.tag_redraw()
|
|
|
|
return {'FINISHED'}
|
|
|
|
'''
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RP_GT_gizmo(Gizmo):
|
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
def mode_from_event(self, event):
|
|
|
|
if event.alt:
|
|
|
|
return 'SUBSTRACT'
|
|
|
|
elif event.ctrl or event.shift:
|
|
|
|
return 'EXTEND'
|
|
|
|
else:
|
|
|
|
return 'SET'
|
|
|
|
|
2022-04-06 10:12:32 +02:00
|
|
|
def test_select(self, context, location):
|
|
|
|
ob = context.object
|
|
|
|
|
|
|
|
picker = PICKERS.get(ob)
|
|
|
|
if not picker:
|
|
|
|
return -1
|
|
|
|
|
|
|
|
picker.move_event(location)
|
2024-02-26 14:13:43 +01:00
|
|
|
context.region.tag_redraw()
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
return 1
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
|
|
|
|
def draw(self, context):
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
print('DRAW_SELECT', self.border)
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
if not self.draw_border:
|
|
|
|
return
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
gpu.state.blend_set('ALPHA')
|
|
|
|
gpu.state.depth_test_set('ALWAYS')
|
|
|
|
gpu.state.depth_mask_set(False)
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
#print('DRAW BORDER')
|
|
|
|
|
|
|
|
self.color_shader.bind()
|
|
|
|
self.color_shader.uniform_float("color", self.bg_color)
|
|
|
|
self.bg_batch.draw(self.color_shader)
|
2022-04-06 10:12:32 +02:00
|
|
|
|
2024-02-26 14:13:43 +01:00
|
|
|
self.dash_shader.bind()
|
|
|
|
matrix = gpu.matrix.get_projection_matrix()
|
|
|
|
|
|
|
|
self.dash_shader.uniform_float("color", self.border_color)
|
|
|
|
self.dash_shader.uniform_float("viewMatrix", matrix)
|
|
|
|
self.dash_shader.uniform_float("dashSize", 5)
|
|
|
|
self.dash_shader.uniform_float("gapSize", 4)
|
|
|
|
|
|
|
|
self.contour_batch.draw(self.dash_shader)
|
|
|
|
|
|
|
|
#gpu.state.depth_mask_set(False)
|
|
|
|
gpu.state.blend_set('NONE')
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
def invoke(self, context, event):
|
|
|
|
print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
|
2024-02-26 14:13:43 +01:00
|
|
|
|
|
|
|
print(self)
|
|
|
|
|
|
|
|
if context.object.mode != 'POSE':
|
|
|
|
bpy.ops.object.posemode_toggle()
|
|
|
|
|
|
|
|
#self.timer = None
|
|
|
|
#self.mode = self.mode_from_event(event)
|
|
|
|
#self.invoke_event = event.copy()
|
|
|
|
#self.region = context.region
|
|
|
|
self.draw_border = False
|
|
|
|
|
|
|
|
self.picker = PICKERS[context.object]
|
|
|
|
|
|
|
|
self.start_mouse = event.mouse_region_x, event.mouse_region_y
|
|
|
|
#self.shader = line_strip_shader
|
|
|
|
self.border_color = [1, 1, 1, 1]
|
|
|
|
self.bg_color = [1, 1, 1, 0.05]
|
|
|
|
|
|
|
|
#args = (self, context)
|
|
|
|
self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR')
|
|
|
|
self.dash_shader = SHADERS['dashed_line']
|
|
|
|
#self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
|
|
|
|
|
|
|
|
self.border = [(0, 0), (0, 0), (0, 0), (0, 0)]
|
|
|
|
#context.window_manager.modal_handler_add(self)
|
|
|
|
self.mode = self.mode_from_event(event)
|
|
|
|
self.picker.press_event(self.mode)
|
|
|
|
context.region.tag_redraw()
|
|
|
|
|
2022-04-06 10:12:32 +02:00
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def modal(self, context, event, tweak):
|
2024-02-26 14:13:43 +01:00
|
|
|
#print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
|
|
|
|
|
|
|
|
self.mouse = event.mouse_region_x, event.mouse_region_y
|
|
|
|
|
|
|
|
self.border = bounding_rect((self.start_mouse, self.mouse))
|
|
|
|
|
|
|
|
self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border})
|
|
|
|
self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border})
|
|
|
|
|
|
|
|
self.draw_border = True
|
|
|
|
|
|
|
|
context.region.tag_redraw()
|
|
|
|
#self.draw(context)
|
|
|
|
|
2022-04-06 10:12:32 +02:00
|
|
|
return {'RUNNING_MODAL'}
|
|
|
|
|
|
|
|
def exit(self, context, cancel):
|
2024-02-26 14:13:43 +01:00
|
|
|
scn = context.scene
|
|
|
|
|
|
|
|
if scn.rig_picker.use_pick_bone:
|
|
|
|
self.picker.assign_bone_event()
|
|
|
|
|
|
|
|
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
|
|
|
|
self.picker.border_select(self.border, self.mode)
|
|
|
|
else:
|
|
|
|
self.picker.move_event(self.mouse)
|
|
|
|
self.picker.release_event(self.mode)
|
|
|
|
|
|
|
|
bpy.ops.ed.undo_push(message="Box Select")
|
|
|
|
self.draw_border = False
|
|
|
|
context.region.tag_redraw()
|
|
|
|
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RP_GT_gizmogroup(GizmoGroup):
|
|
|
|
""" test gizmo button 2d """
|
|
|
|
bl_idname = "view3d.gizmo_button_2d"
|
|
|
|
bl_label = "Test button 2d"
|
|
|
|
bl_space_type = 'NODE_EDITOR'
|
|
|
|
bl_region_type = 'WINDOW'
|
|
|
|
bl_options = {'PERSISTENT'}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
|
|
|
return context.space_data.tree_type == 'RigPickerTree'
|
|
|
|
|
|
|
|
def setup(self, context):
|
|
|
|
self.gizmo = self.gizmos.new("RP_GT_gizmo")
|
2024-02-26 14:13:43 +01:00
|
|
|
self.gizmo.draw_border = False
|
|
|
|
self.gizmo.border = []
|
|
|
|
self.gizmo.use_draw_modal = True
|
2022-04-06 10:12:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes = (
|
|
|
|
RP_GT_gizmo,
|
|
|
|
RP_GT_gizmogroup
|
|
|
|
)
|
|
|
|
|
|
|
|
def register():
|
|
|
|
for cls in classes:
|
|
|
|
bpy.utils.register_class(cls)
|
|
|
|
|
|
|
|
|
|
|
|
def unregister():
|
|
|
|
|
|
|
|
for cls in reversed(classes):
|
|
|
|
bpy.utils.unregister_class(cls)
|