2013年5月21日火曜日

[Maya] インスタンスを実オブジェクトにベイクする、Mel Script。

だいぶ昔に書いた、instanceを実オブジェクトにベイクするスクリプト。
particleShapeのアトリビュートとか結構決めうちだったような。。。
修正するついでにPython化しようと思ってたけど、めんどくさくて放置。

global proc bakeInstance()
{
 string $instanceObj[];
 string $sel[];
 string $tmpStr;
 string $tmpStrArray[];
 string $particleShape[];
 string $copiedObj[];
 string $ppName;
 string $rotAttr;
 string $scaleAttr;
 string $idAttr;

 int $particleCnt;
 int $startFrame;
 int $curFrame;
 int $endFrame;
 int $cnt;
 int $instanceCnt;
 int $tmpInt;
 int $isCopy[];

 float $particlePos[];
 float $particleRot[];
 float $particleScale[];
 float $objScale[];
 float $instanceId[];
 float $amount;
 float $curStep;
 float $stepValue;
 float $status;

 // instancerを選択し
 $sel = `ls -sl`;
 // instancerが選択されていなかったらエラーを返す
 if($sel[0] == "" || `nodeType $sel[0]` != "instancer")
 {
  error "select instancer";
 }

 // particleShapeも取得
 $particleShape = `listConnections ($sel[0] + ".inputPoints")`;
 // lifespanがLive foreverではなかったらエラーを返す
 if(`getAttr ($particleShape[0] + ".lifespanMode")` != 0)
 {
  error "only lifespanMode \"Live forever\"";
 }

 // rotationのアトリビュート名
 $rotAttr = `particleInstancer -name $sel[0] -q -rotation $particleShape`;
 $scaleAttr = `particleInstancer -name $sel[0] -q -scale $particleShape`;
 $idAttr = `particleInstancer -name $sel[0] -q -objectIndex  $particleShape`;

 // Bakeするframeのレンジ
 // timerSliderから取得
 $startFrame = `playbackOptions -q -min`;
 $curFrame = `playbackOptions -q -min`;
 $endFrame = `playbackOptions -q -max`;

 // instanceされているオブジェクト名を取得(配列)
 $instanceObj = `listConnections ($sel[0] + ".inputHierarchy")`;

 // instacneされているオブジェクトの数を取得
 $instanceCnt = `getAttr ($sel[0] + ".hierarchyCount")`;

 // progressWindowの準備
 $amount = 0;
 $stepValue = 100.0 / ($endFrame - $startFrame);
 $status = 0;
 $curStep = 0;
 progressWindow
  -title "instanceBake"
  -progress $amount
  -minValue $startFrame
  -maxValue $endFrame
  -status ("bake:" + $status + "%")
  -isInterruptable true;
 // 処理するframeの間
 while(true)
 {
  // ESCが押されるか、最後まで処理が進んだら終了
  if(`progressWindow -query -isCancelled`)
  {
   select $copiedObj;
   group -n ($sel[0] + "BakeObj");
//   parent -w;
   progressWindow -endProgress;
   error "instanceBake cancelled";
  }
  if($curFrame > $endFrame) break;

  // frameを進めて・・・
  currentTime $curFrame;

  // particle数を取得
  $particleCnt = `getAttr ($particleShape[0] + ".count")`;

  // そのframeで存在するparticleの数の分処理
  for($cnt = 0; $cnt < $particleCnt; $cnt++)
  {
   // perParcile
   $ppName = $particleShape[0] + ".pt[" + $cnt + "]";

   // そのinstanceオブジェクトはコピー済み?
   if(!($isCopy[$cnt]))
   {
    // 未コピーだったらコピーし
    // particleIdとオブジェクト名を配列に格納
    $instanceId = `getParticleAttr -at $idAttr $ppName`;
    $tmpInt = $instanceId[0];
    $tmpStrArray = `duplicate -rr $instanceObj[ $tmpInt ]`;
    $copiedObj[$cnt] = $tmpStrArray[0];
    // 発生したタイミングでvisibilityにキーを打つ
    setKeyframe -at "visibility" -s 0 -v 0 -t ($curFrame - 1) $copiedObj[$cnt];
    setKeyframe -at "visibility" -s 0 -v 1 -t ($curFrame) $copiedObj[$cnt];

    // スケールを取得
    if($scaleAttr !="")
    {
     $particleScale = `getParticleAttr - at $scaleAttr $ppName`;
     $tmpStr = $copiedObj[$cnt] + ".scale";
     $objScale = `getAttr $tmpStr`;
     $particleScale[0] *= $objScale[0];
     $particleScale[1] *= $objScale[1];
     $particleScale[2] *= $objScale[2];
     setAttr $tmpStr $particleScale[0] $particleScale[1] $particleScale[2];
     setKeyframe $tmpStr;
    }
    // コピー済みフラグを立てる
    $isCopy[$cnt] = true;

   }
   // particleのポジションを取得
   $particlePos = `getParticleAttr -at worldPosition $ppName`;
   $tmpStr = $copiedObj[$cnt] + ".translate";
   setAttr $tmpStr $particlePos[0] $particlePos[1] $particlePos[2];
   setKeyframe $tmpStr;

   // 同じく回転を取得
   if($rotAttr != "")
   {
    $particleRot = `getParticleAttr -at $rotAttr $ppName`;
    $tmpStr = $copiedObj[$cnt] + ".rotate";
    setAttr $tmpStr $particleRot[0] $particleRot[1] $particleRot[2];
    setKeyframe $tmpStr;
   }
  }
  $curFrame++;

  // progressWindowの処理
  $amount =  $curFrame;
  $curStep += $stepValue;
  $status = `floor($curStep)`;
  progressWindow -edit
   -progress $curFrame
   -status("bake:" + $status + "%");
 }
 // Bakeオブジェクトを、グループに分けて終了
 select $copiedObj;
 group -n ($sel[0] + "BakeObj");
// parent -w;

 progressWindow -endProgress;
 print("// instanceBake finished");
}

0 件のコメント:

コメントを投稿