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