Maya Script Pyton – Mayaからフォトショップに送る その2

Mayaからフォトショップに送る方法その2です。
Pythonのwin32apiを使います。
win32api Pythonで調べるとライブラリを見つけられるかと思います。

 

Pythonのバージョンにあったものが必要で、2014では2.7それ以前では2.6のPythonバージョンの物をインストールすれば
大丈夫だと思います。
ただ、それをインストールしてもインストールしたマシンでしか、使用することができないようなので、
MayaでPythonパスと環境変数の追加をする必要があります。
win32apiを入れると、
C:\Python27\Lib\site-packages\
に色々と追加されます。
追加される項目は、
adodbapi
isapi
pythonwin
pywin32_system32
win32
win32com
win32comext
pythoncom.py
pythoncom.pyc
pythoncom.pyo
PyWin32.chm
pywin32.pth
pywin32.version.txt
pywin32-218-py2.7.egg-info
のようです。
全てが必要なわけではありませんが、ネットワークに置いて、他の人に使って貰う場合は、
共有ディレクトリに「site-packages」というディレクトリを作成し、そこに上記のものを全て入れてしまうのが
楽かと思います。
Pythonパスの追加は、スクリプトエディタで、

import sys
sys.path.append("Z:/site-packages")

などとすれば追加が可能です。
userSetup.pyに書くなりして共有が必要です。
環境変数の追加は、

import os
pywinPath = "Z:/site-packages/pywin32_system32"
print pywinPath in os.environ.get("PATH")
if not pywinPath in os.environ.get("PATH"):
	os.environ["PATH"] =  os.environ.get("PATH") + ";" + pywinPath

とすればMayaを起動している間は環境変数にパスを追加できるようです。
恐らくこれでwin32apiを使う準備が整ったかと思います。
win32apiがあると、Windowsで設定される読み取り専用属性が解除できます。
解除は、

import pymel.util.path as pmp
import win32file,win32con

Path = pmp("C:\\test")
for x in Path.walk():
	win32file.SetFileAttributes(x,win32con.FILE_ATTRIBUTE_NORMAL)

のようにするとC:\\test以下の全てのファイルの解除を行えます。

 

肝心のフォトショップに送信する方法は、

import win32com.client

texFile =  "C:\\test\\test.tga"
jsPath = "E:\\test\\test.js"

ps = win32com.client.Dispatch("Photoshop.Application")
ps.Open(texFile)
ps.DoJavaScriptFile(jsPath,[],1)

とすると送信できます。
Mayaからフォトショップにコマンドを送信するにはVBでないとダメだそうで、仕方なくフォトショップのサンプルにある
VBのスクリプトをいつくか見てみたのですが、最終的にジャバスクリプトを実行して処理しているものが多かったので、
真似してJavaScriptを実行するようにしました。
VBできちんとコマンドを書けばテクスチャのファイルパスを操作することもPythonを使ってできるので、
楽に色々できるかと思いますが、VBを書くのが面倒くさい。
今のところこれで事足りるからいいや。と、現状満足です。

Maya Script Pymel – スケール変更

pymelやはり便利です。
最近はベクトルの計算なんかもほんの少しですが、やっております。
で、特定のノードのスケール変更です。
リグを作った後に見難いのでスケールを変えたいときなどに使えるかと思います。

import pymel.core as pm

rigNodes = [x for x in pm.ls(type=pm.nt.Transform) if "_Rig" == x.name()[-4:]]
if rigNodes:
	pDic = dict([x,x.getParent()] for x in rigNodes)
	[x.setParent(None) for x in rigNodes]
	[[x.sx.unlock(),x.sy.unlock(),x.sz.unlock(),x.tx.unlock(),x.ty.unlock(),x.tz.unlock()] for x in rigNodes]
	[x.setScale(pm.datatypes.Vector(x.getScale())*2) for x in rigNodes]
	[k.setParent(v) for k,v in pDic.items()]

シーン内に「_Rig」で終わるトランスフォームノードに対してスケールを変更します。

 

ここで役に立ったのが、「pm.datatypes.Vector()」通常getScale()メソッドで取得できる値はリストで、
ベクトルの計算はできない。
しかし、上記の物を使うとベクトルとして扱えるので、計算が楽になる。
これは面白い。

Maya Script Python – Mayaからフォトショップでスクリプトを実行

随分と間が開きました。
ひたすらとスクリプトを作る日々です。

 

色々と勉強できたので、忘れないように書いておきます。
Mayaに読み込まれているテクスチャファイルを特定の処理を施すためにフォトショップに持って行きたい時があります。
そんな時のための方法。まずはその一。

import pymel.core as pm
import os,os.path
import subprocess

#フォトショップアプリケーションのパスの例。環境によって変えてください。
psExe = "C:\\Program Files (x86)\\Adobe\\Adobe Photoshop CS2\\Photoshop.exe"

#用意したジャバスクリプトのパスの例。
jsPath = "E:\\test\\test.js"

def send_ps():
	files = pm.ls(typ=pm.nt.File,type=pm.nt.MentalrayTexture)
	if not files:
		pm.system.displayWarning(u"テクスチャファイルが見つかりませんでした")
		return
	filesPath = [x.ftn.get().replace("/","\\") for x in files if os.path.exists(x.ftn.get()) and ".tga" in x.ftn.get().lower()]
	if not filesPath:
		pm.system.displayWarning(u"処理できるテクスチャファイルが見つかりませんでした")
		return

	subprocess.Popen(psExe+" "+" ".join(filePath)+" "+jsPath)
send_ps()

サブプロセスを使っています。
フォトショップexeのパスと、ファイルのパスと実行したいジャバスクリプトのパスをつなげて送るとスクリプトが自動で実行されます。
中々便利。

 

因みにosやos.pathなんかは実はpymelのutilに同じものが入っています。
ファイルの削除やディレクトリのコピーにいちいち違うモジュールを読み込むよりも一つで済むならば、そちらのほうが楽だ。
また今度違う方法を紹介します。

MayaScript Python – melで作られたUIの値をPythonで変更する方法

melで作成されたエクスポートウィンドウなんかの値を変えたい時はありませんか?
ゲームCGの仕事をしていると、良くあります。多分。
毎回決まったことを入力するだけですが、シーン名やノード名を取ってくることがあります。
直接そのコマンドにアクセスできれば良いのですが、そうも行かない時はエクスポートのウィンドウに入れるべきテキストをスクリプトで入れてしまいます。
で、そのスクリプトがmelで書かれている場合、どうすればPythonで取得できるかという方法です。
オブジェクトに名前が設定されている場合は簡単です。
エクスポートウィンドウを開き、

import pymel.core as pm

textF = pm.textField("test",e=1)
textF.setText("TEST")

とやってしまうと、簡単に変更可能です。
問題なのは、オブジェクト名が設定されておらず、変数に入っている場合です。
調べてみるとMayaのマニュアルにありました。

import pymel.core as pm

temp = pm.mel.eval("$temp = $test")
textF = pm.textField(temp,e=1)
textF.setText("TEST")

この場合melの変数「$test」に変更したいUIオブジェクトが入っています。
それをmel上で「$temp」などの適当な名前の変数に入れてしまいます。
更にそれを「temp」(名前は適当)というPythonの変数に入れて使うそうです。
なるほどこれは便利だ。

 

最近は今更ながらにPySideをやっております。
日本語はおろか、英語のドキュメントも少ない、、
しかしその威力は絶大だ。

 

どうすればよりプログラムの理解が深まるのだろうか。と考えておりましたが、
ある程度まで来たらUIの勉強をするのが良い。そんな事を発見しました。
PyQtやPySideに比べるとMayaコマンドのUIはおもちゃのように見えてくる。
でも手軽で良い。

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

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

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