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

ENH: Improvements in AMR probe filter

Modularized and improved the implementation and added
TestAMRProbe example to the repository.
parent fc841028
......@@ -15,6 +15,7 @@
#include <cassert>
#include <list>
#include <set>
#include <algorithm>
#include "vtkInformation.h"
......@@ -25,8 +26,10 @@
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkPointSet.h"
#include "vtkPoints.h"
#include "vtkUniformGrid.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkAMRBox.h"
#include "vtkAMRGridIndexEncoder.h"
vtkStandardNewMacro(vtkAMRProbeFilter);
......@@ -63,6 +66,91 @@ void vtkAMRProbeFilter::SetProbePoints( vtkPointSet *probes )
this->SetInput(1,probes);
}
//------------------------------------------------------------------------------
bool vtkAMRProbeFilter::PointInAMRBlock(
double x, double y, double z,
int levelIdx, int blockIdx,
vtkHierarchicalBoxDataSet *amrds )
{
assert( "pre: input AMR dataset is NULL" && (amrds != NULL) );
assert( "pre: level index is out of bounds!" &&
( (levelIdx >= 0) && (levelIdx < amrds->GetNumberOfLevels() ) ) );
assert( "pre: block index is out of bounds!" &&
( (blockIdx >= 0) && (blockIdx < amrds->GetNumberOfDataSets(levelIdx) ) ) );
vtkAMRBox amrBox;
amrds->GetMetaData( levelIdx, blockIdx, amrBox );
if( amrBox.HasPoint( x, y, z ) )
return true;
return false;
}
//------------------------------------------------------------------------------
bool vtkAMRProbeFilter::FindPointInLevel(
double x, double y, double z,
int levelIdx,vtkHierarchicalBoxDataSet *amrds,
int &blockId )
{
assert( "pre: input AMR dataset is NULL" && (amrds != NULL) );
assert( "pre: level index is out of bounds!" &&
( (levelIdx >= 0) && (levelIdx < amrds->GetNumberOfLevels() ) ) );
unsigned int dataIdx = 0;
for( ; dataIdx < amrds->GetNumberOfDataSets( levelIdx ); ++dataIdx )
{
if( this->PointInAMRBlock(x,y,z,levelIdx,dataIdx,amrds) )
{
blockId = static_cast< int >( dataIdx );
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
void vtkAMRProbeFilter::ExtractAMRBlocks(
vtkMultiBlockDataSet *mbds, vtkHierarchicalBoxDataSet *amrds,
std::set< unsigned int > &blocksToExtract )
{
assert( "pre: multi-block dataset is NULL" && (mbds != NULL) );
assert( "pre: AMR dataset is NULL" && (amrds != NULL) );
mbds->SetNumberOfBlocks( blocksToExtract.size() );
unsigned int blockIdx = 0;
std::set< unsigned int >::iterator iter = blocksToExtract.begin();
for( ; iter != blocksToExtract.end(); ++iter )
{
unsigned int gridIdx = *iter;
int blockId = -1;
int levelId = -1;
vtkAMRGridIndexEncoder::decode( gridIdx, levelId, blockId );
assert( "level index out-of-bounds" &&
( (levelId >= 0) && ( levelId < amrds->GetNumberOfLevels())));
assert( "block index out-of-bounds" &&
( (blockId >= 0) && (blockId < amrds->GetNumberOfDataSets(levelId))));
vtkUniformGrid *ug = amrds->GetDataSet( levelId, blockId );
if( ug != NULL )
{
vtkUniformGrid *clone = ug->NewInstance();
clone->ShallowCopy( ug );
clone->SetCellVisibilityArray( NULL );
clone->SetPointVisibilityArray( NULL );
mbds->SetBlock( blockIdx, clone );
++blockIdx;
clone->Delete();
}
} // END for all blocks
}
//------------------------------------------------------------------------------
void vtkAMRProbeFilter::ProbeAMR(
vtkPointSet *probes, vtkHierarchicalBoxDataSet *amrds,
......@@ -73,39 +161,62 @@ void vtkAMRProbeFilter::ProbeAMR(
assert( "pre: input probe pointset is NULL" && (probes != NULL) );
assert( "pre: multiblock output is NULL" && (mbds != NULL) );
std::list< vtkIdType > probeIds;
unsigned int pnt = 0;
for( ; pnt < probes->GetNumberOfPoints(); ++pnt )
probeIds.push_front( pnt );
// Loop through all levels from highest to lowest and while there
// are still probe points.
unsigned int level=amrds->GetNumberOfLevels()-1;
for( ; !probeIds.empty() && (level >= 0); --level )
// Contains the packed (levelId,blockId) pair of the blocks
// to extract in the multiblock dataset.
std::set< unsigned int > blocksToExtract;
// STEP 0: Initialize work ID list
std::list< vtkIdType > workIdList;
for( vtkIdType idx=0; idx < probes->GetNumberOfPoints(); ++idx )
workIdList.push_front( idx );
// STEP 1: loop while the workIdList is not empty, searching for a block
// that contains the point, starting from highest resolution level to
// lowest resolution
while( !workIdList.empty() )
{
vtkIdType currentIdx = workIdList.front();
workIdList.pop_front();
std::list< vtkIdType >::iterator probeIter = probeIds.begin();
for( ; probeIter != probeIds.end(); ++probeIter )
double pnt[3];
probes->GetPoint( currentIdx, pnt );
int blockId = -1;
unsigned int currentLevel = amrds->GetNumberOfLevels()-1;
bool isBlockFound = false;
for( ; currentLevel >= 0; --currentLevel )
{
vtkIdType idx = *probeIter;
double coords[3];
probes->GetPoint( idx, coords );
unsigned int dataIdx = 0;
for( ; dataIdx < amrds->GetNumberOfDataSets(level); ++dataIdx )
if( this->FindPointInLevel(
pnt[0],pnt[1],pnt[2],
currentLevel,amrds,blockId ) )
{
vtkAMRBox box;
amrds->GetMetaData( level, dataIdx, box );
if( box.HasPoint(coords[0],coords[1],coords[2]) )
{
// TODO: implement this
}
assert( "invalid block ID" &&
( (blockId >= 0) &&
(blockId < amrds->GetNumberOfDataSets(currentLevel) ) ) );
int level = static_cast< int >( currentLevel );
unsigned int grididx =
vtkAMRGridIndexEncoder::encode(level,blockId);
blocksToExtract.insert( grididx );
isBlockFound = true;
break;
}
} // END for all data
} // END for all probes
} // END for all levels
if( !isBlockFound )
{
//
// TODO: What should we do with probes that were not found?
//
}
} // END for all levels
} // END while work ID list is not empty
// STEP 2: Extract the AMR blocks
this->ExtractAMRBlocks( mbds, amrds, blocksToExtract );
}
//------------------------------------------------------------------------------
......
......@@ -29,6 +29,7 @@
#define VTKAMRPROBEFILTER_H_
#include "vtkMultiBlockDataSetAlgorithm.h"
#include <set> // For C++ STL set
class vtkHierarchicalBoxDataSet;
class vtkMultiBlockDataSet;
......@@ -56,6 +57,26 @@ class VTK_AMR_EXPORT vtkAMRProbeFilter : public vtkMultiBlockDataSetAlgorithm
vtkAMRProbeFilter();
virtual ~vtkAMRProbeFilter();
// Description:
// Extracts the AMR blocks into a multi-block dataset instance.
void ExtractAMRBlocks(
vtkMultiBlockDataSet *mbds,
vtkHierarchicalBoxDataSet *amrds,
std::set< unsigned int > &blocksToExtract );
// Description:
// Determines if a point is within a block at a given level
bool FindPointInLevel(
double x, double y, double z,
int levelIdx, vtkHierarchicalBoxDataSet *amrds, int &blockId );
// Description:
// Determines if a point is within an AMR block given the x,y,z coordinates
// and the level and ID of the target block.
bool PointInAMRBlock(
double x, double y, double z,
int levelIdx, int blockIdx, vtkHierarchicalBoxDataSet *amrds );
// Description:
// Given a user-supplied pointset, this method finds the blocks
// that contain these points from the input AMR dataset, amrds,
......
......@@ -77,6 +77,18 @@ TARGET_LINK_LIBRARIES( Generate2DAMRDataSetWithPulse
vtkParallel
${MPI_LIBRARIES}
)
## Add TestAMRProbe executable
ADD_EXECUTABLE( TestAMRProbe TestAMRProbe.cxx )
TARGET_LINK_LIBRARIES( TestAMRProbe
vtkGraphics
vtkFiltering
vtkRendering
vtkIO
vtkAMR
vtkParallel
${MPI_LIBRARIES}
)
## Add TestImageDataToStructuredGridFilter
ADD_EXECUTABLE( TestImageDataToStructuredGridFilter
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestAMRProbe.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 TestAMRProbe.cxx -- demonstrates/tests the AMR probing functionality
//
// .SECTION Description
// This is a simple utility code to demonstrate and test the functionality of
// the AMR probe filter.
#include "AMRCommon.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkAMRBox.h"
#include "vtkPointSet.h"
#include "vtkUnstructuredGrid.h"
#include "vtkAMRProbeFilter.h"
#include "vtkMultiBlockDataSet.h"
#include <cassert>
// Description:
// Returns the list of probes.
vtkPointSet *GetProbes();
//
// Main
//
int main( int argc, char **argv )
{
std::string file = std::string(argv[1]);
vtkHierarchicalBoxDataSet *amrds = AMRCommon::ReadAMRData( file );
assert( "pre: AMR dataset is NULL" && (amrds != NULL) );
vtkPointSet *pntSet = GetProbes();
assert( "pre: probes are NULL" && (pntSet != NULL) );
vtkAMRProbeFilter *amrProbeFilter = vtkAMRProbeFilter::New();
assert( "pre: AMR probe filter is NULL" && (amrProbeFilter != NULL) );
amrProbeFilter->SetAMRDataSet( amrds );
amrProbeFilter->SetProbePoints( pntSet );
amrProbeFilter->Update();
vtkMultiBlockDataSet *mbds = amrProbeFilter->GetOutput();
assert( "pre: Multi-block dataset output is NULL" && (mbds != NULL) );
AMRCommon::WriteMultiBlockData( mbds, "ProbedBlocks" );
// De-allocate
// mbds->Delete();
amrds->Delete();
pntSet->Delete();
amrProbeFilter->Delete();
return 0;
}
//------------------------------------------------------------------------------
vtkPointSet *GetProbes()
{
vtkPoints *probes = vtkPoints::New();
probes->SetNumberOfPoints( 2 );
probes->SetPoint(0,-1.0, -1.0, 0.0 );
probes->SetPoint(1, 2.0, 1.0, 0.0 );
vtkUnstructuredGrid *ug = vtkUnstructuredGrid::New();
ug->SetPoints( probes );
return( ug );
}
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