python
node = "npc_chengnv002_meilin:biped_Head_ctrl"
for t_node in pm.listRelatives(node, ad=1, type="transform"):
children = pm.listRelatives(t_node, children=True, shapes=True) or []
if children:
continue
if pm.keyframe(t_node, query=True, keyframeCount=True) > 0:
print("clean {} anim key".format(t_node.name()))
pm.cutKey(t_node, clear=True)
python
attribute_dict = {
"tx": 0,
"ty": 0,
"tz": 0,
"rx": 0,
"ry": 0,
"rz": 0,
"sx": 1,
"sy": 1,
"sz": 1
}
all_curves = pm.ls(type='nurbsCurve')
for curve in all_curves:
# 获取曲线的父变换节点
transform_node_name = pm.listRelatives(curve, parent=True, type='transform')[0].name()
for attr, value in attribute_dict.items():
full_attr_name = "{}.{}".format(transform_node_name, attr)
if pm.getAttr(full_attr_name) == value:
print('clear attr {}'.format(full_attr_name))
pm.cutKey(full_attr_name, clear=True)
世界空间M
舞台中心M
输出角色基于世界空间,
所以要计算从世界空间 到舞台中心的变换矩阵, 即舞台中心在世界空间的Transform Matrix 的逆
python
def create_stage_calculate_setting(stage_center_node):
# set time
pm.currentTime(pm.playbackOptions(query=True, minTime=True))
error_info = {"No Global Ctrl":list(), "No Env Ctrl":list()}
asset_lst = stage_center_node.getAttr('Assets')
cam_lst = stage_center_node.getAttr('Cameras')
if not isinstance(asset_lst, list):
asset_lst = [asset_lst]
if not isinstance(cam_lst, list):
cam_lst = [cam_lst]
temp_constraint_lst = list()
disconnected_connections = list()
mute_lst = list()
if not asset_lst and not cam_lst:
return temp_constraint_lst, disconnected_connections
# constraint asset
for asset_namespace in asset_lst:
global_ctrl_name = "{}:global_ctrl".format(asset_namespace)
if not pm.objExists(global_ctrl_name):
error_info["No Global Ctrl"].append(asset_namespace)
continue
global_ctrl = pm.ls(global_ctrl_name)[0]
# break constraint type connection
d, m = find_and_disconnect_constraints(global_ctrl)
disconnected_connections.extend(d)
mute_lst.extend(m)
# create constraint
p_cons = pm.parentConstraint(stage_center_node, global_ctrl, mo=True)
temp_constraint_lst.append(p_cons.name())
motion_node_name = "{}_motion_node".format(asset_namespace)
if pm.objExists(motion_node_name):
motion_node = pm.ls(motion_node_name)[0]
d, m = find_and_disconnect_constraints(motion_node)
disconnected_connections.extend(d)
mute_lst.extend(m)
motion_node_cons = pm.parentConstraint(stage_center_node, motion_node_name, mo=True)
temp_constraint_lst.append(motion_node_cons.name())
# constraint cam
for cam_shape_name in cam_lst:
cam_ns = cam_shape_name.split(':')[0]
cam_ctrl = "{}:env_ctrl".format(cam_ns)
if not pm.objExists(cam_ctrl):
error_info["No Env Ctrl"].append(cam_ctrl)
continue
cam_ctrl = pm.ls(cam_ctrl)[0]
d, m = find_and_disconnect_constraints(cam_ctrl)
disconnected_connections.extend(d)
mute_lst.extend(m)
# move stage_center to zero
org_pos = pm.xform(stage_center_node, q=1, t=1, ws=1)
org_ro = pm.xform(stage_center_node, q=1, ro=1, ws=1)
pm.xform(stage_center_node, t=[0, 0, 0], ws=1)
pm.xform(stage_center_node, ro=[0, 0, 0], ws=1)
info_dict = dict()
info_dict['TR'] = [org_pos, org_ro]
info_dict['temp_constraint_lst'] = temp_constraint_lst
info_dict['disconnected_connections'] = disconnected_connections
info_dict['mute_attr'] = mute_lst
return info_dict
def recover_stage_calculate_setting(info_dict):
# set time
pm.currentTime(pm.playbackOptions(query=True, minTime=True))
TR = info_dict.get('TR')
temp_constraint_lst = info_dict.get('temp_constraint_lst')
disconnected_connections = info_dict.get('disconnected_connections')
mute_attrs = info_dict.get('mute_attr')
stage_center_node = get_stage_center()
if TR and stage_center_node:
T, R = TR
pm.xform(stage_center_node, t=T, ws=1)
pm.xform(stage_center_node, ro=R, ws=1)
# remove_constraint_node
if temp_constraint_lst:
try:
pm.delete(temp_constraint_lst)
except:
print("Stage :: Delete Constraint Failed. ")
# recover constraint connection
if disconnected_connections:
for source_attr, dest_attr in disconnected_connections:
try:
cmds.connectAttr(source_attr, dest_attr, force=True)
except:
print("Stage :: Recover constraint connection failed {} {}."
.format(source_attr, dest_attr))
# mute
for _mute in mute_attrs:
pm.mute(_mute, disable=0)