1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkGenericCellTessellator.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 // .NAME vtkGenericCellTessellator - helper class to perform cell tessellation 16 // .SECTION Description 17 // vtkGenericCellTessellator is a helper class to perform adaptive tessellation 18 // of particular cell topologies. The major purpose for this class is to 19 // transform higher-order cell types (e.g., higher-order finite elements) 20 // into linear cells that can then be easily visualized by VTK. This class 21 // works in conjunction with the vtkGenericDataSet and vtkGenericAdaptorCell 22 // classes. 23 // 24 // This algorithm is based on edge subdivision. An error metric along each 25 // edge is evaluated, and if the error is greater than some tolerance, the 26 // edge is subdivided (as well as all connected 2D and 3D cells). The process 27 // repeats until the error metric is satisfied. 28 // 29 // A significant issue addressed by this algorithm is to insure face 30 // compatibility across neigboring cells. That is, diagonals due to face 31 // triangulation must match to insure that the mesh is compatible. The 32 // algorithm employs a precomputed table to accelerate the tessellation 33 // process. The table was generated with the help of vtkOrderedTriangulator; 34 // the basic idea is that the choice of diagonal is made by considering the 35 // relative value of the point ids. 36 37 38 #ifndef vtkGenericCellTessellator_h 39 #define vtkGenericCellTessellator_h 40 41 #include "vtkCommonDataModelModule.h" // For export macro 42 #include "vtkObject.h" 43 44 class vtkCellArray; 45 class vtkDoubleArray; 46 class vtkCollection; 47 class vtkGenericAttributeCollection; 48 class vtkGenericAdaptorCell; 49 class vtkGenericCellIterator; 50 class vtkPointData; 51 class vtkGenericDataSet; 52 53 //----------------------------------------------------------------------------- 54 // 55 // The tessellation object 56 class VTKCOMMONDATAMODEL_EXPORT vtkGenericCellTessellator : public vtkObject 57 { 58 public: 59 vtkTypeMacro(vtkGenericCellTessellator,vtkObject); 60 void PrintSelf(ostream& os, vtkIndent indent); 61 62 // Description: 63 // Tessellate a face of a 3D `cell'. The face is specified by the 64 // index value. 65 // The result is a set of smaller linear triangles in `cellArray' with 66 // `points' and point data `internalPd'. 67 // \pre cell_exists: cell!=0 68 // \pre valid_dimension: cell->GetDimension()==3 69 // \pre valid_index_range: (index>=0) && (index<cell->GetNumberOfBoundaries(2)) 70 // \pre att_exists: att!=0 71 // \pre points_exists: points!=0 72 // \pre cellArray_exists: cellArray!=0 73 // \pre internalPd_exists: internalPd!=0 74 virtual void TessellateFace(vtkGenericAdaptorCell *cell, 75 vtkGenericAttributeCollection *att, 76 vtkIdType index, 77 vtkDoubleArray *points, 78 vtkCellArray *cellArray, 79 vtkPointData *internalPd)=0; 80 81 // Description: 82 // Tessellate a 3D `cell'. The result is a set of smaller linear 83 // tetrahedra in `cellArray' with `points' and point data `internalPd'. 84 // \pre cell_exists: cell!=0 85 // \pre valid_dimension: cell->GetDimension()==3 86 // \pre att_exists: att!=0 87 // \pre points_exists: points!=0 88 // \pre cellArray_exists: cellArray!=0 89 // \pre internalPd_exists: internalPd!=0 90 virtual void Tessellate(vtkGenericAdaptorCell *cell, 91 vtkGenericAttributeCollection *att, 92 vtkDoubleArray *points, 93 vtkCellArray *cellArray, 94 vtkPointData *internalPd )=0; 95 96 // Description: 97 // Triangulate a 2D `cell'. The result is a set of smaller linear triangles 98 // in `cellArray' with `points' and point data `internalPd'. 99 // \pre cell_exists: cell!=0 100 // \pre valid_dimension: cell->GetDimension()==2 101 // \pre att_exists: att!=0 102 // \pre points_exists: points!=0 103 // \pre cellArray_exists: cellArray!=0 104 // \pre internalPd_exists: internalPd!=0 105 virtual void Triangulate(vtkGenericAdaptorCell *cell, 106 vtkGenericAttributeCollection *att, 107 vtkDoubleArray *points, 108 vtkCellArray *cellArray, 109 vtkPointData *internalPd)=0; 110 111 // Description: 112 // Specify the list of error metrics used to decide if an edge has to be 113 // splitted or not. It is a collection of vtkGenericSubdivisionErrorMetric-s. 114 virtual void SetErrorMetrics(vtkCollection *someErrorMetrics); 115 vtkGetObjectMacro(ErrorMetrics,vtkCollection); 116 117 // Description: 118 // Initialize the tessellator with a data set `ds'. 119 virtual void Initialize(vtkGenericDataSet *ds)=0; 120 121 // Description: 122 // Init the error metric with the dataset. Should be called in each filter 123 // before any tessellation of any cell. 124 void InitErrorMetrics(vtkGenericDataSet *ds); 125 126 // Description: 127 // If true, measure the quality of the fixed subdivision. 128 vtkGetMacro(Measurement,int); 129 vtkSetMacro(Measurement,int); 130 131 // Description: 132 // Get the maximum error measured after the fixed subdivision. 133 // \pre errors_exists: errors!=0 134 // \pre valid_size: sizeof(errors)==GetErrorMetrics()->GetNumberOfItems() 135 void GetMaxErrors(double *errors); 136 137 protected: 138 vtkGenericCellTessellator(); 139 ~vtkGenericCellTessellator(); 140 141 // Description: 142 // Does the edge need to be subdivided according to at least one error 143 // metric? The edge is defined by its `leftPoint' and its `rightPoint'. 144 // `leftPoint', `midPoint' and `rightPoint' have to be initialized before 145 // calling RequiresEdgeSubdivision(). 146 // Their format is global coordinates, parametric coordinates and 147 // point centered attributes: xyx rst abc de... 148 // `alpha' is the normalized abscissa of the midpoint along the edge. 149 // (close to 0 means close to the left point, close to 1 means close to the 150 // right point) 151 // \pre leftPoint_exists: leftPoint!=0 152 // \pre midPoint_exists: midPoint!=0 153 // \pre rightPoint_exists: rightPoint!=0 154 // \pre clamped_alpha: alpha>0 && alpha<1 155 // \pre valid_size: sizeof(leftPoint)=sizeof(midPoint)=sizeof(rightPoint) 156 // =GetAttributeCollection()->GetNumberOfPointCenteredComponents()+6 157 int RequiresEdgeSubdivision(double *left, double *mid, double *right, 158 double alpha); 159 160 161 // Description: 162 // Update the max error of each error metric according to the error at the 163 // mid-point. The type of error depends on the state 164 // of the concrete error metric. For instance, it can return an absolute 165 // or relative error metric. 166 // See RequiresEdgeSubdivision() for a description of the arguments. 167 // \pre leftPoint_exists: leftPoint!=0 168 // \pre midPoint_exists: midPoint!=0 169 // \pre rightPoint_exists: rightPoint!=0 170 // \pre clamped_alpha: alpha>0 && alpha<1 171 // \pre valid_size: sizeof(leftPoint)=sizeof(midPoint)=sizeof(rightPoint) 172 // =GetAttributeCollection()->GetNumberOfPointCenteredComponents()+6 173 virtual void UpdateMaxError(double *leftPoint, double *midPoint, 174 double *rightPoint, double alpha); 175 176 // Description: 177 // Reset the maximal error of each error metric. The purpose of the maximal 178 // error is to measure the quality of a fixed subdivision. 179 void ResetMaxErrors(); 180 181 // Description: 182 // List of error metrics. Collection of vtkGenericSubdivisionErrorMetric 183 vtkCollection *ErrorMetrics; 184 185 // Description: 186 // Send the current cell to error metrics. Should be called at the beginning 187 // of the implementation of Tessellate(), Triangulate() 188 // or TessellateFace() 189 // \pre cell_exists: cell!=0 190 void SetGenericCell(vtkGenericAdaptorCell *cell); 191 192 vtkGenericDataSet *DataSet; 193 194 int Measurement; // if true, measure the quality of the fixed subdivision. 195 double *MaxErrors; // max error for each error metric, for measuring the 196 // quality of a fixed subdivision. 197 int MaxErrorsCapacity; 198 199 private: 200 vtkGenericCellTessellator(const vtkGenericCellTessellator&); // Not implemented. 201 void operator=(const vtkGenericCellTessellator&); // Not implemented. 202 }; 203 204 #endif 205