Maya Script Python UV境界の選択

import maya.cmds as cmds
import maya.mel

def select_uv_border() :
	finalBorder = []
	meshList = cmds.ls( sl= 1, o= 1 )
	pLusE = []
	for mesh in meshList :
		uvs = cmds.polyUVSet( mesh, q=True, allUVSets=True )
		cmds.select( mesh + ".map[*]" , r= 1 )
		maya.mel.eval("polySelectBorderShell 1;")
		borders = cmds.polyListComponentConversion( te= 1 )
		borders = cmds.ls( borders , fl= 1 )
		for border in borders :
			edge = cmds.polyListComponentConversion( border , tuv= 1 )
			edge = cmds.ls( edge , fl= 1 )
			if len( edge ) > 2 :
				finalBorder.append( border )
		cmds.select( mesh + ".e[*]" , r= 1 )
		maya.mel.eval("polySelectBorderShell 1;")
		if cmds.ls( sl= 1, fl= 1 ) != [] :
			pLusE.extend( cmds.ls( sl= 1, fl= 1 ) )
	if pLusE != [] :
		cmds.select( pLusE ,add= 1 )
	cmds.select( finalBorder ,add= 1 )
	cmds.select( meshList , add= 1 )
select_uv_border()

modoでは標準で付いているのですが、MayaではUV選択でしかできないかと思います。
元々はmelで書かれていたものを見つけて使っていたのですが、Pythonに書きなおしてみました。
少し前に書いたものなので、改めて見てみると、さらなる改造ができそうだったので改造しました。

 

元々のmelでは、UV境界のみの選択で、ポリゴンの切れている部分は選択してくれませんでした。
別段それでも問題ないし、この取り方だとそうするのは難しいなぁ、と諦めていましたが、出来ました。
複数のオブジェクトを選択しても単一のオブジェクトを選択しても動作します。カレントUVのUVボーダーを選択してくれます。

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になります。

 

エディタにも四捨五入を組み込みました。
エディタでは、値に関係なく全ての情報を取得し、マイナスの値が入っていればゼロにするようにしました。
始めはリアルタイムで動作するようにしてみたのですが、選択している頂点の数が多くなると大変なことになるので、ボタンを押して選択している頂点の
ウェイトを処理するようにしました。
あれやこれやと機能を付けております。しかし、これ、と感じるものは少ないかと思います。とにかく使い勝手が良いように。

 

機能を追加してデバッグの繰り返しです。

雑記91

Mayaでウェイトエディタを作ろうか、と着手したのですが、意外なほどに必要な機能は簡単に付けられました。
しかし、ペイントを実行させる所でPythonからmelを使わないとできないところがある。
うーん、悔しい。
絶対にPythonだけで出来るはずだとは思うのですが、資料が少ないので、仕方なくコマンドを実行してmelを書き写しています。

 

絵もそうだが、何かを習得するには模写、写本といったように、先人の作ったものを手本にするのが一番いい。
ということを改めて実感します。なるほどなぁ、と感心しきりです。
きちんと出来たらアップします。

 

それと、modo601、リトポにかんしては3Dcoatがあるからいいや。
と、大して触っておりませんでしたが、トポロジペン、良いですね。ちょっと感動しました。
リトポだけではなく、普通のモデリングにもある程度使えそうな気がします。

フォトショップスクリプト – ベタ塗レイヤーの色情報を取得

function getSolidFillColor(){
	var ref = new ActionReference();
	ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
	var desc = executeActionGet(ref)
	var adjList = desc.getList(stringIDToTypeID('adjustment'));
	var adjDesc = adjList.getObjectValue(0);
	var colorDesc = adjDesc.getObjectValue(stringIDToTypeID('color'));
	var Colour = new SolidColor();
	Colour.rgb.red = colorDesc.getDouble(charIDToTypeID('Rd  '));
	Colour.rgb.green = colorDesc.getDouble(charIDToTypeID('Grn '));
	Colour.rgb.blue = colorDesc.getDouble(charIDToTypeID('Bl  '))
	return Colour;
}

アドビのフォーラムで偶然見つけました。
var color = getSolidFillColor() ;
alert( color.rgb.red );
等とすると選択されているベタ塗りレイヤーの色情報を取得できます。

 

フォトショップのスクリプトで一番困るのは、どんな関数が存在するのかわからないのと、
その関数に何を入れると何が帰ってくるのか分からないことです。
どこかに情報があるのでしょうか?いつもそれで困ります。

 

しかも不思議なことに、それがわからないからアラートを出すようにして探ると、
その変数が使用される前にアラートを出すようにしても、その変数が使用されるところでアラートが出なくなる。
なので、使っている変数を順番にアラートに出すようにすると、どこで躓いているのかが分かる。
という意味の分からない仕様です。
自分が理解していないだけ、というのももちろんありますが、腑に落ちない。
そもそも疑っている。

 

フォトショップのCS6がアナウンスされています。
もっとスクリプトが使いやすくなっていないだろうか。と淡い期待を抱きますが、恐らく無理でしょう。
しかし、ともかくも長年の疑問が晴れました。公開してくれた人ありがとうございます。

Maya Script Python スキニングウェイト情報のコピペ

import maya.cmds as cmds

oJnt2 = []
oSel = cmds.ls( sl= 1, o= 1 )[0]
oSkt = cmds.listHistory( oSel )
oCls = cmds.ls( oSkt, type= "skinCluster" )[0]
oVtx = cmds.filterExpand( sm= 31 )[0]
oJnt = cmds.skinPercent( oCls, oVtx, query= 1, ib= 0, transform= None )
for oJ in oJnt :
	if oJ.find("|") != -1 :
		oJ = oJ.rsplit("|",1)[1]
	oJnt2.append( oJ )
oWei = cmds.skinPercent( oCls, oVtx, query= 1, ib= 0, value= 1 )
oDic = dict( zip( oJnt2, oWei ) )
print "{0:-^60}".format( "CopyWeight" )
for k, v in oDic.items() :
	print "{0:_<30}{1:_>30}".format( k, v )
print "\n\n"
import maya.cmds as cmds

print "{0:-^60}".format( "PasteWeight" )
for k, v in oDic.items() :
	print "{0:_<30}{1:_>30}".format( k, v )
print "\n"
oSel2 = cmds.ls( sl= 1, o= 1, fl= 1 )
oVtx2 = cmds.filterExpand( sm= 31 )
for s in oSel2 :
	oSkt2 = cmds.listHistory( s )
	oCls2 = cmds.ls( oSkt2, type= "skinCluster" )[0]
	for v in oVtx2 :
		if v.split( "." )[0] == "".join( s.split( "Shape" ) ) :
			print "{0}".format( v )
			cmds.skinPercent( oCls2, v, nrm= 0 , transformValue= ( oDic.items() ) )
print "\n\n"

上のコードがコピーで下のコードがペーストです。
2011か2012からか、標準機能でコピペは出来ます。
しかし、複数のターゲットにペースト出来なかったり(確か?記憶が定かではありません)、別オブジェクトにペースト出来なかったり(これは確かです、かな?)しました。
なので、人様が作ったスクリプトに頼っておりましたが、それも改造しなければ使えなかった様に思います。
なので、作りました。

 
頂点を選択し上のスクリプトを実行します。複数の頂点が選ばれていてもひとつの頂点の情報しか読み取りません。
そして、複数のオブジェクトや頂点を選択し、下のスクリプトを実行します。スクリプトエディタにリザルトが表示されるようになっているので、その部分を消しても使うことはできます。

 

惜しいことに、Pythonの場合グローバルの関数というものが無いため、関数化には至りませんでした。
Pickle化して、StringIOでメモリに格納。という手段も考えたのですが、StringIOで詰まりました。

今回からmayamelをインポートしなくても使えるようなスキンクラスタの取得の仕方に変更しました。
後は意味なさそうですが、同じ骨構造のシーンを読んで、jointの名前に親のジョイント名が付属されてしまう場合でも正しく動作するようにしました。

modo601 その1

modo601について、少し書きます。
小さいことですが、個人的に嬉しかったのは、初期設定>入力>選択
に「シェーディングスタイル無視」というチェックボックスが加わったことでしょうか。
これにチェックを入れると、マウスの中ボタンと左ボタンで裏側も選択するか否かを統一することができます。

 

自分はズボラなのでシェーディングによりそれらが切り替わることを覚えませんでした。
なので、いつも間違えてやり直します。
やり直すくらいなら覚えれば良いだけの話なのですが、覚えるよりも間違えてやり直す方を選んでおりました。
今回から覚える必要が全くなくなりました。
本当に下らない話ですが、自分にとってはとてもありがたいです。
そんな下らないことしか書けないのか。と突っ込まれそうですが、そのくらいうれしいのです。

 

そして、もうひとつ嬉しかったのは、マップのアルファをビューで確認できるようになったことです。
要するにマップの透明度を視認できます。これも嬉しい。
しかし、ブレンドモードは視認できない。これは悔しい。
これさえ出来ればリアルタイムモデルの制作には言うことが無くなる。
ペイントの書き味も良くなったように思います。ムラができない。
人の肌を塗るにはいい感じだ。と言い聞かせていたムラがなくなったことで、すべての責任が自分に帰ってくる。

 

UVのスナップがきちんと効くようになりました。
以前ではスナップさせるととんでもないことになるので、「融合」を使っていました。
それでも問題はないのですが、スナップできたほうがありがたい。
出来ればピクセルスナップがあれば尚ありがたい。
展開のアルゴリズムが改良されたように思います。
「面積ウェイト」という値が加わり、尚調整が可能になりました。素晴らしい。
出来ればUV対称の時は選択したら片方の選択範囲の中心にハンドルが表示されるとありがたいのですが、
これはそうはなってはおりませんでした。modoはハンドルを自由に変更できるので大した問題ではないのですが、
やはりそうであると嬉しい機能だと思います。
後、501で使用できるスクリプトは601でも使用できるのがありがたい。
内部的なコマンドが大分変わったかと思ったのですが、そこまででは無かったようです。

 

そして、スカルプトですが、以前よりは少し軽快になっているように感じます。
それでもZBrushには遠く及ばない。でも少し近づいている。そんな感じです。

 

そういえば、ウェイト。
まだバインドのやり方はわからないのですが、既にバインドされているサンプルデータを見てみました。
ウェイトの値が%表示だったので、もしや整数表記なのか?と少し期待したのですが、浮動小数点でした。
やはり今の時代そこまでしてしまうと、映像の方での使用に耐えられないのでしょう。
ゲームの方でも、ツール側で整数でも、中間データで恐らく浮動小数点に変更されてしまう。
そして、データを見て懐かしく感じてしまいましたが、LightWaveの仕様と同じです。
一つのマップで複数の骨のウェイトが表示されるのではなく、一つの骨に一つのマップ。
随分と古い記憶が蘇りました。
インフルエンスの数の設定はどうなるのだろうか?COLLADA経由で他にデータを持ってゆくことは出来るのだろうか?
非常に興味深いところです。

 

そして、始めに驚かされたのが、「丸めエッジ幅」が見つからなかったことです。
レンダリング時に表現されるシェーダでのエッジベベルです。
どうやら501の初期設定をエクスポートして601に読み込んでいたのが原因だったようで、601のデフォルトに戻したら使えるようになりました。
マテリアルのオプションとして、「スムージング角度」の下に普通にありました。
ショートカットはそれ程大幅にカスタマイズしませんが、やはり不便さを感じてしまいます。
カスタマイズは初めにやることなので、何を設定したのか忘れてしまう。

 

少しと言いながら、大分書きました。
しかし、新たな機能については殆ど書けていないし、それ程触れてもいない。
とにかく今回のバージョンアップは凄い量です。

modo601

modo601ついに発表されましたね。
びっくりしたことに発表と同時に発売です。
日本では代理店が変わり対応が遅くなりましたが、もう日本語マニュアルも用意してあるそうです。
素晴らしい、失礼しました。

 

今回はスレルトンがついに搭載され、レンダリングパスも付いたそうです。
しかも、リジッドボディー、ソフトボディー、ボリュームレンダリング。盛り沢山です。
Pythonにうつつを抜かしている間に、凄いことになっております。
うーん、まだ3Dcoatも全然触れていないのになぁ、、これは絶対買ってしまう、、高いおもちゃだ。

 

ビデオで見るかぎりは、新たな機能はまだ中途半端感が漂います。
これからなのだと思います。しかし、この値段でオールインパックの3DCGツールは素晴らしい。
しかもモデリングは抜群に良いし、プレビューレンダリングの速さは秀逸です。
それでもボクセルのレンダリングにはそれなりに掛かるようですね。

 

リトポは確かに以前に比べ充実しましたが、3Dcoatには及ばない感じです。
セミオートリトポ、凄すぎます。今までの苦労は何だったのだろう。と唖然としてしまう。

 

Mayaでウェイトエディタのツールを作ろうかと構想しておりました。
もしかしたらmodoでもそういったツールが作られるのかな?
Mayaで予習しておこう。

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

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

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