//------------------------------------------------------------
// $Id: volumeSerializable.cc,v 1.1.1.1 1999/11/25 06:26:10 yamauchi Exp $
//------------------------------------------------------------
//	(M\pi)^2 implementation of volume
//	implementation SerializableIF 
//	1998年10月17日(土)
//	Copyright (C) 1998 YAMAUCHI Hitoshi 山内 斉
//------------------------------------------------------------
#include "volume.h"

//------------------------------------------------------------
// GlobalGridInfoClass 
// member		       size
//    int     mID;	      //[1]global な ID (volume の分割元 ID)
//    IntVec3 mResolSize;     //[3]分割元の grid サイズ [0, size) が accessible
//    Vector3 mMinPos;	      //[3]global volume の物理的最小位置 (eg. unit: m)
//    Vector3 mMaxPos;	      //[3]   〃       	 の物理的最大位置
//    double  mVoxelEdgeLen;  //[1]voxel の一辺の物理的長さ 	  (eg. unit: m)
//    int     mVolumeRGBDepth;//[1] RGB 色の depth
//------------------------------------------------------------
int GlobalGridInfoClass::
getSerializedSize(void) const
{
    // (+ 1 3 3 3 1 1)
    return(12);
}

double *GlobalGridInfoClass::
newSerializedArray(void)
{
    double *r = new double [this->getSerializedSize()];
    
    r[ 0] = (double)this->mID;    
    r[ 1] = (double)(this->mResolSize.get(IntVec3::X));
    r[ 2] = (double)(this->mResolSize.get(IntVec3::Y));
    r[ 3] = (double)(this->mResolSize.get(IntVec3::Z));
    this->mMinPos.getAsArray(&(r[4])); // [4], [5], [6]
    this->mMaxPos.getAsArray(&(r[7])); // [7], [8], [9]
    r[10] = this->mVoxelEdgeLen;
    r[11] = this->mVolumeRGBDepth;

    return(r);
}

void GlobalGridInfoClass::
deserialize(double *pBuf)
{
    this->mID			= (int)(pBuf[0]);
    this->mResolSize.set((int)(pBuf[1]), (int)(pBuf[2]), (int)(pBuf[3]));
    this->mMinPos.setByArray(&(pBuf[4]));
    this->mMaxPos.setByArray(&(pBuf[7]));
    this->mVoxelEdgeLen 	= pBuf[10];
    this->mVolumeRGBDepth 	= (int)pBuf[11];
}


//------------------------------------------------------------
// SubGridInfoClass
//     Vector3 mMinPos;		// subvolume 位置 Min
//     Vector3 mMaxPos;		//    〃          Max
//     IntVec3 mSpcPos;		// この volume の存在する部分空間 index
//     int     mGridResMin[3];	// subvolume の存在範囲 Min を voxel 単位で
//     int     mGridResMax[3];	// subvolume の存在範囲 Max を voxel 単位で
//------------------------------------------------------------
int SubGridInfoClass::
getSerializedSize(void) const
{
    // 3 + 3 + 3 + 3 + 3
    return(15);
}

double *SubGridInfoClass::
newSerializedArray(void)
{
    double *r = new double [this->getSerializedSize()];

    this->mMinPos.getAsArray(&(r[0])); // [0], [1], [2]
    this->mMaxPos.getAsArray(&(r[3])); // [3], [4], [5]
    r[6] = (double)(this->mSpcPos.get(IntVec3::X));
    r[7] = (double)(this->mSpcPos.get(IntVec3::Y));
    r[8] = (double)(this->mSpcPos.get(IntVec3::Z));

    int baseMin =  9;		//  9, 10, 11 に GridResMin
    int baseMax = 12;		// 12, 13, 14 に GridResMax
    for(int i = 0; i < 3; i++)
    {
	r[baseMin + i] = (double)(this->mGridResMin.get(i));
	r[baseMax + i] = (double)(this->mGridResMax.get(i));
    }
    return(r);
}

void SubGridInfoClass::
deserialize(double *pBuf)
{
    this->mMinPos.setByArray(&(pBuf[0])); // [0], [1], [2]
    this->mMaxPos.setByArray(&(pBuf[3])); // [3], [4], [5]
    this->mSpcPos.set((int)(pBuf[6]), (int)(pBuf[7]), (int)(pBuf[8]));
    this->mGridResMin.set((int)(pBuf[ 9]), (int)(pBuf[10]), (int)(pBuf[11]));
    this->mGridResMax.set((int)(pBuf[12]), (int)(pBuf[13]), (int)(pBuf[14]));
}


//------------------------------------------------------------
// EffectiveGridInfoClass : 部分ボリュームの有効な範囲
// 有効範囲は [min, max] である
//     int     mInitedEffectiveRange; 	// 初期化済み?
//     Vector3 mEfMinPos;		// 有効範囲最小位置
//     Vector3 mEfMaxPos;		// 有効範囲最大位置
//------------------------------------------------------------
int EffectiveGridInfoClass::
getSerializedSize(void) const
{
    // 1 + 3 + 3
    return(7);
}

double *EffectiveGridInfoClass::
newSerializedArray(void)
{
    double *r = new double [this->getSerializedSize()];

    r[0] = (double)(this->mInitedEffectiveRange);
    this->mEfMinPos.getAsArray(&(r[1])); // [1], [2], [3]
    this->mEfMaxPos.getAsArray(&(r[4])); // [4], [5], [6]
    return(r);
}

void EffectiveGridInfoClass::
deserialize(double *pBuf)
{
    this->mInitedEffectiveRange = (int)(pBuf[0]);
    this->mEfMinPos.setByArray(&(pBuf[1])); // 1, 2, 3
    this->mEfMaxPos.setByArray(&(pBuf[4])); // 4, 5, 6
}

//------------------------------------------------------------
// VolumeClass
//     GlobalGridInfoClass mGlobalGrid; // 分割前の global な volume の情報
//     SubGridInfoClass    mSubGrid;    // 分割後の部分 volume の情報
//     EffectiveGridInfoClass mEffiGrid;// 有効な部分 volume の情報
//     array3dClass < gridColor > mGrid; // grid data
//------------------------------------------------------------
int VolumeClass::
getSerializedSize(void) const
{
    // GlobalGridInfo + SubGridInfoClass + 
    // EffectiveGridInfoClass + array3dClass
    int size = this->mGlobalGrid.getSerializedSize() + 
    	this->mSubGrid.getSerializedSize() + 
	this->mEffiGrid.getSerializedSize() +
	this->mGrid.getSerializedSize();
    return(size);
}

double *VolumeClass::
newSerializedArray(void)
{
    double *r = new double [this->getSerializedSize()];

    int i;
    int idx = 0;

    // global grid
    double *pGgs = this->mGlobalGrid.newSerializedArray();
    for(i = 0; i < this->mGlobalGrid.getSerializedSize(); i++)
    {
	r[idx] = pGgs[i];
	idx++;
    }
    delete [] pGgs;

    // sub grid
    double *pSgs = this->mSubGrid.newSerializedArray();
    for(i = 0; i < this->mSubGrid.getSerializedSize(); i++)
    {
	r[idx] = pSgs[i];
	idx++;
    }
    delete [] pSgs;

    // effective grid
    double *pEgs = this->mEffiGrid.newSerializedArray();
    for(i = 0; i < this->mEffiGrid.getSerializedSize(); i++)
    {
	r[idx] = pEgs[i];
	idx++;
    }
    delete [] pEgs;

    // array3D
    double *pGrid = this->mGrid.newSerializedArray();
    for(i = 0; i < this->mGrid.getSerializedSize(); i++)
    {
	r[idx] = pGrid[i];
	idx++;
    }
    delete [] pGrid;

    return(r);
}

void VolumeClass::
deserialize(double *pBuf)
{
    int idx = 0;
    // global grid
    this->mGlobalGrid.deserialize(&(pBuf[idx]));
    idx += this->mGlobalGrid.getSerializedSize();

    // sub grid
    this->mSubGrid.deserialize(&(pBuf[idx]));
    idx += this->mSubGrid.getSerializedSize();

    // efficient grid 
    this->mEffiGrid.deserialize(&(pBuf[idx]));
    idx += this->mEffiGrid.getSerializedSize();    

    // array3D
    this->mGrid.deserialize(&(pBuf[idx]));
    idx += this->mGrid.getSerializedSize();
}
