Files
blender-portable-repo/extensions/user_default/amzncharactertools/ops/Devices_FreshPlacement.py
T
2026-03-17 15:25:32 -06:00

196 lines
7.3 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():
# 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()