Merge branch 'Alpha-4' into alpha4-vrmconverter

This commit is contained in:
Yusarina
2025-08-09 15:47:30 +01:00
committed by GitHub
14 changed files with 3160 additions and 24 deletions
+47 -1
View File
@@ -8,6 +8,7 @@ from ...core.translations import t
import traceback
from ...core.common import (
get_all_meshes,
get_meshes_for_armature,
fix_zero_length_bones,
remove_unused_vertex_groups,
clear_unused_data_blocks,
@@ -28,10 +29,32 @@ class AvatarToolkit_OT_MergeArmature(bpy.types.Operator):
@classmethod
def poll(cls, context: Context) -> bool:
return len(get_all_meshes(context)) > 1
# Check if we have valid armature selections for merging
base_armature_name: str = context.scene.avatar_toolkit.merge_armature_into
merge_armature_name: str = context.scene.avatar_toolkit.merge_armature
if not base_armature_name or not merge_armature_name:
return False
base_armature: Optional[Object] = bpy.data.objects.get(base_armature_name)
merge_armature: Optional[Object] = bpy.data.objects.get(merge_armature_name)
return (base_armature is not None and
merge_armature is not None and
base_armature.type == 'ARMATURE' and
merge_armature.type == 'ARMATURE' and
base_armature != merge_armature)
def execute(self, context: Context) -> Set[str]:
try:
# Store original mode to restore later
original_mode: str = context.mode
logger.debug(f"Original mode: {original_mode}")
# Switch to object mode if not already
if context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')
wm = context.window_manager
wm.progress_begin(0, 100)
@@ -85,6 +108,18 @@ class AvatarToolkit_OT_MergeArmature(bpy.types.Operator):
merge_armature_obj = bpy.data.objects[merge_armature_name_stored]
restore_breaking_settings_armature(merge_armature_obj, data_breaking_merge)
# Restore original mode if it wasn't OBJECT
try:
if original_mode == 'EDIT_ARMATURE':
bpy.ops.object.mode_set(mode='EDIT')
elif original_mode == 'POSE':
bpy.ops.object.mode_set(mode='POSE')
elif original_mode != 'OBJECT':
logger.debug(f"Restoring to original mode: {original_mode}")
# For other modes, stay in object mode as it's safest
except Exception:
logger.warning(f"Could not restore original mode: {original_mode}")
self.report({'INFO'}, t('MergeArmature.success'))
return {'FINISHED'}
@@ -92,6 +127,17 @@ class AvatarToolkit_OT_MergeArmature(bpy.types.Operator):
except Exception as e:
logger.error(f"Error merging armatures: {str(e)}\n{traceback.format_exc()}")
self.report({'ERROR'}, traceback.format_exc())
# Try to restore original mode even on error
try:
if 'original_mode' in locals() and original_mode != 'OBJECT':
if original_mode == 'EDIT_ARMATURE':
bpy.ops.object.mode_set(mode='EDIT')
elif original_mode == 'POSE':
bpy.ops.object.mode_set(mode='POSE')
except Exception:
logger.warning("Could not restore mode after error")
return {'CANCELLED'}
def delete_rigidbodies_and_joints(armature: Object) -> None:
+4 -2
View File
@@ -119,8 +119,10 @@ class AvatarToolkit_OT_ExplodeMesh(Operator):
@classmethod
def poll(cls, context: Context) -> bool:
return context.view_layer.objects.active.type == "MESH" and len(context.view_layer.objects.selected) == 1
active_obj = context.view_layer.objects.active
return (active_obj is not None and
active_obj.type == "MESH" and
len(context.view_layer.objects.selected) == 1)
+1 -7
View File
@@ -55,12 +55,6 @@ class AvatarToolkit_OT_StandardizeArmature(Operator):
logger.info(f"Starting armature standardization for {armature.name}")
is_valid, _, _ = validate_armature(armature)
if is_valid:
logger.info("Armature already meets standards, no changes needed")
self.report({'INFO'}, t("Tools.standardize_already_valid"))
return {'FINISHED'}
original_mode: str = context.mode
logger.debug(f"Original mode: {original_mode}")
bpy.ops.object.mode_set(mode='OBJECT')
@@ -90,7 +84,7 @@ class AvatarToolkit_OT_StandardizeArmature(Operator):
logger.info(f"Fixed {fixed_scale} scale issues")
bpy.ops.object.mode_set(mode='OBJECT')
is_valid, messages, _ = validate_armature(armature)
is_valid, messages, _ = validate_armature(armature, override_mode='STRICT')
if is_valid:
logger.info("Armature successfully standardized")