myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

Selection.Clear || DeselectAll ?

昨日はググっていたらJunkiさんの昔の記事にたどり着きました。

GetValue("SelectionList") と Selection の違いは色々実験してから分かったんですけど、この記事のコメントをもっと早く読めば苦労せずにすんだのに。

最後にgaruさんとJunkiさんのコメントにSelection.ClearとDeselectAllの話になっています。

その記事に載っていない自分の解釈です:

Selection.ClearとDeselectAllの違いは2つあります。

スピード

あの記事にも載っていますが、スクリプトエディターから実行するとスピードが全然違います。
しかし、本当はそんなに差が大きくないんですよ。

Selection.Clear は OMなのでコマンドログを残しません。
速いです。

DeselectAll はコマンドなので、コマンドログを残します。
コマンドログを残すことによって遅くなってしまいます。
しかし、コマンドログをOFFにすれば大した差が出ません


では、実験してみましょう。

ヌルを作成して、そのヌルを選択して、選択解除 の100回の繰り返し。
最後にヌルを削除して、これで何ミリ秒が掛かったをログに残します。

コードを弄りたくない人は最後にPPG付きのテストスクリプトも載せていますのでそっちを使ったほうが楽でしょう。


var obj = GetPrim("null");
var tStart = new Date();

for( var i=0; i<100; i++ ){
Select.Add(obj); //コマンド残さない Select でオブジェクト選択
//Selection.Clear() ;
DeselectAll() ;
}
DeleteObj(obj);

var tEnd = new Date();
LogMessage((tEnd.getTime()-tStart.getTime())/1000) ;



そして、ログをオフにするため以下のコードを上記のコードの頭に追記します。

// Turn Log Off
var prefs = Application.Preferences;
prefs.SetPreferenceValue( "scripting.cmdlog", false );




実験結果は

Selection.Clear    0.174
DeselectAll(No Log) 0.201
DeselectAll(Log)  1.212
        

コマンドログをオフにしても、スクリプト完了する時にプリファレンスが元に戻るので安心していじってて良いです。

なので結論としてコマンドログが要らない時に、オフにしたほうが良いでしょう。


しかし!まぁ、そんな単純なことじゃないんです。


スクリプトをコマンド化にするとコマンドログが出ません。

先日のプラグインの記事にも説明しましたが、スクリプトファイルでボタンを作るとコマンド化されます。


じゃあ、スクリプトにLog offコードを付けなくて良いじゃん。


そうかもしれないけど、PPGを作るとPPGの_OnClickedファンクションなどでログが出てしまいます

なので、Logを出したくなければ、LogOffのファンクションを作って、ロジックに入れて、全ファンクションにこのLog Offを読みこめば良い。(最近思いついたやり方です)

サンプルとして、今回の実験にPPGを付けて見ました:
var oPSet = XSIFactory.CreateObject("CustomProperty");
oPSet.name = "Deselect Test"
oPSet.AddParameter2( "NoLog", siBool,1);

var oLayout = oPSet.PPGLayout;
var oItem = oLayout.AddItem("NoLog");
var oItem = oLayout.AddButton ("Run0","TEST 1 Select.Clear");
oItem.SetAttribute( siUICX, 315);
oItem.SetAttribute( siUICY, 50);
var oItem = oLayout.AddButton ("Run1","TEST 2 DeselectAll");
oItem.SetAttribute( siUICX, 315);
oItem.SetAttribute( siUICY, 50);
oLayout.Logic = Run0_OnClicked.toString()
+ Run1_OnClicked.toString()
+ deselect.toString()
+ nolog.toString();
oLayout.Language = "JScript" ;

InspectObj( oPSet,null,null,3 ) ;

function Run1_OnClicked()
{ deselect (1) }

function Run0_OnClicked()
{ deselect (0) }

function nolog()
{
//Turn off log
if (PPG.NoLog.value){
var prefs = Application.Preferences;
prefs.SetPreferenceValue( "scripting.cmdlog", false );
}
}

function deselect(option)
{
nolog();
var obj = GetPrim("null");
var tStart = new Date();

for( var i=0; i<100; i++ ){
Selection.Add(obj)
if (option == 0 ) {Selection.Clear()}
else if (option == 1 ) {DeselectAll()}
}
DeleteObj(obj);
var tEnd = new Date();
LogMessage("-----------------------")
if (option == 0 ) {LogMessage("Selection.Clear")}
if (option == 1 ) {LogMessage("DeselectAll")}
LogMessage((tEnd.getTime()-tStart.getTime())/1000) ;
}



サブコンポネント

これはサブコンポネント系のスクリプトを書いてた時に気づいたことです。

サブコンポネント(ポイント、エッジ、ポリゴン)を選択している場合に

Select.Clear()
を実行すると、SelectFilter("object"); になり、
オブジェクト選択解除されます。
サブコンポネント選択ツールに戻すと、さっきの選択がまだ生きてることが分かります。
これは場合によって良いかもしれませんが、サブコンポネント選択解除には駄目ですね。

DeselectAll()
一方、DeselectAllを実行すると、サブコンポネント選択解除されますが選択ツールが変わりません。



----- 追記 -----

Selection でもサブコンポネント選択解除が出来ることに気づきました。
Clearではなく、 Removeにすれば良いです。


selection.Remove(selection(0).subcomponent)


結果は DeselectAll と全く同じです。

以上。

Comments

Post a comment


Only the blog author may view the comment.

Trackbacks

Trackbacks URL
http://myara.blog.fc2.com/tb.php/53-429b5f05
Use trackback on this entry.