Maya Script – 選択しているフェースが所属するマテリアルのフェースを選択

タイトル長いです。
図で説明すると、
2016_08_03_111
キューブの上下にそれぞれ違うマテリアルをアサインしております。
そのうちの一つのフェースを選択し、スクリプトを実行すると、そのジオメトリに設定されている同じマテリアルのフェースを選択して欲しい。
という欲求から作りました。
実行すると、
2016_08_03_112
こんな感じになるのが理想です。

 

マテリアル境界で頂点カラーによるブレンドをしたいと思い、作りました。
なので、フェースを選択して、ホットキーに割り当てたコマンドを実行するだけで、マテリアルに含まれるフェースを選択できるのが理想です。
それを、境界エッジに変更すれば、目的は果たせます。

 

とにかく早く欲しかったので、手っ取り早いpymelで作ってみました。

import pymel.core as pm

def material_face_select_pymel():
	sel = pm.ls(sl=1,l=1,fl=1)
	if not sel and type(sel[0]) != pm.nt.MeshFace:
		return
	selShape = pm.ls(sl=1,o=1)
	sg = selShape[0].inputs(type=pm.nt.ShadingEngine)
	if not sg:
		return
	msg = []
	for x in sg:
		if pm.sets(x,im=sel[0]):
			msg.append(x)
	pm.select(msg[0],r=1)

material_face_select_pymel()

とりあえず、急場はしのげましたが、これだと同じマテリアルを使用している他のノードのコンポーネントまで選択されてしまう。
という問題が発生します。
ただ、Mayaのバージョンは忘れましたが、選択範囲が勝手に保存されるので、一度オブジェクト選択モードに移行して、再び目的のジオメトリを
選択し、フェース選択に切り替えれば、問題ありません。

 

問題はないのですが、悔しいので時間が少し空いた時にMayaコマンドで作りなおすついでに、その辺りも解消しようと作りなおしました。

import maya.cmds as cmds

def material_face_select():
	sel = cmds.ls(sl=1,l=1,fl=1)
	mat = cmds.ls(mat=1)
	if not sel or not mat:
		return
	selType = sel[0].rsplit(".")
	if not selType:
		return
	if selType[-1][0] != "f" :
		return
	selShape = cmds.ls(sl=1,o=1)
	sg = []
	for m in mat:
		s = cmds.listConnections(m,s=1,type="shadingEngine")
		if s:
			sg.append(s[-1])
	if not sg:
		return
	nSel = []
	for s in sg:
		sFace = cmds.ls(cmds.sets(s,q=1),fl=1,l=1)
		if sel[0] in sFace:
			for f in sFace:
				if selType[0] == f.rsplit(".")[0]:
					nSel.append(f)
	if nSel:
		cmds.select(nSel,r=1)

material_face_select()

forループが二重になってる、、
うーん、これも余り時間がなかったので、色々と突っ込みどころはありますが、とりあえず目的は達成できております。
で、じゃあそれをさらにpymelでやったらどうなのだろう。と、改造しました。
そんなことする暇あるなら、コードをきちんとしろよ。と、突っ込みたくなるところではあるのですが、、

import pymel.core as pm

def material_face_select_pymel2():
	sel = pm.ls(sl=1,l=1,fl=1)
	if not sel and type(sel[0]) != pm.nt.MeshFace:
		return
	selType = sel[0].name().rsplit(".")
	selShape = pm.ls(sl=1,o=1)
	sg = selShape[0].inputs(type=pm.nt.ShadingEngine)
	if not sg:
		return
	nSel = []
	for x in sg:
		sFace = pm.ls(x.members(),fl=1,l=1)
		if sel[0] in sFace:
			for f in sFace:
				if selType[0] == f.name().rsplit(".")[0]:
					nSel.append(f)
	if nSel:
		pm.select(nSel,r=1)

material_face_select_pymel2()

こんな感じでしょうか?どちらにせよ二重ですが、、
因みにこれは実行しないほうが良いです。
数万ポリゴンのシーンで実行すると、しばらく帰ってこなくなります。
Mayaコマンドであれば、少し待てば帰ってきます。やはりAPIで作るべきなんでしょうねぇ。

 

とりあえず、備忘録です。

コメントする

post date*

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

トラックバックする

トラックバック用URL:

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

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

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