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(): # 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 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() print("Successfully appended Device") else: print("Error: Device not found in blend file") return # Set transforms before parenting device_obj.location = (-0.030083, 0.002195, -0.000632) device_obj.rotation_euler = ( math.radians(-89.493), math.radians(0.63873), math.radians(85.309) ) # Get the active armature active_armature = bpy.context.active_object if not active_armature or active_armature.type != 'ARMATURE': print("Error: No active armature selected") return # Find the DEF-forearm.L bone forearm_bone = active_armature.data.bones.get('DEF-forearm.L') if not forearm_bone: print("Error: Bone 'DEF-forearm.L' not found in active armature") return # Parent the device to the armature and the specific bone device_obj.parent = active_armature device_obj.parent_type = 'BONE' device_obj.parent_bone = 'DEF-forearm.L' print(f"Successfully parented 'Device' to {active_armature.name} bone 'DEF-forearm.L'") def append_and_parent_finger_scanner(): # Get path from addon preferences prefs = get_addon_preferences() if not prefs: print("Error: Could not access addon preferences") return scanner_blend_path = prefs.amzn_scanner_assets_path if not scanner_blend_path or not os.path.exists(scanner_blend_path): print(f"Error: Scanner assets library path not set or file not found: {scanner_blend_path}") return # Append the Finger-Scanner object with bpy.data.libraries.load(scanner_blend_path, link=False) as (data_from, data_to): if 'Finger-Scanner' in data_from.objects: data_to.objects = ['Finger-Scanner'] # Link the Finger-Scanner to the current scene if 'Finger-Scanner' in bpy.data.objects: scanner_obj = bpy.data.objects['Finger-Scanner'] bpy.context.collection.objects.link(scanner_obj) # Make it no longer an asset scanner_obj.asset_clear() print("Successfully appended Finger-Scanner") else: print("Error: Finger-Scanner not found in blend file") return # Set transforms before parenting (from latest screenshot) scanner_obj.location = (0.000367, -0.012914, 0.002702) scanner_obj.rotation_euler = ( math.radians(0), math.radians(-185), math.radians(-180) ) scanner_obj.scale = (0.493, 0.493, 0.493) # Get the active armature active_armature = bpy.context.active_object if not active_armature or active_armature.type != 'ARMATURE': print("Error: No active armature selected") return # Find the DEF-f_index.01.R bone finger_bone = active_armature.data.bones.get('DEF-f_index.01.R') if not finger_bone: print("Error: Bone 'DEF-f_index.01.R' not found in active armature") return # Parent the finger scanner to the armature and the specific bone scanner_obj.parent = active_armature scanner_obj.parent_type = 'BONE' scanner_obj.parent_bone = 'DEF-f_index.01.R' print(f"Successfully parented 'Finger-Scanner' to {active_armature.name} bone 'DEF-f_index.01.R'") 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() append_and_parent_finger_scanner() rename_device_band() rename_geometry_data()