マークされたパラメータの取得。
現在マークされているパラメータをパラメータオブジェクトのコレクションとして取得するのが、意外と厄介に思えるのですよ。
問題点は、以前、この記事で詳しく書きました。
コメント欄で、複数のお方と、濃い会話をしています。勉強になりました。
その記事で勉強したことを元に、パラメータオブジェクトを取得するファンクションを2つ載せてみます。
でも、この2つは、どんな場合でも上手く行くのか、まだわかりません。
一つ目は上の記事のガッデムPlotというツールの中から切り出したものです。
JScript
------------------------------------------------------------
var oMarkedParams = GetTheFuckMarkedParams( Selection )
if ( oMarkedParams )
{
Logmessage( "マークされたパラメータ : " + oMarkedParams.count );
for ( var i=0; i<oMarkedParams.count; i++ )
{
Logmessage( " (" + (i+1) + ") " + oMarkedParams(i) );
}
}
else
{
Logmessage( "fuck you." );
}
function GetTheFuckMarkedParams( oObjects )
{
MarkingList = GetMarking( );
if ( MarkingList != null )
{
var oMarkedParams = XSIFactory.CreateObject( "XSI.Collection" );
oMarkedParams.unique = true;
var aMarkedParams = new VBArray( MarkingList ).toArray( );
for ( var i=0; i<aMarkedParams.length; i++ )
{
for ( var j=0; j<oObjects.count; j++ )
{
var oParam = Dictionary.GetObject( oObjects(j) + "." + aMarkedParams[i], false );
if ( oParam )
{
// XYZ 同時にマークされてるためにマーキングリストが scl/euler/pos とかで終わってる場合は
// NestedObjects で XYZ 個別パラメータを取得
// Expression や Op の場合も NestedObjects に引っかかるのでトラップ
var oNestedParams = oParam.NestedObjects;
if ( oNestedParams.count != 0 )
{
for ( var k=0; k<oNestedParams.count; k++ )
{
if ( oNestedParams(k).IsClassOf( siExpressionID ) )
{
oMarkedParams.Add( oParam ); // NestedObjects が Expression だった場合
}
else if ( oNestedParams(k).IsClassOf( siOperatorID ) || oNestedParams(k).IsClassOf( siCustomOperatorID ))
{
oMarkedParams.Add( oParam ); // NestedObjects が Op だった場合
}
else
{
oMarkedParams.Add( oNestedParams(k) ); // 上記以外は、個別 XYZ。 たぶん。 自信ない。
}
}
}
else
{
oMarkedParams.Add( oParam ); // posx とかなら、NestedObjects は無い
}
}
}
}
if ( oMarkedParams.count != 0 )
{
return oMarkedParams;
}
else
{
return null;
}
}
else
{
return null;
}
}
------------------------------------------------------------
全然エレガントではなく、ちょっと黒魔術っぽいですが、まあ、仕事はできてます。
もうひとつは、コメント欄で教えてもらったものですね。
JScript
------------------------------------------------------------
var oMarkedParams = GetTheFuckMarkedParams( Selection )
if ( oMarkedParams )
{
Logmessage( "マークされたパラメータ : " + oMarkedParams.count );
for ( var i=0; i<oMarkedParams.count; i++ )
{
Logmessage( " (" + (i+1) + ") " + oMarkedParams(i) );
}
}
else
{
Logmessage( "fuck you." );
}
function GetTheFuckMarkedParams( oObjects )
{
var oCol = XSIFactory.CreateObject( "XSI.Collection" );
oCol.items = oObjects;
var aMarkings = GetMarking().toArray();
var oCol2 = oCol.FindObjectsByMarkingAndCapabilities( aMarkings.join(), 0 );
var oMarkedParams = XSIFactory.CreateObject( "XSI.Collection" );
for ( var i=0; i<oCol2.count; i++ )
{
// Expression が入っていた場合、Parameter オブジェクト以外に、
// CompoundParameter というタイプのものもコレクションに入ってしまうため、
// Parameter オブジェクトのみを選別するループが必要と思われる
// デバッグ用
//Logmessage( oCol2(i).fullname + " = type :" + oCol2(i).type );
if ( oCol2(i).type == "Parameter" )
{
oMarkedParams.Add( oCol2(i) );
}
}
if ( oMarkedParams.count != 0 )
{
return oMarkedParams;
}
else
{
return null;
}
}
------------------------------------------------------------
FindObjectsByMarkingAndCapabilities を使っていますが、戻り値が Parameter だけなら楽なんだけど、 Compound Parameter とかいうタイプのオブジェクトが混じることがあるんですよね。 パラメータに Expression が入っていると、こいつが混じる気がします。なので選り分けが必要になります。
その選り分けに、上のコードでは type が "Parameter" かどうかで判別していますが、これを ClassID で選り分けようと IsClassOf( siParameterID ) を使うと、この Compound Parameter も siParameterID にヒットしてしまうようで、選り分けにならないんですよ。 なので type を使うことにしています。
ガッデムPlot の時は、このツールの中核である PlotAndApplyAction コマンドがパラメータコレクションを引数として要求してくるので、上のようなファンクションを書いたのでした。 そして今書いている途中の StoreAction コマンドを使ったツールも同様です。 StoreAction コマンドが中核になるわけですが、引数でパラメータコレクションを渡さねばなりません。
もちろんストアすべきパラメータが最初から決まっていれば楽ちんですが、「ユーザが現在マークしているパラメータ」となると、イッキに難易度が上がる気がします。 ひとまず上のどちらかの方法でインプリメントしてみます。
もっといい方法ないでしょうかねえ。
っていうか、SDK 側でそのものズバリの機能を用意して欲しいです。
嘔吐デスク様。
.
| 固定リンク
コメント