2008/11/26

Sukio Sukio Sukio Python - V

みなさまこんにちは。5回目になりました。

さて、今回は、OM、オブジェクトモデルの探し方です。
せっかくオブジェクト指向の言語Pythonを使用していますので、XSIも合わせて使ってみましょう。

その前に、オブジェクト指向とはなんでしょうか?
ワタクシも上手く伝え切れませんが、XSIをモデルに考えると、Explorerをイメージすると分かりやすいと思います。
Nullには、Primitive、Kinematics、Visibility、Display
とプロパティの引き出しがあり、そのそれぞれにパラメータを持ち、値を変えることが出来ます。
Pythonの中にもこういった階層構造があり、stringでさえオブジェクトモデルでありその下には

'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',

'index','isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join',

'ljust','lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',

'rsplit','rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate',

'upper','zfill'


と本当にたくさんの便利なメソッドが用意されています。
これらを使いこなしてこそ、Pythonを使う意味があるというもの。
OMを使わなければ、Pythonでなくても良いのです。
このように、XSIのメソッドを知るということと、Pythonのメソッドを知るということは別のことであり、両方学ばなければ十分に力が発揮されないことが理解出来ることでしょう。

では、本題に戻りましょう。

まず、テキトーに物を作って、階層構造を作って、ランダマイズを掛け、値をいじって、移動して、レンダリングをオフ、グループを作成して、というCMのログを見てみます。


Application.NewScene("", "")
Application.GetPrim("Null", "", "", "")
Application.CreatePrim("Sphere", "MeshSurface", "", "")
Application.CopyPaste("sphere", "", "null", 1)
Application.ApplyOp("Randomize", "sphere", 3, "siPersistentOperation", "", 0)
Application.SetValue("sphere.polymsh.randomizeop.amplx", 2, "")
Application.SetValue("sphere.polymsh.randomizeop.amply", 2, "")
Application.SetValue("sphere.polymsh.randomizeop.amplz", 2, "")
Application.Translate("", 1, 0, 0, "siAbsolute", "siPivot", "siObj", "siX", "", "", "", "", "","", "", "", "", 0, "")
Application.Translate("", 0, 1, 0, "siAbsolute", "siPivot", "siObj", "siY", "", "", "", "", "","", "", "", "", 0, "")
Application.SetValue("sphere.visibility.rendvis", 0, "")
Application.CreateGroup("", "", "")


こんな感じです。
多くのスクリプトは

Application.SetValue(oObj+".polymsh.randomizeop.amplx", 2, "")

などして、汎用性を高めているに留まっています。
これを実行しても、立派にスクリプトと言えるでしょう。
ですが、ちょっと見にくい感じです。
ですので、もう一段階レベルを上げる事を考えて見ます。
このCMをほとんどOMに変えてみます。


app=Application
app.NewScene()
oRoot = app.ActiveSceneRoot
oNull = oRoot.AddNull()
oObj = oNull.AddGeometry('Sphere','MeshSurface')
oOp = XSIFactory.CreateObjectFromPreset( "Randomize", "Operators" )
oOp.connect(oObj)
oOp.amplx.Value = 2
oOp.amply.Value = 2
oOp.amplz.Value = 2
oObj.posx.Value = 1
oObj.posy.Value = 1
oObj.rendvis.Value = False
oRoot.AddGroup(oObj)


物凄くスッキリしました。
そして、実行すると一瞬で返ってきます。
CMは、NewScene()のみです。

app=Application

まず、Applicationはとても長いので、appと短い変数にしてあげます。
xsiとしている人も居ます。自分が分かればOKです。

さて、Scene_Rootは、何を実行すれば取得出来るでしょうか?
ApplicationのSDKマニュアルを見てみましょう。
このオブジェクトには、これだけのメソッド、プロパティが用意されています。

メソッド
ActivateWorkgroup  AddCommand  AddWorkgroup  Advise  
ClassName  CreateAddon  CreateCommand  CreateProject  
ExecuteScript  ExecuteScriptCode  ExecuteScriptCommand  GetCommandByScriptingName  
InstallAddon  IsClassOf  IsEqualTo  LoadPlugin  
LogMessage  RemoveCommand  RemoveWorkgroup  RescanWorkgroups  
Unadvise  UnInstallAddon  UnloadPlugin  UpdatePlugins  
Version           

プロパティ
ActiveProject  ActiveSceneRoot  ActiveToolName  Application  
Categories  Commands  Desktop  Devices  
Dictionary  EventInfos  Filters  FullName  
Help  InstallationPath  Interactive  License  
Name  NestedObjects  Origin  OriginPath  
Parent  Platform  Plugins  Preferences  
Selection  StatusBar  Type  Workgroups  


たくさんありますね。

Application.Selection

としてあげれば、選択されたものが取得出来ます。
肝心のScene_Rootですが、プロパティの2つ目、ActiveSceneRootがそれに当たります。

oRoot = app.ActiveSceneRoot

Scene_Rootに行う処理は、2回ありますので、取り合えず変数oRootに入れておきます。
次に、ActiveSceneRootにNullを追加したいので、ActiveSceneRootのページに行き戻り値Modelというリンクを辿ってみましょう。
これまた物凄くたくさんのメソッド群ですね。
ここからNullが出そうなものはAddNullというメソッドを利用しようと思います。

oNull = oRoot.AddNull()

またまたリンクを辿るとAddNullには、ひとつ引数を与えられるみたいです。
Stringを与えれば、その名前で追加します。

AddNull('null_generate_by_script')

などですね。今回は、省略します。
ついでに出したNullは、oNullという変数に入れてあげます。

oObj = oNull.AddGeometry('Sphere','MeshSurface')

nullの子供にSphereを加えたいので、AddGeometry()を使います。第一引数は、プリセット。第二引数は、メッシュなのかナーブスかです。これもついでにoObjとしておきます。

oOp = XSIFactory.CreateObjectFromPreset( "Randomize", "Operators" )
oOp.connect(oObj)

オペレータは、ApplyOp()を主に使いますが、今回は、完全OMにしてみました。
Randomizeオペレータを一度シーンに呼び出し、適用させたいオブジェクト(この場合oObjです)にコネクトします。
ですが、ApplyOp()はとても便利ですので、そのまま使ったほうが良いときがほとんどです。
この場合は

app.ApplyOp("Randomize",oObj)

でOKでしょう。
ただし、返り値が問題です。
コマンド、ApplyOp()は、配列のXSICollectionで返ってきてしまいます。
オペレータオブジェクトの外側にXSICollectionという殻が付いている状態です。
(OperatorObject)←こんな感じ。

ですので、殻の中身を食べたいのでこの様に大抵(0)を付けてあげて、0番目の配列を選んであげます。
これにより、オペレータオブジェクトを直に変数に入れています。

oOp = app.ApplyOp("Randomize",oObj)(0)

こんな感じですね。oOpには、ランダマイズオペレータが入っています。
それでは、ランダマイズオペレータのDisplacementをXYZ全て2にします。
Operatorで検索をかけ、Operatorページに行ってみましょう。
おや?アンプリチュードの値を変えられそうなメソッド、プロパティは、無さそうです。
そうなのです。パラメータの値は、いちいちマニュアルには書いて居ないのです。
パラメータの名前を知るには、オペレータを選択して、Inspectし、Markingします。
Xをクリックしてみましょう。
するとログには、こう出ます。

Application.SetMarking("amplx")

DisplacementのXの値は、"amplx"という名前なのが分かりました。
ですので、この値をセットするには

oOp.amplx.Value = 2
oOp.amply.Value = 2
oOp.amplz.Value = 2

このように書きます。
本来ですと

oOp.Parameters("amplx").Value = 2

と書きます。
これはショートカットがききますので、ダイレクトにも書くことが出来ます。
ショートカットで検索すれば、いろいろ出てきますので、参考にしましょう。
出来ないものと出来るものがあるので、注意です。
出来なかったら、Parametersを使えばOKです。

oObj.posx.Value = 1
oObj.posy.Value = 1

Kinematicsも同様の探し方です。
ショートカットを使いましょう。
本来の書き方は

oObj.Kinematics.Local.posx.Value = 1

です。
さて、次は、VisibilityのRenderViewのチェックをオフです。
これもショートカットが存在します。
良く使うものには大抵ついています。

oObj.rendvis.Value = False

これでOKです。

oObj.Properties("Visibility").Parameters("rendvis").Value

どちらでもといった感じでしょうか。
ちなみに、Explorerで、四角いノードは、プロパティを示しています。
名前が分かれば、Propertiesで取得出来ます。

最後に、グループです。
グループは、モデルに付くものです。ですので、Modelのマニュアルを覗いて見ると
ありました、AddGroup()。
これを使用しましょう。

oRoot.AddGroup(oObj)

第一引数は、メンバーを入れます。
ここに入るのは、OMでないと受け付けてくれません。
OMで処理するには、OMを使用しなければなりません。

Application.CreateGroup(sName,oObj)

逆に、CMは、StringでもOMでも入れればGroupに入れてくれるようです。
融通はこちらのほうが上でしょうか。

現存のグループの名前が分かっている場合の取得方法は

Application.ActiveSceneRoot.Groups("ABC")

とすれば、ABCという名前のグループが取得出来ます。
こちらも便利でしょ?

という感じです。
未だPythonのOMには、たどり着きませんでしたが、いかがでしたか?
今回は、Pythonの部分に全く触れていないので、この説明は、vbでもjsでも同じことが言えます。

題材をちょっと間違えたかもなぁ・・・ω
ま、いっか。

OMには、いろんなメリットがあり、必要なオブジェクトに瞬時にアクセスすることが出来ます。
そして、処理スピードには、天と地の差が開く事になります。
覚えるのは結構大変ですが、SDKマニュアルとお友達になれば、いつでも助けてくれることでしょう。

というわけで、次回は、Pythonの使い方に注目してみましょう。
String、List辺りをやってみようと思います。
ファイル操作もやってみてもいいかも知れません。

それでは、またお会い出来るのを心待ちにしてます。

おたのしみに。

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...