任意の数と位置に存在する複数個のロケーターを選択し、各位置をpvとするnurbsカーブを作成するスクリプト。
まず大まかなアルゴリズムを考えてみた。
0)ロケータの作成、配置、選択 (マニュアル操作)
1)選択したロケータの各名称を取得し、配列に格納
2)配列のサイズを取得
3)for文、配列のサイズより1つ小さい数まで繰り返す。
4)それぞれのロケータのtx,ty,tzを取得。
5)nurbsカーブを作成、そのときにcvの位置が上記の場所を通るようにする。
この中でわからないのはnurbsカーブをコマンドで作成する方法。
オンラインヘルプで調べると、以下のようにポイントを指定できることがわかった。
-p(-point)はポイントの位置
curve -p 0 0 0 -p 3 5 6 -p 5 6 7 -p 9 9 9;
-d(degree)を使ってcurveの次数を指定できる。デフォルトでは次数3。
curve -p 13 13 13 -p 13 15 16 -degree 1;
-a(append)を使い、カーブ名を指定することで作成したカーブにポイントを追加できる。
curve -a -p 10 10 10 curve2;
ロケータの数だけこの-pフラグを増やしていけばよいのだと思う。
やり方としては二つ考えられる。
一つ目は、curveコマンドをすべてのポイント位置と共にまずテキストで作成し、evalで実行。
二つ目は、最初のポイントを使ってcurveを作成し、以後増えたpointの数だけappendしていく。
スクリプトとしては二つ目の方がすっきりとまとまりそうなので、-appendフラグを使う方法を使うことにする。
for文のロケータ位置の取得と共に、for文の中で実行することが出来そうだが、
これをfor文の中で以下のことを行う必要がある。
●ロケータ位置の取得
●curveコマンドで最初のpointをもったカーブ作成。
●pointをAppendしていく。
カウンタである$iはゼロから始まり1ずつ増加し、ロケータ総数に達したら終了する。
curve -p x y z;
これは最初に一度だけ実行。
curve -a -p x y z;
これを(総数-1)回、繰り返す。追加するカーブの名称が必要だが、この時点では選択されているので問題ないだろう。
これで出来そうだ。
あとはこれをfor文の中で使ってやれば良いだけだ。
まずここまでで座標が取得できるところまで作ってみた。
{
vector $position;
string $name[] = `ls -sl`;
int $total = size($name);
for ($i=0; $i<$total; $i++){
$position = `xform -q -t -ws $name[$i]`;
}
print $position;
}
最初に$positionを宣言しておかないと、for文の中で宣言してもprint文の時には「宣言されていない変数」になってしまう。
これはブロックの外にでてしまうからだろう。
また最初vectorでなくfloatで宣言していたため、xformの返り値を代入するときに
// エラー: float[] 型のデータを float 型に変換できません。 //
となってしまった。
それからxformの-qフラグを付け忘れていたため、// エラー: 無効なリニア単位: -ws // となってしまった。
これで座標の取得は出来たので、curveを作れるように以下のスクリプトを作ってみたが
{
vector $position;
string $name[] = `ls -sl`;
int $total = size($name);
for ($i=0; $i<1;>
$position = `xform -q -t -ws $name[$i]`;
if ($i=0) { eval ("curve -p " + $position); }
else { eval ("curve -a -p " + $position); }
}
print $position;
}
// エラー: "-r" または "-a" フラグでカーブを指定する必要があります。 //
となるので、ためしにelseの所を削除してためしてみたら、
Mayaがフリーズするようになってしまった。
elseの中身にprint$positionをおいてみると、繰り返し$positionを表示し続けて固まっている。
無限ループにはなっていないと思うのだが。
そのうち、何度か繰り返しているとフリーズはしなくなったが、エラーは無くならない。
どうしても行き詰まったのでチャットでシニアアーティストに聞いてみた。
彼からのアドバイスは以下の通り、
1)evalはloopの外で使う。例:以下が教えてもらった物
{$blah = ($blah + " -p ")}
string $curve = ("curve -d " + $blah + ";");
2)if($i==0){}にすべき。
アドバイスのとおり実行してみたつもりだが、
どうやってもダメで、エラーは無くならない。
` `バッククォーテーション とevalはfor文の中ではちゃんと機能しないのか?
if分がfor文の中にあると、ちゃんと機能しないのか?
仕方がないので、-appendフラグを使わないで、全座標をふくむコマンド全体を作ってevalで処理するしかない。
これの解決方法を考えてみた。
必要なのは
AAA
AAA+BBB
AAA+BBB+CCC
AAA+BBB+CCC+DDD・・・
と言う風に新しい値が後ろに付け加わっていくようにして-pフラグ部分を作成し、
それをあとで、文字列「curve」と結合し、evalで実行すれば良い。
{
vector $pObj;
string $point;
string $name[] = `ls -sl`;
int $total = size($name);
for($i=0; $i<$total; $i++){
$pObj = `xform -q -t -ws $name[$i]`;
$point = $point + " -p " +$pObj;
}
eval ("curve" + $point);
}
やってみると、これでちゃんとカーブが作成された。
2009年5月19日火曜日
登録:
コメントの投稿 (Atom)
以下のスクリプトでうまくいきました。
返信削除elseの処理を少し変えました。
{
vector $pos[];
$name=`ls -sl`;
int $total=size($name);
for($i=0;$i<$total;$i++)
{
$pos[$i] = `xform -q -t -ws $name[$i]`;
if($i==0)
{
eval("curve -p "+$pos[$i]);
}
else
{
$curve=`ls -sl`;
eval("curve -a -p "+$pos[$i]+" "+$curve[0]);
}
}
}
匿名さん、コメントありがとうございます!
返信削除elseの処理でもできるんですね。(イヤできるはずw)
着想としては良かったけど詰めが甘かったんですね。
いやできる事がわかってすっきりしました。ありがとうございます!!