2016年3月8日火曜日

「配列は参照渡し」について

たとえば、

proc testCallByReference(
    int $value,                         // 値
    int $array[] )                      // 配列
/******************************************************************************
    参照渡しのテスト
 ******************************************************************************/
{
    $value=($value+1);
    $array[0]=($array[0]+1);
    
}


// main procedure.
{
    int $value;
    int $array[];
    $value=1;
    $array[0]=1;
    
    testCallByReference( $value,$array );
    print("\n-- 結果 --");
    print("\n   $value: "+$value);
    print("\n$array[0]: "+$array[0]);
    
}


こんなスクリプトで、通常のインテジャーと配列のインテジャーを引数にして
testCallByReferenceから帰ってくると、
$valueのほうは1のままで、$arrayは2になって返ってきます。


配列はプロシージャ間を行き来できるようになっています。
この特徴を利用して、再帰処理と組み合わせると、階層構造の解析などが楽に行えます。

まず HumanIK の Skeleton を作成した状態で、下のスクリプトを実行すると、

proc createHierarchyTrans(
    string $myname,
    string $CBR_names[],
    string $CBR_tx[],
    string $CBR_ty[],
    string $CBR_tz[] )
/******************************************************************************
    ジョイント名と座標を取得※再帰
 ******************************************************************************/
{
    $CBR_names[size($CBR_names)]=$myname;
    $CBR_tx[size($CBR_tx)]=`getAttr ($myname+".tx")`;
    $CBR_ty[size($CBR_ty)]=`getAttr ($myname+".ty")`;
    $CBR_tz[size($CBR_tz)]=`getAttr ($myname+".tz")`;
    
    string $childs[]=`listRelatives -c -typ "joint" $myname`;
    if(!`size $childs`) return;
    
    for( $child in $childs ) createHierarchyTrans( $child,$CBR_names,$CBR_tx,$CBR_ty,$CBR_tz );
    
}


// main procedure.
{
    string $hips[]=`ls -typ "joint" "*_Hips"`;
    
    string $names[];
    string $tx[];
    string $ty[];
    string $tz[];
    createHierarchyTrans( $hips[0],$names,$tx,$ty,$tz );
    
    
    int $size=size( $names );
    for( $i=0; $i<$size; $i++ ) print("\n"+$names[$i]+": "+$tx[$i]+", "+$ty[$i]+", "+$tx[$i]);
    
}


階層構造のジョイント名とローカル座標が表示されます。

通常、ひとつしか取得できない返値を複数持っているように振る舞えます。
無駄に global 変数を使わなくて済むということですね。


配列の寿命は普通の変数と扱いが違っているので、ループの中で使う場合などでは、意図しない配列になることがあるので注意が必要です。
特にスクリプトエディタ上では前回実行した内容が残っている場合があります。

0 件のコメント:

コメントを投稿