フリーウェアでシミュレーション結果アニメーションを作る

Pov-Ray 編 2. 流体データの場合

<< Prev - Index - Next >>

3. df3ファイル

■ 絵が表示されたのはいいのですが、まだどのような文法のデータを読んでいたのかを説明していませんでした。
Pov-Rayの読み込めるボリュームデータの文法について説明します。

■ Pov-Rayの読めるボリュームデータは、(ver3.5の時点で) unsigned byte つまり 0-255 の範囲の整数の3次元配列 data[z][y][x]です。つまり格子一つ当たりに256段階しか情報を持てないので、ダイナミックレンジの大きいシミュレーションデータなどは予めlogを取って保存したファイルを作るなどの工夫が必要になります。
追記:実は見てた情報がver3.5より古いものだったみたいで、ver3.5の時点で unsigned byte, unsigned short, unsigned int に対応しているそうです。

■データファイルの頭には、シミュレーションボックスの格子数を指示するためのヘッダーが必要です。これは、short int 形式(2byte)の数字でxyz3つで計 6 byte です。
但し、high order byte first のデータ形式に対応しているので、多くのPCでは出力の際にバイトの順番をひっくり返さないといない。何を言っているか良くわからない場合は、この辺の詳細はビッグエンディアン、リトルエンディアン等のキーワードで検索して調べてみてください。

■ヘッダーの後には、データー本体が unsigned byte の集合体として続きます。1byteデータなので、byteの順番も気にせずにそのまま配列として書き出せば大丈夫です。

■例として c++ 言語で32x32x32のデータの書き出し部分はこんな感じになります。(FILE *pFile等は定義済みとする)。

unsigned char ucvalue[32][32][32]; //データ本体がこの中にあるとする

// ヘッダー書き出し
short size3[3] = {32, 32, 32};
ChangeEndian(&size3[0], sizeof(short)); //byteをひっくり返す
ChangeEndian(&size3[1], sizeof(short));
ChangeEndian(&size3[2], sizeof(short));
fwrite(size3, sizeof(short), 3, pFile);

// 本体部分書き出し
for (int z = 0; z < 32; z++) 
    for (int y = 0; y < 32; y++) 
        for (int x = 0; x < 32; x++) 
            fwrite(&ucvalue[z][y][x], sizeof(char), 1, pFile);


書き出し部分は本当はループ無しに一度に書き出せますが、分かりやすさのためにループで1byteづつ書き出しています。

■ byteをひっくり返す関数の例として次のようになります。

// 関数定義 (ポインタ位置、byte長)
void ChangeEndian(void *pHead, unsigned int length);

// 関数本体
void ChangeEndian(void* pHead, unsigned int length){
    unsigned char *pBuf = new unsigned char [length]; // 一時データ置き場

    // 一時データ置き場にコピー
    for (unsigned int i = 0; i < length; i++)
        pBuf[i] = *((unsigned char*)pHead + i);

    // 一時データ置き場から逆順にコピー
    for (unsigned int i = 0; i < length; i++)
        *((unsigned char*)pHead + i) = pBuf[length - 1 - i];

    delete pBuf; // 一時データ置き場開放
}

<< Prev - Index - Next >>
inserted by FC2 system