2014年01月17日

ACSを使ってみた その44 modo701 SP2

前回に引き続きACSのコントローラを左右反転させるスクリプトを作って行きたい。

今回はコントローラのルートアイテムから下ってコントローラアイテムを全て取得してリスト化する部分だ。こういうツリー構造のアイテムを探索するのは再帰的なファンクションを使うと手っ取り早い。

これがそのコード。

ACS_Items={}

def item_search(root):
 children = lx.evalN('query sceneservice item.children ? %s' % root)
 if children == None :
  return
 for item in children :
  name = lx.eval('query sceneservice item.name ? %s' % item)
  ACS_Items[name]=[item]
  item_search(item)
return

このファンクションに調べたいアイテムツリーのルートアイテムを渡すと、ツリー内の全アイテムをACS_Items辞書に登録して戻ってくる。「{ }」はカラの辞書オブジェクトを作る式だ。これを変数ACS_Itemsに割り当てている。

ACS_Items={}

ファンクションでは変数「root」に引数として渡されたアイテムIDに対して、「item.children」をクエリしてそのアイテムの子アイテムリストを取得する。もし子アイテムが無ければファンクションを終了して呼び出しもとに戻る。

子アイテムがあった場合はそれを全て巡回して以下の処理をする

for item in children :

まず子アイテムを「item.name」でクエリしてアイテムの名前を求める。アイテムを識別するにはアイテム名とアイテムIDがあって、アイテム名はアイテムリストに表示されてユーザーが自由に変更できるラベルで、アイテムIDはmodoが識別するためにつけた名前でこちらは変更出来ない。スクリプトでアイテムを操作する時はアイテムIDを使うけど、左右で対のアイテムを見つけるためにはアイテム名が必要になるのでここで取得しておくわけだ。

アイテムIDと取得したアイテム名は辞書オブジェクトの値とキーとして登録する。配列が要素を通し番号で管理するように、Pythonの辞書オブジェクトは要素を「キー」と呼ばれる文字列で管理する。

配列が要素5番に”Locator 523”という文字列の値を代入する時に

array[5] = "Locator 523"

とするのと同じように辞書でキー「L_Hand」に”Locator 523”という文字列の値を代入する時は

dic["L_Hand"] = "Locator 523"

とすればいい。辞書から値を呼び出す時も配列が要素番号で呼び出すのと同様、辞書ではキーで呼び出せばいいだけだ。

print array[5]

print dic["L_Hand"]

今回はキーをアイテム名、値をアイテムIDが入ったリストオブジェクトにしている。

ACS_Items[name]=[item]

リストにした理由はこのリストにこのアイテムと対になるアイテムのIDも記録したいからだ。

最終的にアイテム名からそのアイテムIDと対になるアイテムIDがわかるようにしたいってわけだ。

そしてこれが最大のミソなんだけど見つかった子アイテムを引数として自分自身である「item_search( )」ファンクションを呼び出す。これが「再帰的」と言われるゆえんで、呼び出されたファンクションは引数で与えたアイテムの下の層で子アイテムを探して辞書登録し、さらにそれらのアイテムに対して「item_search( )」ファンクションを呼び出す。だから1度「item_search( )」ファンクションを呼び出すとそれがさらに下位のアイテムで「item_search( )」ファンクションを呼び出し、そこで見つかったアイテムでさらに「item_search( )」ファンクションを呼び出し、アイテムが見つからなくなるまでツリー内の全てのアイテムに対してファンクションを繰り返し呼び出すことになる。結果として全てのアイテムが辞書に登録される仕組みだ。

再帰的なファンクションはこういう複雑な処理をとてもシンプルに書けるのがいいところだけど、ファンクションの呼び出しはメモリーを消費するのでリストの大きさがある程度限られている時に使うといいようだ。リストがループしていて終りが無いようなものだと帰ってこなくなるし、処理系によってはネストして呼び出せる回数に制限があるものなんかもあるので使う時は注意が必要だ。

ファンクションが定義できたらあとは前回取得したコントローラアイテムリストのルートアイテムである「〜__Custom_Rig (Folder)」のアイテムIDが入った変数「item」を渡せば、変数「ACS_Items」に「アイテム名 : [ アイテムID ] 」の形で全アイテムが入った辞書が出来上がる。

item_search(item)

この辞書を使って対になるアイテムを検索して行けばアイテムの組み合わせが出来て、左右のポーズを入れ替えできるようになるわけだ。

それではまた来週。

modo701ブログ目次



take_z_ultima at 11:30│Comments(0)TrackBack(0)modo | CG

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives