Merge branch 'alpha4-vrmconverter' into Alpha-4
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from ...core.logging_setup import logger
|
||||
|
||||
|
||||
class AvatarToolkit_OT_RemoveAllColliders(Operator):
|
||||
"""Remove all objects with 'collider' in their name"""
|
||||
bl_idname = "avatar_toolkit.remove_all_colliders"
|
||||
bl_label = "Remove All Colliders"
|
||||
bl_description = "Remove all objects that have 'collider' in their name"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
logger.info("Starting standalone collider removal")
|
||||
|
||||
# Store current mode and active object
|
||||
current_mode = bpy.context.mode
|
||||
original_active = bpy.context.view_layer.objects.active
|
||||
|
||||
# Switch to object mode
|
||||
if current_mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
try:
|
||||
# Find all collider objects
|
||||
collider_names = []
|
||||
all_objects = list(bpy.data.objects)
|
||||
|
||||
logger.info(f"Scanning {len(all_objects)} objects for colliders")
|
||||
|
||||
for obj in all_objects:
|
||||
if 'collider' in obj.name.lower():
|
||||
collider_names.append(obj.name)
|
||||
logger.info(f"Found collider: {obj.name}")
|
||||
|
||||
if not collider_names:
|
||||
self.report({'INFO'}, "No collider objects found")
|
||||
logger.info("No collider objects found")
|
||||
return {'FINISHED'}
|
||||
|
||||
logger.info(f"Found {len(collider_names)} collider objects to remove")
|
||||
self.report({'INFO'}, f"Found {len(collider_names)} collider objects")
|
||||
|
||||
# Remove each collider
|
||||
removed_count = 0
|
||||
failed_count = 0
|
||||
|
||||
for obj_name in collider_names:
|
||||
try:
|
||||
if obj_name in bpy.data.objects:
|
||||
obj = bpy.data.objects[obj_name]
|
||||
|
||||
# Deselect all objects first
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
# Select and make active
|
||||
obj.select_set(True)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
|
||||
# Delete the object
|
||||
bpy.ops.object.delete(use_global=False)
|
||||
|
||||
removed_count += 1
|
||||
logger.info(f"Removed collider: {obj_name}")
|
||||
|
||||
else:
|
||||
logger.debug(f"Object {obj_name} no longer exists")
|
||||
|
||||
except Exception as e:
|
||||
failed_count += 1
|
||||
logger.error(f"Failed to remove {obj_name}: {str(e)}")
|
||||
self.report({'WARNING'}, f"Failed to remove {obj_name}: {str(e)}")
|
||||
|
||||
# Report results
|
||||
if removed_count > 0:
|
||||
success_msg = f"Successfully removed {removed_count} collider objects"
|
||||
logger.info(success_msg)
|
||||
self.report({'INFO'}, success_msg)
|
||||
|
||||
if failed_count > 0:
|
||||
failure_msg = f"Failed to remove {failed_count} collider objects"
|
||||
logger.warning(failure_msg)
|
||||
self.report({'WARNING'}, failure_msg)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error during collider removal: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
self.report({'ERROR'}, error_msg)
|
||||
return {'CANCELLED'}
|
||||
|
||||
finally:
|
||||
# Restore original state
|
||||
try:
|
||||
if original_active and original_active.name in bpy.data.objects:
|
||||
bpy.context.view_layer.objects.active = original_active
|
||||
|
||||
if current_mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode=current_mode)
|
||||
except:
|
||||
pass
|
||||
|
||||
return {'FINISHED'}
|
||||
@@ -0,0 +1,88 @@
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from ...core.common import get_active_armature
|
||||
from ...core.translations import t
|
||||
from ...core.vrm_unity_converter import convert_vrm_to_unity, validate_unity_hierarchy
|
||||
from ...core.logging_setup import logger
|
||||
from ...core.armature_validation import validate_armature
|
||||
|
||||
|
||||
class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
|
||||
"""Convert VRM armature bone names to Unity humanoid format"""
|
||||
bl_idname = "avatar_toolkit.convert_vrm_to_unity"
|
||||
bl_label = "Convert VRM to Unity"
|
||||
bl_description = "Convert VRM armature bone names to Unity humanoid naming convention"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
armature = get_active_armature(context)
|
||||
return armature is not None
|
||||
|
||||
def execute(self, context):
|
||||
armature = get_active_armature(context)
|
||||
if not armature:
|
||||
logger.warning("No active armature found for VRM conversion")
|
||||
self.report({'ERROR'}, "No active armature selected")
|
||||
return {'CANCELLED'}
|
||||
|
||||
logger.info(f"Starting VRM to Unity conversion for armature: {armature.name}")
|
||||
|
||||
# Get conversion settings
|
||||
remove_colliders = context.scene.avatar_toolkit.vrm_remove_colliders
|
||||
remove_root = context.scene.avatar_toolkit.vrm_remove_root
|
||||
logger.info(f"Collider removal setting: {remove_colliders}")
|
||||
logger.info(f"Root bone removal setting: {remove_root}")
|
||||
|
||||
# Log all objects with 'collider' in name for debugging
|
||||
collider_objects = [obj.name for obj in bpy.data.objects if 'collider' in obj.name.lower()]
|
||||
if collider_objects:
|
||||
logger.info(f"Found {len(collider_objects)} objects with 'collider' in name:")
|
||||
for obj_name in collider_objects:
|
||||
logger.info(f" - {obj_name}")
|
||||
|
||||
success, messages, converted_count = convert_vrm_to_unity(armature, remove_colliders, remove_root)
|
||||
|
||||
if not success:
|
||||
logger.warning(f"VRM conversion failed: {messages}")
|
||||
for msg in messages:
|
||||
self.report({'WARNING'}, msg)
|
||||
return {'CANCELLED'}
|
||||
|
||||
logger.info(f"VRM conversion completed successfully. Converted {converted_count} bones")
|
||||
for msg in messages:
|
||||
self.report({'INFO'}, msg)
|
||||
|
||||
# Validate the converted armature
|
||||
try:
|
||||
is_valid, validation_messages = validate_unity_hierarchy(armature)
|
||||
|
||||
if is_valid:
|
||||
logger.info("Unity hierarchy validation passed")
|
||||
self.report({'INFO'}, "Unity hierarchy validation passed")
|
||||
else:
|
||||
logger.warning("Unity hierarchy validation found issues")
|
||||
self.report({'WARNING'}, "Conversion completed but hierarchy validation found issues:")
|
||||
for msg in validation_messages:
|
||||
self.report({'WARNING'}, msg)
|
||||
|
||||
try:
|
||||
armature_valid, armature_messages, _ = validate_armature(armature)
|
||||
if armature_valid:
|
||||
logger.info("Full armature validation passed")
|
||||
self.report({'INFO'}, "Armature passes standard validation")
|
||||
else:
|
||||
logger.info("Full armature validation found minor issues")
|
||||
# Don't report these as errors since the conversion was successful
|
||||
# Just log them for debugging
|
||||
for msg in armature_messages[:3]:
|
||||
logger.debug(f"Armature validation: {msg}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error during full armature validation: {str(e)}")
|
||||
# Don't fail the operation for validation errors
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during hierarchy validation: {str(e)}")
|
||||
self.report({'WARNING'}, f"Conversion completed but validation failed: {str(e)}")
|
||||
|
||||
return {'FINISHED'}
|
||||
Reference in New Issue
Block a user