1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkFlyingEdges3D.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class vtkFlyingEdges3D 17 * @brief generate isosurface from 3D image data (volume) 18 * 19 * vtkFlyingEdges3D is a reference implementation of the 3D version of the 20 * flying edges algorithm. It is designed to be highly scalable (i.e., 21 * parallelizable) for large data. It implements certain performance 22 * optimizations including computational trimming to rapidly eliminate 23 * processing of data regions, packed bit representation of case table 24 * values, single edge intersection, elimination of point merging, and 25 * elimination of any reallocs (due to dynamic data insertion). Note that 26 * computational trimming is a method to reduce total computational cost in 27 * which partial computational results can be used to eliminate future 28 * computations. 29 * 30 * This is a four-pass algorithm. The first pass processes all x-edges and 31 * builds x-edge case values (which, when the four x-edges defining a voxel 32 * are combined, are equivalent to vertex-based case table except edge-based 33 * approaches are separable in support of parallel computing). Next x-voxel 34 * rows are processed to gather information from yz-edges (basically to count 35 * the number of y-z edge intersections and triangles generated). In the third 36 * pass a prefix sum is used to count and allocate memory for the output 37 * primitives. Finally in the fourth pass output primitives are generated into 38 * pre-allocated arrays. This implementation uses voxel cell axes (a x-y-z 39 * triad located at the voxel origin) to ensure that each edge is intersected 40 * at most one time. Note that this implementation also reuses the VTK 41 * Marching Cubes case table, although the vertex-based MC table is 42 * transformed into an edge-based table on object instantiation. 43 * 44 * See the paper "Flying Edges: A High-Performance Scalable Isocontouring 45 * Algorithm" by Schroeder, Maynard, Geveci. Proc. of LDAV 2015. Chicago, IL. 46 * 47 * @warning 48 * This filter is specialized to 3D volumes. This implementation can produce 49 * degenerate triangles (i.e., zero-area triangles). 50 * 51 * @warning 52 * If you are interested in extracting segmented regions from a label mask, 53 * consider using vtkDiscreteFlyingEdges3D. 54 * 55 * @warning 56 * This class has been threaded with vtkSMPTools. Using TBB or other 57 * non-sequential type (set in the CMake variable 58 * VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly. 59 * 60 * @sa 61 * vtkContourFilter vtkFlyingEdges2D vtkSynchronizedTemplates3D 62 * vtkMarchingCubes vtkDiscreteFlyingEdges3D vtkContour3DLinearGrid 63 * vtkFlyingEdgesPlaneCutter 64 */ 65 66 #ifndef vtkFlyingEdges3D_h 67 #define vtkFlyingEdges3D_h 68 69 #include "vtkContourValues.h" // Passes calls through 70 #include "vtkFiltersCoreModule.h" // For export macro 71 #include "vtkPolyDataAlgorithm.h" 72 73 class vtkImageData; 74 75 class VTKFILTERSCORE_EXPORT vtkFlyingEdges3D : public vtkPolyDataAlgorithm 76 { 77 public: 78 static vtkFlyingEdges3D* New(); 79 vtkTypeMacro(vtkFlyingEdges3D, vtkPolyDataAlgorithm); 80 void PrintSelf(ostream& os, vtkIndent indent) override; 81 82 /** 83 * Because we delegate to vtkContourValues. 84 */ 85 vtkMTimeType GetMTime() override; 86 87 ///@{ 88 /** 89 * Set/Get the computation of normals. Normal computation is fairly 90 * expensive in both time and storage. If the output data will be processed 91 * by filters that modify topology or geometry, it may be wise to turn 92 * Normals and Gradients off. 93 */ 94 vtkSetMacro(ComputeNormals, vtkTypeBool); 95 vtkGetMacro(ComputeNormals, vtkTypeBool); 96 vtkBooleanMacro(ComputeNormals, vtkTypeBool); 97 ///@} 98 99 ///@{ 100 /** 101 * Set/Get the computation of gradients. Gradient computation is fairly 102 * expensive in both time and storage. Note that if ComputeNormals is on, 103 * gradients will have to be calculated, but will not be stored in the 104 * output dataset. If the output data will be processed by filters that 105 * modify topology or geometry, it may be wise to turn Normals and 106 * Gradients off. 107 */ 108 vtkSetMacro(ComputeGradients, vtkTypeBool); 109 vtkGetMacro(ComputeGradients, vtkTypeBool); 110 vtkBooleanMacro(ComputeGradients, vtkTypeBool); 111 ///@} 112 113 ///@{ 114 /** 115 * Set/Get the computation of scalars. 116 */ 117 vtkSetMacro(ComputeScalars, vtkTypeBool); 118 vtkGetMacro(ComputeScalars, vtkTypeBool); 119 vtkBooleanMacro(ComputeScalars, vtkTypeBool); 120 ///@} 121 122 ///@{ 123 /** 124 * Indicate whether to interpolate other attribute data. That is, as the 125 * isosurface is generated, interpolate all point attribute data across 126 * the edge. This is independent of scalar interpolation, which is 127 * controlled by the ComputeScalars flag. 128 */ 129 vtkSetMacro(InterpolateAttributes, vtkTypeBool); 130 vtkGetMacro(InterpolateAttributes, vtkTypeBool); 131 vtkBooleanMacro(InterpolateAttributes, vtkTypeBool); 132 ///@} 133 134 /** 135 * Set a particular contour value at contour number i. The index i ranges 136 * between 0<=i<NumberOfContours. 137 */ SetValue(int i,double value)138 void SetValue(int i, double value) { this->ContourValues->SetValue(i, value); } 139 140 /** 141 * Get the ith contour value. 142 */ GetValue(int i)143 double GetValue(int i) { return this->ContourValues->GetValue(i); } 144 145 /** 146 * Get a pointer to an array of contour values. There will be 147 * GetNumberOfContours() values in the list. 148 */ GetValues()149 double* GetValues() { return this->ContourValues->GetValues(); } 150 151 /** 152 * Fill a supplied list with contour values. There will be 153 * GetNumberOfContours() values in the list. Make sure you allocate 154 * enough memory to hold the list. 155 */ GetValues(double * contourValues)156 void GetValues(double* contourValues) { this->ContourValues->GetValues(contourValues); } 157 158 /** 159 * Set the number of contours to place into the list. You only really 160 * need to use this method to reduce list size. The method SetValue() 161 * will automatically increase list size as needed. 162 */ SetNumberOfContours(int number)163 void SetNumberOfContours(int number) { this->ContourValues->SetNumberOfContours(number); } 164 165 /** 166 * Get the number of contours in the list of contour values. 167 */ GetNumberOfContours()168 vtkIdType GetNumberOfContours() { return this->ContourValues->GetNumberOfContours(); } 169 170 /** 171 * Generate numContours equally spaced contour values between specified 172 * range. Contour values will include min/max range values. 173 */ GenerateValues(int numContours,double range[2])174 void GenerateValues(int numContours, double range[2]) 175 { 176 this->ContourValues->GenerateValues(numContours, range); 177 } 178 179 /** 180 * Generate numContours equally spaced contour values between specified 181 * range. Contour values will include min/max range values. 182 */ GenerateValues(int numContours,double rangeStart,double rangeEnd)183 void GenerateValues(int numContours, double rangeStart, double rangeEnd) 184 { 185 this->ContourValues->GenerateValues(numContours, rangeStart, rangeEnd); 186 } 187 188 ///@{ 189 /** 190 * Set/get which component of the scalar array to contour on; defaults to 0. 191 */ 192 vtkSetMacro(ArrayComponent, int); 193 vtkGetMacro(ArrayComponent, int); 194 ///@} 195 196 protected: 197 vtkFlyingEdges3D(); 198 ~vtkFlyingEdges3D() override; 199 200 vtkTypeBool ComputeNormals; 201 vtkTypeBool ComputeGradients; 202 vtkTypeBool ComputeScalars; 203 vtkTypeBool InterpolateAttributes; 204 int ArrayComponent; 205 vtkContourValues* ContourValues; 206 207 int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 208 int RequestUpdateExtent(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 209 int FillInputPortInformation(int port, vtkInformation* info) override; 210 211 private: 212 vtkFlyingEdges3D(const vtkFlyingEdges3D&) = delete; 213 void operator=(const vtkFlyingEdges3D&) = delete; 214 }; 215 216 #endif 217