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

101 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()