.df3 フォーマット

df3ファイル

Pov-Rayの読めるボリュームデータは、整数の3次元配列 data[z][y][x]です。unsigned byte, unsigned short, unsigned intに対応をしています。
ループの順番は z-y-x の順に親子関係を持つように解釈をします。

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

データの本体が、unsigned byte, unsigned short, unsigned int のどれなのかは、ヘッダにあるデータの格子数とファイルサイズを比較して判定されます。
ヘッダーの後には、データー本体が続きます unsigned byte の場合は、1byteデータなので、byteの順番も気にせずにそのまま配列として書き出せば大丈夫です。
Oosawaでは、unsigned byte, unsigned short のデータを読み込むことができます。但し、内部的には各格子は 1 byte で処理をしているので、unsigned shortのデータも256段階に変換されます。

例として 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; // 一時データ置き場開放
}
inserted by FC2 system