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 ensure 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(); 178 ~vtkPolyDataNormals() override = default; 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* CellPoints; 199 vtkIdList* NeighborPoints; 200 vtkIdList* Map; 201 vtkPolyData* OldMesh; 202 vtkPolyData* NewMesh; 203 int* Visited; 204 vtkFloatArray* PolyNormals; 205 double CosAngle; 206 207 // Uses the list of cell ids (this->Wave) to propagate a wave of 208 // checked and properly ordered polygons. 209 void TraverseAndOrder(void); 210 211 // Check the point id give to see whether it lies on a feature 212 // edge. If so, split the point (i.e., duplicate it) to topologically 213 // separate the mesh. 214 void MarkAndSplit(vtkIdType ptId); 215 216 private: 217 vtkPolyDataNormals(const vtkPolyDataNormals&) = delete; 218 void operator=(const vtkPolyDataNormals&) = delete; 219 }; 220 221 #endif 222