From 5cad28a41bb42bca13700f69eee89f2570b2b63d Mon Sep 17 00:00:00 2001 From: 989onan Date: Wed, 2 Apr 2025 20:35:59 -0400 Subject: [PATCH] fix pointers fix pointers in operators to point to class bl_idname property --- core/common.py | 14 ++++++++ functions/custom_tools/armature_merging.py | 17 ++-------- functions/tools/bone_tools.py | 19 ++++++++++- functions/tools/uv_tools.py | 2 ++ functions/visemes.py | 4 +-- ui/atlas_materials_panel.py | 8 ++--- ui/custom_avatar_panel.py | 14 ++++---- ui/optimization_panel.py | 13 +++++--- ui/quick_access_panel.py | 17 ++++++---- ui/settings_panel.py | 5 +-- ui/tools_panel.py | 37 ++++++++++++++-------- ui/uv_panel.py | 3 +- ui/uv_tools.py | 8 +++-- ui/visemes_panel.py | 5 +-- 14 files changed, 103 insertions(+), 63 deletions(-) diff --git a/core/common.py b/core/common.py index 4190571..f26dd6c 100644 --- a/core/common.py +++ b/core/common.py @@ -495,6 +495,20 @@ def fix_zero_length_bones(armature: Object) -> None: bone.length = 0.001 bpy.ops.object.mode_set(mode='OBJECT') +def remove_unused_vertex_groups(mesh: Object) -> None: + """Remove vertex groups with no weights""" + for vg in mesh.vertex_groups: + has_weights: bool = False + for vert in mesh.data.vertices: + for group in vert.groups: + if group.group == vg.index and group.weight > 0.001: + has_weights = True + break + if has_weights: + break + if not has_weights: + mesh.vertex_groups.remove(vg) + def calculate_bone_orientation(mesh: Object, vertices: List[Any]) -> Tuple[Vector, float]: """Calculate optimal bone orientation based on mesh geometry""" if not vertices: diff --git a/functions/custom_tools/armature_merging.py b/functions/custom_tools/armature_merging.py index e9ddb25..7cd0807 100644 --- a/functions/custom_tools/armature_merging.py +++ b/functions/custom_tools/armature_merging.py @@ -7,6 +7,7 @@ from ...core.translations import t from ...core.common import ( get_all_meshes, fix_zero_length_bones, + remove_unused_vertex_groups, clear_unused_data_blocks, join_mesh_objects, remove_unused_shapekeys, @@ -174,7 +175,7 @@ def merge_armatures( merge_armature_data: bpy.types.Armature = merge_armature.data for bone in merge_armature_data.bones: original_parents[bone.name] = bone.parent.name if bone.parent else None - + # Switch to edit mode on merge armature and rename bones bpy.context.view_layer.objects.active = merge_armature bpy.ops.object.mode_set(mode='EDIT') @@ -377,20 +378,6 @@ def mix_vertex_groups(mesh: Object, vg_from_name: str, vg_to_name: str) -> None: vg_to.add(range(num_vertices), weights_combined.tolist(), 'REPLACE') mesh.vertex_groups.remove(vg_from) -def remove_unused_vertex_groups(mesh: Object) -> None: - """Remove vertex groups with no weights""" - for vg in mesh.vertex_groups: - has_weights: bool = False - for vert in mesh.data.vertices: - for group in vert.groups: - if group.group == vg.index and group.weight > 0.001: - has_weights = True - break - if has_weights: - break - if not has_weights: - mesh.vertex_groups.remove(vg) - def apply_armature_to_mesh(armature: Object, mesh: Object) -> None: """Apply armature deformation to mesh""" armature_mod: ArmatureModifier = mesh.modifiers.new('PoseToRest', 'ARMATURE') diff --git a/functions/tools/bone_tools.py b/functions/tools/bone_tools.py index 78e6c72..966fe84 100644 --- a/functions/tools/bone_tools.py +++ b/functions/tools/bone_tools.py @@ -7,7 +7,8 @@ from ...core.common import ( get_active_armature, get_all_meshes, ProgressTracker, - restore_bone_transforms + restore_bone_transforms, + remove_unused_vertex_groups, ) from ...core.armature_validation import validate_armature, validate_bone_hierarchy @@ -262,6 +263,22 @@ class AvatarToolKit_OT_RemoveZeroWeightBones(Operator): self.report({'INFO'}, t("Tools.clean_weights_success", count=removed_count)) return {'FINISHED'} +class AvatarToolKit_OT_RemoveZeroWeightVertexGroups(Operator): + """Operator to remove vertex groups with no weights""" + bl_idname = "avatar_toolkit.clean_vertex_groups" + bl_label = t("Tools.clean_vertex_groups") + bl_description = t("Tools.clean_vertex_groups_desc") + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context: Context) -> set[str]: + meshes: list[bpy.types.Object] = get_all_meshes(context) + + for mesh_obj in meshes: + remove_unused_vertex_groups(mesh_obj) + + return {'FINISHED'} + + class AvatarToolKit_OT_RemoveSelectedBones(Operator): """Operator to remove selected bones from the zero weight bones list""" bl_idname = "avatar_toolkit.remove_selected_bones" diff --git a/functions/tools/uv_tools.py b/functions/tools/uv_tools.py index e7dcc5d..6002d73 100644 --- a/functions/tools/uv_tools.py +++ b/functions/tools/uv_tools.py @@ -31,6 +31,8 @@ class AvatarToolkit_OT_AlignUVEdgesToTarget(Operator): return False if not context.space_data: return False + if not hasattr(context.space_data, "show_uvedit"): + return False if not context.space_data.show_uvedit: return False if context.scene.tool_settings.use_uv_select_sync: diff --git a/functions/visemes.py b/functions/visemes.py index da332bc..889306a 100644 --- a/functions/visemes.py +++ b/functions/visemes.py @@ -124,7 +124,7 @@ class VisemePreview: cls._preview_shapes = None cls._mesh_name = "" -class ATOOLKIT_OT_preview_visemes(Operator): +class AvatarToolkit_OT_PreviewVisemes(Operator): """Operator for previewing viseme shapes in real-time""" bl_idname: str = "avatar_toolkit.preview_visemes" bl_label: str = t("Visemes.preview_label") @@ -181,7 +181,7 @@ def validate_deformation(mesh, mix_data): mesh_size = max(mesh.dimensions) return max_deform < (mesh_size * 0.4) -class ATOOLKIT_OT_create_visemes(Operator): +class AvatarToolkit_OT_CreateVisemes(Operator): """Operator for generating VRChat-compatible viseme shape keys""" bl_idname: str = "avatar_toolkit.create_visemes" bl_label: str = t("Visemes.create_label") diff --git a/ui/atlas_materials_panel.py b/ui/atlas_materials_panel.py index 8f8c056..35e6316 100644 --- a/ui/atlas_materials_panel.py +++ b/ui/atlas_materials_panel.py @@ -97,14 +97,14 @@ class AvatarToolKit_UL_MaterialTextureAtlasProperties(UIList): row = layout.row(align=True) row.scale_y = 1.2 - row.operator("avatar_toolkit.select_all_materials", text="", icon='CHECKBOX_HLT', + row.operator(AvatarToolKit_OT_SelectAllMaterials.bl_idname, text="", icon='CHECKBOX_HLT', emboss=True).tooltip = t("TextureAtlas.select_all_tooltip") - row.operator("avatar_toolkit.select_none_materials", text="", icon='CHECKBOX_DEHLT', + row.operator(AvatarToolKit_OT_SelectNoneMaterials.bl_idname, text="", icon='CHECKBOX_DEHLT', emboss=True).tooltip = t("TextureAtlas.select_none_tooltip") row.separator(factor=0.5) - row.operator("avatar_toolkit.expand_all_materials", text="", icon='DISCLOSURE_TRI_DOWN', + row.operator(AvatarToolKit_OT_ExpandAllMaterials.bl_idname, text="", icon='DISCLOSURE_TRI_DOWN', emboss=True).tooltip = t("TextureAtlas.expand_all_tooltip") - row.operator("avatar_toolkit.collapse_all_materials", text="", icon='DISCLOSURE_TRI_RIGHT', + row.operator(AvatarToolKit_OT_CollapseAllMaterials.bl_idname, text="", icon='DISCLOSURE_TRI_RIGHT', emboss=True).tooltip = t("TextureAtlas.collapse_all_tooltip") row.separator(factor=1.0) diff --git a/ui/custom_avatar_panel.py b/ui/custom_avatar_panel.py index 3ebf160..451c88d 100644 --- a/ui/custom_avatar_panel.py +++ b/ui/custom_avatar_panel.py @@ -175,12 +175,12 @@ class AvatarToolKit_PT_CustomPanel(Panel): # Armature selection with better alignment row: UILayout = col.row(align=True) row.label(text=t('MergeArmature.into'), icon='ARMATURE_DATA') - row.operator("avatar_toolkit.search_merge_armature_into", + row.operator(AvatarToolkit_OT_SearchMergeArmatureInto.bl_idname, text=toolkit.merge_armature_into) row: UILayout = col.row(align=True) row.label(text=t('MergeArmature.from'), icon='ARMATURE_DATA') - row.operator("avatar_toolkit.search_merge_armature", + row.operator(AvatarToolkit_OT_SearchMergeArmature.bl_idname, text=toolkit.merge_armature) # Merge button with emphasis @@ -188,7 +188,7 @@ class AvatarToolKit_PT_CustomPanel(Panel): 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') + row.operator(AvatarToolkit_OT_MergeArmature.bl_idname, icon='ARMATURE_DATA') def draw_mesh_tools(self, layout: UILayout, context: Context) -> None: """Draw the mesh attachment tools section""" @@ -213,17 +213,17 @@ class AvatarToolKit_PT_CustomPanel(Panel): # Selection rows with icons and better alignment row: UILayout = col.row(align=True) row.label(text=t('CustomPanel.select_armature'), icon='ARMATURE_DATA') - row.operator("avatar_toolkit.search_merge_armature_into", + row.operator(AvatarToolkit_OT_SearchMergeArmatureInto.bl_idname, text=toolkit.merge_armature_into) row: UILayout = col.row(align=True) row.label(text=t('CustomPanel.select_mesh'), icon='MESH_DATA') - row.operator("avatar_toolkit.search_attach_mesh", + row.operator(AvatarToolkit_OT_SearchAttachMesh.bl_idname, text=toolkit.attach_mesh) row: UILayout = col.row(align=True) row.label(text=t('CustomPanel.select_bone'), icon='BONE_DATA') - row.operator("avatar_toolkit.search_attach_bone", + row.operator(AvatarToolkit_OT_SearchAttachBone.bl_idname, text=toolkit.attach_bone) # Attach button with emphasis @@ -231,4 +231,4 @@ class AvatarToolKit_PT_CustomPanel(Panel): 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') + row.operator(AvatarToolkit_OT_AttachMesh.bl_idname, icon='ARMATURE_DATA') diff --git a/ui/optimization_panel.py b/ui/optimization_panel.py index 57e9802..04eb8dc 100644 --- a/ui/optimization_panel.py +++ b/ui/optimization_panel.py @@ -3,6 +3,9 @@ from typing import Set from bpy.types import Panel, Context, UILayout, Operator from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME from ..core.translations import t +from ..functions.optimization.materials_tools import AvatarToolkit_OT_CombineMaterials +from ..functions.optimization.remove_doubles import AvatarToolkit_OT_RemoveDoubles,AvatarToolkit_OT_RemoveDoublesAdvanced +from ..functions.optimization.mesh_tools import AvatarToolkit_OT_JoinAllMeshes, AvatarToolkit_OT_JoinSelectedMeshes class AvatarToolKit_PT_OptimizationPanel(Panel): """Panel containing mesh and material optimization tools for avatar optimization""" @@ -26,7 +29,7 @@ class AvatarToolKit_PT_OptimizationPanel(Panel): col.separator(factor=0.5) # Material Operations - col.operator("avatar_toolkit.combine_materials", icon='MATERIAL') + col.operator(AvatarToolkit_OT_CombineMaterials.bl_idname, icon='MATERIAL') # Mesh Cleanup Box cleanup_box: UILayout = layout.box() @@ -36,8 +39,8 @@ class AvatarToolKit_PT_OptimizationPanel(Panel): # Remove Doubles Row row: UILayout = col.row(align=True) - row.operator("avatar_toolkit.remove_doubles", icon='MESH_DATA') - row.operator("avatar_toolkit.remove_doubles_advanced", icon='PREFERENCES') + row.operator(AvatarToolkit_OT_RemoveDoubles.bl_idname, icon='MESH_DATA') + row.operator(AvatarToolkit_OT_RemoveDoublesAdvanced.bl_idname, icon='PREFERENCES') # Join Meshes Box join_box: UILayout = layout.box() @@ -47,5 +50,5 @@ class AvatarToolKit_PT_OptimizationPanel(Panel): # Join Meshes Row row: UILayout = col.row(align=True) - row.operator("avatar_toolkit.join_all_meshes", icon='OBJECT_DATA') - row.operator("avatar_toolkit.join_selected_meshes", icon='RESTRICT_SELECT_OFF') + row.operator(AvatarToolkit_OT_JoinAllMeshes.bl_idname, icon='OBJECT_DATA') + row.operator(AvatarToolkit_OT_JoinSelectedMeshes.bl_idname, icon='RESTRICT_SELECT_OFF') diff --git a/ui/quick_access_panel.py b/ui/quick_access_panel.py index 59fbd6d..d0d6755 100644 --- a/ui/quick_access_panel.py +++ b/ui/quick_access_panel.py @@ -23,7 +23,10 @@ from ..functions.pose_mode import ( AvatarToolkit_OT_ApplyPoseAsShapekey, AvatarToolkit_OT_ApplyPoseAsRest ) -from ..core.armature_validation import validate_armature +from ..core.armature_validation import validate_armature, AvatarToolkit_OT_ValidateTPose +from ..core.importers.importer import AvatarToolKit_OT_Import +from ..core.resonite_utils import AvatarToolKit_OT_ExportResonite +from ..functions.tools.standardize_armature import AvatarToolkit_OT_StandardizeArmature class AvatarToolKit_OT_ExportFBX(Operator): """Export selected objects as FBX""" @@ -41,8 +44,8 @@ class AvatarToolKit_MT_ExportMenu(Menu): def draw(self, context: Context) -> None: layout: UILayout = self.layout - layout.operator("avatar_toolkit.export_fbx", text=t("QuickAccess.export_fbx")) - layout.operator("avatar_toolkit.export_resonite", text=t("QuickAccess.export_resonite")) + layout.operator(AvatarToolKit_OT_ExportFBX.bl_idname, text=t("QuickAccess.export_fbx")) + layout.operator(AvatarToolKit_OT_ExportResonite.bl_idname, text=t("QuickAccess.export_resonite")) class AvatarToolKit_OT_ExportMenu(Operator): """Open the export menu""" @@ -170,7 +173,7 @@ class AvatarToolKit_PT_QuickAccessPanel(Panel): col = pose_box.column(align=True) col.label(text=t("Validation.tpose.label"), icon='ARMATURE_DATA') col.separator(factor=0.5) - col.operator("avatar_toolkit.validate_tpose", icon='CHECKMARK') + col.operator(AvatarToolkit_OT_ValidateTPose.bl_idname, icon='CHECKMARK') if props.show_tpose_validation: validation_box = col.box() @@ -207,7 +210,7 @@ class AvatarToolKit_PT_QuickAccessPanel(Panel): # Add standardize button standardize_box = info_box.box() - standardize_box.operator("avatar_toolkit.standardize_armature", + standardize_box.operator(AvatarToolkit_OT_StandardizeArmature.bl_idname, text=t("QuickAccess.standardize_armature"), icon='MODIFIER') @@ -247,5 +250,5 @@ class AvatarToolKit_PT_QuickAccessPanel(Panel): # Import/Export Buttons button_row: UILayout = col.row(align=True) button_row.scale_y = 1.5 - button_row.operator("avatar_toolkit.import", text=t("QuickAccess.import"), icon='IMPORT') - button_row.operator("avatar_toolkit.export", text=t("QuickAccess.export"), icon='EXPORT') + button_row.operator(AvatarToolKit_OT_Import.bl_idname, text=t("QuickAccess.import"), icon='IMPORT') + button_row.operator(AvatarToolKit_OT_ExportMenu.bl_idname, text=t("QuickAccess.export"), icon='EXPORT') diff --git a/ui/settings_panel.py b/ui/settings_panel.py index 6e7c322..0036ef6 100644 --- a/ui/settings_panel.py +++ b/ui/settings_panel.py @@ -10,6 +10,7 @@ from bpy.types import ( ) from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME from ..core.translations import t, get_languages_list +from ..core.armature_validation import AvatarToolkit_OT_HighlightProblemBones, AvatarToolkit_OT_ClearBoneHighlighting class AvatarToolkit_OT_TranslationRestartPopup(Operator): """Popup dialog shown after language change to inform about restart requirement""" @@ -71,9 +72,9 @@ class AvatarToolKit_PT_SettingsPanel(Panel): col.separator() col.prop(props, "highlight_problem_bones") if props.highlight_problem_bones: - col.operator("avatar_toolkit.highlight_problem_bones", icon='COLOR') + col.operator(AvatarToolkit_OT_HighlightProblemBones.bl_idname, icon='COLOR') else: - col.operator("avatar_toolkit.clear_bone_highlighting", icon='X') + col.operator(AvatarToolkit_OT_ClearBoneHighlighting.bl_idname, icon='X') # Debug Settings debug_box = layout.box() diff --git a/ui/tools_panel.py b/ui/tools_panel.py index 7fbfe71..2d2b625 100644 --- a/ui/tools_panel.py +++ b/ui/tools_panel.py @@ -4,6 +4,15 @@ from bpy.types import Panel, Context, UILayout, Operator, UIList from .main_panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME from ..core.translations import t +from ..core.resonite_utils import AvatarToolkit_OT_ConvertResonite +from ..functions.tools.mesh_separation import AvatarToolKit_OT_SeparateByLooseParts, AvatarToolKit_OT_SeparateByMaterials +from ..functions.tools.additional_tools import AvatarToolkit_OT_ApplyTransforms, AvatarToolkit_OT_CleanShapekeys +from ..functions.tools.bone_tools import AvatarToolKit_OT_CreateDigitigradeLegs, AvatarToolKit_OT_DeleteBoneConstraints, AvatarToolKit_OT_RemoveSelectedBones, AvatarToolKit_OT_RemoveZeroWeightBones, AvatarToolKit_OT_RemoveZeroWeightVertexGroups +from ..functions.tools.standardize_armature import AvatarToolkit_OT_StandardizeArmature +from ..functions.tools.merge_tools import AvatarToolkit_OT_MergeToActive, AvatarToolkit_OT_MergeToParent, AvatarToolkit_OT_ConnectBones +from ..functions.tools.rigify_converter import AvatarToolkit_OT_ConvertRigifyToUnity + + class AVATAR_TOOLKIT_UL_ZeroWeightBones(UIList): """UI List for displaying zero weight bones with selection options""" def draw_item(self, context, layout, data, item, icon, active_data, active_propname): @@ -37,7 +46,7 @@ class AvatarToolKit_PT_ToolsPanel(Panel): col: UILayout = tools_box.column(align=True) col.label(text=t("Tools.general_title"), icon='TOOL_SETTINGS') col.separator(factor=0.5) - col.operator("avatar_toolkit.convert_resonite", text=t("Tools.convert_resonite"), icon='EXPORT') + col.operator(AvatarToolkit_OT_ConvertResonite.bl_idname, text=t("Tools.convert_resonite"), icon='EXPORT') # Separation Tools sep_box: UILayout = layout.box() @@ -45,22 +54,22 @@ class AvatarToolKit_PT_ToolsPanel(Panel): col.label(text=t("Tools.separate_title"), icon='MOD_EXPLODE') col.separator(factor=0.5) row: UILayout = col.row(align=True) - row.operator("avatar_toolkit.separate_materials", text=t("Tools.separate_materials"), icon='MATERIAL') - row.operator("avatar_toolkit.separate_loose", text=t("Tools.separate_loose"), icon='MESH_DATA') + row.operator(AvatarToolKit_OT_SeparateByMaterials.bl_idname, text=t("Tools.separate_materials"), icon='MATERIAL') + row.operator(AvatarToolKit_OT_SeparateByLooseParts.bl_idname, text=t("Tools.separate_loose"), icon='MESH_DATA') # Bone Tools bone_box: UILayout = layout.box() col = bone_box.column(align=True) col.label(text=t("Tools.bone_title"), icon='BONE_DATA') col.separator(factor=0.5) - col.operator("avatar_toolkit.create_digitigrade", text=t("Tools.create_digitigrade"), icon='BONE_DATA') + col.operator(AvatarToolKit_OT_CreateDigitigradeLegs.bl_idname, text=t("Tools.create_digitigrade"), icon='BONE_DATA') # Standardization Tools standardize_box: UILayout = bone_box.box() col = standardize_box.column(align=True) col.label(text=t("Tools.standardize_title"), icon='OUTLINER_OB_ARMATURE') col.separator(factor=0.5) - col.operator("avatar_toolkit.standardize_armature", icon='CHECKMARK') + col.operator(AvatarToolkit_OT_StandardizeArmature.bl_idname, icon='CHECKMARK') # Weight Tools weight_box: UILayout = bone_box.box() @@ -78,12 +87,12 @@ class AvatarToolKit_PT_ToolsPanel(Panel): toolkit, "zero_weight_bones_index") col = box.column(align=True) - col.operator("avatar_toolkit.remove_selected_bones", + col.operator(AvatarToolKit_OT_RemoveSelectedBones.bl_idname, text=t("Tools.remove_selected_bones")) row = col.row(align=True) - row.operator("avatar_toolkit.clean_weights", text=t("Tools.clean_weights"), icon='GROUP_BONE') - row.operator("avatar_toolkit.clean_constraints", text=t("Tools.clean_constraints"), icon='CONSTRAINT_BONE') + row.operator(AvatarToolKit_OT_RemoveZeroWeightBones.bl_idname, text=t("Tools.clean_weights"), icon='GROUP_BONE') + row.operator(AvatarToolKit_OT_DeleteBoneConstraints.bl_idname, text=t("Tools.clean_constraints"), icon='CONSTRAINT_BONE') # Merge Tools merge_box: UILayout = layout.box() @@ -91,22 +100,22 @@ class AvatarToolKit_PT_ToolsPanel(Panel): col.label(text=t("Tools.merge_title"), icon='AUTOMERGE_ON') col.separator(factor=0.5) row = col.row(align=True) - row.operator("avatar_toolkit.merge_to_active", text=t("Tools.merge_to_active"), icon='BONE_DATA') - row.operator("avatar_toolkit.merge_to_parent", text=t("Tools.merge_to_parent"), icon='BONE_DATA') - col.operator("avatar_toolkit.connect_bones", text=t("Tools.connect_bones"), icon='BONE_DATA') + row.operator(AvatarToolkit_OT_MergeToActive.bl_idname, text=t("Tools.merge_to_active"), icon='BONE_DATA') + row.operator(AvatarToolkit_OT_MergeToParent.bl_idname, text=t("Tools.merge_to_parent"), icon='BONE_DATA') + col.operator(AvatarToolkit_OT_ConnectBones.bl_idname, text=t("Tools.connect_bones"), icon='BONE_DATA') # Additional Tools extra_box: UILayout = layout.box() col = extra_box.column(align=True) col.label(text=t("Tools.additional_title"), icon='TOOL_SETTINGS') col.separator(factor=0.5) - col.operator("avatar_toolkit.apply_transforms", text=t("Tools.apply_transforms"), icon='OBJECT_DATA') - col.operator("avatar_toolkit.clean_shapekeys", text=t("Tools.clean_shapekeys"), icon='SHAPEKEY_DATA') + col.operator(AvatarToolkit_OT_ApplyTransforms.bl_idname, text=t("Tools.apply_transforms"), icon='OBJECT_DATA') + col.operator(AvatarToolkit_OT_CleanShapekeys.bl_idname, text=t("Tools.clean_shapekeys"), icon='SHAPEKEY_DATA') # Rigify Tools rigify_box: UILayout = layout.box() col = rigify_box.column(align=True) col.label(text=t("Tools.rigify_title"), icon='ARMATURE_DATA') col.separator(factor=0.5) - col.operator("avatar_toolkit.convert_rigify_to_unity", icon='ARMATURE_DATA') + col.operator(AvatarToolkit_OT_ConvertRigifyToUnity.bl_idname, icon='ARMATURE_DATA') col.prop(context.scene.avatar_toolkit, "merge_twist_bones") diff --git a/ui/uv_panel.py b/ui/uv_panel.py index d5499b6..b7d5596 100644 --- a/ui/uv_panel.py +++ b/ui/uv_panel.py @@ -1,6 +1,7 @@ import bpy from bpy.types import Panel, Context, UILayout from ..core.translations import t +from .main_panel import CATEGORY_NAME class AvatarToolKit_PT_UVPanel(Panel): """Main UV Tools panel for Avatar Toolkit""" @@ -8,7 +9,7 @@ class AvatarToolKit_PT_UVPanel(Panel): bl_idname = "OBJECT_PT_avatar_toolkit_uv_main" bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'UI' - bl_category = "Avatar Toolkit" + bl_category = CATEGORY_NAME def draw(self, context: Context) -> None: layout: UILayout = self.layout diff --git a/ui/uv_tools.py b/ui/uv_tools.py index ecb258e..4bb60eb 100644 --- a/ui/uv_tools.py +++ b/ui/uv_tools.py @@ -1,6 +1,8 @@ import bpy from bpy.types import Panel, Context, UILayout from ..core.translations import t +from ..functions.tools.uv_tools import AvatarToolkit_OT_AlignUVEdgesToTarget +from .uv_panel import AvatarToolKit_PT_UVPanel class AvatarToolKit_PT_UVTools(Panel): """UV Tools panel containing UV manipulation operators""" @@ -8,8 +10,8 @@ class AvatarToolKit_PT_UVTools(Panel): bl_idname = "OBJECT_PT_avatar_toolkit_uv_tools" bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'UI' - bl_category = "Avatar Toolkit" - bl_parent_id = "OBJECT_PT_avatar_toolkit_uv_main" + bl_category = "UV Tools" + bl_parent_id = AvatarToolKit_PT_UVPanel.bl_idname bl_order = 3 bl_options = {'DEFAULT_CLOSED'} @@ -22,6 +24,6 @@ class AvatarToolKit_PT_UVTools(Panel): col.separator(factor=0.5) row: UILayout = col.row(align=True) - row.operator("avatar_toolkit.align_uv_edges_to_target", + row.operator(AvatarToolkit_OT_AlignUVEdgesToTarget.bl_idname, text=t("UVTools.align_edges"), icon='GP_MULTIFRAME_EDITING') diff --git a/ui/visemes_panel.py b/ui/visemes_panel.py index 0ebb472..11d2a30 100644 --- a/ui/visemes_panel.py +++ b/ui/visemes_panel.py @@ -3,6 +3,7 @@ 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 +from ..functions.visemes import AvatarToolkit_OT_PreviewVisemes, AvatarToolkit_OT_CreateVisemes class AvatarToolKit_PT_VisemesPanel(Panel): """Panel containing viseme creation and preview tools""" @@ -65,11 +66,11 @@ class AvatarToolKit_PT_VisemesPanel(Panel): col.separator() 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') + col.operator(AvatarToolkit_OT_PreviewVisemes.bl_idname, text=preview_text, icon='HIDE_OFF') # Create Box create_box: UILayout = layout.box() 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') + col.operator(AvatarToolkit_OT_CreateVisemes.bl_idname, icon='ADD')