Update
This commit is contained in:
@@ -23,19 +23,16 @@ class IKFKSwitchUI(object):
|
||||
"""Initialize UI"""
|
||||
self.target_fields = {}
|
||||
self.target_values = {
|
||||
'target_01': '',
|
||||
'target_02': '',
|
||||
'target_03': '',
|
||||
'target_04': '',
|
||||
'target_05': '',
|
||||
'target_06': '',
|
||||
'target_07': '',
|
||||
'target_08': '',
|
||||
'target_09': '',
|
||||
'target_10': '',
|
||||
'target_11': '',
|
||||
'target_12': '',
|
||||
'target_13': ''
|
||||
'target_01': '', # FK Joint Root
|
||||
'target_02': '', # FK Joint Mid
|
||||
'target_03': '', # FK Joint End
|
||||
'target_04': '', # FK Ctrl Root
|
||||
'target_05': '', # FK Ctrl Mid
|
||||
'target_06': '', # FK Ctrl End
|
||||
'target_07': '', # IK Ctrl Root
|
||||
'target_08': '', # IK Ctrl Pole
|
||||
'target_09': '', # Switch Ctrl
|
||||
'target_10': '' # Switch Attr
|
||||
}
|
||||
|
||||
def create_ui(self):
|
||||
@@ -87,12 +84,8 @@ class IKFKSwitchUI(object):
|
||||
ik_frame = cmds.frameLayout(label="Load IK Ctrl")
|
||||
cmds.columnLayout(rowSpacing=2, adjustableColumn=True)
|
||||
|
||||
self._create_text_field_row('target_07', '< IK Joint Root')
|
||||
self._create_text_field_row('target_08', '< IK Joint Mid')
|
||||
self._create_text_field_row('target_09', '< IK Joint End')
|
||||
cmds.separator(style='in', height=5)
|
||||
self._create_text_field_row('target_10', '< IK Ctrl Root')
|
||||
self._create_text_field_row('target_11', '< IK Ctrl Pole')
|
||||
self._create_text_field_row('target_07', '< IK Ctrl Root')
|
||||
self._create_text_field_row('target_08', '< IK Ctrl Pole')
|
||||
|
||||
cmds.setParent('..')
|
||||
cmds.setParent('..')
|
||||
@@ -101,11 +94,11 @@ class IKFKSwitchUI(object):
|
||||
switch_frame = cmds.frameLayout(label="Load Switch Ctrl")
|
||||
cmds.columnLayout(rowSpacing=2, adjustableColumn=True)
|
||||
|
||||
self._create_text_field_row('target_12', '< Switch Ctrl')
|
||||
self._create_text_field_row('target_09', '< Switch Ctrl')
|
||||
|
||||
# Special row for attribute selection
|
||||
cmds.rowLayout(numberOfColumns=2, adjustableColumn=1, columnWidth2=(45, 60))
|
||||
self.target_fields['target_13'] = cmds.textField(text='')
|
||||
self.target_fields['target_10'] = cmds.textField(text='')
|
||||
cmds.button(width=120, label='< Switch Attr', command=lambda x: self.load_attr())
|
||||
cmds.setParent('..')
|
||||
|
||||
@@ -149,10 +142,10 @@ class IKFKSwitchUI(object):
|
||||
return
|
||||
|
||||
attr_name = attrs[0]
|
||||
cmds.textField(self.target_fields['target_13'], edit=True, text=attr_name)
|
||||
self.target_values['target_13'] = attr_name
|
||||
cmds.textField(self.target_fields['target_10'], edit=True, text=attr_name)
|
||||
self.target_values['target_10'] = attr_name
|
||||
except Exception as e:
|
||||
cmds.warning(f"Failed to load attribute: {e}")
|
||||
cmds.warning("Failed to load attribute: {}".format(e))
|
||||
|
||||
def execute(self):
|
||||
"""Execute the seamless switching setup"""
|
||||
@@ -163,19 +156,17 @@ class IKFKSwitchUI(object):
|
||||
fk_ctrl_root = cmds.textField(self.target_fields['target_04'], query=True, text=True)
|
||||
fk_ctrl_mid = cmds.textField(self.target_fields['target_05'], query=True, text=True)
|
||||
fk_ctrl_end = cmds.textField(self.target_fields['target_06'], query=True, text=True)
|
||||
ik_joint_root = cmds.textField(self.target_fields['target_07'], query=True, text=True)
|
||||
ik_joint_mid = cmds.textField(self.target_fields['target_08'], query=True, text=True)
|
||||
ik_joint_end = cmds.textField(self.target_fields['target_09'], query=True, text=True)
|
||||
ik_ctrl_root = cmds.textField(self.target_fields['target_10'], query=True, text=True)
|
||||
ik_ctrl_pole = cmds.textField(self.target_fields['target_11'], query=True, text=True)
|
||||
switch_ctrl = cmds.textField(self.target_fields['target_12'], query=True, text=True)
|
||||
switch_attr = cmds.textField(self.target_fields['target_13'], query=True, text=True)
|
||||
ik_ctrl_root = cmds.textField(self.target_fields['target_07'], query=True, text=True)
|
||||
ik_ctrl_pole = cmds.textField(self.target_fields['target_08'], query=True, text=True)
|
||||
switch_ctrl = cmds.textField(self.target_fields['target_09'], query=True, text=True)
|
||||
switch_attr = cmds.textField(self.target_fields['target_10'], query=True, text=True)
|
||||
|
||||
# Call the seamless switching function
|
||||
# Note: IK joints use FK joints for reference (same as MEL version)
|
||||
seamless_switching(
|
||||
fk_joint_root, fk_joint_mid, fk_joint_end,
|
||||
fk_ctrl_root, fk_ctrl_mid, fk_ctrl_end,
|
||||
ik_joint_root, ik_joint_mid, ik_joint_end,
|
||||
fk_joint_root, fk_joint_mid, fk_joint_end, # IK joints = FK joints
|
||||
ik_ctrl_root, ik_ctrl_pole,
|
||||
switch_ctrl, switch_attr
|
||||
)
|
||||
@@ -252,19 +243,19 @@ def seamless_switching(
|
||||
switch_attr: Switch attribute name
|
||||
"""
|
||||
# Create locator for storing data
|
||||
locator_name = f"{switch_ctrl}_Switch_Locator"
|
||||
locator_name = "{}_Switch_Locator".format(switch_ctrl)
|
||||
|
||||
if not cmds.objExists(locator_name):
|
||||
locator_shape = cmds.createNode('locator', name=locator_name)
|
||||
locator_transform = cmds.listRelatives(locator_shape, parent=True)[0]
|
||||
cmds.parent(locator_shape, switch_ctrl, shape=True, add=True)
|
||||
cmds.delete(locator_transform)
|
||||
cmds.setAttr(f"{locator_name}.visibility", 0)
|
||||
cmds.setAttr("{}.visibility".format(locator_name), 0)
|
||||
|
||||
# Add IKFK_Seamless attribute if it doesn't exist
|
||||
if not cmds.objExists(f"{switch_ctrl}.IKFK_Seamless"):
|
||||
if not cmds.objExists("{}.IKFK_Seamless".format(switch_ctrl)):
|
||||
cmds.addAttr(switch_ctrl, longName="IKFK_Seamless", attributeType="enum", enumName="IK:FK:", keyable=False)
|
||||
cmds.setAttr(f"{switch_ctrl}.IKFK_Seamless", channelBox=True)
|
||||
cmds.setAttr("{}.IKFK_Seamless".format(switch_ctrl), channelBox=True)
|
||||
|
||||
# Add Location attribute to all objects
|
||||
objs = [
|
||||
@@ -275,8 +266,12 @@ def seamless_switching(
|
||||
]
|
||||
|
||||
for obj in objs:
|
||||
if not cmds.objExists(f"{obj}.Location"):
|
||||
cmds.addAttr(obj, longName="Location", dataType="string", keyable=True)
|
||||
# Check if object name is not empty and exists
|
||||
if obj and cmds.objExists(obj):
|
||||
if not cmds.objExists("{}.Location".format(obj)):
|
||||
cmds.addAttr(obj, longName="Location", dataType="string", keyable=True)
|
||||
else:
|
||||
cmds.warning("Object does not exist or is empty: {}".format(obj))
|
||||
|
||||
# Add attributes to locator and connect
|
||||
attrs_data = {
|
||||
@@ -297,17 +292,17 @@ def seamless_switching(
|
||||
}
|
||||
|
||||
for attr_name, attr_value in attrs_data.items():
|
||||
if not cmds.objExists(f"{locator_name}.{attr_name}"):
|
||||
if not cmds.objExists("{}.{}".format(locator_name, attr_name)):
|
||||
cmds.addAttr(locator_name, longName=attr_name, dataType="string", keyable=True)
|
||||
|
||||
cmds.setAttr(f"{locator_name}.{attr_name}", attr_value, type="string")
|
||||
cmds.setAttr("{}.{}".format(locator_name, attr_name), attr_value, type="string")
|
||||
|
||||
# Connect to Location attribute (except for special attributes)
|
||||
if attr_name not in ["IKFK_Seamless_Switching", "Switch_Attr"]:
|
||||
target_obj = attr_value
|
||||
if cmds.objExists(f"{target_obj}.Location"):
|
||||
if not cmds.isConnected(f"{locator_name}.{attr_name}", f"{target_obj}.Location"):
|
||||
cmds.connectAttr(f"{locator_name}.{attr_name}", f"{target_obj}.Location", force=True)
|
||||
if cmds.objExists("{}.Location".format(target_obj)):
|
||||
if not cmds.isConnected("{}.{}".format(locator_name, attr_name), "{}.Location".format(target_obj)):
|
||||
cmds.connectAttr("{}.{}".format(locator_name, attr_name), "{}.Location".format(target_obj), force=True)
|
||||
|
||||
# Create switching script
|
||||
create_switching_script()
|
||||
@@ -315,7 +310,7 @@ def seamless_switching(
|
||||
# Create script job for this control
|
||||
create_script_job(switch_ctrl, locator_name)
|
||||
|
||||
print(f"IKFK Seamless Switching setup completed for {switch_ctrl}")
|
||||
print("IKFK Seamless Switching setup completed for {}".format(switch_ctrl))
|
||||
|
||||
|
||||
def create_switching_script():
|
||||
@@ -419,34 +414,34 @@ global proc sg_switching (string $Switch)
|
||||
else:
|
||||
cmds.scriptNode(script_node_name, edit=True, beforeScript=mel_script)
|
||||
|
||||
cmds.setAttr(f"{script_node_name}.scriptType", 1)
|
||||
cmds.setAttr("{}.scriptType".format(script_node_name), 1)
|
||||
cmds.scriptNode(script_node_name, executeBefore=True)
|
||||
|
||||
|
||||
def create_script_job(switch_ctrl, locator_name):
|
||||
"""Create script job for automatic switching"""
|
||||
script_node_name = f"{switch_ctrl}_Switching_Script"
|
||||
script_node_name = "{}_Switching_Script".format(switch_ctrl)
|
||||
|
||||
# MEL script for script job creation
|
||||
mel_script = f'''
|
||||
mel_script = '''
|
||||
string $Locator_all[]=`ls -typ "locator"`;
|
||||
for($Locator in $Locator_all){{
|
||||
if(`objExists ($Locator+".IKFK_Seamless_Switching")`){{
|
||||
string $tmp=`getAttr ($Locator+".IKFK_Seamless_Switching")`;
|
||||
if($tmp=="{locator_name}"){{
|
||||
if($tmp=="{0}"){{
|
||||
string $Switch[]=`listConnections ($Locator+".Switch_Ctrl")`;
|
||||
scriptJob -ac ($Switch[0]+".IKFK_Seamless") ("sg_switching "+$Locator) -kws;
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
'''
|
||||
'''.format(locator_name)
|
||||
|
||||
if not cmds.objExists(script_node_name):
|
||||
cmds.scriptNode(beforeScript=mel_script, name=script_node_name)
|
||||
else:
|
||||
cmds.scriptNode(script_node_name, edit=True, beforeScript=mel_script)
|
||||
|
||||
cmds.setAttr(f"{script_node_name}.scriptType", 1)
|
||||
cmds.setAttr("{}.scriptType".format(script_node_name), 1)
|
||||
cmds.scriptNode(script_node_name, executeBefore=True)
|
||||
|
||||
|
||||
|
||||
@@ -23,19 +23,16 @@ class IKFKSwitchUI(object):
|
||||
"""Initialize UI"""
|
||||
self.target_fields = {}
|
||||
self.target_values = {
|
||||
'target_01': '',
|
||||
'target_02': '',
|
||||
'target_03': '',
|
||||
'target_04': '',
|
||||
'target_05': '',
|
||||
'target_06': '',
|
||||
'target_07': '',
|
||||
'target_08': '',
|
||||
'target_09': '',
|
||||
'target_10': '',
|
||||
'target_11': '',
|
||||
'target_12': '',
|
||||
'target_13': ''
|
||||
'target_01': '', # FK Joint Root
|
||||
'target_02': '', # FK Joint Mid
|
||||
'target_03': '', # FK Joint End
|
||||
'target_04': '', # FK Ctrl Root
|
||||
'target_05': '', # FK Ctrl Mid
|
||||
'target_06': '', # FK Ctrl End
|
||||
'target_07': '', # IK Ctrl Root
|
||||
'target_08': '', # IK Ctrl Pole
|
||||
'target_09': '', # Switch Ctrl
|
||||
'target_10': '' # Switch Attr
|
||||
}
|
||||
|
||||
def create_ui(self):
|
||||
@@ -87,12 +84,8 @@ class IKFKSwitchUI(object):
|
||||
ik_frame = cmds.frameLayout(label="Load IK Ctrl")
|
||||
cmds.columnLayout(rowSpacing=2, adjustableColumn=True)
|
||||
|
||||
self._create_text_field_row('target_07', '< IK Joint Root')
|
||||
self._create_text_field_row('target_08', '< IK Joint Mid')
|
||||
self._create_text_field_row('target_09', '< IK Joint End')
|
||||
cmds.separator(style='in', height=5)
|
||||
self._create_text_field_row('target_10', '< IK Ctrl Root')
|
||||
self._create_text_field_row('target_11', '< IK Ctrl Pole')
|
||||
self._create_text_field_row('target_07', '< IK Ctrl Root')
|
||||
self._create_text_field_row('target_08', '< IK Ctrl Pole')
|
||||
|
||||
cmds.setParent('..')
|
||||
cmds.setParent('..')
|
||||
@@ -101,11 +94,11 @@ class IKFKSwitchUI(object):
|
||||
switch_frame = cmds.frameLayout(label="Load Switch Ctrl")
|
||||
cmds.columnLayout(rowSpacing=2, adjustableColumn=True)
|
||||
|
||||
self._create_text_field_row('target_12', '< Switch Ctrl')
|
||||
self._create_text_field_row('target_09', '< Switch Ctrl')
|
||||
|
||||
# Special row for attribute selection
|
||||
cmds.rowLayout(numberOfColumns=2, adjustableColumn=1, columnWidth2=(45, 60))
|
||||
self.target_fields['target_13'] = cmds.textField(text='')
|
||||
self.target_fields['target_10'] = cmds.textField(text='')
|
||||
cmds.button(width=120, label='< Switch Attr', command=lambda x: self.load_attr())
|
||||
cmds.setParent('..')
|
||||
|
||||
@@ -149,10 +142,10 @@ class IKFKSwitchUI(object):
|
||||
return
|
||||
|
||||
attr_name = attrs[0]
|
||||
cmds.textField(self.target_fields['target_13'], edit=True, text=attr_name)
|
||||
self.target_values['target_13'] = attr_name
|
||||
cmds.textField(self.target_fields['target_10'], edit=True, text=attr_name)
|
||||
self.target_values['target_10'] = attr_name
|
||||
except Exception as e:
|
||||
cmds.warning(f"Failed to load attribute: {e}")
|
||||
cmds.warning("Failed to load attribute: {}".format(e))
|
||||
|
||||
def execute(self):
|
||||
"""Execute the seamless switching setup"""
|
||||
@@ -163,19 +156,17 @@ class IKFKSwitchUI(object):
|
||||
fk_ctrl_root = cmds.textField(self.target_fields['target_04'], query=True, text=True)
|
||||
fk_ctrl_mid = cmds.textField(self.target_fields['target_05'], query=True, text=True)
|
||||
fk_ctrl_end = cmds.textField(self.target_fields['target_06'], query=True, text=True)
|
||||
ik_joint_root = cmds.textField(self.target_fields['target_07'], query=True, text=True)
|
||||
ik_joint_mid = cmds.textField(self.target_fields['target_08'], query=True, text=True)
|
||||
ik_joint_end = cmds.textField(self.target_fields['target_09'], query=True, text=True)
|
||||
ik_ctrl_root = cmds.textField(self.target_fields['target_10'], query=True, text=True)
|
||||
ik_ctrl_pole = cmds.textField(self.target_fields['target_11'], query=True, text=True)
|
||||
switch_ctrl = cmds.textField(self.target_fields['target_12'], query=True, text=True)
|
||||
switch_attr = cmds.textField(self.target_fields['target_13'], query=True, text=True)
|
||||
ik_ctrl_root = cmds.textField(self.target_fields['target_07'], query=True, text=True)
|
||||
ik_ctrl_pole = cmds.textField(self.target_fields['target_08'], query=True, text=True)
|
||||
switch_ctrl = cmds.textField(self.target_fields['target_09'], query=True, text=True)
|
||||
switch_attr = cmds.textField(self.target_fields['target_10'], query=True, text=True)
|
||||
|
||||
# Call the seamless switching function
|
||||
# Note: IK joints use FK joints for reference (same as MEL version)
|
||||
seamless_switching(
|
||||
fk_joint_root, fk_joint_mid, fk_joint_end,
|
||||
fk_ctrl_root, fk_ctrl_mid, fk_ctrl_end,
|
||||
ik_joint_root, ik_joint_mid, ik_joint_end,
|
||||
fk_joint_root, fk_joint_mid, fk_joint_end, # IK joints = FK joints
|
||||
ik_ctrl_root, ik_ctrl_pole,
|
||||
switch_ctrl, switch_attr
|
||||
)
|
||||
@@ -252,19 +243,19 @@ def seamless_switching(
|
||||
switch_attr: Switch attribute name
|
||||
"""
|
||||
# Create locator for storing data
|
||||
locator_name = f"{switch_ctrl}_Switch_Locator"
|
||||
locator_name = "{}_Switch_Locator".format(switch_ctrl)
|
||||
|
||||
if not cmds.objExists(locator_name):
|
||||
locator_shape = cmds.createNode('locator', name=locator_name)
|
||||
locator_transform = cmds.listRelatives(locator_shape, parent=True)[0]
|
||||
cmds.parent(locator_shape, switch_ctrl, shape=True, add=True)
|
||||
cmds.delete(locator_transform)
|
||||
cmds.setAttr(f"{locator_name}.visibility", 0)
|
||||
cmds.setAttr("{}.visibility".format(locator_name), 0)
|
||||
|
||||
# Add IKFK_Seamless attribute if it doesn't exist
|
||||
if not cmds.objExists(f"{switch_ctrl}.IKFK_Seamless"):
|
||||
if not cmds.objExists("{}.IKFK_Seamless".format(switch_ctrl)):
|
||||
cmds.addAttr(switch_ctrl, longName="IKFK_Seamless", attributeType="enum", enumName="IK:FK:", keyable=False)
|
||||
cmds.setAttr(f"{switch_ctrl}.IKFK_Seamless", channelBox=True)
|
||||
cmds.setAttr("{}.IKFK_Seamless".format(switch_ctrl), channelBox=True)
|
||||
|
||||
# Add Location attribute to all objects
|
||||
objs = [
|
||||
@@ -275,8 +266,12 @@ def seamless_switching(
|
||||
]
|
||||
|
||||
for obj in objs:
|
||||
if not cmds.objExists(f"{obj}.Location"):
|
||||
cmds.addAttr(obj, longName="Location", dataType="string", keyable=True)
|
||||
# Check if object name is not empty and exists
|
||||
if obj and cmds.objExists(obj):
|
||||
if not cmds.objExists("{}.Location".format(obj)):
|
||||
cmds.addAttr(obj, longName="Location", dataType="string", keyable=True)
|
||||
else:
|
||||
cmds.warning("Object does not exist or is empty: {}".format(obj))
|
||||
|
||||
# Add attributes to locator and connect
|
||||
attrs_data = {
|
||||
@@ -297,17 +292,17 @@ def seamless_switching(
|
||||
}
|
||||
|
||||
for attr_name, attr_value in attrs_data.items():
|
||||
if not cmds.objExists(f"{locator_name}.{attr_name}"):
|
||||
if not cmds.objExists("{}.{}".format(locator_name, attr_name)):
|
||||
cmds.addAttr(locator_name, longName=attr_name, dataType="string", keyable=True)
|
||||
|
||||
cmds.setAttr(f"{locator_name}.{attr_name}", attr_value, type="string")
|
||||
cmds.setAttr("{}.{}".format(locator_name, attr_name), attr_value, type="string")
|
||||
|
||||
# Connect to Location attribute (except for special attributes)
|
||||
if attr_name not in ["IKFK_Seamless_Switching", "Switch_Attr"]:
|
||||
target_obj = attr_value
|
||||
if cmds.objExists(f"{target_obj}.Location"):
|
||||
if not cmds.isConnected(f"{locator_name}.{attr_name}", f"{target_obj}.Location"):
|
||||
cmds.connectAttr(f"{locator_name}.{attr_name}", f"{target_obj}.Location", force=True)
|
||||
if cmds.objExists("{}.Location".format(target_obj)):
|
||||
if not cmds.isConnected("{}.{}".format(locator_name, attr_name), "{}.Location".format(target_obj)):
|
||||
cmds.connectAttr("{}.{}".format(locator_name, attr_name), "{}.Location".format(target_obj), force=True)
|
||||
|
||||
# Create switching script
|
||||
create_switching_script()
|
||||
@@ -315,7 +310,7 @@ def seamless_switching(
|
||||
# Create script job for this control
|
||||
create_script_job(switch_ctrl, locator_name)
|
||||
|
||||
print(f"IKFK Seamless Switching setup completed for {switch_ctrl}")
|
||||
print("IKFK Seamless Switching setup completed for {}".format(switch_ctrl))
|
||||
|
||||
|
||||
def create_switching_script():
|
||||
@@ -419,34 +414,34 @@ global proc sg_switching (string $Switch)
|
||||
else:
|
||||
cmds.scriptNode(script_node_name, edit=True, beforeScript=mel_script)
|
||||
|
||||
cmds.setAttr(f"{script_node_name}.scriptType", 1)
|
||||
cmds.setAttr("{}.scriptType".format(script_node_name), 1)
|
||||
cmds.scriptNode(script_node_name, executeBefore=True)
|
||||
|
||||
|
||||
def create_script_job(switch_ctrl, locator_name):
|
||||
"""Create script job for automatic switching"""
|
||||
script_node_name = f"{switch_ctrl}_Switching_Script"
|
||||
script_node_name = "{}_Switching_Script".format(switch_ctrl)
|
||||
|
||||
# MEL script for script job creation
|
||||
mel_script = f'''
|
||||
mel_script = '''
|
||||
string $Locator_all[]=`ls -typ "locator"`;
|
||||
for($Locator in $Locator_all){{
|
||||
if(`objExists ($Locator+".IKFK_Seamless_Switching")`){{
|
||||
string $tmp=`getAttr ($Locator+".IKFK_Seamless_Switching")`;
|
||||
if($tmp=="{locator_name}"){{
|
||||
if($tmp=="{0}"){{
|
||||
string $Switch[]=`listConnections ($Locator+".Switch_Ctrl")`;
|
||||
scriptJob -ac ($Switch[0]+".IKFK_Seamless") ("sg_switching "+$Locator) -kws;
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
'''
|
||||
'''.format(locator_name)
|
||||
|
||||
if not cmds.objExists(script_node_name):
|
||||
cmds.scriptNode(beforeScript=mel_script, name=script_node_name)
|
||||
else:
|
||||
cmds.scriptNode(script_node_name, edit=True, beforeScript=mel_script)
|
||||
|
||||
cmds.setAttr(f"{script_node_name}.scriptType", 1)
|
||||
cmds.setAttr("{}.scriptType".format(script_node_name), 1)
|
||||
cmds.scriptNode(script_node_name, executeBefore=True)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user