MotionBuilderのPythonスクリプトを始めたい方へ
2014/5/26
Tag: MotionBuilder,python
こんにちは、TD室の森本です。
今回はMotionBuilder(以後MB)の記事は探しても中々見つからないので
これからMBでPythonを始めたい人向けの内容を紹介していこうと思います。
(今回のスクリプトはMB2013で動作検証を行っております)
さて、前にも書いたことにあるようにMBではMAYA等のソフトと違い
操作内容がスクリプトエディタに履歴として書き出されるような機能はありません。
そのためにより取っ掛かりが難しくなっているとは思います。
また、SDKヘルプから調べようとしても、まず自分がやりたいことについて調べるために
どのクラス(FBModelNull,FBConstraint等)について調べばいいのかが分からない。
といった事態にも陥りやすいです。
そこで分からないことは実際に本体に聞いてみよう!ってことで
よく下記のようなスクリプトを準備して中身を調べながらスクリプト作成作業を進めてます。
# *- coding: utf-8 -*- from pyfbsdk import * # 全コンポーネントのリスト lComps = FBSystem().Scene.Components for lComp in lComps: if lComp.Selected==True: # リストの中から選択状態のものを取得 print "----------------------------------------------------------" print lComp.LongName print lComp.ClassName() # 選択ノードのプロパティリストを取得 lPtys=lComp.PropertyList print "<Property>" for oPty in lPtys: print "\t"+oPty.Name # 選択ノードに組み込まれてるファンクション,アトリビュートを取得 Dirs=dir(lComp) print "<dir>" for oDir in Dirs: print "\t"+oDir
このスクリプトは選択しているものの情報をScriptEditorのログに書き出します。
例えばMB2013で適当にNullを一つ作ってそのNullを選択した状態で実行してみます。
するとログには以下のようなログがでてきます。
(ログが長いので途中略している部分があります)
まずMB2013ではNullだけを選択していてもレイヤーの中の一つは常に選択された状態になっているため
選択されているレイヤーとNullの2つのオブジェクトの情報がログにでてきます。
(MB2010ではレイヤーは選択状態になっていません)
緑色の枠で囲った部分がNullの情報部分になっていて
・選択オブジェクト名
・選択オブジェクトのクラス名
・選択オブジェクトのプロパティ一覧
・選択オブジェクトの属性、関数一覧
になっています。
プロパティについてはデフォルトレイアウト時に
右下にあるプロパティウィンドウの中身のことです。
属性、関数一覧についてはそのクラス(ここではFBModelNullクラス)が実行できる機能や持っている情報の一覧になります。
MBのPythonヘルプ内でクラス名で検索すると詳細な使い方がわかるようになっています。
上記ログの例をみてわかるように
プロパティの一覧にShowがあり、属性関数の一覧にもShowがありますが
これはプロパティを直接書き換えることで表示非表示の切り替えができるし
FBModelNullクラスの機能からでも表示非表示の切り替えができます。
どのような流れで進めていくかですが基本的な流れとしては
① 実際にやりたい処理をMB上で手動でやってみる
② MB上のオブジェクトから上記スクリプトをつかってオブジェクトの情報を取得する
③ クラス名からMBのPythonヘルプをみて行いたい処理を行えるものがあるか調べる
④ ③で見つからなければプロパティを直接書き換えて対応できるか調べる
⑤ ③又は④で見つけた方法で実際にスクリプトを組む
③④で調べるとありますが実際どうやって調べればいいかというと
実際にテストをしてみて探していくのが手っ取り早いと思います。
サンプルとして先ほどのNullの表示をオンにするテストをします。
クラスのもつ属性や関数をつかって書き換えテストの場合
# *- coding: utf-8 -*- from pyfbsdk import * # ---------------------------------------------------------------------- # 書き換える場所 oClassName="FBModelNull" # テストしたいクラスの名前 # ---------------------------------------------------------------------- # 全コンポーネントのリスト lComps = FBSystem().Scene.Components for lComp in lComps: if lComp.Selected==True: # リストの中から選択状態のものを取得 if lComp.ClassName()==oClassName: # クラスの絞込み # ---------------------------------------------------------------------- # 書き換える場所 # Pythonヘルプ等で調べた方法で書き換える lComp.Show=True # ----------------------------------------------------------------------
プロパティの書き換えテストの場合
# *- coding: utf-8 -*- from pyfbsdk import * # ---------------------------------------------------------------------- # 書き換える場所 oClassName="FBModelNull" # テストしたいクラスの名前 oProperty="Show" # テストしたいプロパティ名 # ---------------------------------------------------------------------- # 全コンポーネントのリスト lComps = FBSystem().Scene.Components for lComp in lComps: if lComp.Selected==True: # リストの中から選択状態のものを取得 if lComp.ClassName()==oClassName: # クラスの絞込み # プロパティの変更テスト for oPty in lComp.PropertyList: if oPty.Name==oProperty: # 元々のプロパティの中身 print oPty.Data # ---------------------------------------------------------------------- # 書き換える場所 # プロパティの書き換え oPty.Data=True # ----------------------------------------------------------------------
上記の2つはどちらも「選択しているNullモデルの表示をONにする」という動作をします。
クラスのもつ属性や関数についてはヘルプからその使い方を調べてそれに合わせて書き換えます。
プロパティの場合はプロパティ.Dataでプロパティの中身が取り出せるので
その中身を別の設定に差し替えるように書き換えます。
(中身が元々ないような種類のプロパティの場合は中身が取り出せません)
こういった感じで試行錯誤しつつどうすれば行いたい処理が実行できるかテストします。
これで選択したオブジェクトに対して行いたい処理が実行できるようになりますが
このままではいちいち処理を入れたいオブジェクトを選択しなければなりません。
そこでオブジェクトの取得の仕方について書きます。
上記で紹介しているスクリプトは
下記の記述の部分で選択しているオブジェクトを取り出しています。
lComps = FBSystem().Scene.Components
for lComp in lComps:
if lComp.Selected==True:
1行目の「FBSystem().Scene.Components」は全コンポーネントのリストになりますが
グループだけのリストなら「FBSystem().Scene.Groups」、
コンストレインだけのリストなら「FBSystem().Scene.Constraints」、
といったように最初から目的に合わせて対象のリストを絞り込んでおくこともできます。
どのようなリストを取り出すことができるかはクラス名FBSceneのヘルプページを見れば載っています。
2行目で1行目のリストの中身を1つずつ取り出して
3行目で選択されているかどうかで選択しているものを絞り込んでいます。
3行目は2行目で取り出したものに対して条件をつけて絞り込んでいるので
この部分を用途に合わせて条件を変更することで必要なオブジェクトに対して
処理を実行できます。
例えば3行目を
if lComp.Name==”AAA”: #オブジェクトの名前がAAAか?
if not lComp.Name.find(“AAA”)==-1: #オブジェクトの名前の中にAAAが含まれているか?
のように変えれば選択ではなくオブジェクトの名前から絞り込んで条件にあったものだけ処理を実行できます。
以上のように取得したオブジェクトに対して処理を実行できるようになれば
「実行時Geometryグループ(GEOとかの名前のルールがある)の表示を全てONにする」
「実行時アセットのあるオブジェクトの名前を一括でリネームする」
等の簡単な処理を実行するスクリプトを作れます。
私がTDになったのは最初からTDを目指してたわけではなく
自分で手動で行うには面倒な処理を簡単にできるようにちょっとしたスクリプトを
書き始めてそれを続けていくうちにもう少し複雑なこともできるようになりました。
結局は複雑なことも紐解いていけば一つ一つの処理はほぼ変わらないので
まずは普段ちょっと不便だなとおもうところをスクリプトで処理していって慣れていけば
もっと自動化できる部分が増えていくと思います。
また以前のDFTalk記事でのモーションビルダースクリプトTipsや
公式に用意されているサンプルスクリプト等も併用してもらえると出来ることの幅は増えると思います。
今回はまだまだMBのPython記事が少ないので(日本語で書かれているものはさらに)
これからMBでPythonスクリプトを始めたい人向けにちょっとしたことを書いてみました。
始めたくてもどうしていいのかからない人の手助けの一つになればうれしいです。
では、また。
※免責事項※
本記事内で公開している全ての手法の有用性、安全性について、当方は一切の保証を与えるものではありません。
これらの手法を使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご活用ください
初めまして。
mayaと違いログがでないため苦労しておりますので、大変助かります。
こちらに質問していいのかわからないのですが…
pythonでテイクの切り替えをしたいのですが、可能なものでしょうか?
一覧を取り出すことには成功したのですが、ここからどうセットしたらいいのか解らず止まってしまっています。
突然で恐縮ですがよろしくお願いいたします。
takeList=[]
for aTake in FBSystem().Scene.Takes:
takeList.append(aTake.Name)
print takeList
Posted at 2018.07.13 15:34 by ku
初めまして、TD森本です。
CurrentTakeについては
FBSystem().CurrentTake
で取得変更が可能です。
例えばTakeのリストから名前で「Take 001」のTakeに切り替える場合は
from pyfbsdk import *
for aTake in FBSystem().Scene.Takes:
if aTake.Name==”Take 001″:
FBSystem().CurrentTake=aTake
break
でTakeの切り替えが出来ます。
また何か不明な点ありましたら解る範囲でお答えします。
よろしくお願いします。
Posted at 2018.07.17 11:03 by 森本@TD
TD森本様
ありがとうございます!!
FBSystem().CurrentTake=aTakeでできました!
>>また何か不明な点ありましたら解る範囲でお答えします。
ご親切にありがとうございます。
今後ともよろしくお願いいたします。
Posted at 2018.07.18 14:22 by ku