テクスチャーで凹凸マップ
・グリッド出す
・長さを64*48、分割も64*48(640*480比率で正方形に分割されたグリッドできる)
・「レンダー」→「プロパティ」→「テクスチャマップ」→「XZ」(上から投影する設定)
・「アニメート」→「デフォーム」→「デフォーム」→「プッシュ」
→ウインドウ出たらコンセントマークをクリック
→「接続」→「texture map」を選択(かりの画像が貼られる)
この時点では振幅がゼロなので何も起こらない。振幅を適当にいじれば立体処理される
・あらかじめ用意した凹凸用の画像(フォーマットはなんでもOK)をXSI画面にD&D
・クリップに追加されているので選択すると適用される
--------------------------------
別の簡単な方法
--------------------------------
アニメーション→プロパティ→マップペイントツール→ペイントプッシュツール
こちらの場合、最も低い位置から最も高い位置までの幅は「ウェイト値範囲」の変更で行う。変更後にペイントしないと基本的には反映されないので注意
2009年から仕事でMAYAを勉強。MAYAはデフォルトでは使い勝手が悪い。逆にスクリプトを覚えてカスタマイズするとかなり強力なツールになることがわかってきた。
物覚えが悪いので勉強したことはリマインダとしてココに書き留めるようにする。
2009年11月17日火曜日
2009年6月16日火曜日
【MEL】グラフエディター制御
//////////////////////////////////////////////////////////////////
//チェックボックスでグラフエディターの設定をコントロール
//////////////////////////////////////////////////////////////////
//autoFit の設定
string $onc01 = "refreshEditor01(1)";
string $ofc01 = "refreshEditor01(0)";
//バッファカーブの設定
string $onc02 = "refreshEditor02(1)";
string $ofc02 = "refreshEditor02(0)";
//インフィニティディスプレイの設定
string $onc03 = "refreshEditor03(1)";
string $ofc03 = "refreshEditor03(0)";
//()の中は引数で、この値を変数として次のプロシージャに引き渡しています。
//チェックボックスウィンドウ表示
if (`window -ex GEOptionWindow`) deleteUI GEOptionWindow;
window -title "GraphEditor Option" GEOptionWindow;
columnLayout;
checkBox -label "カーブのオートフィット" -onc $onc01 -ofc $ofc01;
checkBox -label "バッファカーブ表示on/off" -onc $onc02 -ofc $ofc02 ;
checkBox -label "インフィニティ" -onc $onc03 -ofc $ofc03 ;
showWindow;
window -e -h 100 -w 180 GEOptionWindow;
//カーブのオートフィットを設定
proc refreshEditor01(int $fit)
{
animCurveEditor -edit -autoFit $fit graphEditor1GraphEd;
}
//カーブのバッファカーブ表示を設定
proc refreshEditor02(int $buf)
{
animCurveEditor -edit -showBufferCurves $buf graphEditor1GraphEd;
}
//カーブのインフィニティを設定
proc refreshEditor03(int $Inf)
{
animCurveEditor -edit -displayInfinities $Inf graphEditor1GraphEd;
}
この書き方はちょっとトリッキーで、カーブの設定毎に別プロシージャを呼んで設定を書き換えています。
本来は全ての変数要素を集めて一つのプロシージャでまとめて設定するのが正統派です。 でも正統派の書き方をするとこのコードよりはるかに長く、かつ複雑になります。これでいいならこのまま使うほうがシンプルでしょう。このスクリプトでは”設定されなかったパラメータは前の状態を維持する”という性質を利用しています。
.
//チェックボックスでグラフエディターの設定をコントロール
//////////////////////////////////////////////////////////////////
//autoFit の設定
string $onc01 = "refreshEditor01(1)";
string $ofc01 = "refreshEditor01(0)";
//バッファカーブの設定
string $onc02 = "refreshEditor02(1)";
string $ofc02 = "refreshEditor02(0)";
//インフィニティディスプレイの設定
string $onc03 = "refreshEditor03(1)";
string $ofc03 = "refreshEditor03(0)";
//()の中は引数で、この値を変数として次のプロシージャに引き渡しています。
//チェックボックスウィンドウ表示
if (`window -ex GEOptionWindow`) deleteUI GEOptionWindow;
window -title "GraphEditor Option" GEOptionWindow;
columnLayout;
checkBox -label "カーブのオートフィット" -onc $onc01 -ofc $ofc01;
checkBox -label "バッファカーブ表示on/off" -onc $onc02 -ofc $ofc02 ;
checkBox -label "インフィニティ" -onc $onc03 -ofc $ofc03 ;
showWindow;
window -e -h 100 -w 180 GEOptionWindow;
//カーブのオートフィットを設定
proc refreshEditor01(int $fit)
{
animCurveEditor -edit -autoFit $fit graphEditor1GraphEd;
}
//カーブのバッファカーブ表示を設定
proc refreshEditor02(int $buf)
{
animCurveEditor -edit -showBufferCurves $buf graphEditor1GraphEd;
}
//カーブのインフィニティを設定
proc refreshEditor03(int $Inf)
{
animCurveEditor -edit -displayInfinities $Inf graphEditor1GraphEd;
}
この書き方はちょっとトリッキーで、カーブの設定毎に別プロシージャを呼んで設定を書き換えています。
本来は全ての変数要素を集めて一つのプロシージャでまとめて設定するのが正統派です。 でも正統派の書き方をするとこのコードよりはるかに長く、かつ複雑になります。これでいいならこのまま使うほうがシンプルでしょう。このスクリプトでは”設定されなかったパラメータは前の状態を維持する”という性質を利用しています。
.
2009年6月10日水曜日
【MEL】指定のタイプを含むノードを選択
以下のようなコードで任意のタイプが含まれるノードを選択できる。
----------------------
string $TypeList[]=`ls -type "★★★"`;
string $connectionList[];
clear $connectionList;
string $buf[];
for($work in $TypeList)
{
$buf=`listConnections $work`;
if(`size $buf`)
{
$connectionList = `stringArrayCatenate $connectionList $buf`;
}
}
select -r $connectionList;
----------------------
★の部分に選択したいタイプを入れる。-typeフラグに使えるタイプで、自分が調べたのは以下。
(ls -showTypeで調べることができる)
オブジェクトに含まれるtypeの種類
ls -type "hogehoge"
でリスト可能なタイプ指定の一覧
animCurve・・・アニメーションカーブ全部
animCurveTL・・・トランスレーションのカーブ
animCurveTA・・・ローテーションのカーブ
animCurveTU・・・スケールとビジビリティのカーブ
ikEffector・・・IKハンドルエフェクター
ikHandle・・・IKハンドル
joint・・・ジョイント
mesh・・・ポリゴン
pointConstraint・・・位置コンストレイン
orientConstraint・・・回転コンストレイン
scaleConstraint・・・スケールコンストレイン
aimConstraint・・・エイムコンストレイン
poleVectorConstraint・・・極ベクトルコンストレイン
locator・・・ロケータ
【注】ロケータ自体はtransformだが、ロケータの形状属性はlocatorと表示される。
一方グループは単なるtransformなのでtypeでlocator属性の含まれるものを抽出すれば
区別できるのかもしれない。
~ここから下は現時点ではよくわからない~
hyperView・・・ハイパービュー(?)
hyperLayout・・・ハイパーレイアウト(?)
lightLinker・・・ライトリンカー(?)
mute・・・ミュート(?)
displayLayer・・・ディスプレイレイヤー
shadingEngine・・・シェーディングエンジン(?)
materialInfo・・・マテリアルインフォ(?)まあきっとマテリアル
file・・・ファイル(?)
place2dTexture ・・・プレイ2Dテクスチャー(?)たぶんテクスチャ
camera・・・カメラ
groupId・・・(?)
groupParts・・・(?)
【注2】上記のような一般的なもの以外にもプラグイン固有のtypeが取得できるので、
typeというのはユーザーが明示的に設定できるようだ。
----------------------
string $TypeList[]=`ls -type "★★★"`;
string $connectionList[];
clear $connectionList;
string $buf[];
for($work in $TypeList)
{
$buf=`listConnections $work`;
if(`size $buf`)
{
$connectionList = `stringArrayCatenate $connectionList $buf`;
}
}
select -r $connectionList;
----------------------
★の部分に選択したいタイプを入れる。-typeフラグに使えるタイプで、自分が調べたのは以下。
(ls -showTypeで調べることができる)
オブジェクトに含まれるtypeの種類
ls -type "hogehoge"
でリスト可能なタイプ指定の一覧
animCurve・・・アニメーションカーブ全部
animCurveTL・・・トランスレーションのカーブ
animCurveTA・・・ローテーションのカーブ
animCurveTU・・・スケールとビジビリティのカーブ
ikEffector・・・IKハンドルエフェクター
ikHandle・・・IKハンドル
joint・・・ジョイント
mesh・・・ポリゴン
pointConstraint・・・位置コンストレイン
orientConstraint・・・回転コンストレイン
scaleConstraint・・・スケールコンストレイン
aimConstraint・・・エイムコンストレイン
poleVectorConstraint・・・極ベクトルコンストレイン
locator・・・ロケータ
【注】ロケータ自体はtransformだが、ロケータの形状属性はlocatorと表示される。
一方グループは単なるtransformなのでtypeでlocator属性の含まれるものを抽出すれば
区別できるのかもしれない。
~ここから下は現時点ではよくわからない~
hyperView・・・ハイパービュー(?)
hyperLayout・・・ハイパーレイアウト(?)
lightLinker・・・ライトリンカー(?)
mute・・・ミュート(?)
displayLayer・・・ディスプレイレイヤー
shadingEngine・・・シェーディングエンジン(?)
materialInfo・・・マテリアルインフォ(?)まあきっとマテリアル
file・・・ファイル(?)
place2dTexture ・・・プレイ2Dテクスチャー(?)たぶんテクスチャ
camera・・・カメラ
groupId・・・(?)
groupParts・・・(?)
【注2】上記のような一般的なもの以外にもプラグイン固有のtypeが取得できるので、
typeというのはユーザーが明示的に設定できるようだ。
2009年6月9日火曜日
【MEL】選択中キーの最大/最小フレーム
選択中キーの最大/最小フレームを抽出する。キーに時間軸方向のスケールを掛ける際に使用。
float $KeyTimeList[] = `keyframe -q`;
float $maxframe = -9999.9;
float $minframe = 9999.9;
for ($val in $KeyTimeList)
{
$maxframe = `max $val $maxframe`;
$minframe = `min $val $minframe`;
}
print ("最大=" + $maxframe + " 最小=" + $minframe+ "\n");
float $KeyTimeList[] = `keyframe -q`;
float $maxframe = -9999.9;
float $minframe = 9999.9;
for ($val in $KeyTimeList)
{
$maxframe = `max $val $maxframe`;
$minframe = `min $val $minframe`;
}
print ("最大=" + $maxframe + " 最小=" + $minframe+ "\n");
2009年6月8日月曜日
【MEL】ifの条件式(応用)
if文は普通は
if ( $test > 0)
のように条件式を書くが、コマンドがtrueかfalseを返す場合は以下のように記述することができる。
//チェックボックスの状態を調べる
if (`checkBox -q -value check1`)
{
hoge
}
if文で何も条件を書いてないのに動くということはつまり、返り値がtrue/falseのものはtrueなら条件を満たしたと判断されるということになる。
もう一個サンプル
//pCubeという物体が存在するかどうか調べる
if( `objExists pCube1` )
{
select pCube1;
}
else
{
warning("No pCube1 exists");
}
.
if ( $test > 0)
のように条件式を書くが、コマンドがtrueかfalseを返す場合は以下のように記述することができる。
//チェックボックスの状態を調べる
if (`checkBox -q -value check1`)
{
hoge
}
if文で何も条件を書いてないのに動くということはつまり、返り値がtrue/falseのものはtrueなら条件を満たしたと判断されるということになる。
もう一個サンプル
//pCubeという物体が存在するかどうか調べる
if( `objExists pCube1` )
{
select pCube1;
}
else
{
warning("No pCube1 exists");
}
.
【MEL】チェックボックス
//////////////////////////////////////////////////////////////////
//結果を反映させる
//////////////////////////////////////////////////////////////////
proc result()
{
if (`checkBox -q -value check1`) //チェック1がオンだったら…
{
textCurves -ch 0 -f "Impacth-20w400c0" -t "check1";
}
if (`checkBox -q -value check2`) //チェック2がオンだったら…
{
polySphere -r 3;
}
if (`checkBox -q -value check3`) //チェック3がオンだったら…
{
ambientLight -intensity 0.8;
}
if (`checkBox -q -value check4`) //チェック4がオンだったら…
{
file -f -new;
}
}
//////////////////////////////////////////////////////////////////
//チェックボックスのウィンドウ
//////////////////////////////////////////////////////////////////
window;
columnLayout;
checkBox -label "チェック 1" check1; //check1というチェック設定のon/off
checkBox -label "チェック 2" check2; //check2というチェック設定のon/off
checkBox -label "チェック 3"check3; //check3というチェック設定のon/off
checkBox -label "クリア "check4; //check4というチェック設定のon/off
button -label "apply" -c "result"; //apllyボタンが押されたらproc result()に飛ぶ
showWindow;
// 重要なのは”チェックボックスに名前をつけておく”ことです。名前をつけておかないと
// 他のプロシージャで結果を反映させることができません。check1~4がチェックボックスの名前です。
.
//結果を反映させる
//////////////////////////////////////////////////////////////////
proc result()
{
if (`checkBox -q -value check1`) //チェック1がオンだったら…
{
textCurves -ch 0 -f "Impacth-20w400c0" -t "check1";
}
if (`checkBox -q -value check2`) //チェック2がオンだったら…
{
polySphere -r 3;
}
if (`checkBox -q -value check3`) //チェック3がオンだったら…
{
ambientLight -intensity 0.8;
}
if (`checkBox -q -value check4`) //チェック4がオンだったら…
{
file -f -new;
}
}
//////////////////////////////////////////////////////////////////
//チェックボックスのウィンドウ
//////////////////////////////////////////////////////////////////
window;
columnLayout;
checkBox -label "チェック 1" check1; //check1というチェック設定のon/off
checkBox -label "チェック 2" check2; //check2というチェック設定のon/off
checkBox -label "チェック 3"check3; //check3というチェック設定のon/off
checkBox -label "クリア "check4; //check4というチェック設定のon/off
button -label "apply" -c "result"; //apllyボタンが押されたらproc result()に飛ぶ
showWindow;
// 重要なのは”チェックボックスに名前をつけておく”ことです。名前をつけておかないと
// 他のプロシージャで結果を反映させることができません。check1~4がチェックボックスの名前です。
.
【MEL】listRelatives
listRelatives
→選択中オブジェクトと関係のあるものをリストする。
listRelatives
選択しているもの自身およびその直下の子をリスト
listRelatives -pa
listRelatives でリストされたものをパス名込みでリスト。
→シーン内に名前の重複したノードがある場合、これを付けないと次の処理で引数の数が合わなくなったりして困る場合がある。重要なフラグ。厳密には『別のコマンドに渡すことができる、適切なオブジェクト名』を返している。
listRelatives -s
選択中ノードに設定されているシェイプアトリビュートをリスト。ジョイントなどシェイプアトリビュートを持たない場合は空白を返す
listRelatives -f
-paとは違いパスを返すのだが、今のところ違いがはっきりしない。変数として渡せば同じように次の処理ができる。階層が深いと当然パスが長くなるので、すっきりした名前を渡したいような場合は-paがいいが、変数で内部的に扱っているだけならどっちでもいいのか・・?
.
→選択中オブジェクトと関係のあるものをリストする。
listRelatives
選択しているもの自身およびその直下の子をリスト
listRelatives -pa
listRelatives でリストされたものをパス名込みでリスト。
→シーン内に名前の重複したノードがある場合、これを付けないと次の処理で引数の数が合わなくなったりして困る場合がある。重要なフラグ。厳密には『別のコマンドに渡すことができる、適切なオブジェクト名』を返している。
listRelatives -s
選択中ノードに設定されているシェイプアトリビュートをリスト。ジョイントなどシェイプアトリビュートを持たない場合は空白を返す
listRelatives -f
-paとは違いパスを返すのだが、今のところ違いがはっきりしない。変数として渡せば同じように次の処理ができる。階層が深いと当然パスが長くなるので、すっきりした名前を渡したいような場合は-paがいいが、変数で内部的に扱っているだけならどっちでもいいのか・・?
.
2009年6月4日木曜日
【MEL】ロード方法による挙動の違い
スクリプトエディターからロードした時と、スクリプトフォルダにMELを入れておいて起動時に読み込ませておくのではスクリプトの挙動が違うようだ。
スクリプトエディターからロードした時にはローカルプロシージャが読めたのに、起動時読み込みだと
見つからなくなる。
ある日急にスクリプトが動かなくなるのはこの辺の挙動の理解が足りていないせいな気がする。
ローカルプロシージャはそのファイル内では呼び出し可能なはずなのに、実際はそうではないのか?
世間で出回っているスクリプトをみても全部グローバルにしちゃっているようだ。
まあ挙動が安定するのは理解できる。しかし他のプロシージャと名前が衝突する危険が高まる。
どーすっかなあこれは。
スクリプトエディターからロードした時にはローカルプロシージャが読めたのに、起動時読み込みだと
見つからなくなる。
ある日急にスクリプトが動かなくなるのはこの辺の挙動の理解が足りていないせいな気がする。
ローカルプロシージャはそのファイル内では呼び出し可能なはずなのに、実際はそうではないのか?
世間で出回っているスクリプトをみても全部グローバルにしちゃっているようだ。
まあ挙動が安定するのは理解できる。しかし他のプロシージャと名前が衝突する危険が高まる。
どーすっかなあこれは。
【MEL】プロシージャ引数についての研究
小規模実験
proc test(string $text,int $val,float $num)
{
print ($text + "\n");
print ($val + "\n");
print ($num + "\n");
}
$temptext = "hello world";
int $onogu;
float $rimo = 3.1415;
test( $temptext, $onogu, $rimo );
これで$onoguや$rimoを変えるとちゃんと結果に表示される。
・引数は数と型があっていれば順番に代入されるので名前の一致は必要ない(ゆえに汎用性が高い。むしろ内容を特定しない名前がいいかも)
・ただし汎用性のために複数の引数をセットしたら、渡す側も同じ数を(空っぽでもいいので)用意しなければいけない
・引数は”使わなきゃいけない”というもんではなく(←ここ勘違いしていた)、用意するかどうかと使うかどうかは全然別個に考えればいい
・returnも書かなければ以降に処理が流れていくだけで特に問題はない。 書けば呼び出した場所に戻る。
proc test(string $text,int $val,float $num)
{
print ($text + "\n");
print ($val + "\n");
print ($num + "\n");
}
$temptext = "hello world";
int $onogu;
float $rimo = 3.1415;
test( $temptext, $onogu, $rimo );
これで$onoguや$rimoを変えるとちゃんと結果に表示される。
・引数は数と型があっていれば順番に代入されるので名前の一致は必要ない(ゆえに汎用性が高い。むしろ内容を特定しない名前がいいかも)
・ただし汎用性のために複数の引数をセットしたら、渡す側も同じ数を(空っぽでもいいので)用意しなければいけない
・引数は”使わなきゃいけない”というもんではなく(←ここ勘違いしていた)、用意するかどうかと使うかどうかは全然別個に考えればいい
・returnも書かなければ以降に処理が流れていくだけで特に問題はない。 書けば呼び出した場所に戻る。
2009年6月3日水曜日
【MEL】3桁の数字の任意の桁数を取り出す
せっかく考えたのに作った後で不要なことに気がついたorz
後で必要になるかもしんないのでメモっとく。
//テスト用の3桁の数字
int $gaga = 278;
//100の位抽出
$hyaku = `floor ($gaga/100)`;
print $hyaku + "\n";
//10の位抽出
$juu = `floor (($gaga - ($hyaku *100)) /10)`;
print $juu + "\n";
//1の位抽出
$ichi = $gaga - ($hyaku *100 + $juu *10);
print $ichi + "\n";
しかしこれ、桁が7くらいになるともうきついよな。ちゃんと関数とか命令があると思うんだけど。
後で必要になるかもしんないのでメモっとく。
//テスト用の3桁の数字
int $gaga = 278;
//100の位抽出
$hyaku = `floor ($gaga/100)`;
print $hyaku + "\n";
//10の位抽出
$juu = `floor (($gaga - ($hyaku *100)) /10)`;
print $juu + "\n";
//1の位抽出
$ichi = $gaga - ($hyaku *100 + $juu *10);
print $ichi + "\n";
しかしこれ、桁が7くらいになるともうきついよな。ちゃんと関数とか命令があると思うんだけど。
【MEL】引数を変数で渡す時の注意
引数を2つ以上要求するフラグに変数で引数を渡す場合
これはダメ
----------------
{
string $col = "0.5 0.8 0.1";
window;
columnLayout;
button -label " test " -bgc $col;
showWindow;
}
----------------
こう書かなくてはいけない
----------------
{
float $colR = "0.5";
float $colG = "0.8";
float $colB = "0.1";
window;
columnLayout;
button -label " test " -bgc $colR $colG $colB;
showWindow;
}
----------------
これはダメ
----------------
{
string $col = "0.5 0.8 0.1";
window;
columnLayout;
button -label " test " -bgc $col;
showWindow;
}
----------------
こう書かなくてはいけない
----------------
{
float $colR = "0.5";
float $colG = "0.8";
float $colB = "0.1";
window;
columnLayout;
button -label " test " -bgc $colR $colG $colB;
showWindow;
}
----------------
【MEL】キーが打たれているか判定
キーが打たれているかどうかを判定するスクリプト
$test4 = `findKeyframe -curve -at "rotateX" pCube1`;
print $test4;
string $attex = $test4[0];
if ( $attex != "")
{
print "移動Xのキーがあります";
}
else
{
print "キーはありません";
}
------------------
...でいいと思っていたが、どうやらこれは2008以降でしか通用しないらしい。
8.5以前にはfindKeyframe命令に-curveのフラグが存在していないのだ。
で、古いバージョンでも使える代用処理を考える。
findKeyframe -t "-99:99" -at "rotateX" pCube1;
-timeフラグで-99から99の範囲を探す。キーがなければ-99を返すので-99以外ならキーはあると判断する。
常識的なキーの打ち方をしていれば問題が起こることはないだろう。
$test4 = `findKeyframe -curve -at "rotateX" pCube1`;
print $test4;
string $attex = $test4[0];
if ( $attex != "")
{
print "移動Xのキーがあります";
}
else
{
print "キーはありません";
}
------------------
...でいいと思っていたが、どうやらこれは2008以降でしか通用しないらしい。
8.5以前にはfindKeyframe命令に-curveのフラグが存在していないのだ。
で、古いバージョンでも使える代用処理を考える。
findKeyframe -t "-99:99" -at "rotateX" pCube1;
-timeフラグで-99から99の範囲を探す。キーがなければ-99を返すので-99以外ならキーはあると判断する。
常識的なキーの打ち方をしていれば問題が起こることはないだろう。
2009年6月2日火曜日
【MELメモ】端数を0か5に
小数点以下任意の最後の桁を「0」か「5」にするロジックのメモ
・任意小数点の桁だけ抽出し1桁の整数にする
・この1桁の整数を3.33で割る
→もし結果が2以上だったら切り上げ
→もし結果が2未満1以上だったらこの桁は5である
→もし結果が1未満だったら切り捨て
小数点以下任意の最後の桁をとりだすやりかたがわからんけど。
あとで検証するので思いついたアイデアをメモしておく。
・・・いやまて、任意の桁を取り出せるなら”その値が3,4,5,6,7のいずれかなら5”
でいいじゃん(汗
・任意小数点の桁だけ抽出し1桁の整数にする
・この1桁の整数を3.33で割る
→もし結果が2以上だったら切り上げ
→もし結果が2未満1以上だったらこの桁は5である
→もし結果が1未満だったら切り捨て
小数点以下任意の最後の桁をとりだすやりかたがわからんけど。
あとで検証するので思いついたアイデアをメモしておく。
・・・いやまて、任意の桁を取り出せるなら”その値が3,4,5,6,7のいずれかなら5”
でいいじゃん(汗
2009年5月29日金曜日
外部ファイルの存在チェック
外部ファイルを読み込もうとしてファイルがないとMAYAがハングするので回避コード。
俺はこうやった。
$fileExCheck = `filetest -f $fname`;
if ($fileExCheck == 0)
{
print "ファイルが見つかりません\n";
}
else
{
int $fid = `fopen $fname "r"`;
ファイルが開いた後の処理をする
}
一方プログラマーからもらったサンプルはこうだった。
// リストファイルを開く
int $fid = `fopen $fname "r"`;
// 開けた?
if( $fid != 0 )
{
ファイルを開いた後の処理をする
}
else
{
// ファイルが開けなかったエラー
print ("ファイルを開けませんでした。"+$fname + "\n");
}
おかしいな、俺がやるとint $fid = `fopen $fname "r"`; の時点でハングするのに・・・
これでいいならわざわざファイルチェック専用のルーチン作らなくていいからシンプルだよね。
.
俺はこうやった。
$fileExCheck = `filetest -f $fname`;
if ($fileExCheck == 0)
{
print "ファイルが見つかりません\n";
}
else
{
int $fid = `fopen $fname "r"`;
ファイルが開いた後の処理をする
}
一方プログラマーからもらったサンプルはこうだった。
// リストファイルを開く
int $fid = `fopen $fname "r"`;
// 開けた?
if( $fid != 0 )
{
ファイルを開いた後の処理をする
}
else
{
// ファイルが開けなかったエラー
print ("ファイルを開けませんでした。"+$fname + "\n");
}
おかしいな、俺がやるとint $fid = `fopen $fname "r"`; の時点でハングするのに・・・
これでいいならわざわざファイルチェック専用のルーチン作らなくていいからシンプルだよね。
.
ラジオボタンの謎 2
昨日は解決した(というか、正解ではないが回避策がわかった)ラジオボタン問題。
mixiのコミュニティで正しい解決法を聞いてみようと思いうまくいかない例を
作ってみたが、なぜかうまく動いてしまう。
いろいろ試すうちに”ウィンドウをたくさん作って消す”ような動作をさせていると
おかしくなる事がわかった。
つまり“MAYA操作中にできるゴミデータが変数に残っている”のが原因じゃなかろうか?
★★★★これでウィンドウをたくさん出しては消し、とやるとおかしくなる★★★★
global proc makePrimitive()
{
global string $radioCollection1;
string $selected;
$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
polySphere;
}
else if($selected == "rB2")
{
polyCube;
}
}
global proc btn()
{
string $windowName = `window -title "test"`;
columnLayout;
text -label "make Primitive";
string $radioCollection1 = `radioCollection`;
radioButton -label "make Sphere" -select rB1;
radioButton -label "make Cube" rB2;
button -label " Aplly " -command "makePrimitive()";
showWindow;
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
なので変数をクリアするおまじないを入れてみた。
★★★★★★★★おまじないをいれた改良版★★★★★★★★
global proc makePrimitive()
{
global string $radioCollection1;
string $selected;
$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
polySphere;
}
else if($selected == "rB2")
{
polyCube;
}
}
global proc btn()
{
global string $radioCollection1;
$radioCollection1 = "";
string $windowName = `window -title "test"`;
columnLayout;
text -label "make Primitive";
string $radioCollection1 = `radioCollection`;
radioButton -label "make Sphere" -select rB1;
radioButton -label "make Cube" rB2;
button -label " Aplly " -command "makePrimitive()";
showWindow;
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
いまのところうまく動作しているようだ。昔作って今動かなくなっている別の
スクリプトにも組み込んでみたが正しく動作した。
どうやらこれが正解のようだ。 こういう仕様はアレかね、動的な扱いができるスクリプトで
あるが故に、ある物体の名前が同じならそれは絶対同一の物体であることを保証できないっつう
ことですかねえ。
なんにせよ変数の初期化やウィンドウの存在確認は懇ろにやっておくにこしたことはないようだ。
.
mixiのコミュニティで正しい解決法を聞いてみようと思いうまくいかない例を
作ってみたが、なぜかうまく動いてしまう。
いろいろ試すうちに”ウィンドウをたくさん作って消す”ような動作をさせていると
おかしくなる事がわかった。
つまり“MAYA操作中にできるゴミデータが変数に残っている”のが原因じゃなかろうか?
★★★★これでウィンドウをたくさん出しては消し、とやるとおかしくなる★★★★
global proc makePrimitive()
{
global string $radioCollection1;
string $selected;
$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
polySphere;
}
else if($selected == "rB2")
{
polyCube;
}
}
global proc btn()
{
string $windowName = `window -title "test"`;
columnLayout;
text -label "make Primitive";
string $radioCollection1 = `radioCollection`;
radioButton -label "make Sphere" -select rB1;
radioButton -label "make Cube" rB2;
button -label " Aplly " -command "makePrimitive()";
showWindow;
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
なので変数をクリアするおまじないを入れてみた。
★★★★★★★★おまじないをいれた改良版★★★★★★★★
global proc makePrimitive()
{
global string $radioCollection1;
string $selected;
$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
polySphere;
}
else if($selected == "rB2")
{
polyCube;
}
}
global proc btn()
{
global string $radioCollection1;
$radioCollection1 = "";
string $windowName = `window -title "test"`;
columnLayout;
text -label "make Primitive";
string $radioCollection1 = `radioCollection`;
radioButton -label "make Sphere" -select rB1;
radioButton -label "make Cube" rB2;
button -label " Aplly " -command "makePrimitive()";
showWindow;
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
いまのところうまく動作しているようだ。昔作って今動かなくなっている別の
スクリプトにも組み込んでみたが正しく動作した。
どうやらこれが正解のようだ。 こういう仕様はアレかね、動的な扱いができるスクリプトで
あるが故に、ある物体の名前が同じならそれは絶対同一の物体であることを保証できないっつう
ことですかねえ。
なんにせよ変数の初期化やウィンドウの存在確認は懇ろにやっておくにこしたことはないようだ。
.
2009年5月28日木曜日
ちょっと寄り道・・・ラジオボタンの謎
何気なく昔作ったラジオボタンを組み込もうとしたら動かない。なぜかサンプルも動かないものがある。2008で仕様が変わってる?原因究明中
→ウィンドウ生成時にはradioCollection4という名前のラジオコレクションだったのに次のプロシージャに飛んだときにはradioCollection5になってる。
→なぜか自分の環境だとradioCollection命令を出すたびに
radioCollection5、radioCollection6・・・と増えていく。なので次のプロシージャでradioCollectionを発行したら名前が違ってしまう。
→なにかを何かしてしまうと上記症状が起こるらしい。でも”何か”がわからん・・・
→新しいソースをゴチャゴチャいじらないで昔ちゃんと動いていたバージョンで原因を探るほうがいいな・・・
→原因が判明。ラジオボタンを表示するウィンドウをプロシージャにしてしまうと、次にradioCollectionを呼び出した時にラジオコレクション名を探し出すことができず、仕方ないので新しいラジオコレクションを生成してしまうらしい。
(05/28 ↑は見当違いであることが判明)
そういえばサンプルコードも全部プロシージャじゃない生のスクリプトになってるわ。
でもこれだとスクリプトフォルダにおいてコマンドで呼び出すことが出来ないので仕様として不自然。なにか解決方法があるはずなのでネットで他のサンプルを漁ることにする。
これだけで7時間も悩んでたよ…
.
→ウィンドウ生成時にはradioCollection4という名前のラジオコレクションだったのに次のプロシージャに飛んだときにはradioCollection5になってる。
→なぜか自分の環境だとradioCollection命令を出すたびに
radioCollection5、radioCollection6・・・と増えていく。なので次のプロシージャでradioCollectionを発行したら名前が違ってしまう。
→なにかを何かしてしまうと上記症状が起こるらしい。でも”何か”がわからん・・・
→新しいソースをゴチャゴチャいじらないで昔ちゃんと動いていたバージョンで原因を探るほうがいいな・・・
→原因が判明。ラジオボタンを表示するウィンドウをプロシージャにしてしまうと、次にradioCollectionを呼び出した時にラジオコレクション名を探し出すことができず、仕方ないので新しいラジオコレクションを生成してしまうらしい。
(05/28 ↑は見当違いであることが判明)
そういえばサンプルコードも全部プロシージャじゃない生のスクリプトになってるわ。
でもこれだとスクリプトフォルダにおいてコマンドで呼び出すことが出来ないので仕様として不自然。なにか解決方法があるはずなのでネットで他のサンプルを漁ることにする。
これだけで7時間も悩んでたよ…
.
汎用パーツをLibみたいにする 2
---------------------------------------
そういえば、もらったサンプルが返す値は変数1個だけだんだけど、配列2個とか複数の値を
返したい場合はどう記述すればいいのんか?
return $val1[] $val2[];
とか?
---------------------------------------
の続き。
えーまず用語がおかしいですね。関数に対して渡すのは引数、戻ってくるのは返り値。
こういうの間違ってると誰かに相談する時意味が伝わらないので注意しないと。ついでに「固執」は“こしつ”でも“こしゅう”でもOK。でも「破綻」は「はじょう」ではなく「はたん」
話がそれまくり。
ということで、昨日の上の書き方ではsyntax errorでダメ。で、どうすればいいか寝ながら考えた。
1)引数みたいに()でくくる
2)2つの返り値を2つの配列で返すのではなく1個の二次配列にする
1)は違う気がするなあ。2)は…floatとstringの混在なんてできるんだろうか。普通は(x,y,z;x2,y2,z2)とかだよな。
.
そういえば、もらったサンプルが返す値は変数1個だけだんだけど、配列2個とか複数の値を
返したい場合はどう記述すればいいのんか?
return $val1[] $val2[];
とか?
---------------------------------------
の続き。
えーまず用語がおかしいですね。関数に対して渡すのは引数、戻ってくるのは返り値。
こういうの間違ってると誰かに相談する時意味が伝わらないので注意しないと。ついでに「固執」は“こしつ”でも“こしゅう”でもOK。でも「破綻」は「はじょう」ではなく「はたん」
話がそれまくり。
ということで、昨日の上の書き方ではsyntax errorでダメ。で、どうすればいいか寝ながら考えた。
1)引数みたいに()でくくる
2)2つの返り値を2つの配列で返すのではなく1個の二次配列にする
1)は違う気がするなあ。2)は…floatとstringの混在なんてできるんだろうか。普通は(x,y,z;x2,y2,z2)とかだよな。
.
2009年5月27日水曜日
汎用パーツをLibみたいにする
一区切りついたのでソースを見やすくする一環の
”汎用ルーチンを別に作って返り値をもらう”の研究。
プログラマからサンプルをもらったので見る。考えるな、盗むんだ。
proc int[] GenerateIndex( int $num )
{
int $newval[];
int $cnt;
// num <= 0 の場合は最低一つ返すようにする
$newval[0] = 0;
for( $cnt=0 ; $cnt<$num ; $cnt++ )
{
$newval[ $cnt ] = $cnt;
}
return $newval;
}
・・・なんだreturnって。はじめて見るぞ。
とにかくforとセットになる命令であることは確かなようだ。これで$newvalの値を返すのか?
返す場所は指定しなくても来た場所に戻るのか?
で、そもそもどこからこれを呼んでいるのか。
// 8個の連続したインデックス配列を作る
int $idxs[] = GenerateIndex(8);
int $idx;
ぬお、変数に直接プロシージャ名を指定してる。こんなことができるのか。
これを参考に試行錯誤した結果、俺のやりたい事はこうすればできると判明
1.サブルーチン的なglobal procをまとめたファイルをhogehogelib.melという
名前で保存しスクリプトフォルダに入れる。
ここで重要なのは hogehogelib.mel の最後に
global proc hogehogelib()
と書いておくこと。
2.適当なスクリプトを書く。そのなかでhogehogelib.melを使いたい場合は1行
hogehogelib;
と書いておきスクリプトをロードさせる。
あとはそのプロシージャの中で、libにあるプロシージャを呼び出せばreturn命令で
戻ってきてくれる。
そういえば、もらったサンプルが返す値は変数1個だけだんだけど、配列2個とか複数の値を
返したい場合はどう記述すればいいのんか?
return $val1[] $val2[];
とか?
”汎用ルーチンを別に作って返り値をもらう”の研究。
プログラマからサンプルをもらったので見る。考えるな、盗むんだ。
proc int[] GenerateIndex( int $num )
{
int $newval[];
int $cnt;
// num <= 0 の場合は最低一つ返すようにする
$newval[0] = 0;
for( $cnt=0 ; $cnt<$num ; $cnt++ )
{
$newval[ $cnt ] = $cnt;
}
return $newval;
}
・・・なんだreturnって。はじめて見るぞ。
とにかくforとセットになる命令であることは確かなようだ。これで$newvalの値を返すのか?
返す場所は指定しなくても来た場所に戻るのか?
で、そもそもどこからこれを呼んでいるのか。
// 8個の連続したインデックス配列を作る
int $idxs[] = GenerateIndex(8);
int $idx;
ぬお、変数に直接プロシージャ名を指定してる。こんなことができるのか。
これを参考に試行錯誤した結果、俺のやりたい事はこうすればできると判明
1.サブルーチン的なglobal procをまとめたファイルをhogehogelib.melという
名前で保存しスクリプトフォルダに入れる。
ここで重要なのは hogehogelib.mel の最後に
global proc hogehogelib()
と書いておくこと。
2.適当なスクリプトを書く。そのなかでhogehogelib.melを使いたい場合は1行
hogehogelib;
と書いておきスクリプトをロードさせる。
あとはそのプロシージャの中で、libにあるプロシージャを呼び出せばreturn命令で
戻ってきてくれる。
そういえば、もらったサンプルが返す値は変数1個だけだんだけど、配列2個とか複数の値を
返したい場合はどう記述すればいいのんか?
return $val1[] $val2[];
とか?
2009年5月26日火曜日
見やすいコーディングを考える
初心者も初心者なりに、コーディングの可読性に悩むわけですよ。
・変数がどんどん増えて、どの関数がどこで使われているのかわかりにくくなってくる。いや無駄な変数はないんだけど、無駄がなくても多いので困る
・インデントはどういうルールで使うのが一番見やすい?
・汎用のルーチン(配列から任意の部分を切り取って新しい配列に入れるとか)はそれ単独でグローバルプロシージャにして返り値をもらうようにすればファイル毎のコードは小さくなる
・forとかループが入り組んでくると、どの[ とどの ] が対応してるのかわかんなくなってくる。ここは慣れ?今はいちいち// end of hogehogeってつけてる(だから余計に見づらい)
余談だけど、このブログもタブによるインデントが効かないからコードが相当見づらいよな…
とりあえずの結論として、ワードパッドでのコーディングは初心者といってもやっぱツライわ…
・変数がどんどん増えて、どの関数がどこで使われているのかわかりにくくなってくる。いや無駄な変数はないんだけど、無駄がなくても多いので困る
・インデントはどういうルールで使うのが一番見やすい?
・汎用のルーチン(配列から任意の部分を切り取って新しい配列に入れるとか)はそれ単独でグローバルプロシージャにして返り値をもらうようにすればファイル毎のコードは小さくなる
・forとかループが入り組んでくると、どの[ とどの ] が対応してるのかわかんなくなってくる。ここは慣れ?今はいちいち// end of hogehogeってつけてる(だから余計に見づらい)
余談だけど、このブログもタブによるインデントが効かないからコードが相当見づらいよな…
とりあえずの結論として、ワードパッドでのコーディングは初心者といってもやっぱツライわ…
2009年5月25日月曜日
skinClusterの名前を引っ張る 2
さらにネットで調べたところ、もっとダイレクトなのを発見
$gaga = `ls -sl`;
findRelatedSkinCluster $gaga[0];
// 結果: skinCluster3 //
そういう命令があるかどうか不明という条件で調査するとこんなにも時間がかかるもんなのか・・・
(プログラマーには”そんなもんだ”といわれた^^;)
$gaga = `ls -sl`;
findRelatedSkinCluster $gaga[0];
// 結果: skinCluster3 //
そういう命令があるかどうか不明という条件で調査するとこんなにも時間がかかるもんなのか・・・
(プログラマーには”そんなもんだ”といわれた^^;)
2009年5月23日土曜日
skinClusterの名前を引っ張る
金曜の時点でskinClusterの名前が取得できずにとまっていたが、解決の兆しあり。
昨日はオブジェクトを選択している前提で、そのオブジェクトに付属しているクラスターの名前をどうやったら引っ張れるのか悩んでいたが、前提が間違いのようだ。
(pCube1というものがあって、その中にpCube1.skinCluster1みたいにぶら下がっているものと推定していた)
MAYAレイアウト右側のチャンネルリストから入力に表示されているスキンクラスターの「入力」からスキンクラスターを選択し、ls -slすると
// 結果: skinCluster1 pCube1 //
おおう、マジかよ。取得できてるじゃん。そしたら
skinPercent -nrm false -tv joint1 0.3 skinCluster1 pCube1.vtx[0];
のところにそのまんま変数で代入すればいいんだ!
昨日はオブジェクトを選択している前提で、そのオブジェクトに付属しているクラスターの名前をどうやったら引っ張れるのか悩んでいたが、前提が間違いのようだ。
(pCube1というものがあって、その中にpCube1.skinCluster1みたいにぶら下がっているものと推定していた)
MAYAレイアウト右側のチャンネルリストから入力に表示されているスキンクラスターの「入力」からスキンクラスターを選択し、ls -slすると
// 結果: skinCluster1 pCube1 //
おおう、マジかよ。取得できてるじゃん。そしたら
skinPercent -nrm false -tv joint1 0.3 skinCluster1 pCube1.vtx[0];
のところにそのまんま変数で代入すればいいんだ!
2009年5月22日金曜日
【MEL】頂点ウェイトの値から端数を取る 3
昨日頂点単位で値を丸めるところはできたので、今日はそれを選択中オブジェクトの全頂点に適用する部分の追加をする。
昨日のうちにちょっとだけ調査は済んでいる。
//選択中オブジェクトの名前を取得。まあ基本中の基本
$Oname = `ls -sl`;
//選択中オブジェクトの頂点個数を調べて変数に(これでforループを回す)
//※頂点リストは必ず順番に数字が振られ、歯抜けになることはないらしい
//※$AmtObjVtxはfor文に使う
//※$val3はpCube1.vtx["*"]の*に代入して頂点を指定
{
string $AmtObjVtx[] = `ls -fl $Oname.vtx["*"]`;
int $val3 = `size $AmtObjVtx`;
}
ls -fl [オブジェクト名] で頂点の名前を取得できる。同時に個数をsizeで調べる。
--------------------------------------
昨日はここまで
--------------------------------------
が、昨日はオブジェクトをls -slで取得して、その変数を使って頂点数を調べようとしていたのがエラーが出て困っていた。要するに
string $AmtObjVtx[] = `ls -fl $Oname.vtx["*"]`;
// エラー: line 1: string[] 型のデータを string 型に変換できません。 //
となるのだ。これがやっと解決した。
なんのことはない、ls -slで取得される文字列は、オブジェクトが1個だったとしても配列データなのだ。
試しにwhatIsを使ってみると
whatIs "$Oname";
// 結果: string[] variable //
うん、配列です。ぐおー聞いてないよ~~~~
だから文字列にするには配列の任意の部分をとりだしてstring配列に入れなおさなければならない。
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
これでとりあえずオブジェクトの名前を1個、文字列として取り出す部分は解決。これを使ってそのオブジェクトの頂点名の配列数でforを回す。以下のようになるはず
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
{
//選択中オブジェクトの名前を取得
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
//オブジェクトの配列を取得
string $AmtObjVtx[] = `ls -fl pCube1.vtx["*"]`;
//これのpCube1を配列に置き換えればよい
//そのオブジェクトの頂点を1つずつ選択していくforループを作る
for ( $val in $AmtObjVtx )
{
select $val;
print ($val+ "\n") ;
}
}
★------------------ 完成 --------------------★
//start proc
{
//選択中オブジェクトの名前を取得
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
//オブジェクトの頂点リストを取得
//オブジェクト頂点リストのpCube1.vtx["*"]を$Oname + ".vtx["*"]"とやろうとしても
//[*]が数値型のため上手くいかないので1文字ずつバラでくっつけて別の変数に格納する
$Vtxname = $Oname2 + ".vtx"+"["+ "*"+ "]";
//くっつけた文字列変数でオブジェクトの頂点名を配列に格納
string $AmtObjVtx[] = `ls -fl $Vtxname`;
//そのオブジェクトの頂点を1つずつ選択していくforループを作る
for ( $val in $AmtObjVtx )
{
//頂点選択する
select $val;
//★★★ここに昨日の丸め処理をつっこむ★★★
}
昨日のうちにちょっとだけ調査は済んでいる。
//選択中オブジェクトの名前を取得。まあ基本中の基本
$Oname = `ls -sl`;
//選択中オブジェクトの頂点個数を調べて変数に(これでforループを回す)
//※頂点リストは必ず順番に数字が振られ、歯抜けになることはないらしい
//※$AmtObjVtxはfor文に使う
//※$val3はpCube1.vtx["*"]の*に代入して頂点を指定
{
string $AmtObjVtx[] = `ls -fl $Oname.vtx["*"]`;
int $val3 = `size $AmtObjVtx`;
}
ls -fl [オブジェクト名] で頂点の名前を取得できる。同時に個数をsizeで調べる。
--------------------------------------
昨日はここまで
--------------------------------------
が、昨日はオブジェクトをls -slで取得して、その変数を使って頂点数を調べようとしていたのがエラーが出て困っていた。要するに
string $AmtObjVtx[] = `ls -fl $Oname.vtx["*"]`;
// エラー: line 1: string[] 型のデータを string 型に変換できません。 //
となるのだ。これがやっと解決した。
なんのことはない、ls -slで取得される文字列は、オブジェクトが1個だったとしても配列データなのだ。
試しにwhatIsを使ってみると
whatIs "$Oname";
// 結果: string[] variable //
うん、配列です。ぐおー聞いてないよ~~~~
だから文字列にするには配列の任意の部分をとりだしてstring配列に入れなおさなければならない。
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
これでとりあえずオブジェクトの名前を1個、文字列として取り出す部分は解決。これを使ってそのオブジェクトの頂点名の配列数でforを回す。以下のようになるはず
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
{
//選択中オブジェクトの名前を取得
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
//オブジェクトの配列を取得
string $AmtObjVtx[] = `ls -fl pCube1.vtx["*"]`;
//これのpCube1を配列に置き換えればよい
//そのオブジェクトの頂点を1つずつ選択していくforループを作る
for ( $val in $AmtObjVtx )
{
select $val;
print ($val+ "\n") ;
}
}
★------------------ 完成 --------------------★
//start proc
{
//選択中オブジェクトの名前を取得
$Oname = `ls -sl`;
//ls -slで取得される文字は配列なので、その1個目を指定して文字列変数に入れなおす
string $Oname2 = $Oname[0];
//オブジェクトの頂点リストを取得
//オブジェクト頂点リストのpCube1.vtx["*"]を$Oname + ".vtx["*"]"とやろうとしても
//[*]が数値型のため上手くいかないので1文字ずつバラでくっつけて別の変数に格納する
$Vtxname = $Oname2 + ".vtx"+"["+ "*"+ "]";
//くっつけた文字列変数でオブジェクトの頂点名を配列に格納
string $AmtObjVtx[] = `ls -fl $Vtxname`;
//そのオブジェクトの頂点を1つずつ選択していくforループを作る
for ( $val in $AmtObjVtx )
{
//頂点選択する
select $val;
//★★★ここに昨日の丸め処理をつっこむ★★★
}
2009年5月21日木曜日
【MEL】頂点ウェイトの値から端数を取る 2
とりあえずウェイト値をひっぱって丸め、頂点に書き戻すところまでのサンプルが完成
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[6]`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
//print $count;
if ( $numloop >0)
{
$wgtvalue = $val2;
//print ($wgtvalue + "\n");
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
// print ($wgtamount + "\n");
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
// print $wgtamount;
$pointwgt[ $count ] = $wgtamount;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
}
//チェックのため配列の中身を表示する
print "\n\n仮配列$pointwgtの中身\n";
print ($pointwgt[0] + "\n");
print ($pointwgt[1]+ "\n");
print ($pointwgt[2]+ "\n");
print "$pointwgtのサイズ\n";
print (`size $pointwgt`+ "\n\n");
//配列をウェイトに書き戻す処理
//とりあえず頂点6番の修正ウェイトを頂点0番に入れる
int $val;
$count2 = 0;
$count = 1;
for ( $val in $pointwgt )
{
$jname = "joint" + $count;
skinPercent -nrm false -tv $jname $pointwgt[$count2] skinCluster1 pCube1.vtx[0];
}
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
次は決め打ちにしているジョイントの名前や頂点の番号を、選択したものから変数でもってこないといけない。
頂点を1個選択すると
select -r pCube1.vtx[4] ;
と出るので頂点番号は問題なかろう。ウェイトがつけられているジョイントの名前は
skinPercent -query -t skinCluster1 pCube1.vtx[0];
-tオプションで取得可能なことを発見
頂点を選択して以下を実行するとその頂点と関連のあるジョイント名を$skintrans配列に格納してくれる。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
print $skintrans;
}
skinPercent -nrm false -tv joint1 0.5 skinCluster1 pCube1.vtx[0];
↑の joint1 は $skintrans で置き換え、pCube1.vtx[0] は $selectvtxで置き換える。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
skinPercent -nrm false -tv $skintrans 0.5 skinCluster1 $selectvtxl;
}
これで“選択中の頂点の、1番目のジョイントに紐付けられているウェイトが0.5に書き換わる”。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
$cnt = 0;
for ($val in $skintrans)
{
skinPercent -nrm false -tv $skintrans[ $cnt ] 0.5 skinCluster1 $selectvtx;
$cnt++;
}
}
こうすると選択頂点にウェイトつけられている全てのジョイントに対するウェイト値に0.5が格納される。
あとはこれを元のスクリプトに合体、0.5のところが配列からとってこれれば最初の段階クリア
★★★★★★★★★★★★★★ 完成 ★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
////////////////////////////////////////
//変数の宣言
////////////////////////////////////////
//現在選択されている頂点の名前を取得
$selectvtx = `ls -sl`;
//選択中頂点と関連付けられているジョイント名を配列で取得
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
////////////////////////////////////////
//スクリプト本体
////////////////////////////////////////
//丸め処理
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
if ( $numloop >0)
{
$wgtvalue = $val2;
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
//print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
$pointwgt[ $count ] = $wgtamount;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
}
//丸めた値の配列をウェイトに書き戻す処理
$cnt = 0;
for ($val in $skintrans)
{
skinPercent -nrm false -tv $skintrans[ $cnt ] $pointwgt [ $cnt ] skinCluster1 $selectvtx;
$cnt++;
}
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[6]`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
//print $count;
if ( $numloop >0)
{
$wgtvalue = $val2;
//print ($wgtvalue + "\n");
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
// print ($wgtamount + "\n");
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
// print $wgtamount;
$pointwgt[ $count ] = $wgtamount;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
}
//チェックのため配列の中身を表示する
print "\n\n仮配列$pointwgtの中身\n";
print ($pointwgt[0] + "\n");
print ($pointwgt[1]+ "\n");
print ($pointwgt[2]+ "\n");
print "$pointwgtのサイズ\n";
print (`size $pointwgt`+ "\n\n");
//配列をウェイトに書き戻す処理
//とりあえず頂点6番の修正ウェイトを頂点0番に入れる
int $val;
$count2 = 0;
$count = 1;
for ( $val in $pointwgt )
{
$jname = "joint" + $count;
skinPercent -nrm false -tv $jname $pointwgt[$count2] skinCluster1 pCube1.vtx[0];
}
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
次は決め打ちにしているジョイントの名前や頂点の番号を、選択したものから変数でもってこないといけない。
頂点を1個選択すると
select -r pCube1.vtx[4] ;
と出るので頂点番号は問題なかろう。ウェイトがつけられているジョイントの名前は
skinPercent -query -t skinCluster1 pCube1.vtx[0];
-tオプションで取得可能なことを発見
頂点を選択して以下を実行するとその頂点と関連のあるジョイント名を$skintrans配列に格納してくれる。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
print $skintrans;
}
skinPercent -nrm false -tv joint1 0.5 skinCluster1 pCube1.vtx[0];
↑の joint1 は $skintrans で置き換え、pCube1.vtx[0] は $selectvtxで置き換える。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
skinPercent -nrm false -tv $skintrans 0.5 skinCluster1 $selectvtxl;
}
これで“選択中の頂点の、1番目のジョイントに紐付けられているウェイトが0.5に書き換わる”。
{
$selectvtx = `ls -sl`;
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
$cnt = 0;
for ($val in $skintrans)
{
skinPercent -nrm false -tv $skintrans[ $cnt ] 0.5 skinCluster1 $selectvtx;
$cnt++;
}
}
こうすると選択頂点にウェイトつけられている全てのジョイントに対するウェイト値に0.5が格納される。
あとはこれを元のスクリプトに合体、0.5のところが配列からとってこれれば最初の段階クリア
★★★★★★★★★★★★★★ 完成 ★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
////////////////////////////////////////
//変数の宣言
////////////////////////////////////////
//現在選択されている頂点の名前を取得
$selectvtx = `ls -sl`;
//選択中頂点と関連付けられているジョイント名を配列で取得
string $skintrans[] = `skinPercent -query -t skinCluster1 $selectvtx`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
////////////////////////////////////////
//スクリプト本体
////////////////////////////////////////
//丸め処理
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
if ( $numloop >0)
{
$wgtvalue = $val2;
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
//print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
$pointwgt[ $count ] = $wgtamount;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
}
//丸めた値の配列をウェイトに書き戻す処理
$cnt = 0;
for ($val in $skintrans)
{
skinPercent -nrm false -tv $skintrans[ $cnt ] $pointwgt [ $cnt ] skinCluster1 $selectvtx;
$cnt++;
}
}
2009年5月20日水曜日
【MEL】頂点ウェイトの値から端数を取る
今日から暫くのお題は「頂点ウェイトの値から端数を取る」
ゲームでは特に端数が困る場合があるのと、MAYAでウェイト値を修正しようとするととんでもない労力がかかるのでボタン一発で端数が消えるようにしたい。
モデルは専門外なので基本的なところを調査。まずpCube1を出してジョイントにスムースバインド。
任意のモデルの任意の頂点を選択するコマンド
select -r pCube1.vtx[0]
その頂点のウェイト値を変更すると以下のコマンドが履歴に出る
skinPercent -tv joint2 0.3 skinCluster1 pCube1.vtx[0];
頂点0番のウェイト情報を調べるには以下
skinPercent -query -value skinCluster1 pCube1.vtx[0];
// 結果: 0.5 0.448465 0.0515349 // ←こんな感じで出る
自動で頂点ウェイトが正規化されてしまうと操作できないのでノーマライズを一旦オフ
skinPercent -nrm false -tv joint1 0.5 skinCluster1 pCube1.vtx[0];
//-nrm = -normarize デフォルトはtrue
--------------------------------------------
とにかく1個の頂点でやりたい事ができれば、あとはループで全部回すだけのはず。
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[0]`;
こうすると$testvalにウェイトの値が入る。
for ( $val in $testval)
{
print ($val + "\n");
}
0.4586304275
0.4586304275
0.08273914506
おお、配列として格納されている。これを四捨五入して書き戻すだけで合計1のきれいな数値になるはずだんが。
ネットで調べた、俺レベルで一番理解しやすかったのは
”0.005を足して、100倍してfloorで小数点以下を切り捨てて100で割る”
これいってみよう。例によってまずベタ書きする。
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[0]`;
float $wgtvalue;
for ( $val2 in $testval)
{
$wgtvalue = $val2;
print ($wgtvalue + "\n");
$wgtvalue += 0.005;
$wgtvalue = $wgtvalue *100;
$wgtvalue = `floor $wgtvalue`;
$wgtvalue = $wgtvalue /100;
print ($wgtvalue + "\n");
}
}
★★★結果↓★★★
0.4025395377
0.4
0.4025395377
0.4
0.1949209247
0.19
ってオイ!合計が1にならんよ!! 合計が1なら四捨五入しても1になると思ってたorz
というわけで1にならない場合の処理か、必ず1になる処理を考えないとイカン.
ちなみに要素数が3個とは限らないので底も考慮しなくてはならない。個数はsizeで調べればわかるので、最後の1個は四捨五入せずに(1-それまでの計算結果の合計)としないといけない。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[1]`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
//print $count;
if ( $numloop >0)
{
$wgtvalue = $val2;
//print ($wgtvalue + "\n");
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
//print ($wgtamount + "\n");
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
//print $wgtamount;
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
print "\n\n配列の中身\n";
print ($pointwgt[0] + "\n");
print ($pointwgt[1]+ "\n");
print ($pointwgt[2]+ "\n");
print `size $pointwgt`;
//配列をウェイトに書き戻す処理
//これじゃだめ。3つのウェイトの1番目に3回代入してるだけになってる
int $val;
$count = 1;
$jname = "joint" + $count;
for ( $val in $pointwgt )
{
skinPercent -nrm false -tv $jname $pointwgt[$val] skinCluster1 pCube1.vtx[4];
$count++;
}
}
}
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[4]`;
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
これでウェイトを丸めて配列に格納するところまでDONE
しかし頂点に戻せない!
続く
ゲームでは特に端数が困る場合があるのと、MAYAでウェイト値を修正しようとするととんでもない労力がかかるのでボタン一発で端数が消えるようにしたい。
モデルは専門外なので基本的なところを調査。まずpCube1を出してジョイントにスムースバインド。
任意のモデルの任意の頂点を選択するコマンド
select -r pCube1.vtx[0]
その頂点のウェイト値を変更すると以下のコマンドが履歴に出る
skinPercent -tv joint2 0.3 skinCluster1 pCube1.vtx[0];
頂点0番のウェイト情報を調べるには以下
skinPercent -query -value skinCluster1 pCube1.vtx[0];
// 結果: 0.5 0.448465 0.0515349 // ←こんな感じで出る
自動で頂点ウェイトが正規化されてしまうと操作できないのでノーマライズを一旦オフ
skinPercent -nrm false -tv joint1 0.5 skinCluster1 pCube1.vtx[0];
//-nrm = -normarize デフォルトはtrue
--------------------------------------------
とにかく1個の頂点でやりたい事ができれば、あとはループで全部回すだけのはず。
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[0]`;
こうすると$testvalにウェイトの値が入る。
for ( $val in $testval)
{
print ($val + "\n");
}
0.4586304275
0.4586304275
0.08273914506
おお、配列として格納されている。これを四捨五入して書き戻すだけで合計1のきれいな数値になるはずだんが。
ネットで調べた、俺レベルで一番理解しやすかったのは
”0.005を足して、100倍してfloorで小数点以下を切り捨てて100で割る”
これいってみよう。例によってまずベタ書きする。
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[0]`;
float $wgtvalue;
for ( $val2 in $testval)
{
$wgtvalue = $val2;
print ($wgtvalue + "\n");
$wgtvalue += 0.005;
$wgtvalue = $wgtvalue *100;
$wgtvalue = `floor $wgtvalue`;
$wgtvalue = $wgtvalue /100;
print ($wgtvalue + "\n");
}
}
★★★結果↓★★★
0.4025395377
0.4
0.4025395377
0.4
0.1949209247
0.19
ってオイ!合計が1にならんよ!! 合計が1なら四捨五入しても1になると思ってたorz
というわけで1にならない場合の処理か、必ず1になる処理を考えないとイカン.
ちなみに要素数が3個とは限らないので底も考慮しなくてはならない。個数はsizeで調べればわかるので、最後の1個は四捨五入せずに(1-それまでの計算結果の合計)としないといけない。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
//ウェイト値を引っ張ってきて小数点以下1位までに丸める処理
{
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[1]`;
//ウェイトを”値”として操作するのに一時代入する変数を作る
float $wgtvalue;
//最後の1回の例外処理を回すための条件判断用変数
int $numloop = `size $testval`;
//最後の1回はこの値から今までの値を引き算して求める
float $wgtamount = 10; //小数点以下2位まで残すならここが100
//最後に書き戻す用配列
float $pointwgt[];
$count = 0;
for ( $val2 in $testval)
{
$numloop--;
//print $count;
if ( $numloop >0)
{
$wgtvalue = $val2;
//print ($wgtvalue + "\n");
$wgtvalue += 0.05; //小数点以下2位まで残すならここが0.005
$wgtvalue = $wgtvalue *10; //小数点以下2位まで残すならここが100
$wgtvalue = `floor $wgtvalue`;
//
$wgtamount = ($wgtamount - $wgtvalue);
//
$wgtvalue = $wgtvalue /10; //小数点以下2位まで残すならここが100 。ここの値が現在の頂点のウェイト値になる
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
$count++;
}
else
{
//print ($wgtamount + "\n");
$wgtamount = $wgtamount /10;//小数点以下2位まで残すならここが100。ここの値が現在の頂点の最後のウェイト値になる
//print $wgtamount;
$pointwgt[ $count ] = $wgtvalue;
print ("\n配列の中身"+ $count + "\n" + $pointwgt[ $count ] + "\n");
}
print "\n\n配列の中身\n";
print ($pointwgt[0] + "\n");
print ($pointwgt[1]+ "\n");
print ($pointwgt[2]+ "\n");
print `size $pointwgt`;
//配列をウェイトに書き戻す処理
//これじゃだめ。3つのウェイトの1番目に3回代入してるだけになってる
int $val;
$count = 1;
$jname = "joint" + $count;
for ( $val in $pointwgt )
{
skinPercent -nrm false -tv $jname $pointwgt[$val] skinCluster1 pCube1.vtx[4];
$count++;
}
}
}
$testval = `skinPercent -query -value skinCluster1 pCube1.vtx[4]`;
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
これでウェイトを丸めて配列に格納するところまでDONE
しかし頂点に戻せない!
続く
2009年5月19日火曜日
【MEL】複数の配列を格納、読み込み
前回の記事で配列をファイルに読み書きするところはできたので次の段階。これを適用したい元のスクリプトは
変数A
配列B
の2つの保存したい要素があるので、これをちゃんと切り分けて読み書きできないといけない。
とりあえず変数Aは1個しかないのは確定なので変数Aと配列Bをただ直列に並べて
“一つ目の文字列は変数A、2つ目以降は配列”
という決まりごとを設定してしまえばいいと考える。
まず書き込み。
{
string $center = "777";
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "w"`;
//まず1個目に文字列変数$centerを格納
$val = $center+="\n";
fprint $fid $val;
//2個目以降に$strを格納
string $val;
for( $val in $str )
{
$val+="\n";
fprint $fid $val;
}
fclose $fid;
}
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
次に書き込み。しかしうまくいかない…
{
string $str[];
string $center;
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
//ファイルの1行目を$centerに格納
$center=$nextLine;
//試しにロケータを作ってみるが、printで中身はちゃんと表示されるのに名前のないロケータになってしまう…
print $center;
spaceLocator -name $center;
//2行目以降を配列に入れたいが1行目から配列に格納されてしまう
int $cnt = 0;
while ( size( $nextLine ) > 0 )
{
$str[ $cnt ] = $nextLine;
$nextLine = `fgetline $fileId`;
$cnt++;
}
fclose $fileId;
print $str;
for ($val in $str)
{
spaceLocator -name $val;
}
}
変数A
配列B
の2つの保存したい要素があるので、これをちゃんと切り分けて読み書きできないといけない。
とりあえず変数Aは1個しかないのは確定なので変数Aと配列Bをただ直列に並べて
“一つ目の文字列は変数A、2つ目以降は配列”
という決まりごとを設定してしまえばいいと考える。
まず書き込み。
{
string $center = "777";
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "w"`;
//まず1個目に文字列変数$centerを格納
$val = $center+="\n";
fprint $fid $val;
//2個目以降に$strを格納
string $val;
for( $val in $str )
{
$val+="\n";
fprint $fid $val;
}
fclose $fid;
}
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
次に書き込み。しかしうまくいかない…
{
string $str[];
string $center;
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
//ファイルの1行目を$centerに格納
$center=$nextLine;
//試しにロケータを作ってみるが、printで中身はちゃんと表示されるのに名前のないロケータになってしまう…
print $center;
spaceLocator -name $center;
//2行目以降を配列に入れたいが1行目から配列に格納されてしまう
int $cnt = 0;
while ( size( $nextLine ) > 0 )
{
$str[ $cnt ] = $nextLine;
$nextLine = `fgetline $fileId`;
$cnt++;
}
fclose $fileId;
print $str;
for ($val in $str)
{
spaceLocator -name $val;
}
}
【MEL】ファイル(配列)読み込み
ファイルに書き込んだ文字列を読み出す処理。
昨日もらった以下の構文を勉強する
★★★★文字列配列読み込み★★★★
{
string $str[];
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "r"`;
string $val;
int $cnt = 0;
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
{
$str[ $cnt ] = $val;
$cnt++;
}
for( $val in $str )
{
print $val;
}
fclose $fid;
}
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
ここのところが自分にはどうにも難解。
//$val = `fgetline $fid`はfor文の最初に1回だけ行う処理
//2回目からはsize($val) > 0で文字列がなくなるまで回す
//文字列がなくなったら$val = `fgetline $fid`の処理を行う
となっているらしいんだけど、以下でも同じ?
{
//見やすくするために変数はあえて動的に宣言
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
while ( size( $nextLine ) > 0 )
{
print ( $nextLine );
$nextLine = `fgetline $fileId`;
}
fclose $fileId;
}
と、whileで文字列(size( $nextLine ))がなくなるまで繰り返す処理ではダメなんかな?スクリプトエディター上では同じ結果を返すんだけど。
文字列を配列$strに取り込む部分をくっつけると以下のような感じ。
string $str[];
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
int $cnt = 0;
while ( size( $nextLine ) > 0 )
{
print ( $nextLine );
$nextLine = `fgetline $fileId`;
$str[ $cnt ] = $nextLine;
$cnt++;
}
fclose $fileId;
print $str;
ただ、いずれの場合でも排列には改行コード込みの文字列が代入されているようで、これだと困るかもしれない。for構文とwhile構文の差はいずれわかると思うので先にそっちの問題に進む。(とりあえずwhileを選択)
上のスクリプトに以下を追加
for ($val in $str)
{
spaceLocator -name $val;
}
おおっ!ちゃんと名前のついたロケータが生成されるね!オブジェクトの名前にするぶんには問題なさそう・・・と思ったらなんかおかしい。配列の中身は"aaa","bbb","ccc"なのに、生成されるオブジェクトの名前は
"bbb","ccc","locator1"
で1個ずれてしまう。
試しに文字列を取り出すファイルの先頭に強引に1行書き加えてみる。
"aaa","bbb","ccc","locator1"
になった。つまり配列の個数は正しいが文字列が1個ずれて格納されているらしい。
プログラマにもらった構文にロケータ生成部分をくっつけたらちゃんとできた。これがforとwhileの差か!?いやいや、多分自分の書き方がおかしいに違いない。引き続き調査
わかった!!
while ( size( $nextLine ) > 0 )
{
$nextLine = `fgetline $fileId`;
$str[ $cnt ] = $nextLine;
$cnt++;
}
ここで1行目を$strに代入するより先に$nextLineに次の行の文字列が代入されている。順番の問題だった。
while ( size( $nextLine ) > 0 )
{
$str[ $cnt ] = $nextLine;
$nextLine = `fgetline $fileId`;
$cnt++;
}
これでOK!
昨日もらった以下の構文を勉強する
★★★★文字列配列読み込み★★★★
{
string $str[];
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "r"`;
string $val;
int $cnt = 0;
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
{
$str[ $cnt ] = $val;
$cnt++;
}
for( $val in $str )
{
print $val;
}
fclose $fid;
}
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
ここのところが自分にはどうにも難解。
//$val = `fgetline $fid`はfor文の最初に1回だけ行う処理
//2回目からはsize($val) > 0で文字列がなくなるまで回す
//文字列がなくなったら$val = `fgetline $fid`の処理を行う
となっているらしいんだけど、以下でも同じ?
{
//見やすくするために変数はあえて動的に宣言
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
while ( size( $nextLine ) > 0 )
{
print ( $nextLine );
$nextLine = `fgetline $fileId`;
}
fclose $fileId;
}
と、whileで文字列(size( $nextLine ))がなくなるまで繰り返す処理ではダメなんかな?スクリプトエディター上では同じ結果を返すんだけど。
文字列を配列$strに取り込む部分をくっつけると以下のような感じ。
string $str[];
$fname = "C:/onogu2/test.txt";
$fileId=`fopen $fname "r"`;
$nextLine = `fgetline $fileId`;
int $cnt = 0;
while ( size( $nextLine ) > 0 )
{
print ( $nextLine );
$nextLine = `fgetline $fileId`;
$str[ $cnt ] = $nextLine;
$cnt++;
}
fclose $fileId;
print $str;
ただ、いずれの場合でも排列には改行コード込みの文字列が代入されているようで、これだと困るかもしれない。for構文とwhile構文の差はいずれわかると思うので先にそっちの問題に進む。(とりあえずwhileを選択)
上のスクリプトに以下を追加
for ($val in $str)
{
spaceLocator -name $val;
}
おおっ!ちゃんと名前のついたロケータが生成されるね!オブジェクトの名前にするぶんには問題なさそう・・・と思ったらなんかおかしい。配列の中身は"aaa","bbb","ccc"なのに、生成されるオブジェクトの名前は
"bbb","ccc","locator1"
で1個ずれてしまう。
試しに文字列を取り出すファイルの先頭に強引に1行書き加えてみる。
"aaa","bbb","ccc","locator1"
になった。つまり配列の個数は正しいが文字列が1個ずれて格納されているらしい。
プログラマにもらった構文にロケータ生成部分をくっつけたらちゃんとできた。これがforとwhileの差か!?いやいや、多分自分の書き方がおかしいに違いない。引き続き調査
わかった!!
while ( size( $nextLine ) > 0 )
{
$nextLine = `fgetline $fileId`;
$str[ $cnt ] = $nextLine;
$cnt++;
}
ここで1行目を$strに代入するより先に$nextLineに次の行の文字列が代入されている。順番の問題だった。
while ( size( $nextLine ) > 0 )
{
$str[ $cnt ] = $nextLine;
$nextLine = `fgetline $fileId`;
$cnt++;
}
これでOK!
XSI風味のプロジェクトマネージャー
MAYAのカレントプロジェクトの仕様はXSIから来るとどうにも使いづらい。なのでXSI風のプロジェクトマネージャーを作成。ボタンを押せばカレントプロジェクトディレクトリが変わります。
見ればわかるとおり7個分のDBをベタ記述(汗)。そのうち直せればいいなあ。
//プロジェクトマネージャー
//ディレクトリと名称を変数宣言
//ここのパスを書き換えるだけで6つまでプロジェクトリストを登録できます(7つ以上はプロシージャとボタンの追加が必要)
//★注意★MAYAはパスの区切り記号の"\"を認識できません(よう気がする)。必ずスラッシュに置き換えてください
//あとリストウィンドウが更新されなくなるバグがあるようです。原因不明。症状が起きたら一旦ウィンドウを消してみてください(放置でも動作に支障なし)
string $DBdir01 = "C:/onogu2/MAYAproject";
string $DBname01 = "C/ローカルtempフォルダ1";
string $DBdir02 = "C:/onogu2/MAYAproject";
string $DBname02 = "C/ローカルtempフォルダ2";
string $DBdir03 = "C:/onogu2/MAYAproject";
string $DBname03 = "C/ローカルtempフォルダ3";
string $DBdir04 = "C:/users";
string $DBname04 =" (未登録) ";
string $DBdir05 = "C:/users";
string $DBname05 = " (未登録) ";
string $DBdir06 = "C:/users";
string $DBname06 = " (未登録) ";
///////////////////////////////////////////////////////////////////////////
if(`window -ex prjWindow`) deleteUI prjWindow;
//DBリスト1
proc changeDB01()
{
global string $DBdir01;
setProject $DBdir01;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
//DBリスト2
proc changeDB02()
{
global string $DBdir02;
setProject $DBdir02;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -rtf 0 -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
//DBリスト3
proc changeDB03()
{
global string $DBdir03;
setProject $DBdir03;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -rtf 0 -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
//DBリスト4
proc changeDB04()
{
global string $DBdir04;
setProject $DBdir04;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -rtf 0 -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
//DBリスト5
proc changeDB05()
{
global string $DBdir05;
setProject $DBdir05;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -rtf 0 -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
//DBリスト6
proc changeDB06()
{
global string $DBdir06;
setProject $DBdir06;
//ディレクトリリスト更新
if(`window -ex listWindow`) deleteUI listWindow;
window -rtf 0 -wh 250 120 listWindow;
paneLayout ProjPanes;
projFileViewer -dm 0 ProjFileView;
paneLayout -e -cn single -sp ProjFileView 1 ProjPanes;
projFileViewer -e -fr ProjFileView;
showWindow;
}
///////////////////////////////////////////////////////////////////////////
//ファイルのロード
proc load()
{
OpenScene;
}
//ファイルのセーブ
proc save()
{
SaveSceneAs;
}
//ファイルの上書き保存
proc saveOverwrite()
{
file -save;
}
//ファイルのインポート
proc import()
{
Import;
}
///////////////////////////////////////////////////////////////////////////
//ボタンつきウィンドウの設定
window -title "プロジェクトマネージャー" prjWindow;
columnLayout -adjustableColumn true;
text -label "プロジェクトDBの変更";
button -label $DBname01 -align "left" -command "changeDB01";
button -label $DBname02 -align "left" -command "changeDB02";
button -label $DBname03 -align "left" -command "changeDB03";
button -label $DBname04 -align "left" -command "changeDB04";
button -label $DBname05 -align "left" -command "changeDB05";
button -label $DBname06 -align "left" -command "changeDB06";
separator -height 20 ;
setParent ..;
rowLayout -numberOfColumns 4 -columnWidth4 60 60 90 60;
button -label " ロード " -command "load";
button -label " セーブ " -command "save";
button -label " 上書き保存 " -command "saveOverwrite";
button -label "インポート" -command "Import";
setParent ..;
showWindow;
window -e -h 280 -w 320 prjWindow;
///////////////////////////////////////////////////////////////////////////
スクリプトのインデント
ブログはhtmlなのでタブによるインデントが無効になってしまう。
インデントがないと見づらいので
「&emsp;」
で代用する(&は半角に。半角だとスペースとして表示されてしまうのでとりあえず全角にしてあります)
インデントがないと見づらいので
「&emsp;」
で代用する(&は半角に。半角だとスペースとして表示されてしまうのでとりあえず全角にしてあります)
2009年5月18日月曜日
【MEL】ファイルへの配列書き込み 2
(fopen、fprint、fwrite、fclose)
プログラマーから答えをもらっちゃったので(^^;)こっちにコピペしておく。for文で配列を変換しなくてもいいらしい。というか、配列を直接ファイルに書き込もうとするからイカン。for文中で$valにそのとき代入されているものを1つづつ追記するのが以下の構文。
------------------------------------------------
★★★★文字列配列書き込み★★★★
{
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "w"`;
string $val;
for( $val in $str )
{
$val+="\n";
fprint $fid $val;
}
fclose $fid;
}
★★★★文字列配列読み込み★★★★
{
string $str[];
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "r"`;
string $val;
int $cnt = 0;
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
{
$str[ $cnt ] = $val;
$cnt++;
}
for( $val in $str )
{
print $val;
}
fclose $fid;
}
プログラマーから答えをもらっちゃったので(^^;)こっちにコピペしておく。for文で配列を変換しなくてもいいらしい。というか、配列を直接ファイルに書き込もうとするからイカン。for文中で$valにそのとき代入されているものを1つづつ追記するのが以下の構文。
------------------------------------------------
★★★★文字列配列書き込み★★★★
{
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "w"`;
string $val;
for( $val in $str )
{
$val+="\n";
fprint $fid $val;
}
fclose $fid;
}
★★★★文字列配列読み込み★★★★
{
string $str[];
string $fname = "C:/onogu2/test.txt";
int $fid = `fopen $fname "r"`;
string $val;
int $cnt = 0;
for( $val = `fgetline $fid` ; size($val) > 0 ; $val = `fgetline $fid` )
{
$str[ $cnt ] = $val;
$cnt++;
}
for( $val in $str )
{
print $val;
}
fclose $fid;
}
【MEL】ファイルへの配列書き込み
(fopen、fprint、fwrite、fclose)
★単なる変数ならなにも考えずにfprintで書き込めるんだけど、配列は書き込めない。その解決方法
-------------------------
//ファイル書き込み命令fprintは配列をそのまま書き込めないようなので、配列を一旦変数に置き換える。
//『$変数 = $配列』のような記述は型変換できないので、for文で配列の中身を1つずつ追加していく構文にする
string $list = "";
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
for( $val in $str)
{
$list += ($val + "\n");
}
print $list; //ここはチェック用に表示してるだけ
//ここから書き込みスクリプト。
//"C:/onogu2/test2.mel"が書き込むファイルの場所と名前。ファイルは存在しなければ新規に作成される。拡張子は好きにつけられる
$exampleFileName = "C:/onogu2/test2.txt";
$fileId=`fopen $exampleFileName "w"`;
for ($val2 in $tmp);
{
fprint $fileId $list;
}
fclose $fileId;
★単なる変数ならなにも考えずにfprintで書き込めるんだけど、配列は書き込めない。その解決方法
-------------------------
//ファイル書き込み命令fprintは配列をそのまま書き込めないようなので、配列を一旦変数に置き換える。
//『$変数 = $配列』のような記述は型変換できないので、for文で配列の中身を1つずつ追加していく構文にする
string $list = "";
string $str[] = { "aaa", "bbb", "ccc", "ddd" };
for( $val in $str)
{
$list += ($val + "\n");
}
print $list; //ここはチェック用に表示してるだけ
//ここから書き込みスクリプト。
//"C:/onogu2/test2.mel"が書き込むファイルの場所と名前。ファイルは存在しなければ新規に作成される。拡張子は好きにつけられる
$exampleFileName = "C:/onogu2/test2.txt";
$fileId=`fopen $exampleFileName "w"`;
for ($val2 in $tmp);
{
fprint $fileId $list;
}
fclose $fileId;
登録:
投稿 (Atom)
ブログ アーカイブ
-
▼
09
(31)
-
►
5月
(18)
- 外部ファイルの存在チェック
- ラジオボタンの謎 2
- ちょっと寄り道・・・ラジオボタンの謎
- 汎用パーツをLibみたいにする 2
- 汎用パーツをLibみたいにする
- 今日のスクリプト格言
- 見やすいコーディングを考える
- skinClusterの名前を引っ張る 2
- skinClusterの名前を引っ張る
- 【MEL】頂点ウェイトの値から端数を取る 3
- 【MEL】頂点ウェイトの値から端数を取る 2
- 【MEL】頂点ウェイトの値から端数を取る
- 【MEL】複数の配列を格納、読み込み
- 【MEL】ファイル(配列)読み込み
- XSI風味のプロジェクトマネージャー
- スクリプトのインデント
- 【MEL】ファイルへの配列書き込み 2
- 【MEL】ファイルへの配列書き込み
-
►
5月
(18)