1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkEdgeTable.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   vtkEdgeTable
17  * @brief   keep track of edges (edge is pair of integer id's)
18  *
19  * vtkEdgeTable is a general object for keeping track of lists of edges. An
20  * edge is defined by the pair of point id's (p1,p2). Methods are available
21  * to insert edges, check if edges exist, and traverse the list of edges.
22  * Also, it's possible to associate attribute information with each edge.
23  * The attribute information may take the form of vtkIdType id's, void*
24  * pointers, or points. To store attributes, make sure that
25  * InitEdgeInsertion() is invoked with the storeAttributes flag set properly.
26  * If points are inserted, use the methods InitPointInsertion() and
27  * InsertUniquePoint().
28  */
29 
30 #ifndef vtkEdgeTable_h
31 #define vtkEdgeTable_h
32 
33 #include "vtkCommonDataModelModule.h" // For export macro
34 #include "vtkObject.h"
35 
36 class vtkIdList;
37 class vtkPoints;
38 class vtkVoidArray;
39 
40 class VTKCOMMONDATAMODEL_EXPORT vtkEdgeTable : public vtkObject
41 {
42 public:
43   /**
44    * Instantiate object assuming that 1000 edges are to be inserted.
45    */
46   static vtkEdgeTable* New();
47 
48   vtkTypeMacro(vtkEdgeTable, vtkObject);
49   void PrintSelf(ostream& os, vtkIndent indent) override;
50 
51   /**
52    * Free memory and return to the initially instantiated state.
53    */
54   void Initialize();
55 
56   /**
57    * Initialize the edge insertion process. Provide an estimate of the number
58    * of points in a dataset (the maximum range value of p1 or p2).  The
59    * storeAttributes variable controls whether attributes are to be stored
60    * with the edge, and what type of attributes. If storeAttributes==1, then
61    * attributes of vtkIdType can be stored. If storeAttributes==2, then
62    * attributes of type void* can be stored. In either case, additional
63    * memory will be required by the data structure to store attribute data
64    * per each edge.  This method is used in conjunction with one of the three
65    * InsertEdge() methods described below (don't mix the InsertEdge()
66    * methods---make sure that the one used is consistent with the
67    * storeAttributes flag set in InitEdgeInsertion()).
68    */
69   int InitEdgeInsertion(vtkIdType numPoints, int storeAttributes = 0);
70 
71   /**
72    * Insert the edge (p1,p2) into the table. It is the user's
73    * responsibility to check if the edge has already been inserted
74    * (use IsEdge()). If the storeAttributes flag in InitEdgeInsertion()
75    * has been set, then the method returns a unique integer id (i.e.,
76    * the edge id) that can be used to set and get edge
77    * attributes. Otherwise, the method will return 1. Do not mix this
78    * method with the InsertEdge() method that follows.
79    */
80   vtkIdType InsertEdge(vtkIdType p1, vtkIdType p2);
81 
82   /**
83    * Insert the edge (p1,p2) into the table with the attribute id
84    * specified (make sure the attributeId >= 0). Note that the
85    * attributeId is ignored if the storeAttributes variable was set to
86    * 0 in the InitEdgeInsertion() method. It is the user's
87    * responsibility to check if the edge has already been inserted
88    * (use IsEdge()). Do not mix this method with the other two
89    * InsertEdge() methods.
90    */
91   void InsertEdge(vtkIdType p1, vtkIdType p2, vtkIdType attributeId);
92 
93   /**
94    * Insert the edge (p1,p2) into the table with the attribute id
95    * specified (make sure the attributeId >= 0). Note that the
96    * attributeId is ignored if the storeAttributes variable was set to
97    * 0 in the InitEdgeInsertion() method. It is the user's
98    * responsibility to check if the edge has already been inserted
99    * (use IsEdge()). Do not mix this method with the other two
100    * InsertEdge() methods.
101    */
102   void InsertEdge(vtkIdType p1, vtkIdType p2, void* ptr);
103 
104   /**
105    * Return an integer id for the edge, or an attribute id of the edge
106    * (p1,p2) if the edge has been previously defined (it depends upon
107    * which version of InsertEdge() is being used); otherwise -1. The
108    * unique integer id can be used to set and retrieve attributes to
109    * the edge.
110    */
111   vtkIdType IsEdge(vtkIdType p1, vtkIdType p2);
112 
113   /**
114    * Similar to above, but returns a void* pointer is InitEdgeInsertion()
115    * has been called with storeAttributes==2. A nullptr pointer value
116    * is returned if the edge does not exist.
117    */
118   void IsEdge(vtkIdType p1, vtkIdType p2, void*& ptr);
119 
120   /**
121    * Initialize the point insertion process. The newPts is an object
122    * representing point coordinates into which incremental insertion methods
123    * place their data. The points are associated with the edge.
124    */
125   int InitPointInsertion(vtkPoints* newPts, vtkIdType estSize);
126 
127   /**
128    * Insert a unique point on the specified edge. Invoke this method only
129    * after InitPointInsertion() has been called. Return 0 if point was
130    * already in the list, otherwise return 1.
131    */
132   int InsertUniquePoint(vtkIdType p1, vtkIdType p2, double x[3], vtkIdType& ptId);
133 
134   ///@{
135   /**
136    * Return the number of edges that have been inserted thus far.
137    */
138   vtkGetMacro(NumberOfEdges, vtkIdType);
139   ///@}
140 
141   /**
142    * Initialize traversal of edges in table.
143    */
144   void InitTraversal();
145 
146   /**
147    * Traverse list of edges in table. Return the edge as (p1,p2), where p1
148    * and p2 are point id's. Method return value is <0 if list is exhausted;
149    * non-zero otherwise. The value of p1 is guaranteed to be <= p2.
150    */
151   vtkIdType GetNextEdge(vtkIdType& p1, vtkIdType& p2);
152 
153   /**
154    * Similar to above, but fills a void* pointer if InitEdgeInsertion()
155    * has been called with storeAttributes==2. A nullptr pointer value
156    * is filled otherwise.  Returns 0 if list is exhausted.
157    */
158   int GetNextEdge(vtkIdType& p1, vtkIdType& p2, void*& ptr);
159 
160   /**
161    * Reset the object and prepare for reinsertion of edges. Does not delete
162    * memory like the Initialize() method.
163    */
164   void Reset();
165 
166 protected:
167   vtkEdgeTable();
168   ~vtkEdgeTable() override;
169 
170   vtkIdList** Table;
171   vtkIdType TableMaxId; // maximum point id inserted
172   vtkIdType TableSize;  // allocated size of table
173   int Position[2];
174   int Extend;
175   vtkIdType NumberOfEdges;
176   vtkPoints* Points; // support point insertion
177 
178   int StoreAttributes;              //==0:no attributes stored;==1:vtkIdType;==2:void*
179   vtkIdList** Attributes;           // used to store IdTypes attributes
180   vtkVoidArray** PointerAttributes; // used to store void* pointers
181 
182   vtkIdList** Resize(vtkIdType size);
183 
184 private:
185   vtkEdgeTable(const vtkEdgeTable&) = delete;
186   void operator=(const vtkEdgeTable&) = delete;
187 };
188 
189 #endif
190