Files
ThirdParty-6/ParaView-5.0.1/VTK/Parallel/Core/vtkFieldDataSerializer.cxx

502 lines
16 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkFieldDataSerializer.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkDataArray.h"
#include "vtkFieldData.h"
#include "vtkFieldDataSerializer.h"
#include "vtkIdList.h"
#include "vtkIntArray.h"
#include "vtkMultiProcessStream.h"
#include "vtkObjectFactory.h"
#include "vtkStringArray.h"
#include "vtkStructuredData.h"
#include "vtkStructuredExtent.h"
#include <cassert> // For assert()
#include <cstring> // For memcpy
vtkStandardNewMacro(vtkFieldDataSerializer);
//------------------------------------------------------------------------------
vtkFieldDataSerializer::vtkFieldDataSerializer()
{
}
//------------------------------------------------------------------------------
vtkFieldDataSerializer::~vtkFieldDataSerializer()
{
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeMetaData(
vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
if( fieldData == NULL )
{
vtkGenericWarningMacro("Field data is NULL!");
return;
}
// STEP 0: Write the number of arrays
bytestream << fieldData->GetNumberOfArrays();
// STEP 1: Loop through each array and write the metadata
for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
{
vtkDataArray *dataArray = fieldData->GetArray( array );
assert("pre: data array should not be NULL!" && (dataArray != NULL));
int dataType = dataArray->GetDataType();
int numComp = dataArray->GetNumberOfComponents();
int numTuples = dataArray->GetNumberOfTuples();
// serialize array information
bytestream << dataType << numTuples << numComp;
bytestream << std::string( dataArray->GetName() );
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeMetaData(
vtkMultiProcessStream& bytestream,
vtkStringArray *names,
vtkIntArray *datatypes,
vtkIntArray *dimensions)
{
if( bytestream.Empty() )
{
vtkGenericWarningMacro("ByteStream is empty");
return;
}
if( (names == NULL) || (datatypes == NULL) || (dimensions == NULL) )
{
vtkGenericWarningMacro(
"ERROR: caller must pre-allocation names/datatypes/dimensions!");
return;
}
// STEP 0: Extract the number of arrays
int NumberOfArrays;
bytestream >> NumberOfArrays;
if( NumberOfArrays == 0 )
{
return;
}
// STEP 1: Allocate output data-structures
names->SetNumberOfValues(NumberOfArrays);
datatypes->SetNumberOfValues(NumberOfArrays);
dimensions->SetNumberOfComponents(2);
dimensions->SetNumberOfTuples(NumberOfArrays);
std::string *namesPtr = static_cast<std::string*>(names->GetVoidPointer(0));
int *datatypesPtr = static_cast<int*>(datatypes->GetVoidPointer(0));
int *dimensionsPtr = static_cast<int*>(dimensions->GetVoidPointer(0));
// STEP 2: Extract metadata for each array in corresponding output arrays
for( int arrayIdx=0; arrayIdx < NumberOfArrays; ++arrayIdx )
{
bytestream >> datatypesPtr[ arrayIdx ] >> dimensionsPtr[arrayIdx*2] >>
dimensionsPtr[arrayIdx*2+1] >> namesPtr[ arrayIdx ];
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Serialize(
vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
if( fieldData == NULL )
{
vtkGenericWarningMacro("Field data is NULL!");
return;
}
// STEP 0: Write the number of arrays
bytestream << fieldData->GetNumberOfArrays();
if( fieldData->GetNumberOfArrays() == 0 )
{
return;
}
// STEP 1: Loop through each array and serialize its metadata
for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
{
vtkDataArray *dataArray = fieldData->GetArray( array );
vtkFieldDataSerializer::SerializeDataArray( dataArray, bytestream );
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeTuples(
vtkIdList *tupleIds, vtkFieldData *fieldData,
vtkMultiProcessStream& bytestream )
{
if( fieldData == NULL )
{
vtkGenericWarningMacro("Field data is NULL!");
return;
}
// STEP 0: Write the number of arrays
bytestream << fieldData->GetNumberOfArrays();
if( fieldData->GetNumberOfArrays() == 0 )
{
return;
}
// STEP 1: Loop through each array, extract the data on the selected tuples
// and serialize it
for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
{
vtkDataArray *dataArray = fieldData->GetArray( array );
// STEP 2: For each array extract only the selected tuples, i.e., a subset
vtkDataArray *subSet = NULL;
subSet = vtkFieldDataSerializer::ExtractSelectedTuples(tupleIds,dataArray);
assert("pre: subset array is NULL!" && (subSet != NULL) );
// STEP 3: Serialize only a subset of the data
vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
subSet->Delete();
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeSubExtent(
int subext[6], int gridExtent[6], vtkFieldData *fieldData,
vtkMultiProcessStream& bytestream)
{
if( fieldData == NULL )
{
vtkGenericWarningMacro("Field data is NULL!");
return;
}
// STEP 0: Write the number of arrays
bytestream << fieldData->GetNumberOfArrays();
if( fieldData->GetNumberOfArrays() == 0 )
{
return;
}
// STEP 1: Loop through each array, extract the data within the subext
// and serialize it
for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
{
vtkDataArray *dataArray = fieldData->GetArray( array );
// STEP 2: Extract the data within the requested sub-extent
vtkDataArray *subSet = NULL;
subSet = vtkFieldDataSerializer::ExtractSubExtentData(
subext,gridExtent,dataArray);
assert("pre: subset array is NULL!" && (subSet != NULL) );
// STEP 3: Serialize only a subset of the data
vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
subSet->Delete();
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeSerializeToSubExtent(
int subext[6], int gridExtent[6], vtkFieldData* fieldData,
vtkMultiProcessStream& bytestream)
{
assert("pre: sub-extent outside grid-extent" &&
vtkStructuredExtent::Smaller(subext,gridExtent));
if( fieldData == NULL )
{
vtkGenericWarningMacro("Field data is NULL!");
return;
}
int numArrays = 0;
bytestream >> numArrays;
assert("post: numArrays mismatch!" &&
(numArrays==fieldData->GetNumberOfArrays()) );
int ijk[3];
for( int array=0; array < numArrays; ++array )
{
vtkDataArray* dataArray = NULL;
vtkFieldDataSerializer::DeserializeDataArray(bytestream,dataArray);
assert("post: dataArray is NULL!" && (dataArray != NULL) );
assert("post: fieldData does not have array!" &&
fieldData->HasArray(dataArray->GetName()));
vtkDataArray* targetArray = fieldData->GetArray( dataArray->GetName() );
assert("post: ncomp mismatch!" &&
(dataArray->GetNumberOfComponents()==targetArray->GetNumberOfComponents()));
for(ijk[0]=subext[0]; ijk[0] <= subext[1]; ++ijk[0])
{
for(ijk[1]=subext[2]; ijk[1] <= subext[3]; ++ijk[1])
{
for(ijk[2]=subext[4]; ijk[2] <= subext[5]; ++ijk[2])
{
vtkIdType sourceIdx =
vtkStructuredData::ComputePointIdForExtent(subext,ijk);
assert("post: sourceIdx out-of-bounds!" && (sourceIdx >= 0) &&
(sourceIdx < dataArray->GetNumberOfTuples()) );
vtkIdType targetIdx =
vtkStructuredData::ComputePointIdForExtent(gridExtent,ijk);
assert("post: targetIdx out-of-bounds!" && (targetIdx >= 0) &&
(targetIdx < targetArray->GetNumberOfTuples()) );
targetArray->SetTuple(targetIdx,sourceIdx,dataArray);
} // END for all k
} // END for all j
} // END for all i
dataArray->Delete();
} // END for all arrays
}
//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSubExtentData(
int subext[6], int gridExtent[6], vtkDataArray *inputDataArray )
{
if( inputDataArray == NULL )
{
vtkGenericWarningMacro("input data array is NULL!");
return NULL;
}
// STEP 0: Acquire structured data description, i.e, XY_PLANE, XYZ_GRID etc.
int description = vtkStructuredData::GetDataDescriptionFromExtent(gridExtent);
// STEP 1: Allocate subset array
vtkDataArray *subSetArray =
vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
subSetArray->SetName( inputDataArray->GetName() );
subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
subSetArray->SetNumberOfTuples(
vtkStructuredData::GetNumberOfPoints(subext,description));
int ijk[3];
for( ijk[0]=subext[0]; ijk[0] <= subext[1]; ++ijk[0] )
{
for( ijk[1]=subext[2]; ijk[1] <= subext[3]; ++ijk[1] )
{
for( ijk[2]=subext[4]; ijk[2] <= subext[5]; ++ijk[2] )
{
// Compute the source index from the grid extent. Note, this could be
// a cell index if the incoming gridExtent and subext are cell extents.
vtkIdType sourceIdx =
vtkStructuredData::ComputePointIdForExtent(
gridExtent,ijk,description);
assert("pre: source index is out-of-bounds" &&
(sourceIdx >= 0) &&
(sourceIdx < inputDataArray->GetNumberOfTuples()));
// Compute the target index in the subset array. Likewise, this could be
// either a cell index or a node index depending on what gridExtent or
// subext represent.
vtkIdType targetIdx =
vtkStructuredData::ComputePointIdForExtent(
subext,ijk,description);
assert("pre: target index is out-of-bounds" &&
(targetIdx >= 0) &&
(targetIdx < subSetArray->GetNumberOfTuples()));
subSetArray->SetTuple( targetIdx, sourceIdx, inputDataArray );
} // END for all k
} // END for all j
} // END for all i
return(subSetArray);
}
//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSelectedTuples(
vtkIdList *tupleIds, vtkDataArray *inputDataArray )
{
vtkDataArray *subSetArray =
vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
subSetArray->SetName( inputDataArray->GetName() );
subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
subSetArray->SetNumberOfTuples(tupleIds->GetNumberOfIds());
vtkIdType idx = 0;
for( ; idx < tupleIds->GetNumberOfIds(); ++idx )
{
vtkIdType tupleIdx = tupleIds->GetId(idx);
assert("pre: tuple ID is out-of bounds" &&
(tupleIdx >= 0) && (tupleIdx < inputDataArray->GetNumberOfTuples()));
subSetArray->SetTuple( idx, tupleIdx, inputDataArray );
} // END for all tuples to extract
return( subSetArray );
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeDataArray(
vtkDataArray *dataArray, vtkMultiProcessStream& bytestream)
{
if( dataArray == NULL )
{
vtkGenericWarningMacro("data array is NULL!");
return;
}
// STEP 0: Serialize array information
int dataType = dataArray->GetDataType();
int numComp = dataArray->GetNumberOfComponents();
int numTuples = dataArray->GetNumberOfTuples();
// serialize array information
bytestream << dataType << numTuples << numComp;
bytestream << std::string( dataArray->GetName() );
// STEP 1: Push the raw data into the bytestream
// TODO: Add more cases for more datatypes here (?)
unsigned int size = numComp*numTuples;
switch( dataArray->GetDataType() )
{
case VTK_FLOAT:
bytestream.Push(static_cast<float*>(dataArray->GetVoidPointer(0)),size);
break;
case VTK_DOUBLE:
bytestream.Push(static_cast<double*>(dataArray->GetVoidPointer(0)),size);
break;
case VTK_INT:
bytestream.Push(static_cast<int*>(dataArray->GetVoidPointer(0)),size);
break;
case VTK_ID_TYPE:
bytestream.Push(
static_cast<vtkIdType*>(dataArray->GetVoidPointer(0)),size);
break;
default:
assert("ERROR: cannot serialize data of given type" && false);
cerr << "Canot serialize data of type="
<< dataArray->GetDataType() << endl;
}
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Deserialize(
vtkMultiProcessStream& bytestream, vtkFieldData *fieldData)
{
if( fieldData == NULL )
{
vtkGenericWarningMacro("FieldData is NULL!");
return;
}
if( bytestream.Empty() )
{
vtkGenericWarningMacro("Bytestream is empty!");
return;
}
// STEP 0: Get the number of arrays
int numberOfArrays = 0;
bytestream >> numberOfArrays;
if( numberOfArrays == 0 )
{
return;
}
// STEP 1: Loop and deserialize each array
for( int array=0; array < numberOfArrays; ++array )
{
vtkDataArray *dataArray = NULL;
vtkFieldDataSerializer::DeserializeDataArray( bytestream,dataArray );
assert("post: deserialized data array should not be NULL!" &&
(dataArray != NULL));
fieldData->AddArray( dataArray );
dataArray->Delete();
} // END for all arrays
}
//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeDataArray(
vtkMultiProcessStream& bytestream,
vtkDataArray *&dataArray)
{
if( bytestream.Empty() )
{
vtkGenericWarningMacro("Bytestream is empty!");
return;
}
// STEP 0: Deserialize array information
int dataType, numTuples, numComp;
std::string name;
bytestream >> dataType >> numTuples >> numComp >> name;
assert("pre: numComp >= 1" && (numComp >= 1) );
// STEP 1: Construct vtkDataArray object
dataArray = vtkDataArray::CreateDataArray( dataType );
dataArray->SetNumberOfComponents( numComp );
dataArray->SetNumberOfTuples( numTuples );
dataArray->SetName( name.c_str() );
// STEP 2: Extract raw data to vtkDataArray
// TODO: Add more cases for more datatypes here (?)
unsigned int size = numTuples*numComp;
void* rawPtr = dataArray->GetVoidPointer(0);
assert("pre: raw pointer is NULL!" && (rawPtr != NULL) );
switch( dataType )
{
case VTK_FLOAT:
{
float* data = static_cast<float*>(rawPtr);
bytestream.Pop(data,size);
}
break;
case VTK_DOUBLE:
{
double *data = static_cast<double*>(rawPtr);
bytestream.Pop(data,size);
}
break;
case VTK_INT:
{
int *data = static_cast<int*>(rawPtr);
bytestream.Pop(data,size);
}
break;
case VTK_ID_TYPE:
{
vtkIdType* data = static_cast<vtkIdType*>(rawPtr);
bytestream.Pop(data,size);
}
break;
default:
assert("ERROR: cannot serialize data of given type" && false);
cerr << "Canot serialize data of type="
<< dataArray->GetDataType() << endl;
}
}