import bpy import math import os try: from ..utils import get_addon_preferences except (ImportError, ValueError): # Fallback if import fails (e.g., when run as script) def get_addon_preferences(): test_names = ["bl_ext.vscode_development.AmazonCharacterTools", "amzncharactertools", "AmazonCharacterTools"] for addon_name in test_names: addon_prefs = bpy.context.preferences.addons.get(addon_name) if addon_prefs and hasattr(addon_prefs, 'preferences') and hasattr(addon_prefs.preferences, 'amzn_bsdf_materials_path'): return addon_prefs.preferences # Search all addons for addon_name in bpy.context.preferences.addons.keys(): addon_prefs = bpy.context.preferences.addons.get(addon_name) if addon_prefs and hasattr(addon_prefs, 'preferences') and hasattr(addon_prefs.preferences, 'amzn_bsdf_materials_path'): return addon_prefs.preferences return None def append_and_parent_device(): # First, find and rename the existing Device to Device-Old old_device = bpy.data.objects.get('Device') if old_device: print("Found existing Device, renaming to Device-Old") old_device.name = 'Device-Old' # Store the transforms of the old device old_location = old_device.location.copy() old_rotation = old_device.rotation_euler.copy() old_scale = old_device.scale.copy() old_parent = old_device.parent old_parent_type = old_device.parent_type old_parent_bone = old_device.parent_bone else: print("No existing Device found, using default transforms") # Default transforms if no old device exists old_location = (-0.030083, 0.002195, -0.000632) old_rotation = (math.radians(-89.493), math.radians(0.63873), math.radians(85.309)) old_scale = (1.0, 1.0, 1.0) # Get the active armature for default parenting active_armature = bpy.context.active_object if active_armature and active_armature.type == 'ARMATURE': old_parent = active_armature old_parent_type = 'BONE' old_parent_bone = 'DEF-forearm.L' else: old_parent = None old_parent_type = 'OBJECT' old_parent_bone = '' # Get path from addon preferences prefs = get_addon_preferences() if not prefs: print("Error: Could not access addon preferences") return device_blend_path = prefs.amzn_device_path if not device_blend_path or not os.path.exists(device_blend_path): print(f"Error: Device library path not set or file not found: {device_blend_path}") return # Append the Device object with bpy.data.libraries.load(device_blend_path, link=False) as (data_from, data_to): if 'Device' in data_from.objects: data_to.objects = ['Device'] # Link the new Device to the current scene if 'Device' in bpy.data.objects: device_obj = bpy.data.objects['Device'] bpy.context.collection.objects.link(device_obj) # Make it no longer an asset device_obj.asset_clear() # Apply the transforms from the old device device_obj.location = old_location device_obj.rotation_euler = old_rotation device_obj.scale = old_scale # Apply the parenting from the old device device_obj.parent = old_parent device_obj.parent_type = old_parent_type if old_parent_bone: device_obj.parent_bone = old_parent_bone print("Successfully appended new Device with old device transforms") else: print("Error: Device not found in blend file") return def rename_device_band(): # Find and rename arm-band or armband to device-band band_variants = ['arm-band', 'armband', 'Arm-band', 'Armband', 'ARM-BAND', 'ARMBAND'] for variant in band_variants: obj = bpy.data.objects.get(variant) if obj: print(f"Found {variant}, renaming to device-band") obj.name = 'device-band' return True print("No arm-band or armband object found to rename") return False def rename_geometry_data(): # Select all geometry objects (meshes, curves, etc.) bpy.ops.object.select_all(action='DESELECT') renamed_count = 0 skipped_count = 0 not_in_view_layer_count = 0 for obj in bpy.data.objects: if obj.type in ['MESH', 'CURVE', 'SURFACE', 'META']: # Check if object is in current view layer before selecting if obj.name in bpy.context.view_layer.objects: obj.select_set(True) else: not_in_view_layer_count += 1 skipped_count += 1 # Try to rename the data directly try: if obj.data and obj.data.name != obj.name: # Check if data is shared with other objects data_users = [o for o in bpy.data.objects if o.data == obj.data] if len(data_users) == 1: # Only one user, safe to rename obj.data.name = obj.name renamed_count += 1 else: skipped_count += 1 except AttributeError: skipped_count += 1 # Set the first selected object as active (for any remaining operations) selected_objects = [obj for obj in bpy.data.objects if obj.select_get()] if selected_objects: bpy.context.view_layer.objects.active = selected_objects[0] # Now run the operator on the selection bpy.ops.renaming.data_name_from_obj() print(f"Renamed {renamed_count} objects, skipped {skipped_count} objects (not in view layer: {not_in_view_layer_count})") # Execute all operations append_and_parent_device() rename_device_band() rename_geometry_data()