MetaFusion/scripts/utils/ReorderBlendShapes.py

101 lines
3.5 KiB
Python
Raw Normal View History

2025-02-07 05:10:30 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
from scripts.utils.Core import GetMeshes, GetBlendShape, GetBlendShapes
def is_sorted(array):
"""
检查数组是否已排序
参数:
array (list): 要检查的数组
返回:
bool: 如果数组已排序返回True否则返回False
"""
return all(array[i] >= array[i-1] for i in range(1, len(array)))
def are_indices_sorted(array_a, array_b):
"""
检查两个数组中共同元素的索引是否有序
参数:
array_a (list): 第一个数组
array_b (list): 第二个数组
返回:
bool: 如果共同元素的索引都有序返回True否则返回False
"""
# 存储共同元素的索引
common_indices_a = []
common_indices_b = []
# 查找共同元素并记录它们的索引
for i, item_a in enumerate(array_a):
for j, item_b in enumerate(array_b):
if item_a == item_b:
common_indices_a.append(i)
common_indices_b.append(j)
break
# 检查两个索引数组是否都有序
return is_sorted(common_indices_a) and is_sorted(common_indices_b)
def reorder_blend_shapes():
"""重新排序所有网格的混合变形目标"""
# 遍历前50个网格
for mesh_index in range(50):
mesh = GetMeshes(m=mesh_index)
if cmds.objExists(mesh):
blend_shape = GetBlendShape(mesh)
if cmds.objExists(blend_shape):
attr_weight = f"{blend_shape}.weight"
# 获取目标数量和索引
nb_in_tgt = cmds.getAttr(attr_weight, size=True)
existing_indices = cmds.getAttr(attr_weight, multiIndices=True)
# 获取当前和预期的混合变形目标列表
current_blend_shape_list = cmds.listAttr(attr_weight, m=True)
blend_shape_list = GetBlendShapes()
# 检查是否需要重新排序
needs_reorder = (
nb_in_tgt - 1 != existing_indices[-1] or
not are_indices_sorted(blend_shape_list, current_blend_shape_list)
)
if needs_reorder:
# 重新生成所有目标
target_list = []
for j in existing_indices:
target = cmds.sculptTarget(
blend_shape,
e=True,
regenerate=True,
target=j
)
target_list.append(target[0])
# 删除原始混合变形器
cmds.delete(blend_shape)
# 按照预期顺序选择目标
cmds.select(clear=True)
for bs_name in blend_shape_list:
if bs_name in target_list:
cmds.select(bs_name, add=True)
# 创建新的混合变形器
cmds.select(mesh, add=True)
cmds.blendShape(automatic=True, name=blend_shape)
# 清理临时目标
cmds.delete(target_list)
# 如果直接运行此脚本
if __name__ == '__main__':
reorder_blend_shapes()