2023-11-09 10:29:56 +01:00
|
|
|
|
|
|
|
import bpy
|
2024-02-19 11:53:15 +01:00
|
|
|
import gpu
|
|
|
|
from gpu_extras.batch import batch_for_shader
|
2023-11-09 10:29:56 +01:00
|
|
|
import blf
|
|
|
|
from pathlib import Path
|
|
|
|
from .constants import PICKERS
|
2024-02-19 11:53:15 +01:00
|
|
|
from .core.picker import Picker, PickerGroup
|
2023-11-09 10:29:56 +01:00
|
|
|
import json
|
|
|
|
|
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
def draw_rect_2d(position, width, height, color):
|
|
|
|
"""
|
|
|
|
Draw a 2d rectangele.
|
|
|
|
|
|
|
|
:arg position: Position of the lower left corner.
|
|
|
|
:type position: 2D Vector
|
|
|
|
:arg width: Width of the rect.
|
|
|
|
:type width: float
|
|
|
|
:arg height: Height of the rect.
|
|
|
|
:type height: float
|
|
|
|
"""
|
|
|
|
|
|
|
|
coords = ((0, 0), (1, 0), (1, 1), (0, 1))
|
|
|
|
|
|
|
|
shader = gpu.shader.from_builtin('UNIFORM_COLOR')
|
|
|
|
batch = batch_for_shader(
|
|
|
|
shader, 'TRI_FAN',
|
|
|
|
{"pos": coords},
|
|
|
|
)
|
|
|
|
|
|
|
|
with gpu.matrix.push_pop():
|
|
|
|
gpu.matrix.translate(position)
|
|
|
|
gpu.matrix.scale((width, height))
|
|
|
|
shader.uniform_float("color", color)
|
|
|
|
|
|
|
|
batch.draw(shader)
|
|
|
|
|
|
|
|
|
2023-11-09 10:29:56 +01:00
|
|
|
def draw_callback_view():
|
|
|
|
sp = bpy.context.space_data
|
|
|
|
|
|
|
|
if not sp or not sp.tree_type == 'RigPickerTree':
|
|
|
|
return
|
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
if not sp.pin:
|
|
|
|
sp.pin = True
|
|
|
|
sp.show_region_ui = False
|
|
|
|
|
2023-11-09 10:29:56 +01:00
|
|
|
ob = bpy.context.object
|
2024-02-19 11:53:15 +01:00
|
|
|
if not ob or ob.type !='ARMATURE' or not ob.data.rig_picker.sources:
|
2023-11-09 10:29:56 +01:00
|
|
|
return
|
|
|
|
|
|
|
|
if ob not in PICKERS:
|
2024-02-19 11:53:15 +01:00
|
|
|
if 'pickers' in ob.data.rig_picker:
|
|
|
|
picker_datas = [s.to_dict() for s in ob.data.rig_picker['pickers']]
|
2023-11-09 10:29:56 +01:00
|
|
|
else:
|
2024-02-19 11:53:15 +01:00
|
|
|
picker_datas = []
|
|
|
|
for picker in ob.data.rig_picker.sources:
|
|
|
|
picker_path = Path(bpy.path.abspath(picker.source, library=ob.data.library))
|
|
|
|
|
|
|
|
if not picker_path.exists():
|
|
|
|
print(f'Picker path not exists: {picker_path.resolve()}')
|
|
|
|
continue
|
|
|
|
|
|
|
|
print('Load picker from', picker_path.resolve())
|
|
|
|
picker_data = json.loads(picker_path.read_text(encoding='utf-8'))
|
|
|
|
picker_datas.append(picker_data)
|
|
|
|
#shapes = [s.to_dict() for s in ob.data.rig_picker['shapes']]
|
2023-11-09 10:29:56 +01:00
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
PICKERS[ob] = PickerGroup(ob, picker_datas)#[Picker(ob, shapes=picker_data) for picker_data in picker_datas]
|
2023-11-09 10:29:56 +01:00
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
# if 'picker' in ob.data.rig_picker:
|
|
|
|
# picker_datas = [s.to_dict() for s in ob.data.rig_picker['picker']]
|
|
|
|
# else:
|
|
|
|
# picker_path = Path(bpy.path.abspath(ob.data.rig_picker.source, library=ob.data.library))
|
2023-11-09 10:29:56 +01:00
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
# if not picker_path.exists():
|
|
|
|
# print(f'Picker path not exists: {picker_path.resolve()}')
|
|
|
|
# return
|
|
|
|
|
|
|
|
# print('Load picker from', picker_path.resolve())
|
|
|
|
# picker_datas = json.loads(picker_path.read_text())
|
|
|
|
# #shapes = [s.to_dict() for s in ob.data.rig_picker['shapes']]
|
|
|
|
# PICKERS[ob] = Picker(ob, shapes=picker_datas)
|
|
|
|
|
|
|
|
picker_group = PICKERS.get(ob)
|
|
|
|
picker_group.draw()
|
2023-11-09 10:29:56 +01:00
|
|
|
|
|
|
|
def draw_callback_px():
|
|
|
|
sp = bpy.context.space_data
|
|
|
|
if not sp.tree_type == 'RigPickerTree':
|
|
|
|
return
|
|
|
|
|
|
|
|
ob = bpy.context.object
|
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
picker_group = PICKERS.get(ob)
|
|
|
|
if not picker_group or not picker_group.tooltip:
|
2023-11-09 10:29:56 +01:00
|
|
|
return
|
|
|
|
|
2024-02-19 11:53:15 +01:00
|
|
|
text = picker_group.tooltip
|
|
|
|
mouse = picker_group.tooltip_mouse
|
|
|
|
ui_scale = bpy.context.preferences.system.ui_scale
|
2023-11-09 10:29:56 +01:00
|
|
|
|
|
|
|
#print('Draw text', text)
|
|
|
|
font_id = 0
|
2024-02-19 11:53:15 +01:00
|
|
|
blf.size(font_id, int(13 * ui_scale))
|
|
|
|
|
|
|
|
text_size = blf.dimensions(font_id, text)
|
|
|
|
text_pos = (mouse[0] - text_size[0]*0.33, mouse[1] - (34*ui_scale))
|
|
|
|
|
|
|
|
bg_margins = [8, 4]
|
|
|
|
bg_pos = (text_pos[0] - bg_margins[0], text_pos[1] - bg_margins[1]-1)
|
|
|
|
bg_size = (text_size[0] + 2*bg_margins[0], text_size[1] + 2*bg_margins[1])
|
|
|
|
|
|
|
|
gpu.state.blend_set('ALPHA')
|
|
|
|
draw_rect_2d(bg_pos, *bg_size, (0, 0, 0, 0.75))
|
|
|
|
gpu.state.blend_set('NONE')
|
|
|
|
|
|
|
|
|
2023-11-09 10:29:56 +01:00
|
|
|
#blf.dimensions(font_id, text)
|
|
|
|
blf.enable(font_id, blf.SHADOW)
|
|
|
|
|
|
|
|
|
|
|
|
# BLF drawing routine
|
2024-02-19 11:53:15 +01:00
|
|
|
blf.position(font_id, round(text_pos[0]), round(text_pos[1]), 0)
|
2023-11-09 10:29:56 +01:00
|
|
|
blf.color(font_id, 1, 1, 1, 1)
|
|
|
|
|
|
|
|
blf.shadow(font_id , 5, 0.0, 0.0, 0.0, 1)
|
|
|
|
blf.shadow_offset(font_id, 2, -2)
|
|
|
|
|
|
|
|
blf.draw(font_id, text)
|
|
|
|
|
|
|
|
blf.disable(font_id, blf.SHADOW)
|
|
|
|
|
|
|
|
handle_view = None
|
|
|
|
handle_pixel = None
|
|
|
|
|
|
|
|
|
|
|
|
def register():
|
|
|
|
global handle_view
|
|
|
|
global handle_pixel
|
|
|
|
|
|
|
|
handle_view = bpy.types.SpaceNodeEditor.draw_handler_add(draw_callback_view, (), 'WINDOW', 'POST_VIEW')
|
|
|
|
handle_pixel = bpy.types.SpaceNodeEditor.draw_handler_add(draw_callback_px, (), 'WINDOW', 'POST_PIXEL')
|
|
|
|
|
|
|
|
def unregister():
|
|
|
|
global handle_view
|
|
|
|
global handle_pixel
|
|
|
|
|
|
|
|
bpy.types.SpaceNodeEditor.draw_handler_remove(handle_view, 'WINDOW')
|
|
|
|
bpy.types.SpaceNodeEditor.draw_handler_remove(handle_pixel, 'WINDOW')
|
|
|
|
|
|
|
|
handle_view = None
|
|
|
|
handle_pixel = None
|