问题描述
Maya动画丢失的原因有很多种, 修复需要一个带动画的历史版本和一个丢失动画的修改版本.
下面的方案主要用于解决动画节点还在场景中, 连接关系丢失的情况.
解决方案
导出动画连接关系
def get_all_curves():
# 获取所有 NURBS 曲线的形状节点
all_curve_shapes = cmds.ls(type="nurbsCurve")
# 获取所有对应的变换节点
all_curve_transforms = cmds.listRelatives(all_curve_shapes, parent=True, fullPath=True)
return all_curve_transforms
def check_anim_inputs(transform_node):
anim_inputs = {}
# 获取变换节点的所有属性
attrs = cmds.listAttr(transform_node, keyable=True)
print('attrs', attrs)
if attrs is None:
return anim_inputs
for attr in attrs:
# 获取属性的完整名称
attr_full_name = "{}.{}".format(transform_node, attr)
# 获取属性的输入连接
connections = cmds.listConnections(attr_full_name, source=True, destination=False, plugs=True)
if connections:
for conn in connections:
# 检查连接是否是动画节点
if cmds.nodeType(conn.split(".")[0]) in ["animCurveTL", "animCurveTA", "animCurveTT", "animCurveTU"]:
if transform_node not in anim_inputs:
anim_inputs[transform_node] = {}
anim_inputs[transform_node][attr] = conn
return anim_inputs
def main():
curves = get_all_curves()
anim_dict = {}
for curve_ in curves:
print(curve_)
anim_inputs = check_anim_inputs(curve_)
if anim_inputs:
anim_dict.update(anim_inputs)
return anim_dict
还原连接
for anim_node_name, connect_info in anim_dict.items():
for attr_name, target_attr_name in connect_info.items():
missing_node = target_attr_name.split('.')[0]
if not cmds.ls(missing_node):
missing_node_lst.append(missing_node)
continue
source_attr_name = '{}.{}'.format(anim_node_name, attr_name)
cmds.connectAttr(target_attr_name, source_attr_name, force=True)
第二种还原方式
import re
def remove_trailing_digits(input_string):
return re.sub(r'\d+$', '', input_string)
_namespace = "zhujue_male:"
for attr in pm.listConnections(pm.ls("zhujue_maleRN")[0], d=1, p=1):
if "animCurve" not in attr.node().nodeType():
print(attr.node().nodeType())
continue
index = attr.node().name().rfind("_")
node_name = attr.node().name()[:index]
attr_name = attr.node().name()[index+1:]
ctrl_name = "{}{}".format(_namespace, node_name)
# print(node_name, attr_name)
ctrl_attr_name = ctrl_name + "." + remove_trailing_digits(attr_name)
if not pm.objExists(ctrl_attr_name):
print(ctrl_attr_name)
try:
pm.connectAttr(attr, ctrl_attr_name)
except:
print(attr, ctrl_attr_name)