Maya Python スキニングウェイトの四捨五入 その3
Maya2013が発表されていますね。
新たなスキニングが加わるそうで、今作っているエディタもそうですが、これも2013で使えるかわかりません。
import maya.cmds as cmds def round_weight(): oShp = cmds.ls( selection=True )[0] gMainProgressBar = maya.mel.eval( '$tmp = $gMainProgressBar' ) oVcount = cmds.polyEvaluate( oShp, v=True ) oSkt = cmds.listHistory( oShp ) oCls = cmds.ls( oSkt, type= "skinCluster" )[0] [ cmds.skinCluster( oCls, inf= j, e= 1, lw= 0 ) for j in cmds.skinCluster(oCls,q=True,inf=True) ] oMxc = cmds.getAttr( oCls+".maxInfluences" ) cmds.setAttr( oCls + ".normalizeWeights", 0 ) oVtx = cmds.ls( oShp + ".vtx[*]", fl=True ) cmds.progressBar( gMainProgressBar, edit=True,beginProgress=True, status='Now Rounding...', maxValue=oVcount ) for v in oVtx : w2 = 0.0 oJnt = cmds.skinPercent( oCls, v, query= 1, transform= None ) oWei = [ x for x in cmds.skinPercent( oCls, v, query= 1, value= 1 ) if x > 0.0 ] oDic = dict(zip(oJnt,oWei)) i = len(oDic) for j,w in sorted(oDic.items(), key=lambda x:x[1]) : if i > oMxc : w = 0.0 w = float( "{0:.2f}".format( w ) ) if i != 1 : w2 += w if w2 > 1.0: w = w2 - w else : w = 1.0 - w2 oDic[j] = float( "{0:.2f}".format( w ) ) i -= 1 cmds.skinPercent( oCls, v, nrm = False , transformValue=( oDic.items() ) ) cmds.progressBar( gMainProgressBar, edit=True, step=1 ) cmds.setAttr( oCls + ".normalizeWeights", 1 ) cmds.progressBar( gMainProgressBar, edit=True, endProgress=True ) round_weight()
Mayaのスクリプトエディタにコピペして、実行させれば使えます。
変更点は、
ロックされたインフルエンスがある場合、ロックを解除して四捨五入を行います。
Maya2011からスキニングにバグがあるそうです。それが分かりました。
設定されているウェイトの値がゼロ以上のものを取得する際に、ごく稀にマイナスの値が存在します。
同じコマンドで骨の名前を取得するとマイナスの値が入った骨の名前を取得しません。
それは問題になる。しかも再現性が低い。
今回のものでは、ウェイトの値を取得する際にゼロ以下の物を排除します。
なので、ウェイト情報としては適正なのですが、マイナスの値が入った状態は治らないと思います。そういえば試すのを忘れた、いや試したかどうかを忘れた。
とにかく実行スピード重視のということで、この状態で上げておきます。
ちなみに、マイナスの数値が入っていても、実際にはそれはMayaでは無視されていて設定されているウェイトを合計しても1になります。
エディタにも四捨五入を組み込みました。
エディタでは、値に関係なく全ての情報を取得し、マイナスの値が入っていればゼロにするようにしました。
始めはリアルタイムで動作するようにしてみたのですが、選択している頂点の数が多くなると大変なことになるので、ボタンを押して選択している頂点の
ウェイトを処理するようにしました。
あれやこれやと機能を付けております。しかし、これ、と感じるものは少ないかと思います。とにかく使い勝手が良いように。
機能を追加してデバッグの繰り返しです。
コメントする
トラックバックする
トラックバック用URL: