diff --git a/2023/scripts/animation_tools/ikfx_switch.py b/2023/scripts/animation_tools/ikfx_switch.py index 95b9ebf..06a7685 100644 --- a/2023/scripts/animation_tools/ikfx_switch.py +++ b/2023/scripts/animation_tools/ikfx_switch.py @@ -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) diff --git a/2025/scripts/animation_tools/ikfx_switch.py b/2025/scripts/animation_tools/ikfx_switch.py index 95b9ebf..06a7685 100644 --- a/2025/scripts/animation_tools/ikfx_switch.py +++ b/2025/scripts/animation_tools/ikfx_switch.py @@ -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)