You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
7.5 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkSpanSpace.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.
=========================================================================*/
/**
* @class vtkSpanSpace
* @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
* 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
* (or batches) of cells that lie along a particular row in the span
* space. These arrays can then be processed separately or in parallel.
*
* Learn more about span space in these two publications: 1) "A Near
* Optimal Isosorface Extraction Algorithm Using the Span Space."
* Yarden Livnat et al. and 2) Isosurfacing in Span Space with Utmost
* Efficiency." Han-Wei Shen et al.
*
* @sa
* vtkScalarTree vtkSimpleScalarTree
*/
#ifndef vtkSpanSpace_h
#define vtkSpanSpace_h
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkScalarTree.h"
class vtkSpanSpace;
struct vtkInternalSpanSpace;
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkSpanSpace : public vtkScalarTree
{
public:
/**
* Instantiate a scalar tree with default resolution of 100 and automatic
* scalar range computation.
*/
static vtkSpanSpace* New();
//@{
/**
* Standard type related macros and PrintSelf() method.
*/
vtkTypeMacro(vtkSpanSpace, vtkScalarTree);
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/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, 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);
vtkBooleanMacro(ComputeResolution, vtkTypeBool);
//@}
//@{
/**
* Specify the average number of cells in each bucket. This is used to
* indirectly control the resolution if ComputeResolution is enabled.
*/
vtkSetClampMacro(NumberOfCellsPerBucket, int, 1, VTK_INT_MAX);
vtkGetMacro(NumberOfCellsPerBucket, int);
//@}
//----------------------------------------------------------------------
// The following methods satisfy the vtkScalarTree abstract API.
/**
* Initialize the span space. Frees memory and resets object as
* appropriate.
*/
void Initialize() override;
/**
* Construct the scalar tree from the dataset provided. Checks build times
* and modified time from input and reconstructs the tree if necessary.
*/
void BuildTree() override;
/**
* Begin to traverse the cells based on a scalar value. Returned cells will
* have scalar values that span the scalar value specified (within the
* resolution of the span space). Note this method must be called prior to
* parallel or serial traversal since it specifies the scalar value to be
* extracted.
*/
void InitTraversal(double scalarValue) override;
/**
* Return the next cell that may contain scalar value specified to
* InitTraversal(). The value nullptr is returned if the list is
* exhausted. Make sure that InitTraversal() has been invoked first or
* you'll get undefined behavior. This is inherently a serial operation.
*/
vtkCell* GetNextCell(vtkIdType& cellId, vtkIdList*& ptIds, vtkDataArray* cellScalars) override;
// 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 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(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 GetNumberOfCellBatches() beforehand.
*/
const vtkIdType* GetCellBatch(vtkIdType batchNum, vtkIdType& numCells) override;
//@{
/**
* Set/Get the size of the cell batches when processing in
* parallel. By default the batch size = 100 cells in each batch.
*/
vtkSetClampMacro(BatchSize, vtkIdType, 100, VTK_INT_MAX);
vtkGetMacro(BatchSize, vtkIdType);
//@}
protected:
vtkSpanSpace();
~vtkSpanSpace() override;
double ScalarRange[2];
vtkTypeBool ComputeScalarRange;
vtkIdType Resolution;
vtkTypeBool ComputeResolution;
int NumberOfCellsPerBucket;
vtkInternalSpanSpace* SpanSpace;
vtkIdType BatchSize;
private:
// Internal variables supporting span space traversal
vtkIdType RMin[2]; // span space lower left corner
vtkIdType RMax[2]; // span space upper right corner
// This supports serial traversal via GetNextCell()
vtkIdType CurrentRow; // the span space row currently being processed
vtkIdType* CurrentSpan; // pointer to current span row
vtkIdType CurrentIdx; // position into the current span row
vtkIdType CurrentNumCells; // number of cells on the current span row
private:
vtkSpanSpace(const vtkSpanSpace&) = delete;
void operator=(const vtkSpanSpace&) = delete;
};
#endif