Files
blender-portable-repo/extensions/user_default/amzncharactertools/ops/custom_vis.py
T
Raincloud 9fcddeca02 work
update amznchartools
2026-03-18 18:03:21 -06:00

196 lines
7.4 KiB
Python

import bpy
print("=== Custom Visibility Script Starting ===")
print(f"Blender version: {bpy.app.version_string}")
# Check if auto-execution is enabled for drivers
print(f"Auto-execution enabled: {bpy.context.preferences.filepaths.use_scripts_auto_execute}")
if not bpy.context.preferences.filepaths.use_scripts_auto_execute:
print("WARNING: Auto-execution is disabled - drivers may not work properly")
# Get the active object and selected objects
active_obj = bpy.context.active_object
selected_objects = bpy.context.selected_objects
if not active_obj:
print("✗ ERROR: No active object selected")
print("Please select an object and run the script again")
raise Exception("No active object - script aborted")
print(f"Found active object: {active_obj.name}")
print(f"Found {len(selected_objects)} selected object(s): {[obj.name for obj in selected_objects]}")
# Find the armature object in the scene
armature_obj = None
# First, check if the active object is an armature
if active_obj and active_obj.type == 'ARMATURE':
armature_obj = active_obj
print(f"Using active armature: {armature_obj.name}")
else:
# Look for an armature that has a Settings bone
print("Active object is not an armature, searching for armature with Settings bone...")
for obj in bpy.data.objects:
if obj.type == 'ARMATURE' and 'Settings' in obj.pose.bones:
armature_obj = obj
print(f"Found armature with Settings bone: {armature_obj.name}")
break
# If still no armature found, just use the first armature
if not armature_obj:
for obj in bpy.data.objects:
if obj.type == 'ARMATURE':
armature_obj = obj
print(f"Using first available armature: {armature_obj.name}")
break
if not armature_obj:
print("✗ ERROR: No armature object found in scene")
raise Exception("No armature object found - script aborted")
print(f"Selected armature object: {armature_obj.name}")
# Get the Settings pose bone
pose_bone = armature_obj.pose.bones.get('Settings')
if not pose_bone:
print("✗ ERROR: Settings pose bone not found in armature")
print("Available bones:", [bone.name for bone in armature_obj.pose.bones])
raise Exception("Settings pose bone not found - script aborted")
print("✓ Settings pose bone found")
# Create property name based on active object name
property_name = active_obj.name
print(f"Creating visibility property: {property_name}")
# Remove any existing property with this name to avoid duplication
if property_name in pose_bone:
del pose_bone[property_name]
print(f"Removed existing {property_name} property")
# Create custom property as boolean (default to visible)
pose_bone[property_name] = True
# Set up the property UI
ui_data = pose_bone.id_properties_ui(property_name)
ui_data.update(
description=f"Toggle {active_obj.name} visibility",
default=True
)
# Make the property overridable for linked rigs
try:
# Try the newer Blender 4.x API first
if hasattr(pose_bone, 'property_overridable_library_set'):
pose_bone.property_overridable_library_set(f'["{property_name}"]', True)
print(f"✓ Set {property_name} property as library overridable")
else:
print(f"Note: Library override API not available in this Blender version")
except Exception as e:
print(f"Note: Could not set library override: {e}")
print(f"✓ Created '{property_name}' custom property with library override support")
# Set up drivers for object visibility
print(f"Setting up drivers for {active_obj.name} object...")
try:
# Set up drivers for all selected objects
for obj in selected_objects:
print(f" Setting up drivers for {obj.name}...")
# Clear any existing drivers
try:
obj.driver_remove('hide_render')
print(f" Removed existing hide_render driver")
except:
print(" No existing hide_render driver to remove")
try:
obj.driver_remove('hide_viewport')
print(" Removed existing hide_viewport driver")
except:
print(" No existing hide_viewport driver to remove")
# Create hide_render driver (hide when property = False, show when property = True)
driver_fcurve = obj.driver_add('hide_render')
driver = driver_fcurve.driver
driver.type = 'SUM'
var = driver.variables.new()
var.name = 'vis_val'
var.type = 'SINGLE_PROP'
var.targets[0].id_type = 'OBJECT'
var.targets[0].id = armature_obj
var.targets[0].data_path = f'pose.bones["Settings"]["{property_name}"]'
# Use polynomial modifier to invert: hide_render = 1 - vis_val
mod = driver_fcurve.modifiers.new('GENERATOR')
mod.mode = 'POLYNOMIAL'
mod.poly_order = 1
mod.coefficients = (1.0, -1.0) # 1 - x
print(f" ✓ Created hide_render driver for {obj.name}")
# Create hide_viewport driver (same logic)
driver_fcurve = obj.driver_add('hide_viewport')
driver = driver_fcurve.driver
driver.type = 'SUM'
var = driver.variables.new()
var.name = 'vis_val'
var.type = 'SINGLE_PROP'
var.targets[0].id_type = 'OBJECT'
var.targets[0].id = armature_obj
var.targets[0].data_path = f'pose.bones["Settings"]["{property_name}"]'
# Use polynomial modifier to invert: hide_viewport = 1 - vis_val
mod = driver_fcurve.modifiers.new('GENERATOR')
mod.mode = 'POLYNOMIAL'
mod.poly_order = 1
mod.coefficients = (1.0, -1.0) # 1 - x
print(f" ✓ Created hide_viewport driver for {obj.name}")
except Exception as e:
print(f" Error creating drivers: {e}")
print("✓ Driver setup complete")
# Test the toggle functionality
print(f"\n=== Testing {property_name} visibility functionality ===")
# Force update to make sure drivers are working
bpy.context.view_layer.update()
bpy.context.evaluated_depsgraph_get().update()
# Initial state (should be visible)
print(f"Current state: {property_name} = {pose_bone[property_name]} (True=visible, False=hidden)")
for obj in selected_objects:
print(f" {obj.name}: hide_render={obj.hide_render}, hide_viewport={obj.hide_viewport}")
# Test toggle to False (objects hidden)
print(f"\nToggling to False (objects hidden)...")
pose_bone[property_name] = False
bpy.context.view_layer.update()
bpy.context.evaluated_depsgraph_get().update()
print(f"New state: {property_name} = {pose_bone[property_name]}")
for obj in selected_objects:
print(f" {obj.name}: hide_render={obj.hide_render}, hide_viewport={obj.hide_viewport}")
# Test toggle back to True (objects visible)
print(f"\nToggling to True (objects visible)...")
pose_bone[property_name] = True
bpy.context.view_layer.update()
bpy.context.evaluated_depsgraph_get().update()
print(f"Final state: {property_name} = {pose_bone[property_name]}")
for obj in selected_objects:
print(f" {obj.name}: hide_render={obj.hide_render}, hide_viewport={obj.hide_viewport}")
print("\n✓ Custom Visibility script completed successfully!")
print(f"The '{property_name}' property is now available on the Settings bone as a checkbox")
print(f"Use checkbox to toggle visibility of {len(selected_objects)} selected object(s): {[obj.name for obj in selected_objects]}")
print(f" - {property_name} ON (checked): Shows all selected objects")
print(f" - {property_name} OFF (unchecked): Hides all selected objects")