« 呑む?。 | トップページ | 突然 Fcurve 補完のトグル。 »

2010年12月16日 (木)

ガッデムPlot更新。

先日ここに書いた、右クリックから Plot をするツール ガッデムPlot ですが、不具合があったので更新しますた。
http://homepage3.nifty.com/jjj/XSIFiles/Plugin/JJJ_XSI_Plugins.html



Clicked Parameters でプロットする時は問題なかったのですが、Marked Parameters でプロットしようとすると、そのパラメータのアニメーションタイプがFカーブだった場合は問題ないのですが、エクスプレッションやスクリプトオペレータだった場合にエラーで止まってしまっていました。 プロットするべきパラメータを、Fカーブ以外の時にちゃんと取得できてなかったようです。 修正したので、Fカーブでもエクスプレッションでも SCOP でもコンストレインでも、ちゃんとプロットできているように見えます。

あと、Unicode で保存するのを忘れたのか、2011 では問題なかったけど 7.5 とかにインストールすると、右クリックに現れる ガッデムPlot のメニュー文字が文字化けしていましたので、修正しました。


まずまず使えるじゃないか。
最近プロットの多い仕事をしているので。





以下、関連したスクリプティングな話。


どうも、Marked Parameters の取得が、俺、まだ完全に挙動を把握しきれていないような気がします。 GetMarking コマンドでマークされたパラメータ(パラメータオブジェクトではなくパラメータリスト)を Array で取得しているのですが(他に方法を知らない)、 例えば posx だけがマークされていた場合は素直に posx が取得できますが、posx posy posz などと3軸同時にマークされていた場合は、GetMarking コマンドで取得されるものは pos で終わっているのですね。 rot の場合は euler で終わっています。 その先の個別の軸までは取得できていない。 

このままだと都合の悪いこともあり、俺としては、最終的に全てを個別のパラメータオブジェクトとして取得したいのです。 つまり kine.local.posx, kine.local.posy, kine.local.posz という風に取得したいのですが、3軸同時だと kine.local.pos しか取得できないように見えるのです。 kine.local.pos で終わるパラメータなんて無いわけで、当然パラメータオブジェクトに対するメソッドもプロパティも効きません。パラメータオブジェクトを取得できてないわけですから。



なので苦肉の策として思いついたんですが、GetMarking で取得できたものについて、全て NestedObjects を調べます。

もし GetMarking の結果が posx などと個別の軸までたどり着いていた場合は、NestedObjects は1つも存在していないように見えます。 つまり NestedObject.count がゼロかどうかを調べ、ゼロならそれは個別パラメータにたどり着いているとみなして、そのまんまパラメータオブジェクトとして取得します。


一方、GetMarking の結果が pos などで終わっていた場合、pos の下には posx, posy, posz が必ず存在するわけですから、NestedObjects のカウントはゼロにはなりません。 このことを利用して、NestedObjects の数がゼロじゃない場合だけ、NestedObjects の中身をループして内容を調べます。

そのパラメータが Expression や Scripted Operator でアニメーションされていた場合は、NestedObjects にはパラメータではなく Expression オブジェクトや Operator オブジェクトが入っているように見えます。 なので Expression かどうか、Operator かどうかを調べ、そうだったら、NestedObjects ではなくその親パラメータを取得します。つまり GetMarking した後、NestedObejects はゼロではなかったけども、これは NestedObejects に個別軸のパラメータが入っているからではなく、、エクスプレッションなどによって駆動されていたため Expression オブジェクトが入っていたためであって、すでにちゃんとそのパラメータまでたどり着けていたんだよ、だから NestedObjects じゃなくてその親のパラメータを取得するぜ、ということです。 この部分が書けていなかったのが今回のバグ修正。

そのいずれでもない場合は、NestedObjects の中には個別軸のパラメータオブジェクトのみが入っているとみなして、NestedObjects の中身を全部取得します。



一応、これでガッデムPlot は想定通りの挙動をしているようには見えるのですが、挙動の観察からしくみを推測してやっているだけなので、つまりマニュアルにそう書いてあるわけでもないので、自信ありません。 NestedObjects に違うものが入っている場合が出てくるかもしれません。 そうなるとまたエラーで止まったりするのでしょう。 まあ、その時にまたひとつ新たな挙動が判明するわけで、その対処を考えることによって経験値は上がっていくわけで、歓迎すべきことなんですがね。




にしても、マークしているパラメータを、もっと簡単に、何も考えずにパラメータオブジェクトとして取得できる方法はないもんですかね。 

そもそも Marked Parameters というものは、シーン上のオブジェクトの名前などに依存せずに posx などと操作対象のパラメータを指定できることがその目的ですよね。オブジェクト名に関わらずマークしたパラメータだけキーを打てとか、そういうことに使うんだから。 つまり特定のオブジェクトに所属するパラメータを表しているわけではない。 不特定多数のオブジェクトに対する、特定の名前のパラメータを指定するリスト(パラメータ名の記述の羅列)ですよね。

一方、パラメータオブジェクトというものは、cone.polymsh.geom.subdivu とか cube.kine.local.posx のように、conecube という特定のオブジェクトに所属する特定のパラメータを表しているものです。 特定オブジェクトの特定パラメータを表しているからこそ、ユーザが望む特定の効果を与えることができるわけですね。

このことから、GetMarking の結果をパラメータオブジェクトにすることはあり得ないし、あってはならない。

だからパラメータオブジェクトを取得しようとしたら GetMarking の結果を個別オブジェクトに接続するようなことを自分でやらないといけないと思うんですが、そしてこのツールでは実際そのようにやってますが、これがめんどくせえ。今回のように個別軸のパラメータにたどり着けてなかった場合などの処理をいちいち書かないといけない。


GetMarking の結果を、例えば Collection に食わせてやると自動的に個別オブジェクトに接続し、末端のパラメータオブジェクトにまで展開して全部 ParameterCollection にぶち込むとか、そういう機能が用意されていると助かるんだがなあ。 


誰かいい方法教えて下さい。




.

|

« 呑む?。 | トップページ | 突然 Fcurve 補完のトグル。 »

コメント

このやり方ですべて上手くいくか分からないですが、Parameterオブジェクトには、Markedというブール判定プロパティがあるみたいです。

なので、X3DObjectのParametersをループでまわして、parameter.MarkedでTrueのみ取得するって手が使えます。

ポジションの3軸をMarkedして、結果をみたら、ちゃんと取ることが出来たので、Kinematicsは大丈夫みたいです。

投稿: garu | 2010年12月16日 (木) 21時53分

Parameter.Marked は、はい、チェックしておりました。
これって、オブジェクトのパラメータ全てをループしないとダメですよね。
Kinematics 以下だけならいいけど、プロットしたいパラメータは Kinematics 以下じゃない場合もあるから、結局全部をチェックしないとダメですよね。
すんげえ数になりそう。遅そう。
という先入観で避けていました。
やってみるか。

NodeAnimatedParameters とかであらかじめ絞ればいいけど、プロットしたいのは、必ずしもアニメーションされているパラメータだとは限らないからなあ。

カスタムプロパティがある場合はどうなるんだろう? X3DObject じゃないからなあ。 X3DObject.Parameters でカスタムプロパティのパラメータまで取得できたっけ? そのうち実験してみます。



ガルさん、やはり反応してきたか! www

投稿: junki | 2010年12月17日 (金) 02時37分

こういう話は、junkiさんとしか出来ないので、飢えてるんですよ。きっとw

探したり無いだけか…。

投稿: garu | 2010年12月17日 (金) 14時38分

俺もずっと、何年も飢えていました。

最近は、GHさんとかWSさんとかIKさんとかと日常的に濃いスクリプト談義が出来るので、少し幸せでした。

そんなスクリプター達とも、もうすぐお別れです。

投稿: junki | 2010年12月18日 (土) 01時12分

いつも参考にさせて頂いております。
複雑な内容を噛み砕いて解説出来るスキルに脱帽しております。

今回は自分がお役に立てそうです。
VBScriptでしかスクリプトを書いた事がないため少々分かり辛い説明かもしれませんが、
junkiさんならばそれでも問題ないと思いますのでそれで進めます。


今回のケースではFindObjectsByMarkingAndCapabilitiesメソッドを使用すれば解決するのではないでしょうか。

まず、XSIコレクションに必要なノードを放り込んでおいて、

Set oParams = XSIコレクション.FindObjectsByMarkingAndCapabilities( Join( GetMarking, "," ), siAnimatable )

とすれば、oParamsに、XSIコレクション内で現在マーキングされているアニメーション可能なパラメータオブジェクトが格納されます。
もちろんscl/euler/posで終わっていたものも、ちゃんとした記述になった状態で拾えます。

FindObjectsByMarkingAndCapabilitiesメソッドの引数で、

Join( GetMarking, "," )

としてあるのは、GetMarkingの戻り値が配列なため、それを一旦結合してカンマ区切りの文字列として渡す必要があるためです。
文字列と言う事で、最初から"kine.local.ori.euler"と記述するとrotx/roty/rotzを拾う事が出来ます。

また、"MarkingSet"と記述すればXSIコレクションのアイテムが持っているマーキングセットを純粋に拾う事が出来ます。
アニメートされていようがいまいが、SetMarkingされていようがいまいが、マーキングセットに登録してあるパラメータオブジェクトが拾えます。

そしてSDKの該当項目にはJScriptでの例が載っていると思いますので、そちらを参考にして貰っても良いかもしれません。


簡単ですが、以上になります。
これからも記事を楽しみにしています。

投稿: boz | 2010年12月21日 (火) 01時15分

うぉっ boz さんありがとうございます! 後ほど試してみるっす

投稿: junki | 2010年12月21日 (火) 08時35分

boz さん、やってみました。

おっしゃるように、この方法を使うと、3軸いっぺんにマークしていても、ちゃんと個別の軸のパラメータオブジェクトが取得できていました。

しかし。

そのパラメータが、何もアニメーションされていない、あるいはFカーブの時は、問題なくパラメータオブジェクトが取得できているように見えます。ここまではめでたしめでだしです。 しかし Expression が入っていた場合は・・・

var aMarkings = GetMarking().toArray();
var oCol = oObjects.FindObjectsByMarkingAndCapabilities( aMarkings.join() );
これを実行して取得した結果を見ると、Expression が入っていた場合、 Parameterオブジェクトはちゃんと取得できていますが、それ以外に Compound Parameter というオブジェクトも一緒に取得されてしまっているように見えます。SCOP の時はこいつは出てきませんね。Expression の時だけに見えますね。ううむ、Parameterオブジェクトだけが欲しいのになあ。Compound Parameter は Parameterそのものではないので、Plot などに食わせるわけには行きません。

なので、FindObjectsByMarkingAndCapabilitiesの結果をループして、Parameterオブジェクトだけを取り出すという作業をしないといけないように見えます。

第2引数に siKeyable を使うと CompoundParameter は出てきませんが、Keyable Parameter から外されているパラメータを Plot したい時などには使えません。 

第2引数に siAnimatable を使った場合は、Expression があるパラメータがマークされていると、その Expression の Active パラメータ(オンオフ)まで取得されてしまいます。こちらは厳然たる Parameter ですから何も間違ってないのですが、通常これを Plot したいわけじゃないですよね。

そもそもマニュアルを見てみると、FindObjectsByMarkingAndCapabilities の戻り値は ParameterCollection ではなく、XSICollection ですね。つまり。そもそも Parameter オブジェクトだけを戻してくれるメソッドではないのですね。

その意味では、boz さんのサンプルスクリプトで set oParams = となっていますが、戻ってくるものが Parameter だとは保証されてないので、oParams とう変数名はアレかもしれません。Parameter だと思って処理してたら Parameter じゃなかったのでエラー、という事故が起こり得ると思います。

戻ってくるものが Parameter でない場合がある以上、何らかの選別ルーチンを書かなくてはいけないのは、変わらなさそうですね。でも、少なくとも俺がやっていた方法よりは遥かに良さそうなので、もう少し研究してみます。

ありがとうございました! 引き続き情報あればお願いします!

投稿: junki | 2010年12月22日 (水) 17時47分

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/217974/50307323

この記事へのトラックバック一覧です: ガッデムPlot更新。:

« 呑む?。 | トップページ | 突然 Fcurve 補完のトグル。 »