Commit 6d91217b authored by Bill Lorensen's avatar Bill Lorensen
Browse files

ENH: Rearrange classes.

parent 4ce9cf11
......@@ -35,7 +35,6 @@ vtkCell.cxx
vtkCellData.cxx
vtkCellLinks.cxx
vtkCellLocator.cxx
vtkCellLocatorInterpolatedVelocityField.cxx
vtkCellTypes.cxx
vtkColorTransferFunction.cxx
vtkCompositeDataIterator.cxx
......@@ -139,7 +138,6 @@ vtkLocator.cxx
vtkMapper2D.cxx
vtkMeanValueCoordinatesInterpolator.cxx
vtkMergePoints.cxx
vtkModifiedBSPTree.cxx
vtkMultiBlockDataSetAlgorithm.cxx
vtkMultiBlockDataSet.cxx
vtkMultiPieceDataSet.cxx
......
......@@ -32,6 +32,7 @@ vtkButtonSource.cxx
vtkCellCenters.cxx
vtkCellDataToPointData.cxx
vtkCellDerivatives.cxx
vtkCellLocatorInterpolatedVelocityField.cxx
vtkCellQuality.cxx
vtkCleanPolyData.cxx
vtkClipClosedSurface.cxx
......@@ -161,6 +162,7 @@ vtkMergeFields.cxx
vtkMergeFilter.cxx
vtkMeshQuality.cxx
vtkModelMetadata.cxx
vtkModifiedBSPTree.cxx
vtkMultiBlockDataGroupFilter.cxx
vtkMultiBlockMergeFilter.cxx
vtkMultiThreshold.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkCellLocatorInterpolatedVelocityField.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 "vtkCellLocatorInterpolatedVelocityField.h"
#include "vtkMath.h"
#include "vtkDataSet.h"
#include "vtkDataArray.h"
#include "vtkPointData.h"
#include "vtkGenericCell.h"
#include "vtkCellLocator.h"
#include "vtkSmartPointer.h"
#include "vtkObjectFactory.h"
#include "vtkModifiedBSPTree.h"
vtkStandardNewMacro ( vtkCellLocatorInterpolatedVelocityField );
vtkCxxSetObjectMacro( vtkCellLocatorInterpolatedVelocityField, CellLocatorPrototype, vtkAbstractCellLocator );
//----------------------------------------------------------------------------
typedef vtkstd::vector< vtkSmartPointer < vtkAbstractCellLocator > > CellLocatorsTypeBase;
class vtkCellLocatorInterpolatedVelocityFieldCellLocatorsType : public CellLocatorsTypeBase { };
//----------------------------------------------------------------------------
vtkCellLocatorInterpolatedVelocityField::vtkCellLocatorInterpolatedVelocityField()
{
this->LastCellLocator = 0;
this->CellLocatorPrototype = 0;
this->CellLocators = new vtkCellLocatorInterpolatedVelocityFieldCellLocatorsType;
}
//----------------------------------------------------------------------------
vtkCellLocatorInterpolatedVelocityField::~vtkCellLocatorInterpolatedVelocityField()
{
this->LastCellLocator = 0;
this->SetCellLocatorPrototype( 0 );
if ( this->CellLocators )
{
delete this->CellLocators;
this->CellLocators = 0;
}
}
//----------------------------------------------------------------------------
void vtkCellLocatorInterpolatedVelocityField::SetLastCellId
( vtkIdType c, int dataindex )
{
this->LastCellId = c;
this->LastDataSet = ( *this->DataSets )[dataindex];
this->LastCellLocator = ( *this->CellLocators )[dataindex].GetPointer();
this->LastDataSetIndex = dataindex;
// If the dataset changes, then the cached cell is invalidated. We might as
// well prefetch the cached cell either way.
if ( this->LastCellId != -1 )
{
this->LastDataSet->GetCell( this->LastCellId, this->GenCell );
}
}
//----------------------------------------------------------------------------
int vtkCellLocatorInterpolatedVelocityField::FunctionValues
( double * x, double * f )
{
vtkDataSet * vds = NULL;
vtkAbstractCellLocator * loc = NULL;
if( !this->LastDataSet && !this->DataSets->empty() )
{
vds = ( *this->DataSets )[0];
loc = ( *this->CellLocators )[0].GetPointer();
this->LastDataSet = vds;
this->LastCellLocator = loc;
this->LastDataSetIndex = 0;
}
else
{
vds = this->LastDataSet;
loc = this->LastCellLocator;
}
int retVal;
if ( loc )
{
// resort to vtkAbstractCellLocator::FindCell()
retVal = this->FunctionValues( vds, loc, x, f );
}
else
{
// turn to vtkImageData/vtkRectilinearGrid::FindCell()
retVal = this->FunctionValues( vds, x, f );
}
if ( !retVal )
{
for( this->LastDataSetIndex = 0;
this->LastDataSetIndex < static_cast<int>( this->DataSets->size() );
this->LastDataSetIndex ++ )
{
vds = this->DataSets->operator[]( this->LastDataSetIndex );
loc = this->CellLocators->operator[]( this->LastDataSetIndex ).GetPointer();
if( vds && vds != this->LastDataSet )
{
this->ClearLastCellId();
if ( loc )
{
// resort to vtkAbstractCellLocator::FindCell()
retVal = this->FunctionValues( vds, loc, x, f );
}
else
{
// turn to vtkImageData/vtkRectilinearGrid::FindCell()
retVal = this->FunctionValues( vds, x, f );
}
if ( retVal )
{
this->LastDataSet = vds;
this->LastCellLocator = loc;
vds = NULL;
loc = NULL;
return retVal;
}
}
}
this->LastCellId = -1;
this->LastDataSet = ( *this->DataSets )[0];
this->LastCellLocator = ( *this->CellLocators )[0].GetPointer();
this->LastDataSetIndex = 0;
vds = NULL;
loc = NULL;
return 0;
}
vds = NULL;
loc = NULL;
return retVal;
}
//----------------------------------------------------------------------------
int vtkCellLocatorInterpolatedVelocityField::FunctionValues
( vtkDataSet * dataset, vtkAbstractCellLocator * loc, double * x, double * f )
{
f[0] = f[1] = f[2] = 0.0;
vtkDataArray * vectors = NULL;
if ( !dataset || !loc || !dataset->IsA( "vtkPointSet" ) ||
!( vectors = dataset->GetPointData()
->GetVectors( this->VectorsSelection )
)
)
{
vtkErrorMacro( <<"Can't evaluate dataset!" );
vectors = NULL;
return 0;
}
int i;
int subIdx;
int numPts;
int pntIdx;
int bFound = 0;
double vector[3];
double dstns2 = 0.0;
double toler2 = dataset->GetLength() *
vtkCellLocatorInterpolatedVelocityField::TOLERANCE_SCALE;
// check if the point is in the cached cell AND can be successfully evaluated
if ( this->LastCellId != -1 &&
this->GenCell->EvaluatePosition
( x, 0, subIdx, this->LastPCoords, dstns2, this->Weights ) == 1
)
{
bFound = 1;
this->CacheHit ++;
}
if ( !bFound )
{
// cache missing or evaluation failure and then we have to find the cell
this->CacheMiss += !( !( this->LastCellId + 1 ) );
this->LastCellId = loc->FindCell( x, toler2, this->GenCell,
this->LastPCoords, this->Weights );
bFound = !( !( this->LastCellId + 1 ) );
}
// interpolate vectors if possible
if ( bFound )
{
numPts = this->GenCell->GetNumberOfPoints();
for ( i = 0; i < numPts; i ++ )
{
pntIdx = this->GenCell->PointIds->GetId( i );
vectors->GetTuple( pntIdx, vector );
f[0] += vector[0] * this->Weights[i];
f[1] += vector[1] * this->Weights[i];
f[2] += vector[2] * this->Weights[i];
}
if ( this->NormalizeVector == true )
{
vtkMath::Normalize( f );
}
}
vectors = NULL;
return bFound;
}
//----------------------------------------------------------------------------
void vtkCellLocatorInterpolatedVelocityField::AddDataSet( vtkDataSet * dataset )
{
if ( !dataset )
{
vtkErrorMacro( <<"Dataset NULL!" );
return;
}
// insert the dataset (do NOT register the dataset to 'this')
this->DataSets->push_back( dataset );
// We need to attach a valid vtkAbstractCellLocator to any vtkPointSet for
// robust cell location as vtkPointSet::FindCell() may incur failures. For
// any non-vtkPointSet dataset, either vtkImageData or vtkRectilinearGrid,
// we do not need to associate a vtkAbstractCellLocator with it (though a
// NULL vtkAbstractCellLocator is still inserted to this->CellLocators to
// enable proper access to those valid cell locators) since these two kinds
// of datasets themselves are able to guarantee robust as well as fast cell
// location via vtkImageData/vtkRectilinearGrid::FindCell().
vtkSmartPointer< vtkAbstractCellLocator > locator = 0; // MUST inited with 0
if ( dataset->IsA( "vtkPointSet" ) )
{
if ( !this->CellLocatorPrototype )
{
locator = vtkSmartPointer < vtkModifiedBSPTree >::New();
}
else
{
locator.TakeReference( this->CellLocatorPrototype->NewInstance() );
}
locator->SetLazyEvaluation( 1 );
locator->SetDataSet( dataset );
}
this->CellLocators->push_back( locator );
int size = dataset->GetMaxCellSize();
if ( size > this->WeightsSize )
{
this->WeightsSize = size;
if ( this->Weights )
{
delete[] this->Weights;
this->Weights = NULL;
}
this->Weights = new double[size];
}
}
//----------------------------------------------------------------------------
void vtkCellLocatorInterpolatedVelocityField::CopyParameters
( vtkAbstractInterpolatedVelocityField * from )
{
this->Superclass::CopyParameters( from );
if ( from->IsA( "vtkCellLocatorInterpolatedVelocityField" ) )
{
this->SetCellLocatorPrototype
( vtkCellLocatorInterpolatedVelocityField::SafeDownCast( from )
->GetCellLocatorPrototype()
);
}
}
//----------------------------------------------------------------------------
void vtkCellLocatorInterpolatedVelocityField::PrintSelf( ostream & os, vtkIndent indent )
{
this->Superclass::PrintSelf( os, indent );
os << indent << "CellLocators: " << this->CellLocators << endl;
if ( this->CellLocators )
{
os << indent << "Number of Cell Locators: " << this->CellLocators->size();
}
os << indent << "LastCellLocator: " << this->LastCellLocator << endl;
os << indent << "CellLocatorPrototype: " << this->CellLocatorPrototype << endl;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkCellLocatorInterpolatedVelocityField.h
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 vtkCellLocatorInterpolatedVelocityField - A concrete class for
// obtaining the interpolated velocity values at a point.
//
// .SECTION Description
// vtkCellLocatorInterpolatedVelocityField acts as a continuous velocity
// field via cell interpolation on a vtkDataSet, NumberOfIndependentVariables
// = 4 (x,y,z,t) and NumberOfFunctions = 3 (u,v,w). As a concrete sub-class
// of vtkAbstractInterpolatedVelocityField, it adopts vtkAbstractCellLocator's
// sub-classes, e.g., vtkCellLocator and vtkModifiedBSPTree, without the use
// of vtkPointLocator ( employed by vtkDataSet/vtkPointSet::FindCell() in
// vtkInterpolatedVelocityField ). vtkCellLocatorInterpolatedVelocityField
// adopts one level of cell caching. Specifically, if the next point is still
// within the previous cell, cell location is then simply skipped and vtkCell::
// EvaluatePosition() is called to obtain the new parametric coordinates and
// weights that are used to interpolate the velocity function values across the
// vertices of this cell. Otherwise a global cell (the target containing the next
// point) location is instead directly invoked, without exploiting the clue that
// vtkInterpolatedVelocityField makes use of from the previous cell (an immediate
// neighbor). Although ignoring the neighbor cell may incur a relatively high
// computational cost, vtkCellLocatorInterpolatedVelocityField is more robust in
// locating the target cell than its sibling class vtkInterpolatedVelocityField.
// .SECTION Caveats
// vtkCellLocatorInterpolatedVelocityField is not thread safe. A new instance
// should be created by each thread.
// .SECTION See Also
// vtkAbstractInterpolatedVelocityField vtkInterpolatedVelocityField
// vtkGenericInterpolatedVelocityField vtkCachingInterpolatedVelocityField
// vtkTemporalInterpolatedVelocityField vtkFunctionSet vtkStreamer vtkStreamTracer
#ifndef __vtkCellLocatorInterpolatedVelocityField_h
#define __vtkCellLocatorInterpolatedVelocityField_h
#include "vtkAbstractInterpolatedVelocityField.h"
class vtkAbstractCellLocator;
class vtkCellLocatorInterpolatedVelocityFieldCellLocatorsType;
class VTK_GRAPHICS_EXPORT vtkCellLocatorInterpolatedVelocityField : public vtkAbstractInterpolatedVelocityField
{
public:
vtkTypeMacro( vtkCellLocatorInterpolatedVelocityField,
vtkAbstractInterpolatedVelocityField );
void PrintSelf( ostream & os, vtkIndent indent );
// Description:
// Construct a vtkCellLocatorInterpolatedVelocityField without an initial
// dataset. Caching is set on and LastCellId is set to -1.
static vtkCellLocatorInterpolatedVelocityField * New();
// Description:
// Get the cell locator attached to the most recently visited dataset.
vtkGetObjectMacro( LastCellLocator, vtkAbstractCellLocator );
// Description:
// Get the prototype of the cell locator that is used for interpolating the
// velocity field during integration.
vtkGetObjectMacro( CellLocatorPrototype, vtkAbstractCellLocator );
// Description:
// Set a prototype of the cell locator that is used for interpolating the
// velocity field during integration.
void SetCellLocatorPrototype( vtkAbstractCellLocator * prototype );
// Description:
// Import parameters. Sub-classes can add more after chaining.
virtual void CopyParameters( vtkAbstractInterpolatedVelocityField * from );
// Description:
// Add a dataset coupled with a cell locator (of type vtkAbstractCellLocator)
// for vector function evaluation. Note the use of a vtkAbstractCellLocator
// enables robust cell location. If more than one dataset is added, the
// evaluation point is searched in all until a match is found. THIS FUNCTION
// DOES NOT CHANGE THE REFERENCE COUNT OF dataset FOR THREAD SAFETY REASONS.
virtual void AddDataSet( vtkDataSet * dataset );
// Description:
// Evaluate the velocity field f at point (x, y, z).
virtual int FunctionValues( double * x, double * f );
// Description:
// Set the cell id cached by the last evaluation within a specified dataset.
virtual void SetLastCellId( vtkIdType c, int dataindex );
// Description:
// Set the cell id cached by the last evaluation.
virtual void SetLastCellId( vtkIdType c )
{ this->Superclass::SetLastCellId( c ); }
protected:
vtkCellLocatorInterpolatedVelocityField();
~vtkCellLocatorInterpolatedVelocityField();
// Description:
// Evaluate the velocity field f at point (x, y, z) in a specified dataset
// (actually of type vtkPointSet only) through the use of the associated
// vtkAbstractCellLocator::FindCell() (instead of involving vtkPointLocator)
// to locate the next cell if the given point is outside the current cell.
int FunctionValues( vtkDataSet * ds, vtkAbstractCellLocator * loc,
double * x, double * f );
// Description:
// Evaluate the velocity field f at point (x, y, z) in a specified dataset
// (of type vtkImageData or vtkRectilinearGrid only) by invoking FindCell()
// to locate the next cell if the given point is outside the current cell.
virtual int FunctionValues( vtkDataSet * ds, double * x, double * f )
{ return this->Superclass::FunctionValues( ds, x, f ); }
private:
vtkAbstractCellLocator * LastCellLocator;
vtkAbstractCellLocator * CellLocatorPrototype;
vtkCellLocatorInterpolatedVelocityFieldCellLocatorsType * CellLocators;
vtkCellLocatorInterpolatedVelocityField
( const vtkCellLocatorInterpolatedVelocityField & ); // Not implemented.
void operator = ( const vtkCellLocatorInterpolatedVelocityField & ); // Not implemented.
};
#endif
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkModifiedBSPTree.h
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.
=========================================================================*/
/*=========================================================================
This code is derived from an earlier work and is distributed
with permission from, and thanks to
------------------------------------------
Copyright (C) 1997-2000 John Biddiscombe
Rutherford Appleton Laboratory,
Chilton, Oxon, England
------------------------------------------
Copyright (C) 2000-2004 John Biddiscombe
Skipping Mouse Software Ltd,
Blewbury, England
------------------------------------------
Copyright (C) 2004-2009 John Biddiscombe
CSCS - Swiss National Supercomputing Centre
Galleria 2 - Via Cantonale
CH-6928 Manno, Switzerland
------------------------------------
=========================================================================*/
// .NAME vtkModifiedBSPTree - Generate axis aligned BBox tree for raycasting and other Locator based searches
//
// .SECTION Description
// vtkModifiedBSPTree creates an evenly balanced BSP tree using a top down
// implementation. Axis aligned split planes are found which evenly divide
// cells into two buckets. Generally a split plane will intersect some cells
// and these are usually stored in both child nodes of the current parent.
// (Or split into separate cells which we cannot consider in this case).
// Storing cells in multiple buckets creates problems associated with multiple
// tests against rays and increases the required storage as complex meshes
// will have many cells straddling a split plane (and further splits may
// cause multiple copies of these).
//
// During a discussion with Arno Formella in 1998 he suggested using
// a third child node to store objects which straddle split planes. I've not
// seen this published (Yes! - see below), but thought it worth trying. This
// implementation of the BSP tree creates a third child node for storing cells
// lying across split planes, the third cell may overlap the other two, but the
// two 'proper' nodes otherwise conform to usual BSP rules.
//
// The advantage of this implementation is cells only ever lie in one node
// and mailbox testing is avoided. All BBoxes are axis aligned and a ray cast
// uses an efficient search strategy based on near/far nodes and rejects
// all BBoxes using simple tests.
//
// For fast raytracing, 6 copies of cell lists are stored in each leaf node
// each list is in axis sorted order +/- x,y,z and cells are always tested
// in the direction of the ray dominant axis. Once an intersection is found
// any cell or BBox with a closest point further than the I-point can be
// instantly rejected and raytracing stops as soon as no nodes can be closer
// than the current best intersection point.
//
// The addition of the 'middle' node upsets the optimal balance of the tree,
// but is a minor overhead during the raytrace. Each child node is contracted
// such that it tightly fits all cells inside it, enabling further ray/box
// rejections.
//
// This class is intented for persons requiring many ray tests and is optimized
// for this purpose. As no cell ever lies in more than one leaf node, and parent
// nodes do not maintain cell lists, the memory overhead of the sorted cell
// lists is 6*num_cells*4 for 6 lists of ints, each num_cells in length.
// The memory requirement of the nodes themselves is usually of minor
// significance.
//
// Subdividision is controlled by MaxCellsPerNode - any node with more than
// this number will be subdivided providing a good split plane can be found and
// the max depth is not exceeded.
//
// The average cells per leaf will usually be around half the MaxCellsPerNode,
// though the middle node is usually sparsely populated and lowers the average
// slightly. The middle node will not be created when not needed.
// Subdividing down to very small cells per node is not generally suggested
// as then the 6 stored cell lists are effectively redundant.
//
// Values of MaxcellsPerNode of around 16->128 depending on dataset size will
// usually give good results.
//
// Cells are only sorted into 6 lists once - before tree creation, each node
// segments the lists and passes them down to the new child nodes whilst
// maintaining sorted order. This makes for an efficient subdivision strategy.
//
// NB. The following reference has been sent to me
// @Article{formella-1995-ray,
// author = "Arno Formella and Christian Gill",
// title = "{Ray Tracing: A Quantitative Analysis and a New
// Practical Algorithm}",
// journal = "{The Visual Computer}",
// year = "{1995}",
// month = dec,
// pages = "{465--476}",
// volume = "{11}",
// number = "{9}",
// publisher = "{Springer}",
// keywords = "{ray tracing, space subdivision, plane traversal,
// octree, clustering, benchmark scenes}",
// annote = "{We present a new method to accelerate the process of
// finding nearest ray--object intersections in ray
// tracing. The algorithm consumes an amount of memory
// more or less linear in the number of objects. The basic
// ideas can be characterized with a modified BSP--tree
// and plane traversal. Plane traversal is a fast linear
// time algorithm to find the closest intersection point
// in a list of bounding volumes hit by a ray. We use
// plane traversal at every node of the high outdegree
// BSP--tree. Our implementation is competitive to fast
// ray tracing programs. We present a benchmark suite
// which allows for an extensive comparison of ray tracing
// algorithms.}",
// }
//
// .SECTION Thanks
// John Biddiscombe for developing and contributing this class
//
// .SECTION ToDo
// -------------
// Implement intersection heap for testing rays against transparent objects
//
// .SECTION Style
// --------------
// This class is currently maintained by J. Biddiscombe who has specially
// requested that the code style not be modified to the kitware standard.
// Please respect the contribution of this class by keeping the style
// as close as possible to the author's original.
//
#ifndef _vtkModifiedBSPTree_h
#define _vtkModifiedBSPTree_h
#include "vtkAbstractCellLocator.h"