110 lines
3.7 KiB
Python
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) |