为什么 skinPercent() 这么慢?

问题描述 投票:0回答:1

我想将皮肤重量从一个人体模型复制到另一个。这两个模型具有相同的拓扑结构,所以我尝试使用以下代码直接按索引复制权重索引。

for idx, p in enumerate(points):
  # skinValues save first model's skinning
  if idx in skinValues.keys():
    ns = skinValues[str_idx]
    mc.skinPercent(skinClusterIm, p, tv = ns,zri = True)

但是它工作起来很慢(对于具有 50000 个顶点和 300 个关节的模型需要 15 分钟)。有什么办法可以加快这个过程吗?

maya skin
1个回答
0
投票

是的,不幸的是,这将非常缓慢,因为 Maya 正在为每次迭代生成一个撤消步骤。那是 50000 * 300 次撤消步骤,这是相当多的内存分配!

你有两种选择来加快速度。

选项 1: 禁用撤消队列!

// grab current undo state
current_state = mc.undoInfo(q = True, state=True)

// turn off the undo queue
mc.undoInfo(state=False)


// call skinPercent in your double nested for loop now


// restore the state of the undo queue
mc.undoInfo(state = current_state)

方案二:直接修改皮肤集群数据

皮肤集群上的数据地址是这样的:

skinCluster1.wl[VERTEX_INDEX].w[JOINT_INDEX];

您可以完全跳过 skinPercent 命令的需要,只需使用 setAttr 直接设置权重。我有点老派,所以通常使用 MEL,但在 MEL 中,您可以在单个命令中为单个顶点设置所有权重,例如

// this assume the skin cluster has 4 weights per vertex! 
// So we set vertex 0: wl[0], 
// 
// using joint indices 0, 1, 2, and 3; i.e. ".w[0:3]", 
// 
// We can then just list the weights we want to set afterwards.
// 
setAttr "skinCluster1.wl[0].w[0:3]"   0.666 0.334 0 0;

即使启用了撤消堆栈,这也有助于减少撤消步骤的数量(但是,即使使用这种方法,我仍然会禁用撤消堆栈!!)。总的来说,我会 avoid 在 Maya API 中使用 MFnSkinCluster,因为它太慢了。遗憾的是,skinPercent 命令显然是使用 MFnSkinCluster 实现的:(

一个小的 Mel 脚本,用于从皮肤集群中提取关节名称。

proc print_joints(string $cluster) {
    // how big is the matrix array input on the cluster?
    // this will map directly to the number of joints in 
    // the cluster
    $num_joints = `getAttr -size ($cluster + ".matrix")`;
    for($i = 0; $i < $num_joints; ++$i) {

        // look for any source connections to the given array input
        $joint = `listConnections -d 0 -s 1 ($cluster + ".matrix[" + $i + "]")`;

        // print in a readable format
        print($cluster + ".matrix[" + $i + "] --> connected to --> " + $joint[0] + "\n");
    }
}

print_joints("skinCluster1");
© www.soinside.com 2019 - 2024. All rights reserved.