149 lines
5.9 KiB
Python
149 lines
5.9 KiB
Python
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() |