背景
- 特定の joint の skin weight の値を全部ゼロにしたりとか, 特定の頂点の weight の値をプログラマブルに設定したい(距離に応じて weight を設定など)
- Maya 上で UI Paint とか component editor とかで処理するにはめんどい
- hair とか細かい形状とか, 頂点数が多いとか
.ma
をいじるとか, 一旦 weight を xml or texture に出して処理する手もありますが, ここでは Maya Python で処理するのを考えてみます.
方法
手っ取り早く取得, 設定する.
skinPercent コマンドで, joint 名と mesh 名, vtx を指定する.
# vtx[100] の joint1 の weight を取得
cmds.skinPercent( 'skinCluster1', 'pPlane1.vtx[100]', t='joint1', query=True, value=True)
# vtx[100] の weight を. joint を指定して設定
cmds.skinPercent( 'skinCluster1', 'pPlane1.vtx[100]', transformValue=[('joint1', 0.2), ('joint3', 0.8)])
簡単ですが, 頂点数多いと時間かかります(i9 9900K で, 5 万頂点で 4 joint 処理して 4~5 分くらい. また, シングルコア実行なので多コア CPU は役に立たない).
その他(より効率的と思われる方法)
mesh についている skinCluster を取得(mel)
mel で
findRelatedSkincluster <objname> ;
getInfluences などして iterate
import pymel.core as pm
skin = pm.PyNode(SKIN_CLUSTER_NODE)
# joint のリストを返す
skin.getInfluences()
# 実際に weight が設定されている joint を返す
skin.getWeightedInfluence()
# mesh, skinCluster の対応付けが一意とする(たぶん一意のはず)
# weightList は mesh の頂点ぶんある
vtx_id = 3
skin.weightList[vtx_id]
# ただ, weightList[0].w で取得できるウェイトの並びは, joint の順にはなっていない模様...?
skin.getPointsAffectedByInfluence(JOINT_NAME)
で, selectionSet(特定の vtx 範囲)として weight を取得できる. これをうまく処理するのは上記 URL を参考にしてやればいけるはず...?
T.B.W.
TODO
- より効率的な設定/取得方法を調べる続き
-
Maya のなにかメニューとか mel で一括で設定する方法があるか調べる(
skinPercent
は頂点指定が必須っぽい)