MayaScript Python 不正なスキニングウェイトの検出

import maya.cmds as cmds
import maya.mel

def CheckWeight():
	oErr = ""
	oRes = ""
	oSel = cmds.ls( selection=True )
	oShp = oSel[0]
	oFlg = 0
	oVcount = cmds.polyEvaluate( oShp, v=True )
	oSelv = []
	oSkt = "findRelatedSkinCluster " + oShp + ";"
	oCls = maya.mel.eval( oSkt )
	oMxc = cmds.getAttr( oCls+".maxInfluences" )
	oVtx = cmds.ls( oShp + ".vtx[*]", fl=True )

	for v in oVtx :
		oWei = cmds.skinPercent( oCls, v ,query=True, value=True )
		while 0.0 in oWei: oWei.remove(0.0)
		if len( oWei ) > oMxc :
			oFlg = 1
			oSelv.append(v)
			oErr = oErr + str(v) + u" インフルエンスが " + str(oMxc) + u" を超えています" + "\n"
			oRes = oRes + str(v) + u" インフルエンスが " + str(oMxc) + u" を超えています" + "\n"
		oWes = sum(oWei)
		if "%.2f"%oWes != "1.00" :
			oFlg = 1
			oSelv.append(v)
			oErr = oErr + str(v) + u" 合計が1ではありません [" + str(oWes) + "]\n"
			oRes = oRes + str(v) + u" 合計が1ではありません [" + str(oWes) + "]\n"

	if oFlg == 1:
		cmds.select( oSelv, r=1 )
		if len(oSelv) > 1 :
			for v in oSelv :
				cmds.select( v, add=1 )
	if oErr == "" :
		oErr = oErr + u"エラーは見つかりませんでした"+ "\n"
	cmds.confirmDialog( title=u'エラー', message=oErr, button=['Yes'], defaultButton='Yes' )
	print "result-------------------------------------------------------"
	print oRes
	print "-------------------------------------------------------------"
CheckWeight()

前回はスキニングウェイトの四捨五入を紹介しましたが、それだけだと実際にできているか分からないので、それを調査するスクリプトです。
オブジェクトを選択し、スクリプトを実行してください。

 
因みに、直接シェルフに登録する場合は、
4行目を全て削除し、それ以下の行すべてのインデント(段落)を1つずつ削除してください。
Pythonはインデントをきちんと見ているので、インデントがずれていると作動しません。
その状態で、シェルフに中ボタンドラッグをすればファイルに保存しなくても使えます。
Mayaのスクリプトエディタは、Pythonを書くのに適していないのか、スクリプトエディタでPythonの編集を行うと、良くエラーになります。
恐らくインデントが関係しているものだと思います。
大抵テキストエディタで編集して、コピペしています。

 

このスクリプトで検出する精度を変更する時は、18行目「5」の値を少なくしてゆくと精度が高まります。
後は、23行目の「%.3f」の値を変更すると合計値の精度が変えられます。

実行すると、何も問題が無ければ何も起こりません。不親切設計です。
必要があれば、ダイアログの表示やプログレスバーを追加してください。プログレスバーは前回のスクリプトからコピペすれば使えます。
問題がある場合は、その頂点を選択しスクリプトは終了します。
必要があればコンポーネントエディタなどを使い手動で調整してください。
問題の検出は、小数点以下4桁以上の値が入っている頂点。
合計して1になっていない頂点です。

 

最終的な環境にもよりますが、ゲームエンジンで使用されるデータとしてエクスポートする時に四捨五入される場合もあります。
そのデータがアスキーデータであれば、直接テキストエディタで開いて編集してしまうのも手かも知れません。

 

自分はMayaでウェイトを設定する際は、こちらのツールを使っています。
古いツールで、しかも書かれいてる機能が動作しない箇所もあります。それらの機能を使うには改造が必要です。
XSIのような感覚でウェイトを調整できます。ただ、選択した頂点全ての値が表示されるわけではなく、複数頂点を選択するとその平均値であることがちょっと難点でしょうか。

 

どうやらウェイトに関してはアバウトな部分があるようで、
色々と計算を考えたのですが、設定されている値を見て合計値が1になるように設定する方法は自分には分かりませんでした。
しかしコンポーネントエディタで桁数を変更すると勝手に良い具合に四捨五入されます。
どうやら数値が細かくなればなるほど合計の値は1に近づくので(当然ですが)、コンポーネントエディタではそのせめぎあいを勝手にしてくれているようです。
スクリプトで取得する値はそのせめぎあいが無い値が表示されます。
だから桁数を多めにして四捨五入すると程良くなり、ぎりぎりで四捨五入すると1から大きく外れてゆくのだと思います。
色々と勉強になりました。
ああ、そうだ、勉強ついでにこれをpymelに翻訳してみようか。などと考えてしまいました。

 

追記と修正2011/12/10
四捨五入ツールを修正しながらこちらを使ってみようと、中身を開いてびっくりしました、、
一体何を見て検出しているのやら、、うーんこっ恥ずかしい。
お詫ついでにエラー処理を加えておきました。
あれ、急いで更新したので、記事の内容を読んでいませんでしたが、細かい数値のウェイトを見るようにしていたのですね、、
ああ、それだったら良かったのかな?
新たなものでは、四捨五入はされることを前提に、インフルエンスの数を超えている頂点をチェック、合計が1にならない頂点をチェックです。

コメントする

post date*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トラックバックする

トラックバック用URL:

アニメーションが親切に解説されております

レンダリング、ライティングの基本が分かります

図版が見やすい美術解剖書です