Commit 3c01339b authored by Will Schroeder's avatar Will Schroeder

Added support for scalar trees and composite input

In some cases processing of data can be accelerated using instances
of vtkScalarTree. The ability to add and enable a scalar tree has
been provided. In addition, the filter supports composite input. Along
the way the outline filter was modified to support composite inputs as
well (with optional representation types).
parent 1a2e8c34
......@@ -122,6 +122,31 @@ vtkIdType vtkCompositeDataSet::GetNumberOfCells()
return numCells;
}
//----------------------------------------------------------------------------
void vtkCompositeDataSet::GetBounds(double bounds[6])
{
double bds[6];
bounds[0] = bounds[2] = bounds[4] = VTK_DOUBLE_MAX;
bounds[1] = bounds[3] = bounds[5] = -VTK_DOUBLE_MAX;
vtkCompositeDataIterator* iter = this->NewIterator();
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject());
if (ds)
{
ds->GetBounds(bds);
bounds[0] = (bds[0] < bounds[0] ? bds[0] : bounds[0]);
bounds[2] = (bds[2] < bounds[2] ? bds[2] : bounds[2]);
bounds[4] = (bds[4] < bounds[4] ? bds[4] : bounds[4]);
bounds[1] = (bds[1] > bounds[1] ? bds[1] : bounds[1]);
bounds[3] = (bds[3] > bounds[3] ? bds[3] : bounds[3]);
bounds[5] = (bds[5] > bounds[5] ? bds[5] : bounds[5]);
}
}
iter->Delete();
}
//----------------------------------------------------------------------------
void vtkCompositeDataSet::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -124,6 +124,17 @@ public:
*/
virtual vtkIdType GetNumberOfCells();
/**
* Return the geometric bounding box in the form (xmin,xmax, ymin,ymax,
* zmin,zmax). Note that if the composite dataset contains abstract types
* (i.e., non vtkDataSet types) such as tables these will be ignored by the
* method. In cases where no vtkDataSet is contained in the composite
* dataset then the returned bounds will be undefined. THIS METHOD IS
* THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND THE DATASET IS NOT
* MODIFIED.
*/
void GetBounds(double bounds[6]);
/**
* Key used to put node name in the meta-data associated with a node.
*/
......
This diff is collapsed.
......@@ -104,6 +104,18 @@ public:
void FindCellsAlongLine(const double p1[3], const double p2[3],
double tolerance, vtkIdList *cells) override;
//@{
/**
* Given an unbounded plane defined by an origin o[3] and unit normal n[3],
* return the list of unique cell ids in the buckets containing the
* plane. It is possible that an empty cell list is returned. The user must
* provide the vtkIdList cell list to populate. This method returns data
* only after the locator has been built.
*/
void FindCellsAlongPlane(const double o[3], const double n[3],
double tolerance, vtkIdList *cells);
//@}
/**
* Return intersection point (if any) AND the cell which was intersected by
* the finite line. The cell is returned as a cell id and as a generic cell.
......
......@@ -19,6 +19,7 @@
#include "vtkGarbageCollector.h"
#include "vtkObjectFactory.h"
vtkCxxSetObjectMacro(vtkScalarTree,DataSet,vtkDataSet);
vtkCxxSetObjectMacro(vtkScalarTree,Scalars,vtkDataArray);
......@@ -38,6 +39,15 @@ vtkScalarTree::~vtkScalarTree()
this->SetScalars(nullptr);
}
//-----------------------------------------------------------------------------
// Shallow copy enough information for a clone to produce the same result on
// the same data.
void vtkScalarTree::ShallowCopy(vtkScalarTree *stree)
{
this->SetDataSet(stree->GetDataSet());
this->SetScalars(stree->GetScalars());
}
//-----------------------------------------------------------------------------
void vtkScalarTree::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -37,7 +37,7 @@
*
* @sa
* vtkSimpleScalarTree vtkSpanSpace
*/
*/
#ifndef vtkScalarTree_h
#define vtkScalarTree_h
......@@ -51,11 +51,23 @@ class vtkDataSet;
class vtkIdList;
class vtkTimeStamp;
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkScalarTree : public vtkObject
{
public:
//@{
/**
* Standard type related macros and PrintSelf() method.
*/
vtkTypeMacro(vtkScalarTree,vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
/**
* This method is used to copy data members when cloning an instance of the
* class. It does not copy heavy data.
*/
virtual void ShallowCopy(vtkScalarTree *stree);
//@{
/**
......@@ -91,18 +103,18 @@ public:
virtual void Initialize() = 0;
/**
* Begin to traverse the cells based on a scalar value. Returned cells
* will have scalar values that span the scalar value specified. Note
* that changing the scalarValue does not cause the scalar tree to be
* modified, and hence it does not rebuild.
* Begin to traverse the cells based on a scalar value (serial
* traversal). Returned cells will have scalar values that span the scalar
* value specified. Note that changing the scalarValue does not cause the
* scalar tree to be modified, and hence it does not rebuild.
*/
virtual void InitTraversal(double scalarValue) = 0;
/**
* Return the next cell that may contain scalar value specified to
* initialize traversal. The value nullptr is returned if the list is
* exhausted. Make sure that InitTraversal() has been invoked first or
* you'll get erratic behavior.
* InitTraversal() (serial traversal). The value nullptr is returned if the
* list is exhausted. Make sure that InitTraversal() has been invoked first
* or you'll get erratic behavior.
*/
virtual vtkCell *GetNextCell(vtkIdType &cellId, vtkIdList* &ptIds,
vtkDataArray *cellScalars) = 0;
......@@ -114,29 +126,25 @@ public:
double GetScalarValue()
{return this->ScalarValue;}
// The following methods supports parallel (threaded) applications. Basically
// The following methods supports parallel (threaded) traversal. Basically
// batches of cells (which are a portion of the whole dataset) are available for
// processing in a parallel For() operation.
/**
* Get the number of cell batches available for processing. Note
* that this methods should be called after InitTraversal(). This is
* because the number of batches available is typically a function
* of the isocontour value. Note that the cells found in
* [0...(NumberOfCellBatches-1)] will contain all the cells
* potentially containing the isocontour.
* Get the number of cell batches available for processing as a function of
* the specified scalar value. Each batch contains a list of candidate
* cells that may contain the specified isocontour value.
*/
virtual vtkIdType GetNumberOfCellBatches() = 0;
virtual vtkIdType GetNumberOfCellBatches(double scalarValue) = 0;
/**
* Return the array of cell ids in the specified batch. The method
* also returns the number of cell ids in the array. Make sure to
* call InitTraversal() beforehand.
* call GetNumberOfCellBatches() beforehand.
*/
virtual const vtkIdType* GetCellBatch(vtkIdType batchNum,
vtkIdType& numCells) = 0;
protected:
vtkScalarTree();
~vtkScalarTree() override;
......
......@@ -21,7 +21,6 @@
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
vtkStandardNewMacro(vtkSimpleScalarTree);
class vtkScalarNode {};
......@@ -33,6 +32,10 @@ public:
TScalar max;
};
//---The VTK Classes proper------------------------------------------------------
vtkStandardNewMacro(vtkSimpleScalarTree);
//-----------------------------------------------------------------------------
// Instantiate scalar tree with maximum level of 20 and branching
// factor of 3.
......@@ -50,7 +53,7 @@ vtkSimpleScalarTree::vtkSimpleScalarTree()
this->ChildNumber = 0;
this->CellId = 0;
// For supporting parallel computing, list of possible candidates
// Variable for parallel traversal
this->CandidateCells = nullptr;
this->NumCandidates = 0;
}
......@@ -59,11 +62,21 @@ vtkSimpleScalarTree::vtkSimpleScalarTree()
vtkSimpleScalarTree::~vtkSimpleScalarTree()
{
delete [] this->Tree;
if ( this->CandidateCells )
}
//-----------------------------------------------------------------------------
// Shallow copy enough information for a clone to produce the same result on
// the same data.
void vtkSimpleScalarTree::ShallowCopy(vtkScalarTree *stree)
{
vtkSimpleScalarTree *sst = vtkSimpleScalarTree::SafeDownCast(stree);
if ( sst != nullptr )
{
delete [] this->CandidateCells;
this->CandidateCells = nullptr;
this->SetMaxLevel(sst->GetMaxLevel());
this->SetBranchingFactor(sst->GetBranchingFactor());
}
// Now do superclass
this->Superclass::ShallowCopy(stree);
}
//-----------------------------------------------------------------------------
......@@ -365,8 +378,27 @@ vtkCell *vtkSimpleScalarTree::GetNextCell(vtkIdType& cellId,
//-----------------------------------------------------------------------------
// Return the number of cell batches.
vtkIdType vtkSimpleScalarTree::GetNumberOfCellBatches()
//-----------------------------------------------------------------------------
// Return the number of chunks of data that can be iterated over.
vtkIdType vtkSimpleScalarTree::
GetNumberOfCellBatches(double scalarValue)
{
// Modified time prevents rebuilding
this->BuildTree();
vtkScalarRange<double> *TTree =
static_cast< vtkScalarRange<double> * > (this->Tree);
this->ScalarValue = scalarValue;
this->TreeIndex = this->TreeSize;
// Check root of tree for overlap with scalar value
//
if ( TTree[0].min > scalarValue || TTree[0].max < scalarValue )
{
return 0;
}
// Basically we do a traversal of the tree and identify potential candidates.
// It is essential that InitTraversal() has been called first.
this->NumCandidates = 0;
......@@ -406,8 +438,7 @@ vtkIdType vtkSimpleScalarTree::GetNumberOfCellBatches()
}
//-----------------------------------------------------------------------------
// Return the next batch of cells to process. Here we just use the branching
// factor (i.e., group size) as the batch size.
// Return the number of chunks of data that can be iterated over.
const vtkIdType* vtkSimpleScalarTree::
GetCellBatch(vtkIdType batchNum, vtkIdType& numCells)
{
......
......@@ -41,8 +41,8 @@
* threads.
*
* @sa
* vtkSpanSpace
*/
* vtkScalarTree vtkSpanSpace
*/
#ifndef vtkSimpleScalarTree_h
#define vtkSimpleScalarTree_h
......@@ -51,6 +51,7 @@
#include "vtkScalarTree.h"
class vtkScalarNode;
class vtkSimpleScalarTree;
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkSimpleScalarTree : public vtkScalarTree
{
......@@ -69,6 +70,12 @@ public:
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
/**
* This method is used to copy data members when cloning an instance of the
* class. It does not copy heavy data.
*/
void ShallowCopy(vtkScalarTree *stree) override;
//@{
/**
* Set the branching factor for the tree. This is the number of
......@@ -122,28 +129,24 @@ public:
vtkCell *GetNextCell(vtkIdType &cellId, vtkIdList* &ptIds,
vtkDataArray *cellScalars) override;
// The following methods supports parallel (threaded)
// applications. Basically batches of cells (which represent a
// portion of the whole dataset) are available for processing in a
// parallel For() operation.
// The following methods supports parallel (threaded) traversal. Basically
// batches of cells (which are a portion of the whole dataset) are available for
// processing in a parallel For() operation.
/**
* Get the number of cell batches available for processing. Note
* that this methods should be called after InitTraversal(). This is
* because the number of batches available is typically a function
* of the isocontour value. Note that the cells found in
* [0...(NumberOfCellBatches-1)] will contain all the cells
* potentially containing the isocontour.
* Get the number of cell batches available for processing as a function of
* the specified scalar value. Each batch contains a list of candidate
* cells that may contain the specified isocontour value.
*/
vtkIdType GetNumberOfCellBatches() override;
vtkIdType GetNumberOfCellBatches(double scalarValue) override;
/**
* Return the array of cell ids in the specified batch. The method
* also returns the number of cell ids in the array. Make sure to
* call InitTraversal() beforehand.
* call GetNumberOfCellBatches() beforehand.
*/
const vtkIdType* GetCellBatch(vtkIdType batchNum,
vtkIdType& numCells) override;
vtkIdType& numCells) override;
protected:
vtkSimpleScalarTree();
......
......@@ -102,9 +102,17 @@ struct vtkSpanTuple
{
vtkIdType CellId; //originating cellId
vtkIdType Index; //i-j index into span space (numCells in length)
//Operator< used to support sorting operation.
//Operator< used to support sorting operation. Note that the sorting
//occurs over both the index and cell id. This arranges cells in
//ascending order (within a bin) which often makes a difference
//(~10-15%) in large data as it reduces cache misses.
bool operator< (const vtkSpanTuple& tuple) const
{return Index < tuple.Index;}
{
if ( Index < tuple.Index ) return true;
if ( tuple.Index < Index ) return false;
if ( CellId < tuple.CellId ) return true;
return false;
}
};
} //anonymous
......@@ -192,7 +200,7 @@ struct vtkInternalSpanSpace
vtkInternalSpanSpace::
vtkInternalSpanSpace(vtkIdType dim, double sMin, double sMax, vtkIdType numCells)
{
this->Dim = (dim > 0 ? dim : 256);
this->Dim = dim;
this->SMin = sMin;
this->SMax = sMax;
this->Range = (sMax - sMin);
......@@ -263,14 +271,6 @@ Build()
// offsets and cell ids computed.
delete [] this->Space;
this->Space = nullptr;
// The candidate cell list can be allocated
if ( this->CandidateCells )
{
delete [] this->CandidateCells;
this->CandidateCells = nullptr;
}
this->CandidateCells = new vtkIdType [this->NumCells];
}
......@@ -344,7 +344,7 @@ struct MapToSpanSpace
}
};//MapToSpanSpace
// SPecialized method to map unstructured grid cells to span space. Uses
// Specialized method to map unstructured grid cells to span space. Uses
// GetCellPoints() to retrieve points defining the cell.
template <typename TS>
struct MapUGridToSpanSpace
......@@ -392,18 +392,24 @@ struct MapUGridToSpanSpace
}//anonymous namespace
//---The VTK Class proper------------------------------------------------------
//---The VTK Classes proper------------------------------------------------------
vtkStandardNewMacro(vtkSpanSpace);
//-----------------------------------------------------------------------------
// Instantiate empty span space object.
vtkSpanSpace::vtkSpanSpace()
{
this->ScalarRange[0] = 0.0;
this->ScalarRange[1] = 1.0;
this->ComputeScalarRange = true;
this->Resolution = 100;
this->ComputeResolution = true;
this->NumberOfCellsPerBucket = 5;
this->SpanSpace = nullptr;
this->RMin[0] = this->RMin[1] = 0;
this->RMax[0] = this->RMax[1] = 0;
this->BatchSize = 10;
this->Resolution = 100;
this->BatchSize = 100;
}
//-----------------------------------------------------------------------------
......@@ -412,6 +418,24 @@ vtkSpanSpace::~vtkSpanSpace()
this->Initialize();
}
//-----------------------------------------------------------------------------
// Shallow copy enough information for a clone to produce the same result on
// the same data.
void vtkSpanSpace::ShallowCopy(vtkScalarTree *stree)
{
vtkSpanSpace *ss = vtkSpanSpace::SafeDownCast(stree);
if ( ss != nullptr )
{
this->SetScalarRange(ss->GetScalarRange());
this->SetComputeScalarRange(ss->GetComputeScalarRange());
this->SetResolution(ss->GetResolution());
this->SetComputeResolution(ss->GetComputeResolution());
this->SetNumberOfCellsPerBucket(ss->GetNumberOfCellsPerBucket());
}
// Now do superclass
this->Superclass::ShallowCopy(stree);
}
//-----------------------------------------------------------------------------
// Frees memory and resets object as appropriate.
void vtkSpanSpace::Initialize()
......@@ -462,12 +486,24 @@ void vtkSpanSpace::BuildTree()
// boost in performance.
double range[2];
void *scalars = this->Scalars->GetVoidPointer(0);
switch ( this->Scalars->GetDataType() )
if ( this->ComputeScalarRange )
{
vtkTemplateMacro(ComputeRange<VTK_TT>::
Execute(this->Scalars->GetNumberOfTuples(),
(VTK_TT*)scalars, range));
switch ( this->Scalars->GetDataType() )
{
vtkTemplateMacro(ComputeRange<VTK_TT>::
Execute(this->Scalars->GetNumberOfTuples(),
(VTK_TT*)scalars, range));
}
this->ScalarRange[0] = range[0];
this->ScalarRange[1] = range[1];
}
else
{
range[0] = this->ScalarRange[0];
range[1] = this->ScalarRange[1];
}
double R = range[1] - range[0];
if ( R <= 0.0 )
{
......@@ -482,6 +518,13 @@ void vtkSpanSpace::BuildTree()
// (i.e., an integer id into a gridded span space). Later this id will
// be used to sort the cells across the span space, so that cells
// can be processed in order by different threads.
if ( this->ComputeResolution )
{
this->Resolution = static_cast<vtkIdType>(sqrt(static_cast<double>(numCells)/
static_cast<double>(this->NumberOfCellsPerBucket)));
this->Resolution = (this->Resolution < 100 ? 100 :
(this->Resolution > 10000 ? 10000 : this->Resolution));
}
this->SpanSpace = new
vtkInternalSpanSpace(this->Resolution,range[0],range[1],numCells);
......@@ -570,62 +613,97 @@ vtkCell *vtkSpanSpace::GetNextCell(vtkIdType& cellId, vtkIdList* &cellPts,
}
//-----------------------------------------------------------------------------
// Return the number of cell batches. Here we are going to consider a batch the
// number of span space buckets included in the current span rectangle. Note that
// InitTraversal() must have been called, which populates the span rectangle.
vtkIdType vtkSpanSpace::GetNumberOfCellBatches()
// Note the cell ids are copied into memory (CandidateCells) from
// which batches are created. This is done for load balancing
// purposes. The span space can often aggregate many cells in just a
// few bins; meaning that batches cannot just be span rows if the work
// is to shared across many threads.
vtkIdType vtkSpanSpace::
GetNumberOfCellBatches(double scalarValue)
{
// Basicall just perform a serial traversal and populate candidate list
this->SpanSpace->NumCandidates = 0;
// Make sure tree is built, modified time will prevent reexecution.
this->BuildTree();
this->ScalarValue = scalarValue;
// Find the rectangle in span space that spans the isovalue
vtkInternalSpanSpace *sp = this->SpanSpace;;
sp->GetSpanRectangle(scalarValue, this->RMin, this->RMax);
// loop over all rows in span rectangle
// Loop over each span row to count total memory allocation required.
vtkIdType numCandidates = 0;
vtkIdType row, *span, idx, numCells;
for (row=this->RMin[1]; row < this->RMax[1]; ++row)
{
span = this->SpanSpace->
sp->GetCellsInSpan(row, this->RMin, this->RMax, numCells);
numCandidates += numCells;
}//for all rows in span rectangle
// Allocate list of candidate cells. Cache memory to avoid
// reallocation if possible.
if ( sp->CandidateCells != nullptr &&
numCandidates > sp->NumCandidates )
{
delete [] sp->CandidateCells;
sp->CandidateCells = nullptr;
}
sp->NumCandidates = numCandidates;
if ( numCandidates > 0 && sp->CandidateCells == nullptr )
{
sp->CandidateCells = new vtkIdType [sp->NumCandidates];
}
// Now copy cells into the allocated memory. This could be done in
// parallel (a parallel write - TODO) but probably wouldn't provide
// much of a boost.
numCandidates = 0;
for (row=this->RMin[1]; row < this->RMax[1]; ++row)
{
span = sp->
GetCellsInSpan(row, this->RMin, this->RMax, numCells);
for (idx=0; idx < numCells; ++idx)
{
this->SpanSpace->
CandidateCells[this->SpanSpace->NumCandidates++] = span[idx];
sp->CandidateCells[numCandidates++] = span[idx];
}
}//for all rows in span rectangle
// Watch for boundary conditions. Return 10 cells to a batch.
if ( this->SpanSpace->NumCandidates < 1 )
// Watch for boundary conditions. Return BatchSize cells to a batch.
if ( sp->NumCandidates < 1 )
{
return 0;
}
else
{
return ( ((this->SpanSpace->NumCandidates-1)/this->BatchSize) + 1);
return ( ((sp->NumCandidates-1)/this->BatchSize) + 1);
}
}
//-----------------------------------------------------------------------------
// Return the next list of cells to process.
// Call after GetNumberOfCellBatches(isoValue)
const vtkIdType* vtkSpanSpace::
GetCellBatch(vtkIdType batchNum, vtkIdType& numCells)
{
// Make sure that everything is hunky dory
vtkInternalSpanSpace *sp = this->SpanSpace;;
vtkIdType pos = batchNum * this->BatchSize;
if ( this->SpanSpace->NumCells < 1 || ! this->SpanSpace->CandidateCells ||
pos > this->SpanSpace->NumCandidates )
if ( sp->NumCells < 1 || ! sp->CandidateCells ||
pos >= sp->NumCandidates )
{
numCells = 0;
return nullptr;
}
if ( (this->SpanSpace->NumCandidates - pos) >= this->BatchSize )
// Return a batch, or if near the end of the candidate list,
// the remainder batch.
if ( (sp->NumCandidates - pos) >= this->BatchSize )
{
numCells = this->BatchSize;
}
else
{
numCells = this->SpanSpace->NumCandidates % this->BatchSize;
numCells = sp->NumCandidates % this->BatchSize;
}
return this->SpanSpace->CandidateCells + pos;
return sp->CandidateCells + pos;
}
//-----------------------------------------------------------------------------
......@@ -633,6 +711,12 @@ void vtkSpanSpace::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Scalar Range: (" << this->ScalarRange[0] << ","
<< this->ScalarRange[1] << ")\n" ;
os << indent << "Compute Scalar Range: "
<< (this->ComputeScalarRange ? "On\n" : "Off\n");
os << indent << "Resolution: " << this->Resolution << "\n" ;
os << indent << "Batch Size: " << this->BatchSize << "\n" ;
os << indent << "Compute Resolution: "
<< (this->ComputeResolution ? "On\n" : "Off\n");
os << indent << "Number of Cells Per Bucket: " << this->NumberOfCellsPerBucket << "\n";
}
......@@ -17,9 +17,10 @@
* @brief organize data according to scalar span space
*
* This is a helper class used to accelerate contouring operations. Given an
* dataset, it organizes the dataset cells into a 2D binned space, with axes
* (scalar_min,scalar_max). This so-called span space can then be traversed
* quickly to find the cells that intersect a particular contour value.
* dataset, it organizes the dataset cells into a 2D binned space, with
* coordinate axes (scalar_min,scalar_max). This so-called span space can
* then be traversed quickly to find the cells that intersect a specified
* contour value.
*
* This class has an API that supports both serial and parallel
* operation. The parallel API enables the using class to grab arrays
......@@ -41,6 +42,7 @@
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkScalarTree.h"
class vtkSpanSpace;
struct vtkInternalSpanSpace;
......@@ -48,7 +50,8 @@ class VTKCOMMONEXECUTIONMODEL_EXPORT vtkSpanSpace : public vtkScalarTree
{
public:
/**
* Instantiate a scalar tree with default number of rows of 100.
* Instantiate a scalar tree with default resolution of 100 and automatic
* scalar range computation.
*/
static vtkSpanSpace *New();
......@@ -60,23 +63,71 @@ public:
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
/**
* This method is used to copy data members when cloning an instance of the
* class. It does not copy heavy data.
*/
void ShallowCopy(vtkScalarTree *stree) override;
//----------------------------------------------------------------------
// The following methods are specific to the creation and configuration of
// vtkSpanSpace.
//@{
/**
* Specify the scalar range in terms of minimum and maximum values
* (smin,smax). These values are used to build the span space. Note that
* setting the range can have significant impact on the performance of the
* span space as it controls the effective resolution near important
* isocontour values. By default the range is computed automatically; turn
* off ComputeScalarRange is you wish to manually specify it.
*/
vtkSetVector2Macro(ScalarRange, double);
vtkGetVectorMacro(ScalarRange, double, 2);
//@}
//@{
/**
* This boolean controls whether the determination of the scalar range is
* computed from the input scalar data. By default this is enabled.
*/
vtkSetMacro(ComputeScalarRange,vtkTypeBool);
vtkGetMacro(ComputeScalarRange,vtkTypeBool);
vtkBooleanMacro(ComputeScalarRange,vtkTypeBool);
//@}
//@{
/**
* Set/Get the resolution N of the span space. The span space can be
* envisioned as a rectangular lattice of NXN buckets (i.e., N rows
* and N columns), where each bucket stores a list of cell ids. The
* i-j coordinate of each cell (hence its location in the lattice)
* is determined from the cell's 2-tuple (smin,smax) scalar range.
* By default Resolution = 100.
* envisioned as a rectangular lattice of NXN buckets/bins (i.e., N rows
* and N columns), where each bucket stores a list of cell ids. The i-j
* coordinate of each cell (hence its location in the lattice) is
* determined from the cell's 2-tuple (smin,smax) scalar range. By default
* Resolution = 100, with a clamp of 10,000.
*/
vtkSetClampMacro(Resolution,vtkIdType,1,VTK_INT_MAX);
vtkSetClampMacro(Resolution,vtkIdType,1,10000);
vtkGetMacro(Resolution,vtkIdType);
//@}
//@{
/**
* Boolean controls whether the resolution of span space is computed
* automatically from the average number of cells falling in each bucket.
*/
vtkSetMacro(ComputeResolution,vtkTypeBool);
vtkGetMacro(ComputeResolution,vtkTypeBool);