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は書きやすい。
コメントする
トラックバックする
トラックバック用URL: