101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
|
#!/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()
|