1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkSimpleCellTessellator.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   vtkSimpleCellTessellator
17  * @brief   helper class to perform cell tessellation
18  *
19  * vtkSimpleCellTessellator is a helper class to perform adaptive tessellation
20  * of particular cell topologies. The major purpose for this class is to
21  * transform higher-order cell types (e.g., higher-order finite elements)
22  * into linear cells that can then be easily visualized by VTK. This class
23  * works in conjunction with the vtkGenericDataSet and vtkGenericAdaptorCell
24  * classes.
25  *
26  * This algorithm is based on edge subdivision. An error metric along each
27  * edge is evaluated, and if the error is greater than some tolerance, the
28  * edge is subdivided (as well as all connected 2D and 3D cells). The process
29  * repeats until the error metric is satisfied. Since the algorithm is based
30  * on edge subdivision it inherently avoid T-junctions.
31  *
32  * A significant issue addressed by this algorithm is to insure face
33  * compatibility across neigboring cells. That is, diagonals due to face
34  * triangulation must match to insure that the mesh is compatible. The
35  * algorithm employs a precomputed table to accelerate the tessellation
36  * process. The table was generated with the help of vtkOrderedTriangulator
37  * the basic idea is that the choice of diagonal is made only by considering the
38  * relative value of the point ids.
39  *
40  * @sa
41  * vtkGenericCellTessellator vtkGenericSubdivisionErrorMetric vtkAttributesErrorMetric
42  * vtkGeometricErrorMetric vtkViewDependentErrorMetric
43 */
44 
45 #ifndef vtkSimpleCellTessellator_h
46 #define vtkSimpleCellTessellator_h
47 
48 #include "vtkCommonDataModelModule.h" // For export macro
49 #include "vtkGenericCellTessellator.h"
50 
51 class vtkTriangleTile;
52 class vtkTetraTile;
53 class vtkCellArray;
54 class vtkDoubleArray;
55 class vtkGenericEdgeTable;
56 class vtkGenericSubdivisionErrorMetric;
57 class vtkGenericAttributeCollection;
58 class vtkGenericAdaptorCell;
59 class vtkGenericCellIterator;
60 class vtkPointData;
61 class vtkOrderedTriangulator;
62 class vtkPolygon;
63 class vtkIdList;
64 
65 //-----------------------------------------------------------------------------
66 //
67 // The tessellation object
68 class VTKCOMMONDATAMODEL_EXPORT vtkSimpleCellTessellator : public vtkGenericCellTessellator
69 {
70 public:
71   static vtkSimpleCellTessellator *New();
72   vtkTypeMacro(vtkSimpleCellTessellator,vtkGenericCellTessellator);
73   void PrintSelf(ostream& os, vtkIndent indent) override;
74 
75   //@{
76   /**
77    * Get the higher order cell in order to access the evaluation function.
78    */
79   vtkGetObjectMacro(GenericCell, vtkGenericAdaptorCell);
80   //@}
81 
82   /**
83    * Tessellate a face of a 3D `cell'. The face is specified by the
84    * index value.
85    * The result is a set of smaller linear triangles in `cellArray' with
86    * `points' and point data `internalPd'.
87    * \pre cell_exists: cell!=0
88    * \pre valid_dimension: cell->GetDimension()==3
89    * \pre valid_index_range: (index>=0) && (index<cell->GetNumberOfBoundaries(2))
90    * \pre att_exists: att!=0
91    * \pre points_exists: points!=0
92    * \pre cellArray_exists: cellArray!=0
93    * \pre internalPd_exists: internalPd!=0
94    */
95   void TessellateFace(vtkGenericAdaptorCell *cell,
96                       vtkGenericAttributeCollection *att,
97                       vtkIdType index,
98                       vtkDoubleArray *points,
99                       vtkCellArray *cellArray,
100                       vtkPointData *internalPd) override;
101 
102   /**
103    * Tessellate a 3D `cell'. The result is a set of smaller linear
104    * tetrahedra in `cellArray' with `points' and point data `internalPd'.
105    * \pre cell_exists: cell!=0
106    * \pre valid_dimension: cell->GetDimension()==3
107    * \pre att_exists: att!=0
108    * \pre points_exists: points!=0
109    * \pre cellArray_exists: cellArray!=0
110    * \pre internalPd_exists: internalPd!=0
111    */
112   void Tessellate(vtkGenericAdaptorCell *cell,
113                   vtkGenericAttributeCollection *att,
114                   vtkDoubleArray *points,
115                   vtkCellArray *cellArray,
116                   vtkPointData *internalPd ) override;
117 
118   /**
119    * Triangulate a 2D `cell'. The result is a set of smaller linear triangles
120    * in `cellArray' with `points' and point data `internalPd'.
121    * \pre cell_exists: cell!=0
122    * \pre valid_dimension: cell->GetDimension()==2
123    * \pre att_exists: att!=0
124    * \pre points_exists: points!=0
125    * \pre cellArray_exists: cellArray!=0
126    * \pre internalPd_exists: internalPd!=0
127    */
128   void Triangulate(vtkGenericAdaptorCell *cell,
129                    vtkGenericAttributeCollection *att,
130                    vtkDoubleArray *points,
131                    vtkCellArray *cellArray,
132                    vtkPointData *internalPd) override;
133 
134   /**
135    * Reset the output for repeated use of this class.
136    */
137   void Reset();
138 
139 
140   /**
141    * Initialize the tessellator with a data set `ds'.
142    */
143   void Initialize(vtkGenericDataSet *ds) override;
144 
145   /**
146    * Return the number of fixed subdivisions. It is used to prevent from
147    * infinite loop in degenerated cases. For order 3 or higher, if the
148    * inflection point is exactly on the mid-point, error metric will not
149    * detect that a subdivision is required. 0 means no fixed subdivision:
150    * there will be only adaptive subdivisions.
151 
152    * The algorithm first performs `GetFixedSubdivisions' non adaptive
153    * subdivisions followed by at most `GetMaxAdaptiveSubdivisions' adaptive
154    * subdivisions. Hence, there are at most `GetMaxSubdivisionLevel'
155    * subdivisions.
156    * \post positive_result: result>=0 && result<=GetMaxSubdivisionLevel()
157    */
158   int GetFixedSubdivisions();
159 
160   /**
161    * Return the maximum level of subdivision. It is used to prevent from
162    * infinite loop in degenerated cases. For order 3 or higher, if the
163    * inflection point is exactly on the mid-point, error metric will not
164    * detect that a subdivision is required. 0 means no subdivision,
165    * neither fixed nor adaptive.
166    * \post positive_result: result>=GetFixedSubdivisions()
167    */
168   int GetMaxSubdivisionLevel();
169 
170   /**
171    * Return the maximum number of adaptive subdivisions.
172    * \post valid_result: result==GetMaxSubdivisionLevel()-GetFixedSubdivisions()
173    */
174   int GetMaxAdaptiveSubdivisions();
175 
176   /**
177    * Set the number of fixed subdivisions. See GetFixedSubdivisions() for
178    * more explanations.
179    * \pre positive_level: level>=0 && level<=GetMaxSubdivisionLevel()
180    * \post is_set: GetFixedSubdivisions()==level
181    */
182   void SetFixedSubdivisions(int level);
183 
184   /**
185    * Set the maximum level of subdivision. See GetMaxSubdivisionLevel() for
186    * more explanations.
187    * \pre positive_level: level>=GetFixedSubdivisions()
188    * \post is_set: level==GetMaxSubdivisionLevel()
189    */
190   void SetMaxSubdivisionLevel(int level);
191 
192   /**
193    * Set both the number of fixed subdivisions and the maximum level of
194    * subdivisions. See GetFixedSubdivisions(), GetMaxSubdivisionLevel() and
195    * GetMaxAdaptiveSubdivisions() for more explanations.
196    * \pre positive_fixed: fixed>=0
197    * \pre valid_range: fixed<=maxLevel
198    * \post fixed_is_set: fixed==GetFixedSubdivisions()
199    * \post maxLevel_is_set: maxLevel==GetMaxSubdivisionLevel()
200    */
201   void SetSubdivisionLevels(int fixed,
202                             int maxLevel);
203 
204 
205 protected:
206   vtkSimpleCellTessellator();
207   ~vtkSimpleCellTessellator() override;
208 
209   /**
210    * Extract point `pointId' from the edge table to the output point and output
211    * point data.
212    */
213   void CopyPoint(vtkIdType pointId);
214 
215   /**
216    * HashTable instead of vtkPointLocator
217    */
218   vtkGenericEdgeTable *EdgeTable;
219 
220   void InsertEdgesIntoEdgeTable( vtkTriangleTile &tri );
221   void RemoveEdgesFromEdgeTable( vtkTriangleTile &tri );
222   void InsertPointsIntoEdgeTable( vtkTriangleTile &tri );
223 
224   void InsertEdgesIntoEdgeTable( vtkTetraTile &tetra );
225   void RemoveEdgesFromEdgeTable( vtkTetraTile &tetra );
226 
227   /**
228    * Initialize `root' with the sub-tetra defined by the `localIds' points on
229    * the complex cell, `ids' are the global ids over the mesh of those points.
230    * The sub-tetra is also defined by the ids of its edges and of its faces
231    * relative to the complex cell. -1 means that the edge or the face of the
232    * sub-tetra is not an original edge or face of the complex cell.
233    * \pre cell_exists: this->GenericCell!=0
234    * \pre localIds_exists: localIds!=0
235    * \pre localIds_size: sizeof(localIds)==4
236    * \pre ids_exists: ids!=0
237    * \pre ids_size: sizeof(ids)==4
238    * \pre edgeIds_exists: edgeIds!=0
239    * \pre edgeIds_size: sizeof(edgeIds)==6
240    * \pre faceIds_exists: faceIds!=0
241    * \pre faceIds_size: sizeof(faceIds)==4
242    */
243   void InitTetraTile(vtkTetraTile &root,
244                      vtkIdType *localIds,
245                      vtkIdType *ids,
246                      int *edgeIds,
247                      int *faceIds);
248 
249   /**
250    * Triangulate a triangle of `cell'. This triangle can be the top-level
251    * triangle if the cell is a triangle or a toplevel sub-triangle is the cell
252    * is a polygon, or a triangular face of a 3D cell or a top-level
253    * sub-triangle of a face of a 3D cell if the face is not a triangle.
254    * Arguments `localIds', `ids' and `edgeIds' have the same meaning than
255    * for InitTetraTile.
256    * \pre cell_exists: cell!=0
257    * \pre localIds_exists: localIds!=0
258    * \pre localIds_size: sizeof(localIds)==3
259    * \pre ids_exists: ids!=0
260    * \pre ids_size: sizeof(ids)==3
261    * \pre edgeIds_exists: edgeIds!=0
262    * \pre edgeIds_size: sizeof(edgeIds)==3
263    */
264   void TriangulateTriangle(vtkGenericAdaptorCell *cell,
265                            vtkIdType *localIds,
266                            vtkIdType *ids,
267                            int *edgeIds,
268                            vtkGenericAttributeCollection *att,
269                            vtkDoubleArray *points,
270                            vtkCellArray *cellArray,
271                            vtkPointData *internalPd);
272 
273   /**
274    * To access the higher order cell from third party library
275    */
276   vtkGenericAdaptorCell *GenericCell;
277 
278   /**
279    * Allocate some memory if Scalars does not exists or is smaller than size.
280    * \pre positive_size: size>0
281    */
282   void AllocateScalars(int size);
283 
284   /**
285    * Scalar buffer used to save the interpolate values of the attributes
286    * The capacity is at least the number of components of the attribute
287    * collection ot the current cell.
288    */
289 
290   // Scalar buffer that stores the global coordinates, parametric coordinates,
291   // attributes at left, mid and right point. The format is:
292   // lxlylz lrlslt [lalb lcldle...] mxmymz mrmsmt [mamb mcmdme...]
293   // rxryrz rrrsrt [rarb rcrdre...]
294   // The ScalarsCapacity>=(6+attributeCollection->GetNumberOfComponents())*3
295 
296   double *Scalars;
297   int ScalarsCapacity;
298 
299   /**
300    * Number of double value to skip to go to the next point into Scalars array
301    * It is 6+attributeCollection->GetNumberOfComponents()
302    */
303   int PointOffset;
304 
305   /**
306    * Used to iterate over edges boundaries in GetNumberOfCellsUsingEdges()
307    */
308   vtkGenericCellIterator    *CellIterator;
309 
310   /**
311    * To access the higher order field from third party library
312    */
313   vtkGenericAttributeCollection *AttributeCollection;
314 
315   //@{
316   /**
317    * To avoid New/Delete
318    */
319   vtkDoubleArray     *TessellatePoints;  //Allow to use GetPointer
320   vtkCellArray       *TessellateCellArray;
321   vtkPointData *TessellatePointData;
322   //@}
323 
324   int FindEdgeReferenceCount(double p1[3], double p2[3],
325                              vtkIdType &e1, vtkIdType &e2);
326 
327   int GetNumberOfCellsUsingFace( int faceId );
328   int GetNumberOfCellsUsingEdge( int edgeId );
329 
330   /**
331    * Is the edge defined by vertices (`p1',`p2') in parametric coordinates on
332    * some edge of the original tetrahedron? If yes return on which edge it is,
333    * else return -1.
334    * \pre p1!=p2
335    * \pre p1 and p2 are in bounding box (0,0,0) (1,1,1)
336    * \post valid_result: (result==-1) || ( result>=0 && result<=5 )
337    */
338   int IsEdgeOnFace(double p1[3], double p2[3]);
339 
340   /**
341    * Return 1 if the parent of edge defined by vertices (`p1',`p2') in
342    * parametric coordinates, is an edge; 3 if there is no parent (the edge is
343    * inside). If the parent is an edge, return its id in `localId'.
344    * \pre p1!=p2
345    * \pre p1 and p2 are in bounding box (0,0,0) (1,1,1)
346    * \post valid_result: (result==1)||(result==3)
347    */
348   int FindEdgeParent2D(double p1[3], double p2[3], int &localId);
349 
350   /**
351    * Return 1 if the parent of edge defined by vertices (`p1',`p2') in
352    * parametric coordinates, is an edge; 2 if the parent is a face, 3 if there
353    * is no parent (the edge is inside). If the parent is an edge or a face,
354    * return its id in `localId'.
355    * \pre p1!=p2
356    * \pre p1 and p2 are in bounding box (0,0,0) (1,1,1)
357    * \post valid_result: result>=1 && result<=3
358    */
359   int FindEdgeParent(double p1[3], double p2[3], int &localId);
360 
361   /**
362    * Allocate some memory if PointIds does not exist or is smaller than size.
363    * \pre positive_size: size>0
364    */
365   void AllocatePointIds(int size);
366 
367   /**
368    * Are the faces `originalFace' and `face' equal?
369    * The result is independent from any order or orientation.
370    * \pre originalFace_exists: originalFace!=0
371    */
372   int FacesAreEqual(int *originalFace,
373                     int face[3]);
374 
375   /**
376    * Number of points in the dataset to be tessellated.
377    */
378   vtkIdType NumberOfPoints;
379 
380   int FixedSubdivisions;
381   int MaxSubdivisionLevel;
382   int CurrentSubdivisionLevel;
383 
384   /**
385    * For each edge (6) of the sub-tetra, there is the id of the original edge
386    * or -1 if the edge is not an original edge
387    */
388   int *EdgeIds;
389   /**
390    * For each face (4) of the sub-tetra, there is the id of the original face
391    * or -1 if the face is not an original face
392    */
393   int *FaceIds;
394 
395   // The following variables are for complex cells.
396 
397   // Used to create tetra from more complex cells, because the tessellator
398   // is supposed to deal with simplices only.
399   vtkOrderedTriangulator *Triangulator;
400 
401   // Used to store the sub-tetra during the tessellation of complex
402   // cells.
403   vtkCellArray *Connectivity;
404 
405   // Used to create triangles from a face of a complex cell.
406   vtkPolygon *Polygon;
407 
408   // Used to store the sub-triangles during the tessellation of complex cells.
409   vtkIdList *TriangleIds;
410 
411   vtkIdType *PointIds;
412   int PointIdsCapacity;
413 
414 private:
415   vtkSimpleCellTessellator(const vtkSimpleCellTessellator&) = delete;
416   void operator=(const vtkSimpleCellTessellator&) = delete;
417 
418   friend class vtkTetraTile;
419   friend class vtkTriangleTile;
420 
421 };
422 
423 #endif
424