Commit a15996f0 authored by George Zagaris's avatar George Zagaris
Browse files

ENH/BUGFIX: ImageData-To-StructuredGrid Updates

Inherited from vtkStructuredGridAlgorithm instead
of vtkDataSetAlgorithm. Fixed floating point issue
by setting the points array to be double precision.
Added simple example code that demonstrates the use
of the filter and a corresponding test for the filter.
parent cb2ccfc3
......@@ -41,3 +41,12 @@ TARGET_LINK_LIBRARIES( AMRDataTransferPipeline
vtkParallel
${MPI_LIBRARIES}
)
## Add TestImageDataToStructuredGridFilter
ADD_EXECUTABLE( TestImageDataToStructuredGridFilter
TestImageDataToStructuredGridFilter.cxx )
TARGET_LINK_LIBRARIES(TestImageDataToStructuredGridFilter
vtkGraphics
vtkIO
vtkFiltering
)
\ No newline at end of file
/*=========================================================================
Program: Visualization Toolkit
Module: TestImageDataToStructuredGridFilter.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.
=========================================================================*/
// .NAME TestImageDataToStructuredGridFilter.cxx
//
// A simple utility that demonstrates & tests the functionality of the
// vtkImageDataToStructuredGridFilter.
#include "vtkImageDataToStructuredGridFilter.h"
#include "vtkStructuredGrid.h"
#include "vtkImageData.h"
#include "vtkUniformGrid.h"
#include "vtkAssertUtils.hpp"
#include "vtkDoubleArray.h"
#include "vtkCell.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkStructuredGridWriter.h"
// Function Prototypes
vtkUniformGrid* GetGrid( double *origin, double *spacing, int *ndim );
int main( int argc, char **argv )
{
double origin[3] = { 0.0,0.0,0.0 };
double spacing[3] = { 0.5,0.2,0.0 };
int ndim[3] = { 10, 10, 1 };
vtkUniformGrid* myGrid = GetGrid( origin, spacing, ndim );
vtkAssertUtils::assertNotNull( myGrid, __FILE__, __LINE__ );
vtkAssertUtils::assertEquals(
myGrid->GetCellData()->GetNumberOfArrays(),1,__FILE__,__LINE__);
vtkImageDataToStructuredGridFilter* myFilter =
vtkImageDataToStructuredGridFilter::New( );
vtkAssertUtils::assertNotNull( myFilter, __FILE__, __LINE__ );
myFilter->SetInput( myGrid );
myFilter->Update();
vtkStructuredGrid* sGrid = myFilter->GetOutput();
vtkAssertUtils::assertNotNull( sGrid, __FILE__, __LINE__ );
myGrid->Delete();
vtkStructuredGridWriter* myWriter = vtkStructuredGridWriter::New( );
vtkAssertUtils::assertNotNull(myWriter,__FILE__,__LINE__);
myWriter->SetInput( sGrid );
myWriter->SetFileName( "myGrid.vtk" );
myWriter->Update();
myWriter->Delete();
return 0;
}
//------------------------------------------------------------------------------
vtkUniformGrid* GetGrid( double *origin, double *spacing, int *ndim )
{
vtkUniformGrid *grd = vtkUniformGrid::New();
grd->Initialize();
grd->SetOrigin( origin );
grd->SetSpacing( spacing );
grd->SetDimensions( ndim );
vtkDoubleArray* pntData = vtkDoubleArray::New();
pntData->SetName( "XYZ-NODE" );
pntData->SetNumberOfComponents( 1 );
pntData->SetNumberOfTuples( grd->GetNumberOfPoints() );
double node[3];
for( int pntIdx=0; pntIdx < grd->GetNumberOfPoints(); ++pntIdx )
{
grd->GetPoint( pntIdx, node );
pntData->SetValue(pntIdx, (node[0]+node[1]+node[2]) );
} // END for all points
grd->GetPointData()->AddArray( pntData );
vtkDoubleArray* xyz = vtkDoubleArray::New( );
xyz->SetName( "XYZ-CELL" );
xyz->SetNumberOfComponents( 1 );
xyz->SetNumberOfTuples( grd->GetNumberOfCells() );
for( int cellIdx=0; cellIdx < grd->GetNumberOfCells(); ++cellIdx )
{
vtkCell* myCell = grd->GetCell( cellIdx);
vtkAssertUtils::assertNotNull( myCell, __FILE__, __LINE__ );
vtkPoints *cellPoints = myCell->GetPoints();
vtkAssertUtils::assertNotNull( cellPoints, __FILE__, __LINE__ );
double xyzCenter[3];
xyzCenter[0] = 0.0;
xyzCenter[1] = 0.0;
xyzCenter[2] = 0.0;
for( int cp=0; cp < cellPoints->GetNumberOfPoints(); ++cp )
{
double pnt[3];
cellPoints->GetPoint( cp, pnt );
xyzCenter[0] += pnt[0];
xyzCenter[1] += pnt[1];
xyzCenter[2] += pnt[2];
} // END for all cell points
xyzCenter[0] = xyzCenter[0] / (cellPoints->GetNumberOfPoints());
xyzCenter[1] = xyzCenter[1] / (cellPoints->GetNumberOfPoints());
xyzCenter[2] = xyzCenter[2] / (cellPoints->GetNumberOfPoints());
double f = xyzCenter[0]*xyzCenter[0] +
xyzCenter[1]*xyzCenter[1] + xyzCenter[2]*xyzCenter[2];
xyz->SetTuple1(cellIdx,f);
} // END for all cells
grd->GetCellData()->AddArray(xyz);
return grd;
}
......@@ -26,6 +26,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestPolygon.cxx
TestTreeBFSIterator.cxx
TestTriangle.cxx
TestImageDataToStructuredGrid.cxx
EXTRA_INCLUDE vtkTestDriver.h
)
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestImageDataToStructuredGridFilter.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 "vtkUniformGrid.h"
#include "vtkStructuredGrid.h"
#include "vtkCell.h"
#include "vtkMath.h"
#include "vtkPointData.h"
#include "vtkCellData.h"
#include "vtkDataArray.h"
#include "vtkDoubleArray.h"
#include "vtkImageDataToStructuredGridFilter.h"
#include <cmath>
#include <limits>
#include <string>
#include <cstring>
// Description:
// Performs safe division a/b which also checks for underflow & overflow
double SafeDivision( const double a, const double b )
{
// Catch overflow
if( (b < 1) && (a > ( b*std::numeric_limits<double>::max() ) ) )
return std::numeric_limits<double>::max();
// Catch underflow
if( (a == static_cast<double>(0.0)) ||
( (b > 1) && (a < b*std::numeric_limits<double>::max() ) ) )
return( static_cast<double>( 0.0 ) );
return( a/b );
}
// Description:
// Checks if two given floating numbers are equivalent.
// This algorithm is based on Knuth, The of Computer Programming (vol II).
bool FloatNumberEquals( double a, double b, double TOL )
{
double adiff = std::abs( a-b );
double d1 = SafeDivision( adiff,std::abs(a) );
double d2 = SafeDivision( adiff,std::abs(b) );
if( (d1 <= TOL) || (d2 <= TOL) )
return true;
return false;
}
// Description:
// Checks if the given two points a & b are equal
bool ArePointsEqual( double a[3], double b[3], double TOL=1e-9 )
{
for( int i=0; i < 3; ++i )
{
if( !FloatNumberEquals( a[i], b[i], TOL ) )
return false;
}
return true;
}
// Description:
// Constructs a uniform grid instance with the given spacing & dimensions
// at the user-supplied origin.
vtkUniformGrid* GetGrid( double *origin, double *spacing, int *ndim )
{
vtkUniformGrid *grd = vtkUniformGrid::New();
grd->Initialize();
grd->SetOrigin( origin );
grd->SetSpacing( spacing );
grd->SetDimensions( ndim );
vtkDoubleArray* pntData = vtkDoubleArray::New();
pntData->SetName( "XYZ-NODE" );
pntData->SetNumberOfComponents( 1 );
pntData->SetNumberOfTuples( grd->GetNumberOfPoints() );
double node[3];
for( int pntIdx=0; pntIdx < grd->GetNumberOfPoints(); ++pntIdx )
{
grd->GetPoint( pntIdx, node );
pntData->SetValue(pntIdx, (node[0]+node[1]+node[2]) );
} // END for all points
grd->GetPointData()->AddArray( pntData );
vtkDoubleArray* xyz = vtkDoubleArray::New( );
xyz->SetName( "XYZ-CELL" );
xyz->SetNumberOfComponents( 1 );
xyz->SetNumberOfTuples( grd->GetNumberOfCells() );
for( int cellIdx=0; cellIdx < grd->GetNumberOfCells(); ++cellIdx )
{
vtkCell* myCell = grd->GetCell( cellIdx);
vtkPoints *cellPoints = myCell->GetPoints();
double xyzCenter[3];
xyzCenter[0] = 0.0;
xyzCenter[1] = 0.0;
xyzCenter[2] = 0.0;
for( int cp=0; cp < cellPoints->GetNumberOfPoints(); ++cp )
{
double pnt[3];
cellPoints->GetPoint( cp, pnt );
xyzCenter[0] += pnt[0];
xyzCenter[1] += pnt[1];
xyzCenter[2] += pnt[2];
} // END for all cell points
xyzCenter[0] = xyzCenter[0] / (cellPoints->GetNumberOfPoints());
xyzCenter[1] = xyzCenter[1] / (cellPoints->GetNumberOfPoints());
xyzCenter[2] = xyzCenter[2] / (cellPoints->GetNumberOfPoints());
double f = xyzCenter[0]*xyzCenter[0] +
xyzCenter[1]*xyzCenter[1] + xyzCenter[2]*xyzCenter[2];
xyz->SetTuple1(cellIdx,f);
} // END for all cells
grd->GetCellData()->AddArray(xyz);
return grd;
}
// Description
// Checks if the given image data-set is equivalent to the structured grid
// data-set.
bool DataSetsEqual( vtkImageData* img, vtkStructuredGrid* sg )
{
// 0. Check dimensions
int imgdim[3]; int sgdim[3];
img->GetDimensions( imgdim );
sg->GetDimensions( sgdim );
for( int i=0; i < 3; ++i )
{
if( imgdim[i] != sgdim[i] )
return false;
}
// 1. Check Number of elements
if( img->GetNumberOfCells() != sg->GetNumberOfCells() )
return false;
// 2. Check Number of points
if( img->GetNumberOfPoints() != sg->GetNumberOfPoints() )
return false;
// 3. Check Point equality
double pnt1[3]; double pnt2[3];
for( int pntIdx=0; pntIdx < img->GetNumberOfPoints(); ++pntIdx )
{
img->GetPoint( pntIdx, pnt1 );
sg->GetPoint( pntIdx,pnt2 );
if( !ArePointsEqual( pnt1, pnt2 ) )
return false;
}
// 4. Check Point data equality
if( img->GetPointData()->GetNumberOfArrays() !=
sg->GetPointData()->GetNumberOfArrays() )
return false;
int dataArrayIdx = 0;
for(;dataArrayIdx<img->GetPointData()->GetNumberOfArrays();++dataArrayIdx )
{
vtkDataArray* array1 = img->GetPointData()->GetArray( dataArrayIdx );
vtkDataArray* array2 = sg->GetPointData()->GetArray( dataArrayIdx );
if( array1->GetNumberOfComponents() != array2->GetNumberOfComponents() )
return false;
if( array1->GetNumberOfTuples() != array2->GetNumberOfTuples() )
return false;
if( std::strcmp( array1->GetName(), array2->GetName() ) != 0 )
return false;
} // END for all point arrays
// 5. Check Cell data equality
if( img->GetCellData()->GetNumberOfArrays() !=
sg->GetCellData()->GetNumberOfArrays() )
return false;
dataArrayIdx = 0;
for(;dataArrayIdx<img->GetCellData()->GetNumberOfArrays();++dataArrayIdx)
{
vtkDataArray* array1 = img->GetCellData()->GetArray( dataArrayIdx );
vtkDataArray* array2 = sg->GetCellData()->GetArray( dataArrayIdx );
if( array1->GetNumberOfComponents() != array2->GetNumberOfComponents() )
return false;
if( array1->GetNumberOfTuples() != array2->GetNumberOfTuples() )
return false;
if( std::strcmp( array1->GetName(), array2->GetName() ) != 0 )
return false;
} // END for all cell arrays
return true;
}
int TestImageDataToStructuredGrid( int argc, char **argv )
{
int rval = 0;
double origin[3] = {0.0,0.0,0.0};
double spacing[3] = {0.5,0.2,0.0};
int ndim[3] = {10, 10, 1};
vtkUniformGrid* img1 = GetGrid( origin, spacing, ndim );
vtkImageDataToStructuredGridFilter* myFilter =
vtkImageDataToStructuredGridFilter::New( );
myFilter->SetInput( img1 );
myFilter->Update();
vtkStructuredGrid* sg1 = myFilter->GetOutput();
if( !DataSetsEqual( img1, sg1 ) )
rval = 1;
return( rval );
}
......@@ -17,7 +17,13 @@
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkDataObject.h"
#include "vtkAssertUtils.hpp"
#include "vtkImageData.h"
#include "vtkPoints.h"
#include "vtkStructuredGrid.h"
#include "vtkPointData.h"
#include "vtkCellData.h"
#include <cassert>
//
// Standard methods
......@@ -67,8 +73,70 @@ int vtkImageDataToStructuredGridFilter::RequestData(
{
vtkInformation* inInfo = inputVector[0]->GetInformationObject( 0 );
vtkInformation* outInfo = outputVector->GetInformationObject( 0 );
vtkAssertUtils::assertNotNull( inInfo,__FILE__, __LINE__);
vtkAssertUtils::assertNotNull( outInfo,__FILE__,__LINE__);
assert( inInfo != NULL );
assert( outInfo != NULL );
vtkImageData* img = vtkImageData::SafeDownCast(
inInfo->Get(vtkImageData::DATA_OBJECT() ) );
assert( img != NULL );
vtkStructuredGrid* grid = vtkStructuredGrid::SafeDownCast(
outInfo->Get( vtkStructuredGrid::DATA_OBJECT() ) );
assert( grid != NULL );
int dims[3];
img->GetDimensions( dims );
vtkPoints *gridPoints = vtkPoints::New();
assert( gridPoints != NULL );
gridPoints->SetDataTypeToDouble();
gridPoints->SetNumberOfPoints( img->GetNumberOfPoints() );
double pnt[3];
for( int i=0; i < img->GetNumberOfPoints(); ++i )
{
img->GetPoint( i, pnt );
gridPoints->SetPoint(i,pnt);
}
grid->SetDimensions(dims);
grid->SetPoints( gridPoints );
this->CopyPointData( img, grid );
this->CopyCellData( img, grid );
return 1;
}
//------------------------------------------------------------------------------
void vtkImageDataToStructuredGridFilter::CopyPointData(
vtkImageData* img, vtkStructuredGrid* sgrid)
{
assert( img != NULL );
assert( sgrid != NULL );
if( img->GetPointData()->GetNumberOfArrays() == 0 )
return;
for( int i=0; i < img->GetPointData()->GetNumberOfArrays(); ++i)
{
vtkDataArray* myArray = img->GetPointData()->GetArray( i );
sgrid->GetPointData()->AddArray( myArray );
} // END for all node arrays
}
//------------------------------------------------------------------------------
void vtkImageDataToStructuredGridFilter::CopyCellData(
vtkImageData* img, vtkStructuredGrid* sgrid )
{
assert( img != NULL );
assert( sgrid != NULL );
if( img->GetCellData()->GetNumberOfArrays() == 0)
return;
// TODO: implement this
for( int i=0; i < img->GetCellData()->GetNumberOfArrays(); ++i)
{
vtkDataArray* myArray = img->GetCellData()->GetArray( i );
sgrid->GetCellData()->AddArray( myArray );
} // END for all cell arrays
}
......@@ -16,24 +16,25 @@
// data to structured grid.
//
// .SECTION Description
// A concrete instance of vtkDataSetAlgorithm which provides functionality for
// converting vtkImageData to vtkStructuredGrid
// A concrete instance of vtkStructuredGridAlgorithm which provides
// functionality for converting instances of vtkImageData to vtkStructuredGrid.
#ifndef VTKIMAGEDATATOSTRUCTUREDGRIDFILTER_H_
#define VTKIMAGEDATATOSTRUCTUREDGRIDFILTER_H_
#include "vtkDataSetAlgorithm.h"
#include "vtkStructuredGridAlgorithm.h"
class vtkStructuredGrid;
class vtkImageData;
class vtkInformation;
class vtkInformationVector;
class VTK_FILTERING_EXPORT vtkImageDataToStructuredGridFilter : public vtkDataSetAlgorithm
class VTK_FILTERING_EXPORT vtkImageDataToStructuredGridFilter :
public vtkStructuredGridAlgorithm
{
public:
static vtkImageDataToStructuredGridFilter* New();
vtkTypeMacro(vtkImageDataToStructuredGridFilter,vtkDataSetAlgorithm);
vtkTypeMacro(vtkImageDataToStructuredGridFilter,vtkStructuredGridAlgorithm);
void PrintSelf( std::ostream &oss, vtkIndent indent );
protected:
......@@ -45,8 +46,14 @@ class VTK_FILTERING_EXPORT vtkImageDataToStructuredGridFilter : public vtkDataSe
vtkInformationVector** inputVector,
vtkInformationVector* outputVector );
// Description:
// Helper function to copy point/cell data from image to grid
void CopyPointData( vtkImageData*, vtkStructuredGrid* );
void CopyCellData( vtkImageData*, vtkStructuredGrid* );
virtual int FillInputPortInformation(int, vtkInformation* info);
virtual int FillOutputPortInformation(int, vtkInformation* info );
private:
vtkImageDataToStructuredGridFilter(
const vtkImageDataToStructuredGridFilter& ); //Not implemented
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment