From 26d45c08b4d1b107d5259a6bc67ab595580c12d8 Mon Sep 17 00:00:00 2001 From: Joseph Tseng <106340233+Chalkman071@users.noreply.github.com> Date: Mon, 12 Feb 2024 21:26:42 +0800 Subject: [PATCH] EDITOR-#535 [BLENDER] Dancer name tag (#536) * added dancer name tag * disabled deleting objects --- editor-blender/handlers/__init__.py | 6 +- editor-blender/handlers/keymap.py | 111 ++++++++++++++++++ editor-blender/handlers/name_tag.py | 101 ++++++++++++++++ .../operators/clipboard/__init__.py | 83 ------------- 4 files changed, 217 insertions(+), 84 deletions(-) create mode 100644 editor-blender/handlers/keymap.py create mode 100644 editor-blender/handlers/name_tag.py diff --git a/editor-blender/handlers/__init__.py b/editor-blender/handlers/__init__.py index e75189fc2..e645f56b6 100644 --- a/editor-blender/handlers/__init__.py +++ b/editor-blender/handlers/__init__.py @@ -1,13 +1,17 @@ -from . import animation, objects, waveform +from . import animation, keymap, name_tag, objects, waveform def mount_handlers(): animation.mount() objects.mount() waveform.mount() + name_tag.mount() + keymap.mount() def unmount_handlers(): animation.unmount() objects.unmount() waveform.unmount() + name_tag.unmount() + keymap.unmount() diff --git a/editor-blender/handlers/keymap.py b/editor-blender/handlers/keymap.py new file mode 100644 index 000000000..4759a90f7 --- /dev/null +++ b/editor-blender/handlers/keymap.py @@ -0,0 +1,111 @@ +from typing import Dict, List, Optional, cast + +import bpy + +default_clipboard_keymaps = ["view3d.copybuffer", "view3d.pastebuffer"] +default_delete_keymaps = { + "Object Mode": ["object.delete", "anim.keyframe_delete_v3d"], + "Dopesheet": ["action.delete"], + "Outliner": ["outliner.delete", "anim.keyframe_delete"], + "User Interface": ["anim.keyframe_delete_button"], +} + + +def check_keymaps_exist( + keymaps: List[bpy.types.KeyMapItem], + names: List[str], + ctrl: List[int], + oskey: List[int], +) -> List[Optional[bpy.types.KeyMapItem]]: + wm = bpy.context.window_manager + kc_items = cast(Dict[str, bpy.types.KeyMap], wm.keyconfigs.default.keymaps)[ + "3D View" + ].keymap_items + kc_items = cast(List[bpy.types.KeyMapItem], kc_items) + + results: List[Optional[bpy.types.KeyMapItem]] = [None] * len(names) + + for keymap in keymaps: + for i in range(len(names)): + if ( + keymap.idname == names[i] + and keymap.ctrl == ctrl[i] + and keymap.oskey == oskey[i] + ): + results[i] = keymap + + return results + + +def mount(): + wm = bpy.context.window_manager + global default_keymaps + default_keymaps = cast(List[bpy.types.KeyMapItem], []) + # Disable delete keymaps + for keymap_class, keymap_list in default_delete_keymaps.items(): + km_items = cast(Dict[str, bpy.types.KeyMap], wm.keyconfigs.default.keymaps)[ + keymap_class + ].keymap_items + km_items = cast(List[bpy.types.KeyMapItem], km_items) + for keymap in km_items: + if keymap.idname in keymap_list: + keymap.active = False + default_keymaps.append(keymap) + + # Active clipboard keymaps and disable default keymaps + + view_3d_km_items = cast(Dict[str, bpy.types.KeyMap], wm.keyconfigs.default.keymaps)[ + "3D View" + ].keymap_items + view_3d_km_items = cast(List[bpy.types.KeyMapItem], view_3d_km_items) + + for keymap in view_3d_km_items: + if keymap.idname in default_clipboard_keymaps: + keymap.active = False + default_keymaps.append(keymap) + + new_keymaps_config = ( + [ + "lightdance.copy", + "lightdance.copy", + "lightdance.paste", + "lightdance.paste", + ], + ["C", "C", "V", "V"], + [1, 0, 1, 0], + [0, 1, 0, 1], + ) + + new_keymaps = check_keymaps_exist( + view_3d_km_items, + new_keymaps_config[0], + new_keymaps_config[2], + new_keymaps_config[3], + ) + + view_3d_km_items = cast(bpy.types.KeyMapItems, view_3d_km_items) + for i in range(len(new_keymaps)): + new_keymap = new_keymaps[i] + + if new_keymap is None: + new_keymaps[i] = view_3d_km_items.new( + new_keymaps_config[0][i], + new_keymaps_config[1][i], + ctrl=new_keymaps_config[2][i], + oskey=new_keymaps_config[3][i], + value="PRESS", + ) + + else: + new_keymap.active = True + + global clipboard_keymaps + + clipboard_keymaps = cast(List[bpy.types.KeyMapItem], new_keymaps) + + +def unmount(): + for keymap in clipboard_keymaps: + keymap.active = False + for keymap in default_keymaps: + keymap.active = True diff --git a/editor-blender/handlers/name_tag.py b/editor-blender/handlers/name_tag.py new file mode 100644 index 000000000..8b4fbff20 --- /dev/null +++ b/editor-blender/handlers/name_tag.py @@ -0,0 +1,101 @@ +from typing import Any, List, Optional, Tuple, cast + +import blf +import bpy +from bpy_extras.view3d_utils import location_3d_to_region_2d +from mathutils import Vector + +from ..core.states import state +from ..core.utils.ui import redraw_area + + +class NameTagSettings: + def __init__(self): + self.x_offset: float = 0 + self.y_offset: float = 0 + self.z_offset: float = 6.5 + self.fontsize: int = 25 + self.text_rgba: Tuple[float, float, float, float] = (1, 1, 1, 1) + self.font_id: int = 0 + self.name_tag_handle: Any = None + self.name_tag_draw: Any = None + self.region: Optional[bpy.types.Region] = None + + +name_tag_settings = NameTagSettings() + + +def name_tag_draw(): + global name_tag_settings + + blf.size(name_tag_settings.font_id, name_tag_settings.fontsize) + blf.color(name_tag_settings.font_id, *name_tag_settings.text_rgba) + if name_tag_settings.region: + region = name_tag_settings.region + region_data = cast(bpy.types.RegionView3D, region.data) + else: + return + + dancer_names = state.dancer_names + for name in dancer_names: + dancer_obj = cast(bpy.types.Object, bpy.data.objects[name]) + dancer_location = dancer_obj.location + text_location_3d = Vector( + ( + dancer_location[0] + name_tag_settings.x_offset, + dancer_location[1] + name_tag_settings.y_offset, + dancer_location[2] + name_tag_settings.z_offset, + ) + ) + text_view_2d = location_3d_to_region_2d(region, region_data, text_location_3d) + text_w, text_h = cast( + Tuple[float, float], blf.dimensions(name_tag_settings.font_id, name) + ) + blf.position( + name_tag_settings.font_id, + text_view_2d[0] - text_w / 2, + text_view_2d[1] - text_h / 2, + 0, + ) + blf.draw(name_tag_settings.font_id, name) + + +def name_tag_handler(): + global name_tag_settings + if name_tag_settings.name_tag_draw is not None: + bpy.types.SpaceView3D.draw_handler_remove( + name_tag_settings.name_tag_handle, "WINDOW" + ) + name_tag_settings.name_tag_draw = bpy.types.SpaceView3D.draw_handler_add( + name_tag_draw, (), "WINDOW", "POST_PIXEL" + ) + + +def mount(): + global name_tag_settings + screen = cast(bpy.types.Screen, bpy.data.screens["Layout"]) + area = next( + area + for area in cast(List[bpy.types.Area], screen.areas) + if area.type == "VIEW_3D" + ) + region = next( + region + for region in cast(List[bpy.types.Region], area.regions) + if region.type == "WINDOW" + ) + name_tag_settings.region = region + name_tag_settings.name_tag_handle = bpy.types.SpaceView3D.draw_handler_add( + name_tag_handler, (), "WINDOW", "POST_PIXEL" + ) + print("Name tag mounted") + redraw_area({"VIEW_3D"}) + + +def unmount(): + global name_tag_settings + if name_tag_settings.name_tag_handle is not None: + bpy.types.SpaceView3D.draw_handler_remove( + name_tag_settings.name_tag_handle, "WINDOW" + ) + name_tag_settings.name_tag_handle = None diff --git a/editor-blender/operators/clipboard/__init__.py b/editor-blender/operators/clipboard/__init__.py index 1f3437442..9451d7c43 100644 --- a/editor-blender/operators/clipboard/__init__.py +++ b/editor-blender/operators/clipboard/__init__.py @@ -15,9 +15,6 @@ from ...core.utils.notification import notify from ...properties.types import LightType, ObjectType -default_keymaps = ["view3d.copybuffer", "view3d.pastebuffer"] - - # TODO: Add base model to dancer for varification @@ -255,91 +252,11 @@ def execute(self, context: bpy.types.Context): return {"FINISHED"} -def check_keymaps_exist( - keymaps: List[bpy.types.KeyMapItem], - names: List[str], - ctrl: List[int], - oskey: List[int], -) -> List[Optional[bpy.types.KeyMapItem]]: - wm = bpy.context.window_manager - kc_items = cast(Dict[str, bpy.types.KeyMap], wm.keyconfigs.default.keymaps)[ - "3D View" - ].keymap_items - kc_items = cast(List[bpy.types.KeyMapItem], kc_items) - - results: List[Optional[bpy.types.KeyMapItem]] = [None] * len(names) - - for keymap in keymaps: - for i in range(len(names)): - if ( - keymap.idname == names[i] - and keymap.ctrl == ctrl[i] - and keymap.oskey == oskey[i] - ): - results[i] = keymap - - return results - - def register(): bpy.utils.register_class(CopyOperator) bpy.utils.register_class(PasteOperator) - # Active keymaps and disable default keymaps - - wm = bpy.context.window_manager - km_items = cast(Dict[str, bpy.types.KeyMap], wm.keyconfigs.default.keymaps)[ - "3D View" - ].keymap_items - km_items = cast(List[bpy.types.KeyMapItem], km_items) - - for keymap in km_items: - if keymap.idname in default_keymaps: - keymap.active = False - - new_keymaps_config = ( - [ - "lightdance.copy", - "lightdance.copy", - "lightdance.paste", - "lightdance.paste", - ], - ["C", "C", "V", "V"], - [1, 0, 1, 0], - [0, 1, 0, 1], - ) - - new_keymaps = check_keymaps_exist( - km_items, - new_keymaps_config[0], - new_keymaps_config[2], - new_keymaps_config[3], - ) - - km_items = cast(bpy.types.KeyMapItems, km_items) - for i in range(len(new_keymaps)): - new_keymap = new_keymaps[i] - - if new_keymap is None: - new_keymaps[i] = km_items.new( - new_keymaps_config[0][i], - new_keymaps_config[1][i], - ctrl=new_keymaps_config[2][i], - oskey=new_keymaps_config[3][i], - value="PRESS", - ) - - else: - new_keymap.active = True - - global clipboard_keymaps - - clipboard_keymaps = cast(List[bpy.types.KeyMapItem], new_keymaps) - def unregister(): bpy.utils.unregister_class(CopyOperator) bpy.utils.unregister_class(PasteOperator) - - for keymap in clipboard_keymaps: - keymap.active = False