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