/*========================================================================= 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<=iContourValues->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