MetaFusion/scripts/utils/BlendShapeFindFlipTarget.py
2025-02-07 05:10:30 +08:00

110 lines
3.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
import maya.mel as mel
def blend_shape_find_flip_target(axis, target_ids_a, target_ids_b, blend_shape):
"""
查找并设置混合变形目标的镜像关系
参数:
axis (int): 镜像轴向 (1=X, 2=Y, 3=Z, 4=Topology)
target_ids_a (list): 源目标ID列表
target_ids_b (list): 目标ID列表
blend_shape (str): 混合变形节点名称
"""
# 检查混合变形节点是否存在
if not cmds.objExists(blend_shape):
cmds.warning(f"No Exists BlendShape: {blend_shape}")
return
# 检查源目标和目标列表长度是否相等
if len(target_ids_a) != len(target_ids_b):
cmds.warning("Unequal Mirror Targets...")
return
# 获取当前对称建模设置
original_symmetry = cmds.symmetricModelling(query=True, symmetry=True)
symmetry_space = None
symmetry_axis = None
if original_symmetry:
symmetry_space = cmds.symmetricModelling(query=True, about=True)
if symmetry_space == "topo":
symmetry_axis = mel.eval('blendShapeGetTopoSymmetryEdge()')
else:
symmetry_axis = cmds.symmetricModelling(query=True, axis=True)
# 处理每对目标
for target_a, target_b in zip(target_ids_a, target_ids_b):
# 检查并重命名目标
target_name = f"{blend_shape}.weight[{target_a}]"
target_name = cmds.aliasAttr(target_name, query=True)
exist = False
if cmds.objExists(target_name):
exist = True
cmds.rename(target_name, f"{target_name}_temp")
# 重新生成目标并设置连接
target_mesh = cmds.sculptTarget(
blend_shape,
edit=True,
regenerate=True,
target=target_a
)
target_mesh_shape = cmds.listRelatives(target_mesh[0], shapes=True)
# 断开原有连接并建立新连接
cmds.disconnectAttr(
f"{target_mesh_shape[0]}.worldMesh[0]",
f"{blend_shape}.inputTarget[0].inputTargetGroup[{target_a}].inputTargetItem[6000].inputGeomTarget"
)
cmds.connectAttr(
f"{target_mesh_shape[0]}.worldMesh[0]",
f"{blend_shape}.inputTarget[0].inputTargetGroup[{target_b}].inputTargetItem[6000].inputGeomTarget",
force=True
)
# 删除临时目标网格
cmds.delete(target_mesh)
# 恢复原始名称
if exist:
cmds.rename(f"{target_name}_temp", target_name)
# 获取几何体索引
geometry_indices = cmds.blendShape(blend_shape, query=True, geometryIndices=True)
# 构建命令字符串
cmd_parts = []
for geometry in geometry_indices:
cmd = f"blendShape -e "
for target_id in target_ids_b:
cmd += f"-ft {geometry} {target_id} "
if axis == 4:
cmd += "-ss 0 "
else:
cmd += "-ss 1 "
if axis == 1:
cmd += "-sa x "
elif axis == 2:
cmd += "-sa y "
elif axis == 3:
cmd += "-sa z "
cmd += f"{blend_shape};"
cmd_parts.append(cmd)
# 添加对称设置恢复命令
if not original_symmetry or not symmetry_axis:
cmd_parts.append('symmetricModelling -s 0')
elif symmetry_space == "topo":
cmd_parts.append(f'symmetricModelling -e -about {symmetry_space} -s 1 {symmetry_axis}')
else:
cmd_parts.append(f'symmetricModelling -e -about {symmetry_space} -axis {symmetry_axis} -s 1')
# 执行命令
for cmd in cmd_parts:
mel.eval(cmd)