2008/10/25

Sukio Sukio Sukio Python - III

Python好きよ好きよ好きよな初心者のためのPython講座その3です。

今回で、恐らく脱落者続出だと思われますが、意味が全然分からなくても

「ああ、オレってだめぽ・・・。スクリプト向いてないぽ・・・。」

って、思わないで欲しいです。
一朝一夕で覚えられたら、この記事を読まなくてもPythonを使いこなせるはずです。
Pythonは、いつまでも貴方を待ち続けます。

さて、始めましょう。

今回は、def文です。
defは、他の言語の言う所の、functionに当たります。
同じスクリプトで、何度も同じ内容のものを繰り返すときや、処理を見やすくす
るとき、そして、Pythonでは、前に保存したスクリプトのdefを呼び出すことも、簡単に行えます。

まず、何度も使うといえば

Application.LogMessage()

この文は、何度もデバッグのためなどに多用することでしょう。
ですので、例えばログ文を少し豪華にしたいなどのときや、何回も使うものをまとめておきます。

def log(pMsg):
  Application.LogMessage(pMsg)
  return '+ + + ' + pMsg + ' + + +'

log('abc')
log(r'C:\Softimage\XSI_7.0\Application\bin\XSI.exe')
sReturn = log('I love XSI')
log(sReturn)

このようにして、LogMessageを簡略化出来ます。

Pythonの場合、defを変数にすることが出来、最良手はコレですが。
log = Application.LogMessage
log('abc')

logというファンクションを作り、受け取る変数pMsgをセットします。これは、
何個でも作成することが出来ます。

def log(pMsg,pType):

こんな感じです。

下の、logファンクションで、'abc'というストリングを第1引数に入れ実行する
と、上部のpMsgという変数に、'abc'が代入され、

Application.LogMessage('abc')が実行されるシンプルなファンクションです。

def文の中に、return文がありますが、コレは返ってくる値をセットすることが出来ます。
無くても動作します。
'I love XSI'がpMsgに代入されたとすると、返ってくるのは、'+ + + I love XSI + + +'になり、上記の例では、sReturnに代入されるという仕組みです。

r'C:\Softimage\XSI_7.0\Application\bin\XSI.exe'

この文で、スクリプトを書いたことがある方は、へぇ~と思いますが、Pythonには、Row Stringという型が用意されており、バックスラッシュ'\'を通常の文字として認識させることが可能です。
例えば、JScriptで書くには、このようにしなければ、'\'は認識できません。

'C:\\Softimage\\XSI_7.0\\Application\\bin\\XSI.exe'

バックスラッシュの嵐が訪れる事になります。

String型で'\'は、エスケープ文字と呼ばれ、改行やタブを表現することが出来ます。
これにはいろいろあります。

\\:バックスラッシュ (\)
\':一重引用符 (')
\":二重引用符 (")
\a:ASCII 端末ベル (BEL)
\b:ASCII バックスペース (BS)
\f:ASCII フォームフィード (FF)
\n:ASCII 行送り、改行 (LF)
\r:ASCII 復帰 (CR)
\t:ASCII 水平タブ (TAB)
\v:ASCII 水平タブ (VT)
\uxxxx:16-bit の 16 進数値 xxxx を持つ文字 (Unicode のみ)
\Uxxxxxxxx:32-bit の 16 進数値 xxxxxxxx を持つ文字 (Unicode のみ)
\ooo:8 進数値 ooo を持つ文字
\xhh:16 進数値 hh を持つ文字
\N{name}:Unicode データベース中で名前 name を持つ文字 (Unicode のみ)

いろいろありますが、何のことかサッパリ。って感じでしょうか。
ここで、使うだろうなっていうのは、バックスラッシュ(\)、ダブルクォーテーション(")、改行、タブくらいでしょうか。
それだけ覚えておけば、豪華なLogMessageや、ログとしてテキスト吐き出しをするときなど、応用が可能です。

さてそれでは、defを絡めつつ、PickSessionを使用して、動作するScriptを書いて見ましょう。

1. Pickする度に、原点に移動する。
2. 終了するには、右クリックする。

という内容にしましょう。

まず、たくさんのNullを出してバラバラに配置しておきます。
Iで作ったScriptを実行してもOKです。
もちろん、自分で作成されるのがベストです。


def MatchTransformationPickElement():
  oBtn = 1
  while(oBtn != 0):
    oBtn,oMdf,oElm = app.PickElement()
    if oBtn==0: log('Done'); break
    app.ResetTransform(oElm)
    log(oElm)

app = Application
log = app.LogMessage
MatchTransformationPickElement()


こんな感じでしょうか。内容を見ていきましょう。
プログラム的に言えば、上から順に実行されて行きますが、defに関しては

一度メモリに溜め込んで、他の行で実行されて初めて効力を発揮する

というニュアンスです。
このコードは

app = Applicationが一番最初に実行されます。
次に、log = app.LogMessage
次に、作ったファンクションである

MatchTransformationPickElement()

が実行されます。
oBtn = 1 や whileなどがありますが、まず、注目していただきたいのは、PickElement()です。
実は、PickElement()もファンクションなのです。
PickElement()を実行すると、Picking Modeになります。
そして、ユーザーがマウスボタンを押すと3つの戻り値、Return Valueを得ます。

ButtonPressed, ModifierPressed, PickedElement

ButtonPressedは、なんのボタンを押したか。
1:左クリック
2:中クリック
0:右クリック
このような数字が返ってきます。

ModifierPressedは、装飾キーは押しているか。
0:なし
1:+Shiftクリック
2:+Ctrlクリック
3:+Shift+Ctrlクリック
今回は、使いません。

最後のPickedElementは、XSIのオブジェクトを返します。
詳しくはPickElementをハイライトして、マニュアルを見てみましょう。

oBtn, oMdf, oElm = app.PickElement()

変数を並べておけば、それぞれに代入されます。
左クリックでNullを選んだとすると、oBtnに1が、oMdfには0、oElmには、Nullが入る事になります。
次の文に進みます。

if oBtn==0: log('Done'); break
app.ResetTransform(oElm)

前回やった、if文ですが、このようにセミコロン(;)で改行を代用しこのように書くことが出来ます。
つまり、oBtnが0のとき、これは、右クリックしたときに、

log('Done')
break

を実行することを意味します。
終了したいので'Done'とログし、break文で、whileを抜けます。
この場合、defは、もう何もないので、ココで終わります。
breakを実行すると、forwhiledefの途中で終了出来るのです。

左クリックをした場合、ifは、スルーされ

app.ResetTransform(oElm)

が実行され、Nullが原点に戻ります。
実は、ここでスクリプトは、終わりません。それはwhile文というものがあるからです。
while文は、条件式がTrueであれば、ずーっといつまでも実行し続けるというものです。
if文のループ版みたいな感じでしょうか。かなり強力です。
しかし、while文を多用するのはあまりオススメしません。
一歩間違うと、いつまでたっても終わらないスクリプトが完成してしまいます。
ちょっと恐ろしい文です。

while(oBtn != 0):

は、oBtnが、0じゃないとき。つまり、右クリックじゃないときにずーっと実行しなさいという意味になります。
def文のはじめに

oBtn = 1

を定義しているのは、whileに一番最初に入ったとき、oBtnという変数は存在しませんので、エラーになるのを回避するためです。

さて、こんな感じですが、お分かりになりましたでしょうか?
defは結構つかみにくいものであったと記憶してますので、無理に使わなくてもスクリプトを書くことは出来ます。
ですが、構造が理解できると、必ず使うようになります。
少しずつ覚えて行くと良いでしょう。

今回も物凄く長くなってしまいました・・・。
スクリプトは、細かい定義がたくさんあって、説明するのが大変です。
もうちょっとシンプルに行きたいものです。

次回は、GUIの作成をしてみたいと思います。
カスタムパラメータを作り、ボタンをプチっとしたら、何かが起こるというものです。
これが出来れば、結構面白い事が出来るでしょう。
楽しみの幅が広がりますね。

ではでは、またの機会に・・・。

0 件のコメント:

Perforce: 複数のワークスペースを更新するバッチ

batを叩けば全部更新。 @echo off set P4PORT=x.x.x.x:xxxx set P4USER=user set P4PASSWD=password echo %P4PORT% echo %P4USER% echo %P4PASSWD% echo %P4PAS...