Fixes and Improvements
- Improved typing in some areas. - Improved code readability in some areas. - Delete bone constraints would error out if the user is in edit mode, we now start in Object mode first. - Fixed Eye tracking Ajust string not being in the translation files. - There is now a selection box to select the mesh in the current active armature for viseme creation instead of the user having to select it in the 3D scene. - Viseme preview mode won't allow you to start it if your in a other mode, you need to be in Object mode now. - Combine Materials won't allow you to start it if your in a other mode, you need to be in Object mode now. - Added Japanese and Korean UI Languages.
This commit is contained in:
+48
-42
@@ -1,6 +1,6 @@
|
||||
import bpy
|
||||
from typing import Set
|
||||
from bpy.types import Panel, Context, UILayout, Operator
|
||||
from typing import Set, List, Tuple, Any
|
||||
from bpy.types import Panel, Context, UILayout, Operator, Event, WindowManager
|
||||
from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
|
||||
from ..core.translations import t
|
||||
from ..core.common import (
|
||||
@@ -11,10 +11,11 @@ from ..core.common import (
|
||||
)
|
||||
|
||||
class AvatarToolkit_OT_SearchMergeArmatureInto(Operator):
|
||||
bl_idname = "avatar_toolkit.search_merge_armature_into"
|
||||
bl_label = ""
|
||||
bl_description = t('MergeArmature.into_search_desc')
|
||||
bl_property = "search_merge_armature_into_enum"
|
||||
"""Search operator for selecting target armature to merge into"""
|
||||
bl_idname: str = "avatar_toolkit.search_merge_armature_into"
|
||||
bl_label: str = ""
|
||||
bl_description: str = t('MergeArmature.into_search_desc')
|
||||
bl_property: str = "search_merge_armature_into_enum"
|
||||
|
||||
search_merge_armature_into_enum: bpy.props.EnumProperty(
|
||||
name=t('MergeArmature.into'),
|
||||
@@ -22,19 +23,20 @@ class AvatarToolkit_OT_SearchMergeArmatureInto(Operator):
|
||||
items=get_armature_list
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
context.scene.avatar_toolkit.merge_armature_into = self.search_merge_armature_into_enum
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
def invoke(self, context: Context, event: Event) -> Set[str]:
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_SearchMergeArmature(Operator):
|
||||
bl_idname = "avatar_toolkit.search_merge_armature"
|
||||
bl_label = ""
|
||||
bl_description = t('MergeArmature.from_search_desc')
|
||||
bl_property = "search_merge_armature_enum"
|
||||
"""Search operator for selecting source armature to merge from"""
|
||||
bl_idname: str = "avatar_toolkit.search_merge_armature"
|
||||
bl_label: str = ""
|
||||
bl_description: str = t('MergeArmature.from_search_desc')
|
||||
bl_property: str = "search_merge_armature_enum"
|
||||
|
||||
search_merge_armature_enum: bpy.props.EnumProperty(
|
||||
name=t('MergeArmature.from'),
|
||||
@@ -42,44 +44,46 @@ class AvatarToolkit_OT_SearchMergeArmature(Operator):
|
||||
items=get_armature_list
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
context.scene.avatar_toolkit.merge_armature = self.search_merge_armature_enum
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
def invoke(self, context: Context, event: Event) -> Set[str]:
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_SearchAttachMesh(Operator):
|
||||
bl_idname = "avatar_toolkit.search_attach_mesh"
|
||||
bl_label = ""
|
||||
bl_description = t('AttachMesh.search_desc')
|
||||
bl_property = "search_attach_mesh_enum"
|
||||
"""Search operator for selecting mesh to attach to armature"""
|
||||
bl_idname: str = "avatar_toolkit.search_attach_mesh"
|
||||
bl_label: str = ""
|
||||
bl_description: str = t('AttachMesh.search_desc')
|
||||
bl_property: str = "search_attach_mesh_enum"
|
||||
|
||||
search_attach_mesh_enum: bpy.props.EnumProperty(
|
||||
name=t('AttachMesh.select'),
|
||||
description=t('AttachMesh.select_desc'),
|
||||
items=lambda self, context: [
|
||||
(obj.name, obj.name, "")
|
||||
(obj.name, obj.name, "")
|
||||
for obj in bpy.data.objects
|
||||
if obj.type == 'MESH'
|
||||
and not any(mod.type == 'ARMATURE' for mod in obj.modifiers)
|
||||
]
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
context.scene.avatar_toolkit.attach_mesh = self.search_attach_mesh_enum
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
def invoke(self, context: Context, event: Event) -> Set[str]:
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_SearchAttachBone(Operator):
|
||||
bl_idname = "avatar_toolkit.search_attach_bone"
|
||||
bl_label = ""
|
||||
bl_description = t('AttachBone.search_desc')
|
||||
bl_property = "search_attach_bone_enum"
|
||||
"""Search operator for selecting bone to attach mesh to"""
|
||||
bl_idname: str = "avatar_toolkit.search_attach_bone"
|
||||
bl_label: str = ""
|
||||
bl_description: str = t('AttachBone.search_desc')
|
||||
bl_property: str = "search_attach_bone_enum"
|
||||
|
||||
search_attach_bone_enum: bpy.props.EnumProperty(
|
||||
name=t('AttachBone.select'),
|
||||
@@ -90,26 +94,27 @@ class AvatarToolkit_OT_SearchAttachBone(Operator):
|
||||
] if get_active_armature(context) else []
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
context.scene.avatar_toolkit.attach_bone = self.search_attach_bone_enum
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
def invoke(self, context: Context, event: Event) -> Set[str]:
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolKit_PT_CustomPanel(Panel):
|
||||
"""Panel containing tools for custom avatar creation and merging"""
|
||||
bl_label = t('CustomPanel.label')
|
||||
bl_idname = "VIEW3D_PT_avatar_toolkit_custom"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = CATEGORY_NAME
|
||||
bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
|
||||
bl_order = 4
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_label: str = t('CustomPanel.label')
|
||||
bl_idname: str = "VIEW3D_PT_avatar_toolkit_custom"
|
||||
bl_space_type: str = 'VIEW_3D'
|
||||
bl_region_type: str = 'UI'
|
||||
bl_category: str = CATEGORY_NAME
|
||||
bl_parent_id: str = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
|
||||
bl_order: int = 4
|
||||
bl_options: Set[str] = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context: Context) -> None:
|
||||
"""Draw the custom avatar panel UI"""
|
||||
layout: UILayout = self.layout
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
@@ -129,6 +134,7 @@ class AvatarToolKit_PT_CustomPanel(Panel):
|
||||
self.draw_mesh_tools(layout, context)
|
||||
|
||||
def draw_armature_tools(self, layout: UILayout, context: Context) -> None:
|
||||
"""Draw the armature merging tools section"""
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
# Merge Settings Box
|
||||
@@ -148,13 +154,13 @@ class AvatarToolKit_PT_CustomPanel(Panel):
|
||||
col.separator(factor=0.5)
|
||||
|
||||
# Group related options together
|
||||
transform_col = col.column(align=True)
|
||||
transform_col: UILayout = col.column(align=True)
|
||||
transform_col.prop(toolkit, "merge_all_bones")
|
||||
transform_col.prop(toolkit, "apply_transforms")
|
||||
|
||||
col.separator(factor=0.5)
|
||||
|
||||
cleanup_col = col.column(align=True)
|
||||
cleanup_col: UILayout = col.column(align=True)
|
||||
cleanup_col.prop(toolkit, "join_meshes")
|
||||
cleanup_col.prop(toolkit, "remove_zero_weights")
|
||||
cleanup_col.prop(toolkit, "cleanup_shape_keys")
|
||||
@@ -178,12 +184,13 @@ class AvatarToolKit_PT_CustomPanel(Panel):
|
||||
|
||||
# Merge button with emphasis
|
||||
merge_box: UILayout = layout.box()
|
||||
col = merge_box.column(align=True)
|
||||
row = col.row(align=True)
|
||||
col: UILayout = merge_box.column(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator("avatar_toolkit.merge_armatures", icon='ARMATURE_DATA')
|
||||
|
||||
def draw_mesh_tools(self, layout: UILayout, context: Context) -> None:
|
||||
"""Draw the mesh attachment tools section"""
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
# Mesh Tools Box
|
||||
@@ -220,8 +227,7 @@ class AvatarToolKit_PT_CustomPanel(Panel):
|
||||
|
||||
# Attach button with emphasis
|
||||
attach_box: UILayout = layout.box()
|
||||
col = attach_box.column(align=True)
|
||||
row = col.row(align=True)
|
||||
col: UILayout = attach_box.column(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator("avatar_toolkit.attach_mesh", icon='ARMATURE_DATA')
|
||||
|
||||
|
||||
+43
-40
@@ -1,6 +1,6 @@
|
||||
import bpy
|
||||
from typing import Set
|
||||
from bpy.types import Panel, Context, UILayout, Operator
|
||||
from bpy.types import Panel, Context, UILayout, Operator, Event, WindowManager
|
||||
from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
|
||||
from ..core.translations import t
|
||||
from ..core.common import get_active_armature, get_all_meshes
|
||||
@@ -20,32 +20,32 @@ from ..functions.eye_tracking import (
|
||||
|
||||
class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
"""Panel containing eye tracking setup and testing tools"""
|
||||
bl_label = t("EyeTracking.label")
|
||||
bl_idname = "VIEW3D_PT_avatar_toolkit_eye_tracking"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = CATEGORY_NAME
|
||||
bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
|
||||
bl_order = 6
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_label: str = t("EyeTracking.label")
|
||||
bl_idname: str = "VIEW3D_PT_avatar_toolkit_eye_tracking"
|
||||
bl_space_type: str = 'VIEW_3D'
|
||||
bl_region_type: str = 'UI'
|
||||
bl_category: str = CATEGORY_NAME
|
||||
bl_parent_id: str = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
|
||||
bl_order: int = 6
|
||||
bl_options: Set[str] = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context: Context) -> None:
|
||||
"""Draw the eye tracking panel interface"""
|
||||
layout = self.layout
|
||||
layout: UILayout = self.layout
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
# SDK Version Selection Box
|
||||
sdk_box = layout.box()
|
||||
col = sdk_box.column(align=True)
|
||||
sdk_box: UILayout = layout.box()
|
||||
col: UILayout = sdk_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.sdk_version"), icon='PRESET')
|
||||
col.separator(factor=0.5)
|
||||
row = col.row(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.prop(toolkit, "eye_tracking_type", expand=True)
|
||||
|
||||
if toolkit.eye_tracking_type == 'SDK2':
|
||||
# Mode Selection Box
|
||||
mode_box = layout.box()
|
||||
col = mode_box.column(align=True)
|
||||
mode_box: UILayout = layout.box()
|
||||
col: UILayout = mode_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.setup"), icon='TOOL_SETTINGS')
|
||||
col.separator(factor=0.5)
|
||||
col.prop(toolkit, "eye_mode", expand=True)
|
||||
@@ -59,11 +59,12 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
self.draw_av3_setup(context, layout)
|
||||
|
||||
def draw_av3_setup(self, context: Context, layout: UILayout) -> None:
|
||||
"""Draw the AV3 eye tracking setup interface"""
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
# Bone Setup Box
|
||||
bone_box = layout.box()
|
||||
col = bone_box.column(align=True)
|
||||
bone_box: UILayout = layout.box()
|
||||
col: UILayout = bone_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.bone_setup"), icon='BONE_DATA')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
@@ -76,16 +77,17 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
col.label(text=t("EyeTracking.no_armature"), icon='ERROR')
|
||||
|
||||
# Create Button
|
||||
row = layout.row(align=True)
|
||||
row: UILayout = layout.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator(CreateEyesAV3Button.bl_idname, icon='PLAY')
|
||||
|
||||
def draw_creation_mode(self, context: Context, layout: UILayout) -> None:
|
||||
"""Draw the eye tracking creation mode interface"""
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
# Bone Setup Box
|
||||
bone_box = layout.box()
|
||||
col = bone_box.column(align=True)
|
||||
bone_box: UILayout = layout.box()
|
||||
col: UILayout = bone_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.bone_setup"), icon='BONE_DATA')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
@@ -98,15 +100,15 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
col.label(text=t("EyeTracking.no_armature"), icon='ERROR')
|
||||
|
||||
# Mesh Setup Box
|
||||
mesh_box = layout.box()
|
||||
col = mesh_box.column(align=True)
|
||||
mesh_box: UILayout = layout.box()
|
||||
col: UILayout = mesh_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.mesh_setup"), icon='MESH_DATA')
|
||||
col.separator(factor=0.5)
|
||||
col.prop_search(toolkit, "mesh_name_eye", bpy.data, "objects", text="")
|
||||
|
||||
# Shape Key Setup Box
|
||||
shape_box = layout.box()
|
||||
col = shape_box.column(align=True)
|
||||
shape_box: UILayout = layout.box()
|
||||
col: UILayout = shape_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.shapekey_setup"), icon='SHAPEKEY_DATA')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
@@ -120,8 +122,8 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
col.label(text=t("EyeTracking.no_shapekeys"), icon='ERROR')
|
||||
|
||||
# Options Box
|
||||
options_box = layout.box()
|
||||
col = options_box.column(align=True)
|
||||
options_box: UILayout = layout.box()
|
||||
col: UILayout = options_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.options"), icon='SETTINGS')
|
||||
col.separator(factor=0.5)
|
||||
col.prop(toolkit, "disable_eye_blinking")
|
||||
@@ -130,26 +132,27 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
col.prop(toolkit, "eye_distance")
|
||||
|
||||
# Create Button
|
||||
row = layout.row(align=True)
|
||||
row: UILayout = layout.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator(CreateEyesSDK2Button.bl_idname, icon='PLAY')
|
||||
|
||||
def draw_testing_mode(self, context: Context, layout: UILayout) -> None:
|
||||
"""Draw the eye tracking testing mode interface"""
|
||||
toolkit = context.scene.avatar_toolkit
|
||||
|
||||
if context.mode != 'POSE':
|
||||
# Testing Start Box
|
||||
test_box = layout.box()
|
||||
col = test_box.column(align=True)
|
||||
test_box: UILayout = layout.box()
|
||||
col: UILayout = test_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.testing"), icon='PLAY')
|
||||
col.separator(factor=0.5)
|
||||
row = col.row(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator(StartTestingButton.bl_idname, icon='PLAY')
|
||||
else:
|
||||
# Eye Rotation Box
|
||||
rotation_box = layout.box()
|
||||
col = rotation_box.column(align=True)
|
||||
rotation_box: UILayout = layout.box()
|
||||
col: UILayout = rotation_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.rotation_controls"), icon='DRIVER_ROTATIONAL_DIFFERENCE')
|
||||
col.separator(factor=0.5)
|
||||
col.prop(toolkit, "eye_rotation_x", text=t("EyeTracking.rotation.x"))
|
||||
@@ -157,31 +160,31 @@ class AvatarToolKit_PT_EyeTrackingPanel(Panel):
|
||||
col.operator(ResetRotationButton.bl_idname, icon='LOOP_BACK')
|
||||
|
||||
# Eye Adjustment Box
|
||||
adjust_box = layout.box()
|
||||
col = adjust_box.column(align=True)
|
||||
adjust_box: UILayout = layout.box()
|
||||
col: UILayout = adjust_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.adjustments"), icon='MODIFIER')
|
||||
col.separator(factor=0.5)
|
||||
col.prop(toolkit, "eye_distance")
|
||||
col.operator(AdjustEyesButton.bl_idname, icon='CON_TRACKTO')
|
||||
|
||||
# Blinking Test Box
|
||||
blink_box = layout.box()
|
||||
col = blink_box.column(align=True)
|
||||
blink_box: UILayout = layout.box()
|
||||
col: UILayout = blink_box.column(align=True)
|
||||
col.label(text=t("EyeTracking.blink_testing"), icon='HIDE_OFF')
|
||||
col.separator(factor=0.5)
|
||||
row = col.row(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.prop(toolkit, "eye_blink_shape")
|
||||
row.operator(TestBlinking.bl_idname, icon='RESTRICT_VIEW_OFF')
|
||||
row = col.row(align=True)
|
||||
row: UILayout = col.row(align=True)
|
||||
row.prop(toolkit, "eye_lowerlid_shape")
|
||||
row.operator(TestLowerlid.bl_idname, icon='RESTRICT_VIEW_OFF')
|
||||
col.operator(ResetBlinkTest.bl_idname, icon='LOOP_BACK')
|
||||
|
||||
# Stop Testing Button
|
||||
row = layout.row(align=True)
|
||||
row: UILayout = layout.row(align=True)
|
||||
row.scale_y = 1.5
|
||||
row.operator(StopTestingButton.bl_idname, icon='PAUSE')
|
||||
|
||||
# Reset Button
|
||||
row = layout.row(align=True)
|
||||
row: UILayout = layout.row(align=True)
|
||||
row.operator(ResetEyeTrackingButton.bl_idname, icon='FILE_REFRESH')
|
||||
|
||||
+27
-12
@@ -1,6 +1,8 @@
|
||||
from bpy.types import Panel, Context, UILayout
|
||||
import bpy
|
||||
from bpy.types import Panel, Context, UILayout, Object, ShapeKey
|
||||
from ..core.translations import t
|
||||
from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
|
||||
from ..core.common import get_active_armature
|
||||
|
||||
class AvatarToolKit_PT_VisemesPanel(Panel):
|
||||
"""Panel containing viseme creation and preview tools"""
|
||||
@@ -11,26 +13,39 @@ class AvatarToolKit_PT_VisemesPanel(Panel):
|
||||
bl_category: str = CATEGORY_NAME
|
||||
bl_parent_id: str = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
|
||||
bl_order: int = 5
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_options: set[str] = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context: Context) -> None:
|
||||
"""Draw the visemes panel interface"""
|
||||
"""Draw the visemes panel interface with shape key selection and preview controls"""
|
||||
layout: UILayout = self.layout
|
||||
props = context.scene.avatar_toolkit
|
||||
|
||||
# Check for valid mesh with shape keys
|
||||
if not context.active_object or context.active_object.type != 'MESH' or not context.active_object.data.shape_keys:
|
||||
|
||||
# Mesh Selection Box
|
||||
mesh_box: UILayout = layout.box()
|
||||
col: UILayout = mesh_box.column(align=True)
|
||||
col.label(text=t("Visemes.mesh_select"), icon='OUTLINER_OB_MESH')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
armature = get_active_armature(context)
|
||||
if armature:
|
||||
col.prop_search(props, "viseme_mesh", bpy.data, "objects", text="")
|
||||
else:
|
||||
col.label(text=t("Visemes.no_armature"), icon='ERROR')
|
||||
|
||||
# Get selected mesh
|
||||
mesh_obj = bpy.data.objects.get(props.viseme_mesh)
|
||||
if not mesh_obj or not mesh_obj.data.shape_keys:
|
||||
layout.label(text=t("Visemes.no_shapekeys"))
|
||||
return
|
||||
|
||||
# Shape Key Selection Box
|
||||
|
||||
# Shape Key Selection Box
|
||||
shape_box: UILayout = layout.box()
|
||||
col: UILayout = shape_box.column(align=True)
|
||||
col.label(text=t("Visemes.shape_selection"), icon='SHAPEKEY_DATA')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
# Shape key selection with valid data
|
||||
shape_keys = context.active_object.data.shape_keys
|
||||
shape_keys: ShapeKey = mesh_obj.data.shape_keys
|
||||
col.prop_search(props, "mouth_a", shape_keys, "key_blocks", text=t("Visemes.mouth_a"))
|
||||
col.prop_search(props, "mouth_o", shape_keys, "key_blocks", text=t("Visemes.mouth_o"))
|
||||
col.prop_search(props, "mouth_ch", shape_keys, "key_blocks", text=t("Visemes.mouth_ch"))
|
||||
@@ -41,7 +56,7 @@ class AvatarToolKit_PT_VisemesPanel(Panel):
|
||||
|
||||
# Preview Box
|
||||
preview_box: UILayout = layout.box()
|
||||
col = preview_box.column(align=True)
|
||||
col: UILayout = preview_box.column(align=True)
|
||||
col.label(text=t("Visemes.preview_label"), icon='HIDE_OFF')
|
||||
col.separator(factor=0.5)
|
||||
|
||||
@@ -49,12 +64,12 @@ class AvatarToolKit_PT_VisemesPanel(Panel):
|
||||
col.prop(props, "viseme_preview_selection", text="")
|
||||
col.separator()
|
||||
|
||||
preview_text = t("Visemes.stop_preview") if props.viseme_preview_mode else t("Visemes.start_preview")
|
||||
preview_text: str = t("Visemes.stop_preview") if props.viseme_preview_mode else t("Visemes.start_preview")
|
||||
col.operator("avatar_toolkit.preview_visemes", text=preview_text, icon='HIDE_OFF')
|
||||
|
||||
# Create Box
|
||||
create_box: UILayout = layout.box()
|
||||
col = create_box.column(align=True)
|
||||
col: UILayout = create_box.column(align=True)
|
||||
col.label(text=t("Visemes.create_label"), icon='ADD')
|
||||
col.separator(factor=0.5)
|
||||
col.operator("avatar_toolkit.create_visemes", icon='ADD')
|
||||
|
||||
Reference in New Issue
Block a user