1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkPolyDataNormals.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 vtkPolyDataNormals 17 * @brief compute normals for polygonal mesh 18 * 19 * vtkPolyDataNormals is a filter that computes point and/or cell normals 20 * for a polygonal mesh. The user specifies if they would like the point 21 * and/or cell normals to be computed by setting the ComputeCellNormals 22 * and ComputePointNormals flags. 23 * 24 * The computed normals (a vtkFloatArray) are set to be the active normals 25 * (using SetNormals()) of the PointData and/or the CellData (respectively) 26 * of the output PolyData. The name of these arrays is "Normals", so they 27 * can be retrieved either with 28 * vtkArrayDownCast<vtkFloatArray>(output->GetPointData()->GetNormals()) 29 * or with 30 * vtkArrayDownCast<vtkFloatArray>(output->GetPointData()->GetArray("Normals")) 31 * 32 * The filter can reorder polygons to insure consistent 33 * orientation across polygon neighbors. Sharp edges can be split and points 34 * duplicated with separate normals to give crisp (rendered) surface definition. 35 * It is also possible to globally flip the normal orientation. 36 * 37 * The algorithm works by determining normals for each polygon and then 38 * averaging them at shared points. When sharp edges are present, the edges 39 * are split and new points generated to prevent blurry edges (due to 40 * Gouraud shading). 41 * 42 * @warning 43 * Normals are computed only for polygons and triangle strips. Normals are 44 * not computed for lines or vertices. 45 * 46 * @warning 47 * Triangle strips are broken up into triangle polygons. You may want to 48 * restrip the triangles. 49 * 50 * @sa 51 * For high-performance rendering, you could use vtkTriangleMeshPointNormals 52 * if you know that you have a triangle mesh which does not require splitting 53 * nor consistency check on the cell orientations. 54 * 55 */ 56 57 #ifndef vtkPolyDataNormals_h 58 #define vtkPolyDataNormals_h 59 60 #include "vtkFiltersCoreModule.h" // For export macro 61 #include "vtkPolyDataAlgorithm.h" 62 63 class vtkFloatArray; 64 class vtkIdList; 65 class vtkPolyData; 66 67 class VTKFILTERSCORE_EXPORT vtkPolyDataNormals : public vtkPolyDataAlgorithm 68 { 69 public: 70 vtkTypeMacro(vtkPolyDataNormals,vtkPolyDataAlgorithm); 71 void PrintSelf(ostream& os, vtkIndent indent) override; 72 73 /** 74 * Construct with feature angle=30, splitting and consistency turned on, 75 * flipNormals turned off, and non-manifold traversal turned on. 76 * ComputePointNormals is on and ComputeCellNormals is off. 77 */ 78 static vtkPolyDataNormals *New(); 79 80 //@{ 81 /** 82 * Specify the angle that defines a sharp edge. If the difference in 83 * angle across neighboring polygons is greater than this value, the 84 * shared edge is considered "sharp". 85 */ 86 vtkSetClampMacro(FeatureAngle,double,0.0,180.0); 87 vtkGetMacro(FeatureAngle,double); 88 //@} 89 90 //@{ 91 /** 92 * Turn on/off the splitting of sharp edges. 93 */ 94 vtkSetMacro(Splitting,vtkTypeBool); 95 vtkGetMacro(Splitting,vtkTypeBool); 96 vtkBooleanMacro(Splitting,vtkTypeBool); 97 //@} 98 99 //@{ 100 /** 101 * Turn on/off the enforcement of consistent polygon ordering. 102 */ 103 vtkSetMacro(Consistency,vtkTypeBool); 104 vtkGetMacro(Consistency,vtkTypeBool); 105 vtkBooleanMacro(Consistency,vtkTypeBool); 106 //@} 107 108 //@{ 109 /** 110 * Turn on/off the automatic determination of correct normal 111 * orientation. NOTE: This assumes a completely closed surface 112 * (i.e. no boundary edges) and no non-manifold edges. If these 113 * constraints do not hold, all bets are off. This option adds some 114 * computational complexity, and is useful if you don't want to have 115 * to inspect the rendered image to determine whether to turn on the 116 * FlipNormals flag. However, this flag can work with the FlipNormals 117 * flag, and if both are set, all the normals in the output will 118 * point "inward". 119 */ 120 vtkSetMacro(AutoOrientNormals, vtkTypeBool); 121 vtkGetMacro(AutoOrientNormals, vtkTypeBool); 122 vtkBooleanMacro(AutoOrientNormals, vtkTypeBool); 123 //@} 124 125 //@{ 126 /** 127 * Turn on/off the computation of point normals. 128 */ 129 vtkSetMacro(ComputePointNormals,vtkTypeBool); 130 vtkGetMacro(ComputePointNormals,vtkTypeBool); 131 vtkBooleanMacro(ComputePointNormals,vtkTypeBool); 132 //@} 133 134 //@{ 135 /** 136 * Turn on/off the computation of cell normals. 137 */ 138 vtkSetMacro(ComputeCellNormals,vtkTypeBool); 139 vtkGetMacro(ComputeCellNormals,vtkTypeBool); 140 vtkBooleanMacro(ComputeCellNormals,vtkTypeBool); 141 //@} 142 143 //@{ 144 /** 145 * Turn on/off the global flipping of normal orientation. Flipping 146 * reverves the meaning of front and back for Frontface and Backface 147 * culling in vtkProperty. Flipping modifies both the normal 148 * direction and the order of a cell's points. 149 */ 150 vtkSetMacro(FlipNormals,vtkTypeBool); 151 vtkGetMacro(FlipNormals,vtkTypeBool); 152 vtkBooleanMacro(FlipNormals,vtkTypeBool); 153 //@} 154 155 //@{ 156 /** 157 * Turn on/off traversal across non-manifold edges. This will prevent 158 * problems where the consistency of polygonal ordering is corrupted due 159 * to topological loops. 160 */ 161 vtkSetMacro(NonManifoldTraversal,vtkTypeBool); 162 vtkGetMacro(NonManifoldTraversal,vtkTypeBool); 163 vtkBooleanMacro(NonManifoldTraversal,vtkTypeBool); 164 //@} 165 166 //@{ 167 /** 168 * Set/get the desired precision for the output types. See the documentation 169 * for the vtkAlgorithm::DesiredOutputPrecision enum for an explanation of 170 * the available precision settings. 171 */ 172 vtkSetClampMacro(OutputPointsPrecision, int, SINGLE_PRECISION, DEFAULT_PRECISION); 173 vtkGetMacro(OutputPointsPrecision, int); 174 //@} 175 176 protected: 177 vtkPolyDataNormals(); ~vtkPolyDataNormals()178 ~vtkPolyDataNormals() override {} 179 180 // Usual data generation method 181 int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override; 182 183 double FeatureAngle; 184 vtkTypeBool Splitting; 185 vtkTypeBool Consistency; 186 vtkTypeBool FlipNormals; 187 vtkTypeBool AutoOrientNormals; 188 vtkTypeBool NonManifoldTraversal; 189 vtkTypeBool ComputePointNormals; 190 vtkTypeBool ComputeCellNormals; 191 int NumFlips; 192 int OutputPointsPrecision; 193 194 private: 195 vtkIdList *Wave; 196 vtkIdList *Wave2; 197 vtkIdList *CellIds; 198 vtkIdList *Map; 199 vtkPolyData *OldMesh; 200 vtkPolyData *NewMesh; 201 int *Visited; 202 vtkFloatArray *PolyNormals; 203 double CosAngle; 204 205 // Uses the list of cell ids (this->Wave) to propagate a wave of 206 // checked and properly ordered polygons. 207 void TraverseAndOrder(void); 208 209 // Check the point id give to see whether it lies on a feature 210 // edge. If so, split the point (i.e., duplicate it) to topologically 211 // separate the mesh. 212 void MarkAndSplit(vtkIdType ptId); 213 214 private: 215 vtkPolyDataNormals(const vtkPolyDataNormals&) = delete; 216 void operator=(const vtkPolyDataNormals&) = delete; 217 }; 218 219 #endif 220