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.

363 lines
13 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkContour3DLinearGrid.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 vtkContour3DLinearGrid
* @brief fast generation of isosurface from 3D linear cells
*
* vtkContour3DLinearGrid is a specialized filter that generates isocontours
* from an input vtkUnstructuredGrid consisting of 3D linear cells:
* tetrahedra, hexahedra, voxels, pyramids, and/or wedges. (The cells are
* linear in the sense that each cell edge is a straight line.) The filter is
* designed for high-speed, specialized operation. All other cell types are
* skipped and produce no output. (Note: the filter will also process
* input vtkCompositeDataSets containing vtkUnstructuredGrids.)
*
* To use this filter you must specify an input unstructured grid or
* vtkCompositeDataSet, and one or more contour values. You can either use
* the method SetValue() to specify each contour value, or use
* GenerateValues() to generate a series of evenly spaced contours.
*
* The filter performance varies depending on optional output
* information. Basically if point merging is required (when PointMerging,
* InterpolateAttributes, and/or ComputeNormals is enabled), a sorting
* process is required to eliminate duplicate output points in the
* isosurface. Otherwise when point merging is not required, a fast path
* process produces independent triangles representing the isosurface. In
* many situations the results of the fast path are quite good and do not
* require additional processing.
*
* Note that another performance option exists, using a vtkScalarTree, which
* is an object that accelerates isosurface extraction, at the initial cost
* of building the scalar tree. (This feature is useful for exploratory
* isosurface extraction when the isovalue is frequently changed.) In some
* cases this can improve performance, however this algorithm is so highly
* tuned that random memory jumps (due to random access of cells provided by
* the scalar tree) can actually negatively impact performance, especially if
* the input dataset type consists of homogeneous cell types.
*
* @warning
* When the input is of type vtkCompositeDataSet the filter will process the
* unstructured grid(s) contained in the composite data set. As a result the
* output of this filter is then a vtkMultiBlockDataSet containing multiple
* vtkPolyData. When a vtkUnstructuredGrid is provided as input the
* output is a single vtkPolyData.
*
* @warning
* The fast path simply produces output points and triangles (the fast path
* executes when MergePoints if off; InterpolateAttributes is off; and
* ComputeNormals is off). Since the fast path does not merge points, it
* produces many more output points, typically on the order of 5-6x more than
* when MergePoints is enabled. Adding in the other options point merging,
* field interpolation, and normal generation results in additional
* performance impacts. By default the fast path is enabled.
*
* @warning
* When a vtkCompositeDataSet is provided as input, and UseScalarTree is
* enabled and a ScalarTree specified, then the specified scalar tree is
* cloned to create new ones for each dataset in the composite
* dataset. Otherwise (i.e., when vtkUnstructuredGrid input) the specified
* scalar tree is directly used (no cloning required).
*
* @warning
* Internal to this filter, a caching iterator is used to traverse the cells
* that compose the vtkUnstructuredGrid. Maximum performance is obtained if
* the cells are all of one type (i.e., input grid of homogeneous cell
* types); repeated switching from different types may have detrimental
* effects on performance.
*
* @warning
* For unstructured data, gradients are not computed. Normals are computed if
* requested; they are "pseudo-normals" in that the normals of output
* triangles that use a common point are averaged at the point. Alternatively
* use vtkPolyDataNormals to compute the surface normals.
*
* @warning
* The output of this filter is subtly different than the more general filter
* vtkContourGrid. vtkContourGrid eliminates small, degenerate triangles with
* concident points which are consequently not sent to the output. In
* practice this makes little impact on visual appearance but may have
* repercussions if the output is used for modelling and/or analysis.
*
* @warning
* Input cells that are not of 3D linear type (tetrahedron, hexahedron,
* wedge, pyramid, and voxel) are simply skipped and not processed.
*
* @warning
* The filter is templated on types of input and output points, and input
* scalar type. To reduce object file bloat, only real points (float,double) are
* processed, and a limited subset of scalar types.
*
* @warning
* This class has been threaded with vtkSMPTools. Using TBB or other
* non-sequential type (set in the CMake variable
* VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
*
* @sa
* vtkContourGrid vtkContourFilter vtkFlyingEdges3D vtkMarchingCubes
* vtkPolyDataNormals vtkStaticEdgeLocatorTemplate.h vtkScalarTree
* vtkSpanSpace
*/
#ifndef vtkContour3DLinearGrid_h
#define vtkContour3DLinearGrid_h
#include "vtkContourValues.h" // Needed for inline methods
#include "vtkDataObjectAlgorithm.h"
#include "vtkFiltersCoreModule.h" // For export macro
class vtkPolyData;
class vtkUnstructuredGrid;
class vtkScalarTree;
struct vtkScalarTreeMap;
class VTKFILTERSCORE_EXPORT vtkContour3DLinearGrid : public vtkDataObjectAlgorithm
{
public:
//@{
/**
* Standard methods for construction, type info, and printing.
*/
static vtkContour3DLinearGrid* New();
vtkTypeMacro(vtkContour3DLinearGrid, vtkDataObjectAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
//@{
/**
* Methods to set / get contour values.
*/
void SetValue(int i, double value);
double GetValue(int i);
double* GetValues();
void GetValues(double* contourValues);
void SetNumberOfContours(int number);
vtkIdType GetNumberOfContours();
void GenerateValues(int numContours, double range[2]);
void GenerateValues(int numContours, double rangeStart, double rangeEnd);
//@}
//@{
/**
* Indicate whether to merge coincident points. This takes extra time and
* produces fewer output points, creating a "watertight" contour
* surface. By default this is off.
*/
vtkSetMacro(MergePoints, vtkTypeBool);
vtkGetMacro(MergePoints, vtkTypeBool);
vtkBooleanMacro(MergePoints, vtkTypeBool);
//@}
//@{
/**
* Indicate whether to interpolate input attributes onto the isosurface. By
* default this option is off.
*/
vtkSetMacro(InterpolateAttributes, vtkTypeBool);
vtkGetMacro(InterpolateAttributes, vtkTypeBool);
vtkBooleanMacro(InterpolateAttributes, vtkTypeBool);
//@}
//@{
/**
* Indicate whether to compute output point normals. An averaging method is
* used to average shared triangle normals. By default this if off. This is
* a relatively expensive option so use judiciously.
*/
vtkSetMacro(ComputeNormals, vtkTypeBool);
vtkGetMacro(ComputeNormals, vtkTypeBool);
vtkBooleanMacro(ComputeNormals, vtkTypeBool);
//@}
//@{
/**
* Set/get the desired precision for the output types. See the documentation
* for the vtkAlgorithm::Precision enum for an explanation of the available
* precision settings.
*/
void SetOutputPointsPrecision(int precision);
int GetOutputPointsPrecision() const;
//@}
/**
* Overloaded GetMTime() because of delegation to the internal
* vtkContourValues class.
*/
vtkMTimeType GetMTime() override;
//@{
/**
* Enable the use of a scalar tree to accelerate contour extraction. By
* default this is off. If enabled, and a scalar tree is not specified, then
* a vtkSpanSpace instance will be constructed and used.
*/
vtkSetMacro(UseScalarTree, vtkTypeBool);
vtkGetMacro(UseScalarTree, vtkTypeBool);
vtkBooleanMacro(UseScalarTree, vtkTypeBool);
//@}
//@{
/**
* Specify the scalar tree to use. By default a vtkSpanSpace scalar tree is
* used.
*/
virtual void SetScalarTree(vtkScalarTree*);
vtkGetObjectMacro(ScalarTree, vtkScalarTree);
//@}
//@{
/**
* Force sequential processing (i.e. single thread) of the contouring
* process. By default, sequential processing is off. Note this flag only
* applies if the class has been compiled with VTK_SMP_IMPLEMENTATION_TYPE
* set to something other than Sequential. (If set to Sequential, then the
* filter always runs in serial mode.) This flag is typically used for
* benchmarking purposes.
*/
vtkSetMacro(SequentialProcessing, vtkTypeBool);
vtkGetMacro(SequentialProcessing, vtkTypeBool);
vtkBooleanMacro(SequentialProcessing, vtkTypeBool);
//@}
/**
* Return the number of threads actually used during execution. This is
* valid only after algorithm execution.
*/
int GetNumberOfThreadsUsed() { return this->NumberOfThreadsUsed; }
/**
* Inform the user as to whether large ids were used during filter
* execution. This flag only has meaning after the filter has executed.
* Large ids are used when the id of the larges cell or point is greater
* than signed 32-bit precision. (Smaller ids reduce memory usage and speed
* computation. Note that LargeIds are only available on 64-bit
* architectures.)
*/
bool GetLargeIds() { return this->LargeIds; }
/**
* Returns true if the data object passed in is fully supported by this
* filter, i.e., all cell types are linear. For composite datasets, this
* means all dataset leaves have only linear cell types that can be processed
* by this filter. The second array is the name of the array to process.
*/
static bool CanFullyProcessDataObject(vtkDataObject* object, const char* scalarArrayName);
protected:
vtkContour3DLinearGrid();
~vtkContour3DLinearGrid() override;
vtkContourValues* ContourValues;
int OutputPointsPrecision;
vtkTypeBool MergePoints;
vtkTypeBool InterpolateAttributes;
vtkTypeBool ComputeNormals;
vtkTypeBool SequentialProcessing;
int NumberOfThreadsUsed;
bool LargeIds; // indicate whether integral ids are large(==true) or not
// Manage scalar trees, including mapping scalar tree to input dataset
vtkTypeBool UseScalarTree;
vtkScalarTree* ScalarTree;
struct vtkScalarTreeMap* ScalarTreeMap;
// Process the data: input unstructured grid and output polydata
void ProcessPiece(vtkUnstructuredGrid* input, vtkDataArray* inScalars, vtkPolyData* output);
int RequestDataObject(vtkInformation* request, vtkInformationVector** inputVector,
vtkInformationVector* outputVector) override;
int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
vtkInformationVector* outputVector) override;
int FillInputPortInformation(int port, vtkInformation* info) override;
private:
vtkContour3DLinearGrid(const vtkContour3DLinearGrid&) = delete;
void operator=(const vtkContour3DLinearGrid&) = delete;
};
/**
* Set a particular contour value at contour number i. The index i ranges
* between 0<=i<NumberOfContours.
*/
inline void vtkContour3DLinearGrid::SetValue(int i, double value)
{
this->ContourValues->SetValue(i, value);
}
/**
* Get the ith contour value.
*/
inline double vtkContour3DLinearGrid::GetValue(int i)
{
return this->ContourValues->GetValue(i);
}
/**
* Get a pointer to an array of contour values. There will be
* GetNumberOfContours() values in the list.
*/
inline double* vtkContour3DLinearGrid::GetValues()
{
return this->ContourValues->GetValues();
}
/**
* Fill a supplied list with contour values. There will be
* GetNumberOfContours() values in the list. Make sure you allocate
* enough memory to hold the list.
*/
inline void vtkContour3DLinearGrid::GetValues(double* contourValues)
{
this->ContourValues->GetValues(contourValues);
}
/**
* Set the number of contours to place into the list. You only really
* need to use this method to reduce list size. The method SetValue()
* will automatically increase list size as needed.
*/
inline void vtkContour3DLinearGrid::SetNumberOfContours(int number)
{
this->ContourValues->SetNumberOfContours(number);
}
/**
* Get the number of contours in the list of contour values.
*/
inline vtkIdType vtkContour3DLinearGrid::GetNumberOfContours()
{
return this->ContourValues->GetNumberOfContours();
}
/**
* Generate numContours equally spaced contour values between specified
* range. Contour values will include min/max range values.
*/
inline void vtkContour3DLinearGrid::GenerateValues(int numContours, double range[2])
{
this->ContourValues->GenerateValues(numContours, range);
}
/**
* Generate numContours equally spaced contour values between specified
* range. Contour values will include min/max range values.
*/
inline void vtkContour3DLinearGrid::GenerateValues(
int numContours, double rangeStart, double rangeEnd)
{
this->ContourValues->GenerateValues(numContours, rangeStart, rangeEnd);
}
#endif