改善点は以下のとおりです。
1)スタートフレームと終了フレームを指定できる
2)デュプリケートされるオブジェクトの名前を指定できる。
3)デュプリケートされるオブジェクトの名前は「name_111、name_112・・・」というふうにフレーム番号で、連番を付ける。
(これによってそのオブジェクトの名前を見れば、どのフレームかがわかる)
4)全てのオブジェクトを一つのグループにまとめる。
5)そのグループ名をオブジェクト名から自動作成する。
6)すべてがデュプリケートし終わったら、オリジナルのオブジェクトのvisibilityをoffにする。
これを実装したバージョンが以下の物です。
(実行時には、デュプリケートする対象オブジェクトを選択しておく必要があります。)
{
// setting
int $startFrame = 2415;
int $endFrame = 2452;
string $dupName = "boolB_";
string $grpName = ($dupName+"grp");
// scrpit
int $loopEnd = $endFrame +1;
string $obj[] = `ls -sl`;
group -n $grpName -em;
for($i=$startFrame; $i<$loopEnd; $i++)
{
currentTime$i;
string $name[]= `duplicate $obj[0]`;
$name[0] = `rename $name[0] ($dupName+$i)`;
setKeyframe -at visibility -value 0 -t ($i-1) $name[0];
setKeyframe -at visibility -value 1 -t $i $name[0];
setKeyframe -at visibility -value 0 -t ($i+1) $name[0];
parent $name[0] $grpName;
}
setAttr ($obj[0] + ".visibility") 0;
}
----------------------------------------
<GUIの作成>
以上で終わりだったのですが、GUIからフレーム数や名前が入力できるようにしたかったので、本来の作業中に待ち時間が発生したときに、傍らでGUIを作る作業を続けていました。
しかし、本来の仕事のシーンファイルが重くて、マシンがフリーズしてしまったり、グラフィックスカードのドライバの問題なのか、画面がおかしくなりマシンを再起動しなくてはいけなかったりで、10回ぐらい最初からやりなおしになりました。
また、プロシージャーをウインドウ作成部分と、本来の作業をさえる部分の二つに分けたのですが、変数の引き渡し方法がわからず、そこでつまづきました。
仕事場のPCはまだ日本語フォントがインストールされてないため、自分のブログはおろか、日本語ヘルプさえみることができず家に帰っても時間は無いしで、なかなか先へ進みませんでした。
幸いにもその仕事の納品後、別のスクリプトを修正する機会があり、そのときにシニアの人のアイデアをみることができ、この解決方法もわかりました。(参照エントリ:プロシージャー間での情報のやりとり)
今回は、ウインドウ・コントロールの名称を変数で受け渡すのはやめて、名称をそのまま使用することにしてプロシージャ間で情報のやりとりをしなくても済むようにしました。
またその他につまづいた点として、クエリーモードで参照するフラグの指定方法の違いがあります。
「intField」の値をクエリーモードで参照するときは、値は-value(-v)フラグで参照しますが、
「textFieldGrp」の値を参照するときには、値は-text(-tx)になります。
intField -q -v startNum
textFieldGrp -q -tx objectName
以下は、これで作ったGUI作成部分のスクリプトです。
プロシージャ名が「sequenceGeoDup」と成っているのは、このスクリプトの名前です。
「sequence Geometries duplicator」という名称にしたのですが、その省略形です。
ウインドウ作成のプロシージャでなぜその名前にしたかというと、スクリプト起動時に使うプロシージャ名はファイル名と同じである必要があり、ウインドウ作成のプロシージャ名(例:makeWin)では、その機能がわからないからです。
また見てわかるように変数はありません。
global proc sequenceGeoDup()
{
// delete window if exist
if(`window -exists seqGeoDupWin`)
deleteUI seqGeoDupWin;
// make a window
window -t "Sequence Geometries Dupulicator" seqGeoDupWin;
// controls
columnLayout;
//-----start frame--------------------
text -label "put StartFrame here";
intField -value 1 startNum;
//-----end frame--------------------
text -label "put EndFrame here";
intField -value 24 endNum;
//-----object name--------------------
textFieldGrp -label" Object name" objectName;
//-----button--------------------
button -label "create" -command "dupGeo" createButton;
showWindow seqGeoDupWin;
}
(注意:スクリプトエディタで、上記のスクリプトを実行してもプロシージャは自動実行されません。 結果をみるにはプロシージャ名をタイプしてプロシージャを実行してやる必要があります。 この例では「sequenceGeoDup」の部分です。)
これに先ほどの作業部分のスクリプトを加えます。
以下の変数の部分については、それぞれの関係するフィールドから値を取得する必要があるので各コントローラーのコマンドをクエリーモードで使いました。
int $startFrame = 2415;
int $endFrame = 2452;
string $dupName = "boolB_";
またグループを作成しその中にオブジェクトをいれるのは、
groupコマンドをループ外でつかい、一つグループを作成、その後ループ内でオブジェクト作成後に、parentコマンドでグループにいれています。
groupのフラグは以下の通りです。
-n(name):グループノードの名前を指定
-em(empty):オブジェクトが入っていない空のグループを作成。
parentの構文は以下の通り。名称の代わりに名称が入った変数を使う事が出来ます。
parent objextName groupName;
完成したスクリプトは以下の通りです、二つのプロシージャがありますが、これ二つで一つのMelスクリプトとして機能します。
この二つのプロシージャを一つのスクリプトファイルとして保存し、ファイル名を「sequenceGeoDup.mel」にして利用します。
利用時にはプロシージャ名「sequenceGeoDup」だけを実行します。
----------------------------------------
global proc sequenceGeoDup()
{
// delete window if exist
if(`window -exists seqGeoDupWin`)
deleteUI seqGeoDupWin;
// make a window
window -t "Sequence Geometry Dupulicator" seqGeoDupWin;
// controls
columnLayout;
//-----start frame--------------------
text -label "put StartFrame here";
intField -value 1 startNum;
//-----end frame--------------------
text -label "put EndFrame here";
intField -value 24 endNum;
//-----object name--------------------
textFieldGrp -label" Object name" objectName;
//-----button--------------------
button -label "create" -command "dupGeo" createButton;
showWindow seqGeoDupWin;
}
global proc dupGeo()
{
// setting
int $startFrame = `intField -q -v startNum`;
int $endFrame = `intField -q -v endNum`;
string $objName = `textFieldGrp -q -tx objectName`;
//make Group name.
string $grpName = ($objName+"_grp");
// scrpit
int $loopEnd = $endFrame +1;
string $obj[] = `ls -sl`;
group -n $grpName -em;
for($i=$startFrame; $i<$loopEnd; $i++)
{
currentTime$i;
string $name[]= `duplicate $obj[0]`;
$name[0] = `rename $name[0] ($objName+$i)`;
setKeyframe -at visibility -value 0 -t ($i-1) $name[0];
setKeyframe -at visibility -value 1 -t $i $name[0];
setKeyframe -at visibility -value 0 -t ($i+1) $name[0];
parent $name[0] $grpName;
}
setAttr ($obj[0] + ".visibility") 0;
}
----------------------------------------
これで今回は終わりとしましたが、あると便利な機能をいくつか思いつきました。
●連番をフレーム番号と同じにするか、任意の数字から始まる(1を含む)連番にするかという選択。
●タイムラインから直接、開始フレームと、終了フレームを取得する。
●グループ名に自動的に、grpとつけているが、つけないバージョンも選択できるようにする。
●フィールドに値を入れたら、オブジェクトの名前とグループの名前の例を表示する。
0 件のコメント:
コメントを投稿