Maya Script Python numpy

numpyというライブラリーを知りました。
なんでも行列や多次元配列の扱いに特化したモジュールで、その部分の計算が格段に早くなるそうです。
で、早速インストール。
こちらのページ、Pythonのモジュールがたくさんあります。
この中ほど、numpy-MKL-1.7.1.win-amd64-py2.6.‌exeという物を入れてみました。

 

因みにこれをインストールする前にPythonの2.6をインストールする必要があります。
それはこちらにあります。
64bit環境なので、Windows X86-64 MSI Installer (2.6)をインストールしました。

 

しかし、どうやら2013ではdllを入れる必要があるようで、それだけでは使えません。
2012であれば、C:\Python26\Lib\site-packages\にできる、numpyというディレクトリを、
C:\Program Files\Autodesk\Maya2012\Python\Lib\site-packages\にコピーすれば使えます。

 

何を作ってみようか。
そんな時に思いついたのが、以前作った事がある、選択された頂点の周りの頂点の法線から平均を取り、
スムーズさせるツールです。
因みにnumpyを使わないでそれをするには、

import maya.cmds as cmds
import maya.mel

def nomal_smooth():
	gMainProgressBar = maya.mel.eval( '$tmp = $gMainProgressBar' )
	oSels = cmds.ls(sl=1)
	if oSels == []:
		return
	oVtxs = cmds.ls(cmds.polyListComponentConversion(oSels,tv=1),fl=1)
	cmds.undoInfo(swf=0)
	cmds.progressBar(gMainProgressBar,e=1,bp=1,ii=1,st='Now Smoothing...',max=len(oVtxs))
	for oVtx in oVtxs:
		oAroundNors = []
		[oAroundNors.append(cmds.polyNormalPerVertex(x,q=1,xyz=1)[0:3]) for x in cmds.ls(cmds.polyListComponentConversion(cmds.polyListComponentConversion(oVtx,tf=1),tv=1),fl=1)]
		oANorZip = zip(*oAroundNors)
		cmds.polyNormalPerVertex(oVtx,xyz=[sum(oANorZip[0])/len(oANorZip[0]),sum(oANorZip[1])/len(oANorZip[1]),sum(oANorZip[2])/len(oANorZip[2])])
		cmds.progressBar( gMainProgressBar, edit=True, step=1 )
		if cmds.progressBar(gMainProgressBar,q=1,ic=1):
			break
	cmds.progressBar( gMainProgressBar, edit=True, endProgress=True )
	cmds.undoInfo(swf=1)

nomal_smooth()

大量の頂点を選択すると、処理がとても重いことが分かります。
で、numpyで作りなおすと、

import numpy as np
import maya.cmds as cmds

def nomal_smooth_numpy_cmds():
	gMainProgressBar = maya.mel.eval( '$tmp = $gMainProgressBar' )
	oSels = cmds.ls(sl=1)
	if oSels == []:
		return
	oVtxs = cmds.ls(cmds.polyListComponentConversion(oSels,tv=1),fl=1)
	cmds.undoInfo(swf=0)
	cmds.progressBar(gMainProgressBar,e=1,bp=1,ii=1,st='Now Smoothing...',max=len(oVtxs))
	for oVtx in oVtxs:
		aroundVtx = cmds.ls(cmds.polyListComponentConversion(cmds.polyListComponentConversion(oVtx,tf=1),tv=1),fl=1)
		ar = np.transpose(np.array([cmds.polyNormalPerVertex(x,q=1,xyz=1)[0:3] for x in aroundVtx]))
		cmds.polyNormalPerVertex(oVtx,xyz=[np.mean(x) for x in ar])
		cmds.progressBar( gMainProgressBar, edit=True, step=1 )
		if cmds.progressBar(gMainProgressBar,q=1,ic=1):
			break
	cmds.progressBar( gMainProgressBar, edit=True, endProgress=True )
	cmds.undoInfo(swf=1)

nomal_smooth_numpy_cmds()

やってみると分かりますが、速さを実感できない、、
使い方が間違えているのだろうか?
で、それをpymelと併用すると、

import numpy as np
import pymel.core as pm

def nomal_smooth_numpy_pymel():
	gMainProgressBar = pm.mel.eval( '$tmp = $gMainProgressBar' )
	oSels = pm.ls(sl=1)
	if oSels == []:
		return
	oVtxs = pm.ls(pm.polyListComponentConversion(oSels,tv=1),fl=1)
	pm.undoInfo(swf=0)
	pm.progressBar(gMainProgressBar,e=1,bp=1,ii=1,st='Now Smoothing...',max=len(oVtxs))
	for oVtx in oVtxs:
		aroundVtx = pm.ls(pm.polyListComponentConversion(pm.polyListComponentConversion(oVtx,tf=1),tv=1),fl=1)
		ar = np.transpose(np.array([x.getNormals()[0] for x in aroundVtx]))
		pm.polyNormalPerVertex(oVtx,xyz=[np.mean(x) for x in ar])
		pm.progressBar( gMainProgressBar, edit=True, step=1 )
		if pm.progressBar(gMainProgressBar,q=1,ic=1):
			break
	pm.progressBar( gMainProgressBar, edit=True, endProgress=True )
	pm.undoInfo(swf=1)

nomal_smooth_numpy_pymel()

更に遅い、、
確かに記述はスッキリするのですが、高速化には至りませんでした。
更に色々と調べていると、Cythonというものを知りました。
Cのように、ビルドする必要がある、Pythonのようです。
物によってはとても高速になるが、それでも劇的に変わる、ということは無さそうです。
Mayaで使えるのだろうか?
変数や関数の型を静的に書く必要があるのなら、一層のことCを勉強したほうがいいのか?
うーん、気が向かない。
やっぱりPythonは書きやすい。

コメントする

post date*

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

トラックバックする

トラックバック用URL:

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

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

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